summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llvfs/lldir.cpp13
-rw-r--r--indra/llvfs/lldir.h2
-rwxr-xr-xindra/newview/app_settings/settings.xml4
-rw-r--r--indra/newview/llconversationlog.cpp60
-rw-r--r--indra/newview/llconversationlog.h11
-rw-r--r--indra/newview/llfloaterconversationlog.cpp14
-rw-r--r--indra/newview/llfloaterconversationlog.h2
-rw-r--r--indra/newview/llfloaterimcontainer.cpp6
-rw-r--r--indra/newview/llfloaterimnearbychat.cpp27
-rw-r--r--indra/newview/llfloaterimnearbychat.h2
-rw-r--r--indra/newview/llfloaterimsession.cpp12
-rw-r--r--indra/newview/llfloaterimsession.h2
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp6
-rw-r--r--indra/newview/llfloaterimsessiontab.h2
-rwxr-xr-xindra/newview/llfloaterpreference.cpp109
-rw-r--r--indra/newview/llfloaterpreference.h19
-rw-r--r--indra/newview/llimview.cpp37
-rw-r--r--indra/newview/llimview.h2
-rw-r--r--indra/newview/lllogchat.cpp235
-rw-r--r--indra/newview/lllogchat.h15
-rwxr-xr-xindra/newview/llviewermessage.cpp2
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml26
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_chat.xml284
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_privacy.xml226
24 files changed, 641 insertions, 477 deletions
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index 5e5aeefba1..f7bc19574a 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -90,7 +90,8 @@ LLDir::LLDir()
mCAFile(""),
mTempDir(""),
mDirDelimiter("/"), // fallback to forward slash if not overridden
- mLanguage("en")
+ mLanguage("en"),
+ mUserName("undefined")
{
}
@@ -814,6 +815,11 @@ void LLDir::setChatLogsDir(const std::string &path)
}
}
+void LLDir::updatePerAccountChatLogsDir()
+{
+ mPerAccountChatLogsDir = add(getChatLogsDir(), mUserName);
+}
+
void LLDir::setPerAccountChatLogsDir(const std::string &username)
{
// if both first and last aren't set, assume we're grabbing the cached dir
@@ -824,13 +830,14 @@ void LLDir::setPerAccountChatLogsDir(const std::string &username)
std::string userlower(username);
LLStringUtil::toLower(userlower);
LLStringUtil::replaceChar(userlower, ' ', '_');
- mPerAccountChatLogsDir = add(getChatLogsDir(), userlower);
+
+ mUserName = userlower;
+ updatePerAccountChatLogsDir();
}
else
{
llerrs << "NULL name for LLDir::setPerAccountChatLogsDir" << llendl;
}
-
}
void LLDir::setSkinFolder(const std::string &skin_folder, const std::string& language)
diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h
index 300ff1eef6..95cab65149 100644
--- a/indra/llvfs/lldir.h
+++ b/indra/llvfs/lldir.h
@@ -186,6 +186,7 @@ class LLDir
virtual std::string getSkinFolder() const;
virtual std::string getLanguage() const;
virtual bool setCacheDir(const std::string &path);
+ virtual void updatePerAccountChatLogsDir();
virtual void dumpCurrentDirectories();
@@ -243,6 +244,7 @@ protected:
std::vector<std::string> mSearchSkinDirs;
std::string mLanguage; // Current viewer language
std::string mLLPluginDir; // Location for plugins and plugin shell
+ std::string mUserName; // Current user name
};
void dir_exists_or_crash(const std::string &dir_name);
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index fd4d1df894..dd9a0100c0 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4674,9 +4674,9 @@
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Boolean</string>
+ <string>S32</string>
<key>Value</key>
- <integer>1</integer>
+ <integer>2</integer>
</map>
<key>LandBrushSize</key>
<map>
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index ff1f819d7d..8de041f983 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -28,13 +28,14 @@
#include "llagent.h"
#include "llavatarnamecache.h"
#include "llconversationlog.h"
+#include "llnotificationsutil.h"
#include "lltrans.h"
const int CONVERSATION_LIFETIME = 30; // lifetime of LLConversation is 30 days by spec
-struct Conversation_params
+struct ConversationParams
{
- Conversation_params(time_t time)
+ ConversationParams(time_t time)
: mTime(time),
mTimestamp(LLConversation::createTimestamp(time))
{}
@@ -53,7 +54,7 @@ struct Conversation_params
/* LLConversation implementation */
/************************************************************************/
-LLConversation::LLConversation(const Conversation_params& params)
+LLConversation::LLConversation(const ConversationParams& params)
: mTime(params.mTime),
mTimestamp(params.mTimestamp),
mConversationType(params.mConversationType),
@@ -188,33 +189,24 @@ void LLConversationLogFriendObserver::changed(U32 mask)
LLConversationLog::LLConversationLog() :
mAvatarNameCacheConnection()
{
- LLControlVariable* log_instant_message = gSavedPerAccountSettings.getControl("LogInstantMessages").get();
- LLControlVariable* keep_convers_log = gSavedSettings.getControl("KeepConversationLogTranscripts").get();
- bool is_log_message = false;
- bool is_keep_log = false;
+ LLControlVariable * keep_log_ctrlp = gSavedSettings.getControl("KeepConversationLogTranscripts").get();
+ S32 log_mode = keep_log_ctrlp->getValue();
- if (log_instant_message)
+ if (log_mode > 0)
{
- log_instant_message->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
- is_log_message = log_instant_message->getValue().asBoolean();
+ keep_log_ctrlp->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
+ enableLogging(log_mode);
}
- if (keep_convers_log)
- {
- keep_convers_log->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
- is_keep_log = keep_convers_log->getValue().asBoolean();
- }
-
- enableLogging(is_log_message && is_keep_log);
}
-void LLConversationLog::enableLogging(bool enable)
+void LLConversationLog::enableLogging(S32 log_mode)
{
- if (enable)
+ if (log_mode > 0)
{
loadFromFile(getFileName());
LLIMMgr::instance().addSessionObserver(this);
- newMessageSignalConnection = LLIMModel::instance().addNewMsgCallback(boost::bind(&LLConversationLog::onNewMessageReceived, this, _1));
+ mNewMessageSignalConnection = LLIMModel::instance().addNewMsgCallback(boost::bind(&LLConversationLog::onNewMessageReceived, this, _1));
mFriendObserver = new LLConversationLogFriendObserver;
LLAvatarTracker::instance().addObserver(mFriendObserver);
@@ -224,7 +216,7 @@ void LLConversationLog::enableLogging(bool enable)
saveToFile(getFileName());
LLIMMgr::instance().removeSessionObserver(this);
- newMessageSignalConnection.disconnect();
+ mNewMessageSignalConnection.disconnect();
LLAvatarTracker::instance().removeObserver(mFriendObserver);
mConversations.clear();
}
@@ -377,7 +369,7 @@ void LLConversationLog::sessionAdded(const LLUUID& session_id, const std::string
void LLConversationLog::cache()
{
- if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
+ if (gSavedSettings.getS32("KeepConversationLogTranscripts") > 0)
{
saveToFile(getFileName());
}
@@ -450,9 +442,9 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
char part_id_buffer[MAX_STRING];
char conv_id_buffer[MAX_STRING];
char history_file_name[MAX_STRING];
- int has_offline_ims;
- int stype;
- time_t time;
+ S32 has_offline_ims;
+ S32 stype;
+ S64 time;
// before CHUI-348 it was a flag of conversation voice state
int prereserved_unused;
@@ -462,7 +454,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
part_id_buffer[0] = '\0';
conv_id_buffer[0] = '\0';
- sscanf(buffer, "[%ld] %d %d %d %[^|]| %s %s %[^|]|",
+ sscanf(buffer, "[%lld] %d %d %d %[^|]| %s %s %[^|]|",
&time,
&stype,
&prereserved_unused,
@@ -472,7 +464,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
conv_id_buffer,
history_file_name);
- Conversation_params params(time);
+ ConversationParams params((time_t)time);
params.mConversationType = (SessionType)stype;
params.mHasOfflineIMs = has_offline_ims;
params.mConversationName = std::string(conv_name_buffer);
@@ -530,3 +522,17 @@ void LLConversationLog::onAvatarNameCache(const LLUUID& participant_id, const LL
mAvatarNameCacheConnection.disconnect();
updateConversationName(session, av_name.getCompleteName());
}
+
+void LLConversationLog::onClearLog()
+{
+ LLNotificationsUtil::add("PreferenceChatClearLog", LLSD(), LLSD(), boost::bind(&LLConversationLog::onClearLogResponse, this, _1, _2));
+}
+
+void LLConversationLog::onClearLogResponse(const LLSD& notification, const LLSD& response)
+{
+ if (0 == LLNotificationsUtil::getSelectedOption(notification, response))
+ {
+ mConversations.clear();
+ notifyObservers();
+ }
+}
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 35462ec3a4..65a18c02e5 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -31,7 +31,7 @@
#include "llimview.h"
class LLConversationLogObserver;
-struct Conversation_params;
+struct ConversationParams;
typedef LLIMModel::LLIMSession::SType SessionType;
@@ -43,7 +43,7 @@ class LLConversation
{
public:
- LLConversation(const Conversation_params& params);
+ LLConversation(const ConversationParams& params);
LLConversation(const LLIMModel::LLIMSession& session);
LLConversation(const LLConversation& conversation);
@@ -138,6 +138,9 @@ public:
*/
void cache();
+ void onClearLog();
+ void onClearLogResponse(const LLSD& notification, const LLSD& response);
+
private:
LLConversationLog();
@@ -149,7 +152,7 @@ private:
}
}
- void enableLogging(bool enable);
+ void enableLogging(S32 log_mode);
/**
* adds conversation to the conversation list and notifies observers
@@ -182,7 +185,7 @@ private:
LLFriendObserver* mFriendObserver; // Observer of the LLAvatarTracker instance
- boost::signals2::connection newMessageSignalConnection;
+ boost::signals2::connection mNewMessageSignalConnection;
boost::signals2::connection mAvatarNameCacheConnection;
};
diff --git a/indra/newview/llfloaterconversationlog.cpp b/indra/newview/llfloaterconversationlog.cpp
index a40a000bab..a44ebcf6ab 100644
--- a/indra/newview/llfloaterconversationlog.cpp
+++ b/indra/newview/llfloaterconversationlog.cpp
@@ -63,13 +63,9 @@ BOOL LLFloaterConversationLog::postBuild()
getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterConversationLog::onFilterEdit, this, _2));
- LLControlVariable* ctrl = gSavedPerAccountSettings.getControl("LogInstantMessages").get();
- if (ctrl)
- {
- ctrl->getSignal()->connect(boost::bind(&LLFloaterConversationLog::onCallLoggingEnabledDisabled, this, _2));
- onCallLoggingEnabledDisabled(ctrl->getValue().asBoolean()
- && gSavedSettings.getBOOL("KeepConversationLogTranscripts"));
- }
+ LLControlVariable * keep_log_ctrlp = gSavedSettings.getControl("KeepConversationLogTranscripts").get();
+ keep_log_ctrlp->getSignal()->connect(boost::bind(&LLFloaterConversationLog::onCallLoggingEnabledDisabled, this, _2));
+ onCallLoggingEnabledDisabled(keep_log_ctrlp->getValue());
return LLFloater::postBuild();
}
@@ -139,8 +135,8 @@ bool LLFloaterConversationLog::isActionChecked(const LLSD& userdata)
return false;
}
-void LLFloaterConversationLog::onCallLoggingEnabledDisabled(bool enabled)
+void LLFloaterConversationLog::onCallLoggingEnabledDisabled(S32 log_mode)
{
- std::string no_items_msg = enabled ? "" : getString("logging_calls_disabled");
+ std::string no_items_msg = log_mode > 0 ? "" : getString("logging_calls_disabled");
mConversationLogList->setNoItemsCommentText(no_items_msg);
}
diff --git a/indra/newview/llfloaterconversationlog.h b/indra/newview/llfloaterconversationlog.h
index 9e79cbd7d8..aa0f480aae 100644
--- a/indra/newview/llfloaterconversationlog.h
+++ b/indra/newview/llfloaterconversationlog.h
@@ -49,7 +49,7 @@ private:
bool isActionEnabled(const LLSD& userdata);
bool isActionChecked(const LLSD& userdata);
- void onCallLoggingEnabledDisabled(bool enabled);
+ void onCallLoggingEnabledDisabled(S32 log_mode);
LLConversationLogList* mConversationLogList;
};
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index c272e5e391..54e5085490 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -224,7 +224,7 @@ BOOL LLFloaterIMContainer::postBuild()
collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed"));
collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed"));
- LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate));
+ LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false));
mMicroChangedSignal = LLVoiceClient::getInstance()->MicroChangedCallback(boost::bind(&LLFloaterIMContainer::updateSpeakBtnState, this));
if (! mMessagesPane->isCollapsed())
{
@@ -1142,7 +1142,7 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
if ("conversation_log" == item)
{
- return gSavedSettings.getBOOL("KeepConversationLogTranscripts");
+ return gSavedSettings.getS32("KeepConversationLogTranscripts") > 0;
}
//Enable Chat history item for ad-hoc and group conversations
@@ -1793,7 +1793,7 @@ void LLFloaterIMContainer::updateSpeakBtnState()
bool LLFloaterIMContainer::isConversationLoggingAllowed()
{
- return gSavedSettings.getBOOL("KeepConversationLogTranscripts");
+ return gSavedSettings.getS32("KeepConversationLogTranscripts") > 0;
}
void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, bool is_flashes)
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 797d590e1f..17d2341b3c 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -148,8 +148,14 @@ void LLFloaterIMNearbyChat::refresh()
}
}
-void LLFloaterIMNearbyChat::reloadMessages()
+void LLFloaterIMNearbyChat::reloadMessages(bool clean_messages/* = false*/)
{
+ if (clean_messages)
+ {
+ mMessageArchive.clear();
+ loadHistory();
+ }
+
mChatHistory->clear();
LLSD do_not_log;
@@ -174,11 +180,11 @@ void LLFloaterIMNearbyChat::loadHistory()
{
const LLSD& msg = *it;
- std::string from = msg[IM_FROM];
+ std::string from = msg[LL_IM_FROM];
LLUUID from_id;
- if (msg[IM_FROM_ID].isDefined())
+ if (msg[LL_IM_FROM_ID].isDefined())
{
- from_id = msg[IM_FROM_ID].asUUID();
+ from_id = msg[LL_IM_FROM_ID].asUUID();
}
else
{
@@ -189,8 +195,8 @@ void LLFloaterIMNearbyChat::loadHistory()
LLChat chat;
chat.mFromName = from;
chat.mFromID = from_id;
- chat.mText = msg[IM_TEXT].asString();
- chat.mTimeStr = msg[IM_TIME].asString();
+ chat.mText = msg[LL_IM_TEXT].asString();
+ chat.mTimeStr = msg[LL_IM_TIME].asString();
chat.mChatStyle = CHAT_STYLE_HISTORY;
chat.mSourceType = CHAT_SOURCE_AGENT;
@@ -519,20 +525,21 @@ void LLFloaterIMNearbyChat::sendChat( EChatType type )
}
}
-void LLFloaterIMNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
+void LLFloaterIMNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
{
appendMessage(chat, args);
if(archive)
{
mMessageArchive.push_back(chat);
- if(mMessageArchive.size()>200)
+ if(mMessageArchive.size() > 200)
+ {
mMessageArchive.erase(mMessageArchive.begin());
+ }
}
// logging
- if (!args["do_not_log"].asBoolean()
- && gSavedPerAccountSettings.getBOOL("LogNearbyChat"))
+ if (!args["do_not_log"].asBoolean() && gSavedSettings.getS32("KeepConversationLogTranscripts") > 1)
{
std::string from_name = chat.mFromName;
diff --git a/indra/newview/llfloaterimnearbychat.h b/indra/newview/llfloaterimnearbychat.h
index f4213eda5a..14c7d01ecd 100644
--- a/indra/newview/llfloaterimnearbychat.h
+++ b/indra/newview/llfloaterimnearbychat.h
@@ -56,7 +56,7 @@ public:
/*virtual*/ void setVisible(BOOL visible);
void loadHistory();
- void reloadMessages();
+ void reloadMessages(bool clean_messages = false);
void removeScreenChat();
void show();
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index a09dc1914f..07f5515582 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -853,8 +853,18 @@ void LLFloaterIMSession::updateMessages()
}
}
-void LLFloaterIMSession::reloadMessages()
+void LLFloaterIMSession::reloadMessages(bool clean_messages/* = false*/)
{
+ if (clean_messages)
+ {
+ LLIMModel::LLIMSession * sessionp = LLIMModel::instance().findIMSession(mSessionID);
+
+ if (NULL != sessionp)
+ {
+ sessionp->loadHistory();
+ }
+ }
+
mChatHistory->clear();
mLastMessageIndex = -1;
updateMessages();
diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h
index 2049cedfd7..e7fd6f9ff3 100644
--- a/indra/newview/llfloaterimsession.h
+++ b/indra/newview/llfloaterimsession.h
@@ -86,7 +86,7 @@ public:
// get new messages from LLIMModel
/*virtual*/ void updateMessages();
- void reloadMessages();
+ void reloadMessages(bool clean_messages = false);
static void onSendMsg(LLUICtrl*, void*);
void sendMsgFromInputEditor();
void sendMsg(const std::string& msg);
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 37404ab716..f7c6f19450 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -680,7 +680,7 @@ void LLFloaterIMSessionTab::showTranslationCheckbox(BOOL show)
}
// static
-void LLFloaterIMSessionTab::processChatHistoryStyleUpdate()
+void LLFloaterIMSessionTab::processChatHistoryStyleUpdate(bool clean_messages/* = false*/)
{
LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
@@ -689,14 +689,14 @@ void LLFloaterIMSessionTab::processChatHistoryStyleUpdate()
LLFloaterIMSession* floater = dynamic_cast<LLFloaterIMSession*>(*iter);
if (floater)
{
- floater->reloadMessages();
+ floater->reloadMessages(clean_messages);
}
}
LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
if (nearby_chat)
{
- nearby_chat->reloadMessages();
+ nearby_chat->reloadMessages(clean_messages);
}
}
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index beaffc14a6..e90fcbb806 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -53,7 +53,7 @@ public:
~LLFloaterIMSessionTab();
// reload all message with new settings of visual modes
- static void processChatHistoryStyleUpdate();
+ static void processChatHistoryStyleUpdate(bool clean_messages = false);
/**
* Returns true if chat is displayed in multi tabbed floater
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 3d4a1c44d8..7742e5b3c3 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -306,7 +306,8 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mAvatarDataInitialized(false),
mClickActionDirty(false)
{
-
+ LLConversationLog::instance().addObserver(this);
+
//Build Floater is now Called from LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
static bool registered_dialog = false;
@@ -329,8 +330,6 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.VoiceSetKey", boost::bind(&LLFloaterPreference::onClickSetKey, this));
mCommitCallbackRegistrar.add("Pref.VoiceSetMiddleMouse", boost::bind(&LLFloaterPreference::onClickSetMiddleMouse, this));
mCommitCallbackRegistrar.add("Pref.SetSounds", boost::bind(&LLFloaterPreference::onClickSetSounds, this));
-// mCommitCallbackRegistrar.add("Pref.ClickSkipDialogs", boost::bind(&LLFloaterPreference::onClickSkipDialogs, this));
-// mCommitCallbackRegistrar.add("Pref.ClickResetDialogs", boost::bind(&LLFloaterPreference::onClickResetDialogs, this));
mCommitCallbackRegistrar.add("Pref.ClickEnablePopup", boost::bind(&LLFloaterPreference::onClickEnablePopup, this));
mCommitCallbackRegistrar.add("Pref.ClickDisablePopup", boost::bind(&LLFloaterPreference::onClickDisablePopup, this));
mCommitCallbackRegistrar.add("Pref.LogPath", boost::bind(&LLFloaterPreference::onClickLogPath, this));
@@ -351,13 +350,16 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
sSkin = gSavedSettings.getString("SkinCurrent");
- mCommitCallbackRegistrar.add("Pref.ClickActionChange", boost::bind(&LLFloaterPreference::onClickActionChange, this));
+ mCommitCallbackRegistrar.add("Pref.ClickActionChange", boost::bind(&LLFloaterPreference::onClickActionChange, this));
gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2));
gSavedSettings.getControl("NameTagShowFriends")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged, _2));
gSavedSettings.getControl("UseDisplayNames")->getCommitSignal()->connect(boost::bind(&handleDisplayNamesOptionChanged, _2));
LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );
+
+ mCommitCallbackRegistrar.add("Pref.ClearLog", boost::bind(&LLConversationLog::onClearLog, &LLConversationLog::instance()));
+ mCommitCallbackRegistrar.add("Pref.DeleteTranscripts", boost::bind(&LLFloaterPreference::onDeleteTranscripts, this));
}
void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType type )
@@ -425,7 +427,7 @@ void LLFloaterPreference::saveAvatarProperties( void )
BOOL LLFloaterPreference::postBuild()
{
- gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate));
+ gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false));
gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLViewerChat::signalChatFontChanged));
@@ -455,9 +457,24 @@ BOOL LLFloaterPreference::postBuild()
gSavedPerAccountSettings.setString("DoNotDisturbModeResponse", LLTrans::getString("DoNotDisturbModeResponseDefault"));
}
+ // set 'enable' property for 'Clear log...' button
+ changed();
+
+ // set 'enable' property for 'Delete transcripts...' button
+ updateDeleteTranscriptsButton();
+
+ LLLogChat::setSaveHistorySignal(boost::bind(&LLFloaterPreference::onLogChatHistorySaved, this));
+
return TRUE;
}
+void LLFloaterPreference::updateDeleteTranscriptsButton()
+{
+ std::vector<std::string> list_of_transcriptions_file_names;
+ LLLogChat::getListOfTranscriptFiles(list_of_transcriptions_file_names);
+ getChild<LLButton>("delete_transcripts")->setEnabled(list_of_transcriptions_file_names.size() > 0);
+}
+
void LLFloaterPreference::onDoNotDisturbResponseChanged()
{
// set "DoNotDisturbResponseChanged" TRUE if user edited message differs from default, FALSE otherwise
@@ -476,6 +493,8 @@ LLFloaterPreference::~LLFloaterPreference()
{
ctrl_window_size->setCurrentByIndex(i);
}
+
+ LLConversationLog::instance().removeObserver(this);
}
void LLFloaterPreference::draw()
@@ -833,12 +852,12 @@ void LLFloaterPreference::onBtnCancel()
}
// static
-void LLFloaterPreference::updateUserInfo(const std::string& visibility, bool im_via_email, const std::string& email)
+void LLFloaterPreference::updateUserInfo(const std::string& visibility, bool im_via_email)
{
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
if (instance)
{
- instance->setPersonalInfo(visibility, im_via_email, email);
+ instance->setPersonalInfo(visibility, im_via_email);
}
}
@@ -1425,10 +1444,21 @@ void LLFloaterPreference::onClickLogPath()
return; //Canceled!
}
- gSavedPerAccountSettings.setString("InstantMessageLogPath", picker.getDirName());
+ std::string dir_name = picker.getDirName();
+ gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name);
+
+ gDirUtilp->setChatLogsDir(dir_name);
+ gDirUtilp->updatePerAccountChatLogsDir();
+ LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir());
+
+ // refresh IM floaters with new logs from files from new selected directory
+ LLFloaterIMSessionTab::processChatHistoryStyleUpdate(true);
+
+ // enable/disable 'Delete transcripts button
+ updateDeleteTranscriptsButton();
}
-void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im_via_email, const std::string& email)
+void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im_via_email)
{
mGotPersonalInfo = true;
mOriginalIMViaEmail = im_via_email;
@@ -1450,32 +1480,14 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im
}
getChild<LLUICtrl>("online_searchresults")->setEnabled(TRUE);
-
- getChildView("include_im_in_chat_history")->setEnabled(TRUE);
- getChildView("show_timestamps_check_im")->setEnabled(TRUE);
getChildView("friends_online_notify_checkbox")->setEnabled(TRUE);
-
getChild<LLUICtrl>("online_visibility")->setValue(mOriginalHideOnlineStatus);
getChild<LLUICtrl>("online_visibility")->setLabelArg("[DIR_VIS]", mDirectoryVisibility);
getChildView("send_im_to_email")->setEnabled(TRUE);
getChild<LLUICtrl>("send_im_to_email")->setValue(im_via_email);
- getChildView("log_instant_messages")->setEnabled(TRUE);
-// getChildView("log_chat")->setEnabled(TRUE);
-// getChildView("log_instant_messages_timestamp")->setEnabled(TRUE);
-// getChildView("log_chat_timestamp")->setEnabled(TRUE);
- getChildView("log_chat_IM")->setEnabled(TRUE);
- getChildView("log_date_timestamp")->setEnabled(TRUE);
-
getChildView("favorites_on_login_check")->setEnabled(TRUE);
- getChildView("log_nearby_chat")->setEnabled(TRUE);
- getChildView("log_instant_messages")->setEnabled(TRUE);
- getChildView("show_timestamps_check_im")->setEnabled(TRUE);
getChildView("log_path_string")->setEnabled(FALSE);// LineEditor becomes readonly in this case.
getChildView("log_path_button")->setEnabled(TRUE);
- childEnable("logfile_name_datestamp");
- std::string display_email(email);
- getChild<LLUICtrl>("email_address")->setValue(display_email);
-
}
void LLFloaterPreference::onUpdateSliderText(LLUICtrl* ctrl, const LLSD& name)
@@ -1566,6 +1578,35 @@ void LLFloaterPreference::onClickActionChange()
mClickActionDirty = true;
}
+void LLFloaterPreference::onDeleteTranscripts()
+{
+ LLNotificationsUtil::add("PreferenceChatDeleteTranscripts", LLSD(), LLSD(), boost::bind(&LLFloaterPreference::onDeleteTranscriptsResponse, this, _1, _2));
+}
+
+void LLFloaterPreference::onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response)
+{
+ if (0 == LLNotificationsUtil::getSelectedOption(notification, response))
+ {
+ gDirUtilp->deleteFilesInDir(gDirUtilp->getPerAccountChatLogsDir(), "*." + LL_TRANSCRIPT_FILE_EXTENSION);
+
+ std::vector<std::string> list_of_transcriptions_file_names;
+ LLLogChat::getListOfTranscriptFiles(list_of_transcriptions_file_names);
+ getChild<LLButton>("delete_transcripts")->setEnabled(list_of_transcriptions_file_names.size() > 0);
+
+ LLFloaterIMSessionTab::processChatHistoryStyleUpdate(true);
+ }
+}
+
+void LLFloaterPreference::onLogChatHistorySaved()
+{
+ LLButton * delete_transcripts_buttonp = getChild<LLButton>("delete_transcripts");
+
+ if (!delete_transcripts_buttonp->getEnabled())
+ {
+ delete_transcripts_buttonp->setEnabled(true);
+ }
+}
+
void LLFloaterPreference::updateClickActionSettings()
{
const int single_clk_action = getChild<LLComboBox>("single_click_action_combo")->getValue().asInteger();
@@ -1624,6 +1665,11 @@ void LLFloaterPreference::selectChatPanel()
selectPanel("chat");
}
+void LLFloaterPreference::changed()
+{
+ getChild<LLButton>("clear_log")->setEnabled(LLConversationLog::instance().getConversations().size() > 0);
+}
+
//------------------------------Updater---------------------------------------
static bool handleBandwidthChanged(const LLSD& newvalue)
@@ -1717,11 +1763,6 @@ BOOL LLPanelPreference::postBuild()
}
- if (hasChild("online_visibility") && hasChild("send_im_to_email"))
- {
- getChild<LLUICtrl>("email_address")->setValue(getString("log_in_to_change") );
- }
-
//////////////////////PanelPrivacy ///////////////////
if (hasChild("media_enabled"))
{
@@ -1898,7 +1939,7 @@ public:
for (control_values_map_t::iterator it = mSavedValues.begin(); it != mSavedValues.end(); )
{
const std::string setting = it->first->getName();
- if (std::find(mAccountIndependentSettings.begin(),
+ if (find(mAccountIndependentSettings.begin(),
mAccountIndependentSettings.end(), setting) == mAccountIndependentSettings.end())
{
mSavedValues.erase(it++);
@@ -2187,4 +2228,4 @@ void LLFloaterPreferenceProxy::onChangeSocksSettings()
otherHttpProxy->selectFirstItem();
}
-};
+}
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 37a531e99e..f9f1d52244 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -35,7 +35,9 @@
#include "llfloater.h"
#include "llavatarpropertiesprocessor.h"
+#include "llconversationlog.h"
+class LLConversationLogObserver;
class LLPanelPreference;
class LLPanelLCD;
class LLPanelDebug;
@@ -58,7 +60,7 @@ typedef enum
// Floater to control preferences (display, audio, bandwidth, general.
-class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver
+class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver, public LLConversationLogObserver
{
public:
LLFloaterPreference(const LLSD& key);
@@ -70,9 +72,11 @@ public:
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void onClose(bool app_quitting);
+ /*virtual*/ void changed();
+ /*virtual*/ void changed(const LLUUID& session_id, U32 mask) {};
// static data update, called from message handler
- static void updateUserInfo(const std::string& visibility, bool im_via_email, const std::string& email);
+ static void updateUserInfo(const std::string& visibility, bool im_via_email);
// refresh all the graphics preferences menus
static void refreshEnabledGraphics();
@@ -134,15 +138,13 @@ public:
void setKey(KEY key);
void onClickSetMiddleMouse();
void onClickSetSounds();
-// void onClickSkipDialogs();
-// void onClickResetDialogs();
void onClickEnablePopup();
void onClickDisablePopup();
void resetAllIgnored();
void setAllIgnored();
void onClickLogPath();
void enableHistory();
- void setPersonalInfo(const std::string& visibility, bool im_via_email, const std::string& email);
+ void setPersonalInfo(const std::string& visibility, bool im_via_email);
void refreshEnabledState();
void disableUnavailableSettings();
void onCommitWindowedMode();
@@ -166,12 +168,17 @@ public:
void onClickSpellChecker();
void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
void getUIColor(LLUICtrl* ctrl, const LLSD& param);
-
+ void onLogChatHistorySaved();
void buildPopupLists();
static void refreshSkin(void* data);
void selectPanel(const LLSD& name);
private:
+
+ void onDeleteTranscripts();
+ void onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response);
+ void updateDeleteTranscriptsButton();
+
static std::string sSkin;
notifications_map mNotificationOptions;
bool mClickActionDirty; ///< Set to true when the click/double-click options get changed by user.
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 433ddad35d..37c9ee8c99 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -378,15 +378,7 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
}
buildHistoryFileName();
-
- if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
- {
- std::list<LLSD> chat_history;
-
- //involves parsing of a chat history
- LLLogChat::loadChatHistory(mHistoryFileName, chat_history);
- addMessagesFromHistory(chat_history);
- }
+ loadHistory();
// Localizing name of ad-hoc session. STORM-153
// Changing name should happen here- after the history file was created, so that
@@ -579,11 +571,11 @@ void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& histo
{
const LLSD& msg = *it;
- std::string from = msg[IM_FROM];
+ std::string from = msg[LL_IM_FROM];
LLUUID from_id;
- if (msg[IM_FROM_ID].isDefined())
+ if (msg[LL_IM_FROM_ID].isDefined())
{
- from_id = msg[IM_FROM_ID].asUUID();
+ from_id = msg[LL_IM_FROM_ID].asUUID();
}
else
{
@@ -592,8 +584,8 @@ void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& histo
gCacheName->getUUID(legacy_name, from_id);
}
- std::string timestamp = msg[IM_TIME];
- std::string text = msg[IM_TEXT];
+ std::string timestamp = msg[LL_IM_TIME];
+ std::string text = msg[LL_IM_TEXT];
addMessage(from, from_id, text, timestamp, true);
@@ -617,6 +609,20 @@ void LLIMModel::LLIMSession::chatFromLogFile(LLLogChat::ELogLineType type, const
}
}
+void LLIMModel::LLIMSession::loadHistory()
+{
+ mMsgs.clear();
+
+ if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
+ {
+ std::list<LLSD> chat_history;
+
+ //involves parsing of a chat history
+ LLLogChat::loadChatHistory(mHistoryFileName, chat_history);
+ addMessagesFromHistory(chat_history);
+ }
+}
+
LLIMModel::LLIMSession* LLIMModel::findIMSession(const LLUUID& session_id) const
{
return get_if_there(mId2SessionMap, session_id,
@@ -921,8 +927,7 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from,
bool LLIMModel::logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)
{
- if (gSavedPerAccountSettings.getBOOL("LogInstantMessages")
- && gSavedSettings.getBOOL("KeepConversationLogTranscripts"))
+ if (gSavedSettings.getS32("KeepConversationLogTranscripts") > 1)
{
std::string from_name = from;
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 8578fa8c06..da6039a3ae 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -101,6 +101,8 @@ public:
/** ad-hoc sessions involve sophisticated chat history file naming schemes */
void buildHistoryFileName();
+ void loadHistory();
+
LLUUID mSessionID;
std::string mName;
EInstantMessage mType;
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 3692658e9e..545b44ef92 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -58,10 +58,11 @@
const S32 LOG_RECALL_SIZE = 2048;
-const std::string IM_TIME("time");
-const std::string IM_TEXT("message");
-const std::string IM_FROM("from");
-const std::string IM_FROM_ID("from_id");
+const std::string LL_IM_TIME("time");
+const std::string LL_IM_TEXT("message");
+const std::string LL_IM_FROM("from");
+const std::string LL_IM_FROM_ID("from_id");
+const std::string LL_TRANSCRIPT_FILE_EXTENSION("ll.txt");
const static std::string IM_SEPARATOR(": ");
const static std::string NEW_LINE("\n");
@@ -116,6 +117,15 @@ const static int IDX_TEXT = 3;
using namespace boost::posix_time;
using namespace boost::gregorian;
+void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
+{
+ if (!messages.size()) return;
+
+ std::string im_text = messages.back()[LL_IM_TEXT].asString();
+ im_text.append(line);
+ messages.back()[LL_IM_TEXT] = im_text;
+}
+
class LLLogChatTimeScanner: public LLSingleton<LLLogChatTimeScanner>
{
public:
@@ -191,15 +201,17 @@ private:
std::stringstream mTimeStream;
};
+LLLogChat::save_history_signal_t * LLLogChat::sSaveHistorySignal = NULL;
+
//static
std::string LLLogChat::makeLogFileName(std::string filename)
{
/**
- * Testing for in bound and out bound ad-hoc file names
- * if it is then skip date stamping.
- **/
- //LL_INFOS("") << "Befor:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
- boost::match_results<std::string::const_iterator> matches;
+ * Testing for in bound and out bound ad-hoc file names
+ * if it is then skip date stamping.
+ **/
+
+ boost::match_results<std::string::const_iterator> matches;
bool inboundConf = boost::regex_match(filename, matches, INBOUND_CONFERENCE);
bool outboundConf = boost::regex_match(filename, matches, OUTBOUND_CONFERENCE);
if (!(inboundConf || outboundConf))
@@ -220,17 +232,17 @@ std::string LLLogChat::makeLogFileName(std::string filename)
filename += dbuffer;
}
}
- //LL_INFOS("") << "After:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
+
filename = cleanFileName(filename);
- filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS,filename);
- filename += ".txt";
- //LL_INFOS("") << "Full:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
+ filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename);
+ filename += '.' + LL_TRANSCRIPT_FILE_EXTENSION;
+
return filename;
}
std::string LLLogChat::cleanFileName(std::string filename)
{
- std::string invalidChars = "\"\'\\/?*:.<>|[]{}~"; // Cannot match glob or illegal filename chars
+ std::string invalidChars = "\"\'\\/?*:.<>|[]{}~"; // Cannot match glob or illegal filename chars
std::string::size_type position = filename.find_first_of(invalidChars);
while (position != filename.npos)
{
@@ -242,27 +254,24 @@ std::string LLLogChat::cleanFileName(std::string filename)
std::string LLLogChat::timestamp(bool withdate)
{
- time_t utc_time;
- utc_time = time_corrected();
-
std::string timeStr;
- LLSD substitution;
- substitution["datetime"] = (S32) utc_time;
-
if (withdate)
{
- timeStr = "["+LLTrans::getString ("TimeYear")+"]/["
- +LLTrans::getString ("TimeMonth")+"]/["
- +LLTrans::getString ("TimeDay")+"] ["
- +LLTrans::getString ("TimeHour")+"]:["
- +LLTrans::getString ("TimeMin")+"]";
+ timeStr = "[" + LLTrans::getString ("TimeYear") + "]/["
+ + LLTrans::getString ("TimeMonth") + "]/["
+ + LLTrans::getString ("TimeDay") + "] ["
+ + LLTrans::getString ("TimeHour") + "]:["
+ + LLTrans::getString ("TimeMin") + "]";
}
else
{
timeStr = "[" + LLTrans::getString("TimeHour") + "]:["
- + LLTrans::getString ("TimeMin")+"]";
+ + LLTrans::getString ("TimeMin")+"]";
}
+ LLSD substitution;
+ substitution["datetime"] = (S32)time_corrected();
+
LLStringUtil::format (timeStr, substitution);
return timeStr;
}
@@ -270,9 +279,9 @@ std::string LLLogChat::timestamp(bool withdate)
//static
void LLLogChat::saveHistory(const std::string& filename,
- const std::string& from,
- const LLUUID& from_id,
- const std::string& line)
+ const std::string& from,
+ const LLUUID& from_id,
+ const std::string& line)
{
std::string tmp_filename = filename;
LLStringUtil::trim(tmp_filename);
@@ -312,6 +321,11 @@ void LLLogChat::saveHistory(const std::string& filename,
file << LLChatLogFormatter(item) << std::endl;
file.close();
+
+ if (NULL != sSaveHistorySignal)
+ {
+ (*sSaveHistorySignal)();
+ }
}
void LLLogChat::loadHistory(const std::string& filename, void (*callback)(ELogLineType, const LLSD&, void*), void* userdata)
@@ -321,7 +335,7 @@ void LLLogChat::loadHistory(const std::string& filename, void (*callback)(ELogLi
llwarns << "Filename is Empty!" << llendl;
return ;
}
-
+
LLFILE* fptr = LLFile::fopen(makeLogFileName(filename), "r"); /*Flawfinder: ignore*/
if (!fptr)
{
@@ -377,15 +391,6 @@ void LLLogChat::loadHistory(const std::string& filename, void (*callback)(ELogLi
}
}
-void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
-{
- if (!messages.size()) return;
-
- std::string im_text = messages.back()[IM_TEXT].asString();
- im_text.append(line);
- messages.back()[IM_TEXT] = im_text;
-}
-
// static
void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params)
{
@@ -397,19 +402,16 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false;
- //LL_INFOS("") << "Loading:" << file_name << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
- //LL_INFOS("") << "Current:" << makeLogFileName(file_name) << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
LLFILE* fptr = LLFile::fopen(makeLogFileName(file_name), "r");/*Flawfinder: ignore*/
if (!fptr)
- {
+ {
fptr = LLFile::fopen(oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
- if (!fptr)
- {
- if (!fptr) return; //No previous conversation with this name.
- }
+ if (!fptr)
+ {
+ return; //No previous conversation with this name.
+ }
}
- //LL_INFOS("") << "Reading:" << file_name << LL_ENDL;
char buffer[LOG_RECALL_SIZE]; /*Flawfinder: ignore*/
char *bptr;
S32 len;
@@ -454,7 +456,7 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
LLSD item;
if (!LLChatLogParser::parse(line, item, load_params))
{
- item[IM_TEXT] = line;
+ item[LL_IM_TEXT] = line;
}
messages.push_back(item);
}
@@ -462,9 +464,78 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
fclose(fptr);
}
+// static
+std::string LLLogChat::oldLogFileName(std::string filename)
+{
+ // get Users log directory
+ std::string directory = gDirUtilp->getPerAccountChatLogsDir();
+
+ // add final OS dependent delimiter
+ directory += gDirUtilp->getDirDelimiter();
+
+ // lest make sure the file name has no invalid characters before making the pattern
+ filename = cleanFileName(filename);
+
+ // create search pattern
+ std::string pattern = filename + ( filename == "chat" ? "-???\?-?\?-??.txt" : "-???\?-??.txt");
+
+ std::vector<std::string> allfiles;
+ LLDirIterator iter(directory, pattern);
+ std::string scanResult;
+
+ while (iter.next(scanResult))
+ {
+ allfiles.push_back(scanResult);
+ }
+
+ if (allfiles.size() == 0) // if no result from date search, return generic filename
+ {
+ scanResult = directory + filename + '.' + LL_TRANSCRIPT_FILE_EXTENSION;
+ }
+ else
+ {
+ sort(allfiles.begin(), allfiles.end());
+ scanResult = directory + allfiles.back();
+ // this file is now the most recent version of the file.
+ }
+
+ return scanResult;
+}
+
+// static
+void LLLogChat::getListOfTranscriptFiles(std::vector<std::string>& list_of_transcriptions)
+{
+ // get Users log directory
+ std::string directory = gDirUtilp->getPerAccountChatLogsDir();
+
+ // add final OS dependent delimiter
+ directory += gDirUtilp->getDirDelimiter();
+
+ // create search pattern
+ std::string pattern = "*." + LL_TRANSCRIPT_FILE_EXTENSION;
+
+ LLDirIterator iter(directory, pattern);
+ std::string scanResult;
+ while (iter.next(scanResult))
+ {
+ list_of_transcriptions.push_back(scanResult);
+ }
+}
+
+//static
+boost::signals2::connection LLLogChat::setSaveHistorySignal(const save_history_signal_t::slot_type& cb)
+{
+ if (NULL == sSaveHistorySignal)
+ {
+ sSaveHistorySignal = new save_history_signal_t();
+ }
+
+ return sSaveHistorySignal->connect(cb);
+}
+
//*TODO mark object's names in a special way so that they will be distinguishable form avatar name
//which are more strict by its nature (only firstname and secondname)
-//Example, an object's name can be writen like "Object <actual_object's_name>"
+//Example, an object's name can be written like "Object <actual_object's_name>"
void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
{
if (!im.isMap())
@@ -473,19 +544,19 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
return;
}
- if (im[IM_TIME].isDefined())
+ if (im[LL_IM_TIME].isDefined())
{
- std::string timestamp = im[IM_TIME].asString();
+ std::string timestamp = im[LL_IM_TIME].asString();
boost::trim(timestamp);
ostr << '[' << timestamp << ']' << TWO_SPACES;
}
//*TODO mark object's names in a special way so that they will be distinguishable form avatar name
//which are more strict by its nature (only firstname and secondname)
- //Example, an object's name can be writen like "Object <actual_object's_name>"
- if (im[IM_FROM].isDefined())
+ //Example, an object's name can be written like "Object <actual_object's_name>"
+ if (im[LL_IM_FROM].isDefined())
{
- std::string from = im[IM_FROM].asString();
+ std::string from = im[LL_IM_FROM].asString();
boost::trim(from);
if (from.size())
{
@@ -493,9 +564,9 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
}
}
- if (im[IM_TEXT].isDefined())
+ if (im[LL_IM_TEXT].isDefined())
{
- std::string im_text = im[IM_TEXT].asString();
+ std::string im_text = im[LL_IM_TEXT].asString();
//multilined text will be saved with prepended spaces
boost::replace_all(im_text, NEW_LINE, NEW_LINE_SPACE_PREFIX);
@@ -528,12 +599,12 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
LLLogChatTimeScanner::instance().checkAndCutOffDate(timestamp);
}
- im[IM_TIME] = timestamp;
+ im[LL_IM_TIME] = timestamp;
}
else
{
//timestamp is optional
- im[IM_TIME] = "";
+ im[LL_IM_TIME] = "";
}
bool has_stuff = matches[IDX_STUFF].matched;
@@ -559,8 +630,8 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
if (!has_name || name == SYSTEM_FROM)
{
//name is optional too
- im[IM_FROM] = SYSTEM_FROM;
- im[IM_FROM_ID] = LLUUID::null;
+ im[LL_IM_FROM] = SYSTEM_FROM;
+ im[LL_IM_FROM_ID] = LLUUID::null;
}
//possibly a case of complex object names consisting of 3+ words
@@ -569,8 +640,8 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
U32 divider_pos = stuff.find(NAME_TEXT_DIVIDER);
if (divider_pos != std::string::npos && divider_pos < (stuff.length() - NAME_TEXT_DIVIDER.length()))
{
- im[IM_FROM] = stuff.substr(0, divider_pos);
- im[IM_TEXT] = stuff.substr(divider_pos + NAME_TEXT_DIVIDER.length());
+ im[LL_IM_FROM] = stuff.substr(0, divider_pos);
+ im[LL_IM_TEXT] = stuff.substr(divider_pos + NAME_TEXT_DIVIDER.length());
return true;
}
}
@@ -578,7 +649,7 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
if (!has_name)
{
//text is mandatory
- im[IM_TEXT] = stuff;
+ im[LL_IM_TEXT] = stuff;
return true; //parse as a message from Second Life
}
@@ -590,45 +661,15 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
{
std::string agent_name;
LLAgentUI::buildFullname(agent_name);
- im[IM_FROM] = agent_name;
- im[IM_FROM_ID] = gAgentID;
+ im[LL_IM_FROM] = agent_name;
+ im[LL_IM_FROM_ID] = gAgentID;
}
else
{
- im[IM_FROM] = name;
+ im[LL_IM_FROM] = name;
}
- im[IM_TEXT] = name_and_text[IDX_TEXT];
+ im[LL_IM_TEXT] = name_and_text[IDX_TEXT];
return true; //parsed name and message text, maybe have a timestamp too
}
-std::string LLLogChat::oldLogFileName(std::string filename)
-{
- std::string scanResult;
- std::string directory = gDirUtilp->getPerAccountChatLogsDir();/* get Users log directory */
- directory += gDirUtilp->getDirDelimiter();/* add final OS dependent delimiter */
- filename=cleanFileName(filename);/* lest make shure the file name has no invalad charecters befor making the pattern */
- std::string pattern = (filename+(( filename == "chat" ) ? "-???\?-?\?-??.txt" : "-???\?-??.txt"));/* create search pattern*/
- //LL_INFOS("") << "Checking:" << directory << " for " << pattern << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
- std::vector<std::string> allfiles;
-
- LLDirIterator iter(directory, pattern);
- while (iter.next(scanResult))
- {
- //LL_INFOS("") << "Found :" << scanResult << LL_ENDL;
- allfiles.push_back(scanResult);
- }
-
- if (allfiles.size() == 0) // if no result from date search, return generic filename
- {
- scanResult = directory + filename + ".txt";
- }
- else
- {
- std::sort(allfiles.begin(), allfiles.end());
- scanResult = directory + allfiles.back();
- // thisfile is now the most recent version of the file.
- }
- //LL_INFOS("") << "Reading:" << scanResult << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
- return scanResult;
-}
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index d3e9adcc37..b35a94b4b3 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -49,6 +49,7 @@ public:
const std::string& from,
const LLUUID& from_id,
const std::string& line);
+ static void getListOfTranscriptFiles(std::vector<std::string>& list);
/** @deprecated @see loadChatHistory() */
static void loadHistory(const std::string& filename,
@@ -56,8 +57,13 @@ public:
void* userdata);
static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params = LLSD());
+
+ typedef boost::signals2::signal<void ()> save_history_signal_t;
+ static boost::signals2::connection setSaveHistorySignal(const save_history_signal_t::slot_type& cb);
+
private:
static std::string cleanFileName(std::string filename);
+ static save_history_signal_t * sSaveHistorySignal;
};
/**
@@ -113,9 +119,10 @@ protected:
};
// LLSD map lookup constants
-extern const std::string IM_TIME; //("time");
-extern const std::string IM_TEXT; //("message");
-extern const std::string IM_FROM; //("from");
-extern const std::string IM_FROM_ID; //("from_id");
+extern const std::string LL_IM_TIME; //("time");
+extern const std::string LL_IM_TEXT; //("message");
+extern const std::string LL_IM_FROM; //("from");
+extern const std::string LL_IM_FROM_ID; //("from_id");
+extern const std::string LL_TRANSCRIPT_FILE_EXTENSION; //("ll.txt");
#endif
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 8489e92d15..f141419c43 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -6943,7 +6943,7 @@ void process_user_info_reply(LLMessageSystem* msg, void**)
std::string dir_visibility;
msg->getString( "UserData", "DirectoryVisibility", dir_visibility);
- LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email, email);
+ LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email);
LLFloaterSnapshot::setAgentEmail(email);
}
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 6a464ccdc4..9c36873141 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -8316,4 +8316,30 @@ Attempt cancelled.
yestext="Yes"/>
</notification>
+ <notification
+ icon="alertmodal.tga"
+ name="PreferenceChatClearLog"
+ type="alertmodal">
+ This will delete the log of previous conversations, and all transcripts of those conversations. Proceed?
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Confirm before I delete the log of previous conversations."
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="PreferenceChatDeleteTranscripts"
+ type="alertmodal">
+ This will delete transcripts for all previous conversations. The list of conversations will not be affected. Proceed?
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Confirm before I delete transcripts."
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
</notifications>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index 37bfbae991..4f33699aa6 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
border="true"
- follows="left|top|right|bottom"
+ has_border="true"
height="408"
label="Text Chat"
layout="topleft"
@@ -12,8 +12,7 @@
<panel
border="false"
- follows="left|top"
- height="90"
+ height="60"
layout="topleft"
top="10"
left="13"
@@ -27,7 +26,9 @@
layout="topleft"
top="0"
name="play_typing_animation"
- width="330" />
+ width="330">
+ </check_box>
+
<check_box
enabled="false"
height="16"
@@ -35,26 +36,21 @@
layout="topleft"
name="send_im_to_email"
top_pad="6"
- width="330" />
- <check_box
- control_name="KeepConversationLogTranscripts"
- height="16"
- label="Keep a conversation log and transcripts"
- layout="topleft"
- name="keep_convo_log_and_transcripts"
- top_pad="6"
- width="330" />
+ width="330">
+ </check_box>
+
<check_box
- control_name="UseChatBubbles"
- follows="left|top"
+ control_name="VoiceCallsFriendsOnly"
height="16"
- label="Bubble Chat"
+ label="Only friends and groups can call or IM me"
layout="topleft"
+ name="voice_call_friends_only_check"
top_pad="6"
- name="bubble_text_chat"
- width="330" />
+ width="350">
+ <check_box.label_text text_color="White" />
+ </check_box>
+
<text
- follows="left|top"
layout="topleft"
left="345"
height="12"
@@ -63,67 +59,65 @@
top="0">
Font size:
</text>
- <radio_group
- height="90"
- layout="topleft"
- left="352"
+
+ <combo_box
control_name="ChatFontSize"
+ height="23"
+ layout="topleft"
+ left="341"
name="chat_font_size"
- top_pad="0"
- width="50">
- <radio_item
- height="16"
+ top_pad="5"
+ width="100">
+ <item
label="Small"
- layout="topleft"
- name="radio"
- value="0"
- top="10"
- width="125" />
- <radio_item
- height="16"
+ name="Small"
+ value="0"/>
+ <item
label="Medium"
- layout="topleft"
- name="radio2"
- value="1"
- top_pad="6"
- width="125" />
- <radio_item
- height="16"
+ name="Medium"
+ value="1"/>
+ <item
label="Large"
- layout="topleft"
- name="radio3"
- value="2"
- top_pad="6"
- width="125" />
- </radio_group>
-
- </panel>
+ name="Large"
+ value="2"/>
+ <combo_box.drop_down_button label_color="White" />
+ </combo_box>
+
+ <check_box
+ control_name="UseChatBubbles"
+ height="16"
+ label="Bubble Chat"
+ layout="topleft"
+ top_pad="4"
+ name="bubble_text_chat"
+ width="330">
+ </check_box>
+
+ </panel>
<panel
border="false"
- follows="left|top"
- height="198"
+ height="165"
layout="topleft"
left="13"
width="517">
<text
- follows="left|top"
layout="topleft"
height="12"
name="notifications"
left="0"
+ text_color="White"
width="120">
- Notifications:
+ Notifications
</text>
<text
- follows="left|top"
layout="topleft"
height="12"
name="friend_ims"
width="145"
left="0"
- top_pad="15">
+ top_pad="13">
Friend IMs:
</text>
<combo_box
@@ -134,31 +128,30 @@
top_delta="-6"
name="FriendIMOptions"
width="223">
- <combo_box.item
+ <item
label="Open Conversations window"
name="OpenConversationsWindow"
value="openconversations"/>
- <combo_box.item
+ <item
label="Pop up the message"
name="PopUpMessage"
value="toast"/>
- <combo_box.item
+ <item
label="Flash toolbar button"
name="FlashToolbarButton"
value="flash"/>
- <combo_box.item
+ <item
label="None"
name="None"
value="none"/>
</combo_box>
<text
- follows="left|top"
layout="topleft"
height="12"
name="non_friend_ims"
width="145"
left="0"
- top_pad="15">
+ top_pad="9">
Non-friend IMs:
</text>
<combo_box
@@ -169,31 +162,30 @@
top_delta="-6"
name="NonFriendIMOptions"
width="223">
- <combo_box.item
+ <item
label="Open Conversations window"
name="OpenConversationsWindow"
value="openconversations"/>
- <combo_box.item
+ <item
label="Pop up the message"
name="PopUpMessage"
value="toast"/>
- <combo_box.item
+ <item
label="Flash toolbar button"
name="FlashToolbarButton"
value="flash"/>
- <combo_box.item
+ <item
label="None"
name="None"
value="none"/>
</combo_box>
<text
- follows="left|top"
layout="topleft"
left="0"
height="13"
name="conference_ims"
width="145"
- top_pad="14">
+ top_pad="9">
Conference IMs:
</text>
<combo_box
@@ -204,31 +196,30 @@
top_delta="-6"
name="ConferenceIMOptions"
width="223">
- <combo_box.item
+ <item
label="Open Conversations window"
name="OpenConversationsWindow"
value="openconversations"/>
- <combo_box.item
+ <item
label="Pop up the message"
name="PopUpMessage"
value="toast"/>
- <combo_box.item
+ <item
label="Flash toolbar button"
name="FlashToolbarButton"
value="flash"/>
- <combo_box.item
+ <item
label="None"
name="None"
value="none"/>
</combo_box>
<text
- follows="left|top"
layout="topleft"
left="0"
height="13"
name="group_chat"
width="145"
- top_pad="14">
+ top_pad="9">
Group chat:
</text>
<combo_box
@@ -239,31 +230,30 @@
top_delta="-6"
name="GroupChatOptions"
width="223">
- <combo_box.item
+ <item
label="Open Conversations window"
name="OpenConversationsWindow"
value="openconversations"/>
- <combo_box.item
+ <item
label="Pop up the message"
name="PopUpMessage"
value="toast"/>
- <combo_box.item
+ <item
label="Flash toolbar button"
name="FlashToolbarButton"
value="flash"/>
- <combo_box.item
+ <item
label="None"
name="None"
value="none"/>
</combo_box>
<text
- follows="left|top"
layout="topleft"
left="0"
height="12"
name="nearby_chat"
width="145"
- top_pad="14">
+ top_pad="9">
Nearby chat:
</text>
<combo_box
@@ -274,31 +264,30 @@
top_delta="-6"
name="NearbyChatOptions"
width="223">
- <combo_box.item
+ <item
label="Open Conversations window"
name="OpenConversationsWindow"
value="openconversations"/>
- <combo_box.item
+ <item
label="Pop up the message"
name="PopUpMessage"
value="toast"/>
- <combo_box.item
+ <item
label="Flash toolbar button"
name="FlashToolBarButton"
value="flash"/>
- <combo_box.item
+ <item
label="None"
name="None"
value="none"/>
</combo_box>
<text
- follows="left|top"
layout="topleft"
left="0"
height="13"
name="notifications_alert"
width="500"
- top_pad="11"
+ top_pad="9"
visible="true"
text_color="DrYellow">
To temporarily stop all notifications, use Communicate &gt; Do Not Disturb.
@@ -308,14 +297,13 @@
<panel
border="false"
- follows="left|top"
- height="67"
+ height="50"
layout="topleft"
left="13"
+ top_pad="10"
width="517">
<text
- follows="left|top"
layout="topleft"
left="0"
name="play_sound"
@@ -360,9 +348,123 @@
width="150" />
</panel>
+
+ <view_border
+ bevel_style="none"
+ height="0"
+ layout="topleft"
+ left="13"
+ name="cost_text_border"
+ top_pad="5"
+ width="495"/>
+
+ <panel
+ height="50"
+ layout="topleft"
+ left="13"
+ top_pad="10"
+ width="505">
+
+ <text
+ layout="topleft"
+ left="0"
+ text_color="White"
+ height="12"
+ top="5"
+ width="55">
+ Save:
+ </text>
+
+ <combo_box
+ control_name="KeepConversationLogTranscripts"
+ height="23"
+ layout="topleft"
+ left_pad="5"
+ name="chat_font_size"
+ top="0"
+ width="165">
+ <item
+ label="Log and transcripts"
+ value="2"/>
+ <item
+ label="Log only"
+ value="1"/>
+ <item
+ label="No log or transcripts"
+ value="0"/>
+ <drop_down_button label_color="White" />
+ </combo_box>
+
+ <button
+ enabled="false"
+ height="23"
+ label="Clear log..."
+ label_color="White"
+ layout="topleft"
+ left_pad="5"
+ top="0"
+ name="clear_log"
+ width="110">
+ <commit_callback
+ function="Pref.ClearLog" />
+ </button>
+
+ <button
+ enabled="false"
+ height="23"
+ label="Delete transcripts..."
+ label_color="White"
+ layout="topleft"
+ left_pad="5"
+ top="0"
+ name="delete_transcripts"
+ width="147">
+ <button.commit_callback
+ function="Pref.DeleteTranscripts" />
+ </button>
+
+ <text
+ layout="topleft"
+ left="0"
+ text_color="White"
+ height="12"
+ top_pad="15"
+ width="55">
+ Location:
+ </text>
+
+ <line_editor
+ control_name="InstantMessageLogPath"
+ border_style="line"
+ border_thickness="1"
+ font="SansSerif"
+ height="23"
+ layout="topleft"
+ left_pad="55"
+ max_length="4096"
+ name="log_path_string"
+ top_delta="-5"
+ width="185">
+ </line_editor>
+
+ <button
+ enabled="false"
+ follows="left|top"
+ height="23"
+ label="Browse..."
+ label_color="White"
+ label_selected="Browse"
+ layout="topleft"
+ left_pad="5"
+ name="log_path_button"
+ top_delta="0"
+ width="112">
+ <commit_callback function="Pref.LogPath" />
+ </button>
+
+ </panel>
<button
- follows="left|top"
height="23"
label="Translation..."
layout="topleft"
@@ -370,11 +472,10 @@
name="ok_btn"
top="-29"
width="170">
- <button.commit_callback
+ <commit_callback
function="Pref.TranslationSettings" />
</button>
<button
- follows="top|left"
height="23"
layout="topleft"
top_pad="-23"
@@ -385,7 +486,6 @@
width="150">
</button>
<button
- follows="top|left"
height="23"
layout="topleft"
top_pad="-23"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
index 587c461bee..78743d26bb 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
@@ -1,72 +1,69 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
- border="true"
- follows="left|top|right|bottom"
- height="408"
- label="Communication"
- layout="topleft"
- left="102"
- name="im"
- top="1"
- width="517">
- <panel.string
- name="log_in_to_change">
- log in to change
- </panel.string>
- <button
- follows="left|bottom"
- height="23"
- label="Clear History"
- tool_tip="Clear login image, last location, teleport history, web, and texture cache"
- layout="topleft"
- left="30"
- name="clear_cache"
- top="10"
- width="145">
- <button.commit_callback
- function="Pref.WebClearCache" />
- </button>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left_pad="10"
- mouse_opaque="false"
- name="cache_size_label_l"
- top_delta="3"
- text_color="LtGray_50"
- width="300">
- (Locations, images, web, search history)
- </text>
- <check_box
- height="16"
- enabled="false"
- label="Show me in Search results"
- layout="topleft"
- left="30"
- name="online_searchresults"
- top_pad="20"
- width="350" />
- <check_box
- height="16"
- enabled="false"
- label="Only friends and groups know I'm online"
- layout="topleft"
- left="30"
- name="online_visibility"
- top_pad="30"
- width="350" />
- <check_box
- control_name="VoiceCallsFriendsOnly"
- height="16"
- label="Only friends and groups can call or IM me"
- layout="topleft"
- left="30"
- name="voice_call_friends_only_check"
- top_pad="10"
- width="350" />
+ border="true"
+ follows="left|top|right|bottom"
+ height="408"
+ label="Communication"
+ layout="topleft"
+ left="102"
+ name="im"
+ top="1"
+ width="517">
+
+ <panel.string
+ name="log_in_to_change">
+ log in to change
+ </panel.string>
+
+ <button
+ follows="left|bottom"
+ height="23"
+ label="Clear History"
+ tool_tip="Clear login image, last location, teleport history, web, and texture cache"
+ layout="topleft"
+ left="30"
+ name="clear_cache"
+ top="10"
+ width="145">
+ <button.commit_callback
+ function="Pref.WebClearCache" />
+ </button>
+
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="10"
+ mouse_opaque="false"
+ name="cache_size_label_l"
+ top_delta="3"
+ text_color="LtGray_50"
+ width="300">
+ (Locations, images, web, search history)
+ </text>
+
+ <check_box
+ height="16"
+ enabled="false"
+ label="Show me in Search results"
+ layout="topleft"
+ left="30"
+ name="online_searchresults"
+ top_pad="20"
+ width="350" />
+
+ <check_box
+ height="16"
+ enabled="false"
+ label="Only friends and groups know I'm online"
+ layout="topleft"
+ left="30"
+ name="online_visibility"
+ top_pad="30"
+ width="350" />
+
<check_box
enabled_control="EnableVoiceChat"
control_name="AutoDisengageMic"
@@ -87,100 +84,7 @@
name="favorites_on_login_check"
top_pad="10"
width="350" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left="30"
- mouse_opaque="false"
- name="Logs:"
- top_pad="20"
- width="350">
- Chat Logs:
- </text>
- <check_box
- enabled="false"
- control_name="LogNearbyChat"
- height="16"
- label="Save nearby chat logs on my computer"
- layout="topleft"
- left="30"
- name="log_nearby_chat"
- top_pad="10"
- width="350">
- </check_box>
- <check_box
- enabled="false"
- control_name="LogInstantMessages"
- height="16"
- label="Save IM logs on my computer"
- layout="topleft"
- left="30"
- name="log_instant_messages"
- top_pad="10"
- width="350">
- </check_box>
- <check_box
- control_name="LogTimestamp"
- enabled="false"
- height="16"
- label="Add timestamp to each line in chat log"
- layout="topleft"
- left_delta="0"
- name="show_timestamps_check_im"
- top_pad="10"
- width="237" />
- <check_box
- control_name="LogFileNamewithDate"
- enabled="false"
- height="16"
- label="Add datestamp to log file name."
- layout="topleft"
- left_delta="5"
- name="logfile_name_datestamp"
- top_pad="10"
- width="350"/>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="10"
- layout="topleft"
- left_delta="0"
- mouse_opaque="false"
- name="log_path_desc"
- top_pad="30"
- width="128">
- Location of logs:
- </text>
- <line_editor
- bottom="366"
- control_name="InstantMessageLogPath"
- follows="top|left|right"
- halign="right"
- height="23"
- layout="topleft"
- left_delta="0"
- mouse_opaque="false"
- name="log_path_string"
- top_pad="5"
- width="250"/>
- <button
- enabled="false"
- follows="right|bottom"
- height="23"
- label="Browse"
- label_selected="Browse"
- layout="topleft"
- left_pad="5"
- name="log_path_button"
- top_delta="0"
- width="145">
- <button.commit_callback
- function="Pref.LogPath" />
- </button>
+
<button
follows="left|bottom"
height="23"