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
|
#if !defined(HISTORYSTATS_GUARD_STATISTIC_H)
#define HISTORYSTATS_GUARD_STATISTIC_H
#include "stdafx.h"
#include "_consts.h"
#include <vector>
#include <map>
#include <set>
#include <list>
#include "settings.h"
#include "protocol.h"
#include "message.h"
class Contact; // forward declaration instead of #include "contact.h"
class Statistic
: private pattern::NotCopyable<Statistic>
{
public:
enum InvocationSource {
fromOptions,
fromStartup,
fromMenu,
};
enum DBEventTypeRaw {
EVENTTYPE_AVATARCHANGE = 9003, // from pescuma
EVENTTYPE_WAT_REQUEST = 9601, // from WATrack
EVENTTYPE_WAT_ANSWER = 9602, // from WATrack
EVENTTYPE_WAT_ERROR = 9603, // from WATrack
EVENTTYPE_STATUSCHANGE = 25368, // from NewXStatusNotify
};
enum DBEventType {
// messages
etMessage = EVENTTYPE_MESSAGE,
// other events
etFile = EVENTTYPE_FILE,
etURL = EVENTTYPE_URL,
etICQSMS = ICQEVENTTYPE_SMS,
etICQWebPager = ICQEVENTTYPE_WEBPAGER,
etICQEMailExpress = ICQEVENTTYPE_EMAILEXPRESS,
// authorization and contacts
etAuthRequest = EVENTTYPE_AUTHREQUEST,
etAdded = EVENTTYPE_ADDED,
etContacts = EVENTTYPE_CONTACTS,
// status/avatar/nick/... changes
etStatusChange = EVENTTYPE_STATUSCHANGE,
etAvatarChange = EVENTTYPE_AVATARCHANGE,
// WaTrack events
etWATRequest = EVENTTYPE_WAT_REQUEST,
etWATAnswer = EVENTTYPE_WAT_ANSWER,
etWATError = EVENTTYPE_WAT_ERROR,
};
typedef std::vector<Contact*> ContactList;
typedef std::vector<const Contact*> ContactListC;
typedef std::pair<ext::string, ext::string> ConflictingFile; // (desired, temp)
typedef std::list<ConflictingFile> ConflictingFiles;
typedef std::map<Canvas::Digest, ext::string> ImageMap;
private:
static bool m_bRunning;
private:
// settings and the like
Settings m_Settings;
Settings::CharMapper m_CharMapper;
// handles for windows and synchronisation
HINSTANCE m_hInst;
HWND m_hWndProgress;
HANDLE m_hThreadPushEvent;
HANDLE m_hCancelEvent;
InvocationSource m_InvokedFrom;
// list of contacts
ContactList m_Contacts;
// special 'contacts': omitted, totals
Contact* m_pTotals;
Contact* m_pOmitted;
// did we really omit something
bool m_bActuallyOmitted;
// start time for statistics
DWORD m_TimeStarted;
DWORD m_MSecStarted;
// minimum/maximum date/time to include
DWORD m_TimeMin;
DWORD m_TimeMax;
// error processing and the like
ext::string m_ErrorText;
// column management
int m_nNextSlot;
std::vector<Column*> m_ActiveCols;
std::vector<Column*> m_AcquireCols;
std::vector<Column*> m_TransformCols;
// file management
ext::string m_TempPath;
ext::string m_OutputPath;
ext::string m_OutputFile;
ext::string m_OutputPrefix;
ConflictingFiles m_ConflictingFiles;
int m_nLastFileNr;
// PNG management
ImageMap m_Images;
// first/last message
bool m_bHistoryTimeAvailable;
DWORD m_nFirstTime;
DWORD m_nLastTime;
// misc data
DWORD m_AverageMinTime;
private:
// contact handling
void prepareColumns();
void prepareContactData(Contact& contact);
void freeContactData(Contact& contact);
void mergeContactData(Contact& contact, const Contact& include);
void transformContactData(Contact& contact);
Contact& addContact(const ext::string& nick, const ext::string& protoDisplayName, const ext::string& groupName, int nSources);
// misc routines
DWORD getTimeStarted() { return m_TimeStarted; }
bool shouldTerminate() { return (WaitForSingleObject(m_hCancelEvent, 0) == WAIT_OBJECT_0) || (bool_(mu::system::terminated())); }
void handleAddMessage(Contact& contact, Message& msg);
void handleAddChat(Contact& contact, bool bOutgoing, DWORD localTimestampStarted, DWORD duration);
// progress dialog handling
static INT_PTR CALLBACK staticProgressProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
void setProgressMax(bool bSub, int max);
void setProgressLabel(bool bSub, const ext::string& label);
void stepProgress(bool bSub, int step = 1);
static INT_PTR CALLBACK staticConflictProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
// statistics creation steps
bool stepInit();
bool stepReadDB();
bool stepRemoveContacts();
bool stepSortContacts();
bool stepPreOmitContacts();
bool stepOmitContacts();
bool stepCalcTotals();
bool stepPostOmitContacts();
bool stepTransformData();
bool stepWriteHTML();
// private constructor & main statistic creation routine
explicit Statistic(const Settings& settings, InvocationSource invokedFrom, HINSTANCE hInst);
bool createStatistics();
bool createStatisticsSteps();
static void __cdecl threadProc(void *lpParameter);
static void __cdecl threadProcSteps(void *lpParameter);
public:
~Statistic();
public:
static void run(const Settings& settings, InvocationSource invokedFrom, HINSTANCE hInst, HWND hWndParent = NULL);
int countContacts() const { return m_Contacts.size(); }
const Contact& getContact(int index) const;
const Contact& getTotals() const { assert(m_pTotals); return *m_pTotals; }
const Contact& getOmitted() const { assert(m_pOmitted); return *m_pOmitted; }
bool hasTotals() const { return (m_pTotals != NULL) && m_Settings.m_CalcTotals; } // MEMO: only makes sense after 'calc totals'-step
bool hasOmitted() const { return (m_pOmitted != NULL) && m_Settings.m_OmitContacts && m_Settings.m_OmittedInExtraRow && m_bActuallyOmitted; } // MEMO: only makes sense after 'omit'-step
DWORD getFirstTime(); // MEMO: only makes sense after 'calc totals'-step
DWORD getLastTime(); // MEMO: only makes sense after 'calc totals'-step
DWORD getHistoryTime(); // MEMO: only makes sense after 'calc totals'-step
DWORD getAverageMinTime() { return m_AverageMinTime; }
// file management
ext::string createFile(const ext::string& desiredName);
bool newFile(const wchar_t* fileExt, ext::string& writeFile, ext::string& finalURL);
bool newFilePNG(ext::string& writeFile, ext::string& finalURL) { return newFile(L".png", writeFile, finalURL); }
bool newFilePNG(Canvas& canvas, ext::string& finalURL);
};
#endif // HISTORYSTATS_GUARD_STATISTIC_H
|