summaryrefslogtreecommitdiff
path: root/indra/newview/llconversationlog.h
blob: b3a5be321e9ad35874869422b51bb6601917d330 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
/**
 * @file llconversationlog.h
 *
 * $LicenseInfo:firstyear=2002&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2012, Linden Research, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#ifndef LLCONVERSATIONLOG_H_
#define LLCONVERSATIONLOG_H_

#include "llcallingcard.h"
#include "llfloaterimsession.h"
#include "llimview.h"

class LLConversationLogObserver;
struct ConversationParams;

typedef LLIMModel::LLIMSession::SType SessionType;

/*
 * This class represents a particular session(conversation) of any type(im/voice/p2p/group/...) by storing some of session's data.
 * Each LLConversation object has a corresponding visual representation in a form of LLConversationLogListItem.
 */
class LLConversation
{
public:

    LLConversation(const ConversationParams& params);
    LLConversation(const LLIMModel::LLIMSession& session);
    LLConversation(const LLConversation& conversation);

    ~LLConversation();

    const SessionType&  getConversationType()   const   { return mConversationType; }
    const std::string&  getConversationName()   const   { return mConversationName; }
    const std::string&  getHistoryFileName()    const   { return mHistoryFileName; }
    const LLUUID&       getSessionID()          const   { return mSessionID; }
    const LLUUID&       getParticipantID()      const   { return mParticipantID; }
    const std::string&  getTimestamp()          const   { return mTimestamp; }
    const U64Seconds&
                        getTime()               const   { return mTime; }
    bool                hasOfflineMessages()    const   { return mHasOfflineIMs; }

    void setConversationName(const std::string &conv_name) { mConversationName = conv_name; }
    void setOfflineMessages(bool new_messages) { mHasOfflineIMs = new_messages; }
    bool isOlderThan(U32Days days) const;

    /*
     * updates last interaction time
     */
    void updateTimestamp();

    void updateHistoryFileName(const std::string &new_name) { mHistoryFileName = new_name; }

    /*
     * Resets flag of unread offline message to false when im floater with this conversation is opened.
     */
    void onIMFloaterShown(const LLUUID& session_id);

    /*
     * returns string representation(in form of: mm/dd/yyyy hh:mm) of time when conversation was started
     */
    static const std::string createTimestamp(const U64Seconds& utc_time);

private:

    /*
     * If conversation has unread offline messages sets callback for opening LLFloaterIMSession
     * with this conversation.
     */
    void setListenIMFloaterOpened();

    boost::signals2::connection mIMFloaterShowedConnection;

    U64Seconds mTime; // last interaction time
    SessionType     mConversationType;
    std::string     mConversationName;
    std::string     mHistoryFileName;
    LLUUID          mSessionID;
    LLUUID          mParticipantID;
    bool            mHasOfflineIMs;
    std::string     mTimestamp; // last interaction time in form of: mm/dd/yyyy hh:mm
};

/**
 * LLConversationLog stores all agent's conversations.
 * This class is responsible for creating and storing LLConversation objects when im or voice session starts.
 * Also this class saves/retrieves conversations to/from file.
 *
 * Also please note that it may be several conversations with the same sessionID stored in the conversation log.
 * To distinguish two conversations with the same sessionID it's also needed to compare their creation date.
 */

class LLConversationLog : public LLSingleton<LLConversationLog>, LLIMSessionObserver
{
    LLSINGLETON(LLConversationLog);
public:
    void removeConversation(const LLConversation& conversation);

    /**
     * Returns first conversation with matched session_id
     */
    const LLConversation*               getConversation(const LLUUID& session_id);
    const std::vector<LLConversation>&  getConversations() { return mConversations; }

    void addObserver(LLConversationLogObserver* observer);
    void removeObserver(LLConversationLogObserver* observer);

    // LLIMSessionObserver triggers
    virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, bool has_offline_msg) override;
    virtual void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) override {}; // Stub
    virtual void sessionRemoved(const LLUUID& session_id) override{}                                            // Stub
    virtual void sessionVoiceOrIMStarted(const LLUUID& session_id) override{};                              // Stub
    virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) override{};   // Stub

    void notifyObservers();

    void onNewMessageReceived(const LLSD& data);

    /**
     * public method which is called on viewer exit to save conversation log
     */
    void cache();
    // will check if current name is edentical with the one on disk and will rename the one on disk if it isn't
    void verifyFilename(const LLUUID& session_id, const std::string &expected_filename, const std::string &new_session_name);
    bool moveLog(const std::string &originDirectory, const std::string &targetDirectory);
    void getListOfBackupLogs(std::vector<std::string>& list_of_backup_logs);
    void deleteBackupLogs();

    void onClearLog();
    void onClearLogResponse(const LLSD& notification, const LLSD& response);

    bool getIsLoggingEnabled() { return mLoggingEnabled; }
    bool isLogEmpty() { return mConversations.empty(); }

    /**
     * inits connection to per account settings,
     * loads saved file and inits enabled state
     */
    void initLoggingState();

    /**
     * constructs file name in which conversations log will be saved
     * file name is conversation.log
     */
    std::string getFileName();
    LLConversation* findConversation(const LLIMModel::LLIMSession* session);

private:

    virtual ~LLConversationLog()
    {
        if (mAvatarNameCacheConnection.connected())
        {
            mAvatarNameCacheConnection.disconnect();
        }
    }

    void enableLogging(S32 log_mode);

    /**
     * adds conversation to the conversation list and notifies observers
     */
    void logConversation(const LLUUID& session_id, bool has_offline_msg);

    void notifyParticularConversationObservers(const LLUUID& session_id, U32 mask);

    bool saveToFile(const std::string& filename);
    bool loadFromFile(const std::string& filename);

    void onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, const LLIMModel::LLIMSession* session);

    void createConversation(const LLIMModel::LLIMSession* session);
    void updateConversationTimestamp(LLConversation* conversation);
    void updateConversationName(const LLIMModel::LLIMSession* session, const std::string& name);
    void updateOfflineIMs(const LLIMModel::LLIMSession* session, bool new_messages);



    typedef std::vector<LLConversation> conversations_vec_t;
    std::vector<LLConversation>             mConversations;
    std::set<LLConversationLogObserver*>    mObservers;

    LLFriendObserver* mFriendObserver;      // Observer of the LLAvatarTracker instance

    boost::signals2::connection mNewMessageSignalConnection;
    boost::signals2::connection mAvatarNameCacheConnection;

    bool mLoggingEnabled;
};

class LLConversationLogObserver
{
public:

    enum EConversationChange
        {
            CHANGED_TIME = 1, // last interaction time changed
            CHANGED_NAME = 2,  // conversation name changed
            CHANGED_OfflineIMs = 3
        };

    virtual ~LLConversationLogObserver(){}
    virtual void changed() = 0;
    virtual void changed(const LLUUID& session_id, U32 mask){};
};

#endif /* LLCONVERSATIONLOG_H_ */