summaryrefslogtreecommitdiff
path: root/plugins/HistoryStats/src/utils.h
blob: daae0313162c3727239569521d45570aac4c5b1b (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
#if !defined(HISTORYSTATS_GUARD_UTILS_H)
#define HISTORYSTATS_GUARD_UTILS_H

#include "stdafx.h"
#include "_consts.h"

namespace utils
{
	// time formatting
	ext::string timestampToString(time_t value, const wchar_t* format);
	ext::string tmStructToString(const tm& value, const wchar_t* format);
	inline ext::string timestampToDateTime(DWORD value) { return timestampToString(value, L"%c"); }
	inline ext::string timestampToDate(DWORD value) { return timestampToString(value, L"%x"); }
	inline ext::string timestampToTime(DWORD value) { return timestampToString(value, L"%X"); }
	ext::string durationToString(DWORD value);
	DWORD parseDate(const ext::string& date);
	inline ext::string formatDate(time_t timeValue) { return timestampToString(timeValue, L"%Y-%m-%d"); }

	// number formatting
	ext::string intToString(int value);
	ext::string intToPadded(int value, int len);
	ext::string intToGrouped(int value);
	ext::string floatToString(double value, int precision);
	ext::string floatToGrouped(double value, int precision);
	inline ext::string ratioToString(int numerator, int denominator, int precision) { return floatToString((denominator != 0) ? (1.0 * numerator / denominator) : 0.0, precision); }
	inline ext::string ratioToGrouped(int numerator, int denominator, int precision) { return floatToGrouped((denominator != 0) ? (1.0 * numerator / denominator) : 0.0, precision); }
	ext::string ratioToPercent(int numerator, int denominator);

	// text conversion
	void replaceAllInPlace(ext::string& text, const wchar_t* find, const wchar_t* replace);
	void htmlEscapeInPlace(ext::string& text);
	inline ext::string replaceAll(ext::string text, const wchar_t* find, const wchar_t* replace) { replaceAllInPlace(text, find, replace); return text; }
	inline ext::string htmlEscape(ext::string text) { htmlEscapeInPlace(text); return text; }
	const wchar_t* stripPrefix(const wchar_t* szPrefix, const wchar_t* szText);
	ext::string replaceVariables(const ext::string& strFormat, time_t timeValue, const wchar_t* szNick = L"");

	// case conversion
	ext::string toLowerCase(const ext::string& text);
	ext::string toUpperCase(const ext::string& text);
	
	// version conversion
	DWORD dottedToVersion(ext::string version);
	ext::string versionToDotted(DWORD version);

	// character conversion (wide, ansi, utf8)
	ext::a::string convertWToA(const WCHAR* str, size_t len);
	ext::w::string convertAToW(const char* str, size_t len);
	ext::a::string convertTToUTF8(const wchar_t* str, size_t str_len);
	ext::string convertUTF8ToT(const char* str, size_t str_len);
	size_t rawUTF8Encode(const WCHAR* pIn, size_t lenIn, char* pOut);
	size_t getUTF8Len(const char* str);

	// character conversion (convenience functions)
	inline ext::a::string toA(const wchar_t* str) { return convertWToA(str, ext::strfunc::len(str)); }
	inline ext::w::string toW(const wchar_t* str) { return str; }
	inline ext::string fromA(const char* str) { return convertAToW(str, ext::a::strfunc::len(str)); }
	inline ext::string fromW(const WCHAR* str) { return str; }
	inline ext::a::string toA(const ext::string& str) { return convertWToA(str.c_str(), str.length()); }
	inline ext::w::string toW(const ext::string& str) { return str; }
	inline ext::string fromA(const ext::a::string& str) { return convertAToW(str.c_str(), str.length()); }
	inline ext::string fromW(const ext::w::string& str) { return str; }
	inline ext::a::string toUTF8(const wchar_t* str) { return convertTToUTF8(str, ext::strfunc::len(str)); }
	inline ext::string fromUTF8(const char* str) { return convertUTF8ToT(str, ext::a::strfunc::len(str)); }
	inline ext::a::string toUTF8(const ext::string& str) { return convertTToUTF8(str.c_str(), str.length()); }
	inline ext::string fromUTF8(const ext::a::string& str) { return convertUTF8ToT(str.c_str(), str.length()); }

	// file management
	bool fileExists(const ext::string& fileName);
	bool pathExists(const ext::string& path);
	bool isRelative(const ext::string& fileName);
	bool isValidFilePart(ext::string filePart);
	bool isValidFile(const ext::string& fileName);
	ext::string extractPath(const ext::string& fileName);
	ext::string extractFile(const ext::string& fileName);
	bool createPath(const ext::string& path);

	// color management
	ext::string colorToHTML(COLORREF crColor);
	void generateGradient(COLORREF fromColor, COLORREF toColor, COLORREF colorTab[256]);

	// drawing helpers
	struct rect
	{
		RECT r;
		inline rect(int left, int top, int right, int bottom)
		{
			r.left = left; r.top = top; r.right = right; r.bottom = bottom;
		}

		inline operator const RECT*() const { return &r; }
	};

	// misc functionality
	void ensureRange(int& value, int min, int max, int fallback);
	void ensureRange(unsigned int& value, unsigned int min, unsigned int max, unsigned int fallback);
	ext::string getGUID();

	// window positioning
	void centerDialog(HWND hDlg, HWND hParent = nullptr);
	RECT getWindowRect(HWND hParent, HWND hWnd);
	inline RECT getWindowRect(HWND hParent, int nID) { return getWindowRect(hParent, GetDlgItem(hParent, nID)); }
	void moveWindow(HWND hWnd, const RECT& rWnd);
	inline void moveWindow(HWND hParent, int nID, const RECT& rWnd) { moveWindow(GetDlgItem(hParent, nID), rWnd); }

	// cached access to miranda properties
	const ext::string& getMirandaPath();
	const ext::string& getProfilePath();
	const ext::string& getProfileName();
}

class OS
	: private pattern::NotCopyable<OS>
{
private:
	bool m_bIsXPPlus;
	UINT m_ImageListColor;
	SIZE m_SmIcon;

private:
	explicit OS();

private:
	static OS m_Data;

public:
	static bool isXPPlus() { return m_Data.m_bIsXPPlus; }
	static UINT imageListColor() { return m_Data.m_ImageListColor; }
	static int smIconCX() { return m_Data.m_SmIcon.cx; }
	static int smIconCY() { return m_Data.m_SmIcon.cy; }
};

class Locale
	: private pattern::NotCopyable<Locale>
{
private:
	wchar_t m_DecimalPoint;
	wchar_t m_ThousandSep;
	ext::a::string m_Grouping;

private:
	explicit Locale() { }

private:
	static Locale m_Data;

public:
	static void init();
	static wchar_t decimalPoint() { return m_Data.m_DecimalPoint; }
	static wchar_t thousandSep() { return m_Data.m_ThousandSep; }
	static const char* grouping() { return m_Data.m_Grouping.c_str(); }
};

class RTFFilter
	: private pattern::NotCopyable<RTFFilter>
{
private:
	typedef intptr_t (WINAPI *RTFCONVSTRING)(const void *pSrcBuffer, void *pDstBuffer, int nSrcCodePage, int nDstCodePage, unsigned long dwFlags, size_t nMaxLen);

private:
	enum {
		CP_UNICODE                =      1200,
		CONVMODE_NO_OUTPUT_BOM    =  0x20000u,
		CONVMODE_USE_SYSTEM_TABLE = 0x800000u,
	};

private:
	HMODULE m_hRTFConv;
	RTFCONVSTRING m_RTFConvString;
	mir_cs m_RTFConvCS;

private:
	explicit RTFFilter();

private:
	static RTFFilter m_Data;

public:
	static void init();
	static void uninit();
	static bool available() { return !!m_Data.m_hRTFConv; }
	static ext::t::string filter(const ext::t::string& str);
};

#endif // HISTORYSTATS_GUARD_UTILS_H