summaryrefslogtreecommitdiff
path: root/plugins/UserInfoEx/src/dlg_propsheet.h
blob: 824fa48868fc63cd6724d3ea5dadd5e67f1812f0 (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
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
/*
UserinfoEx plugin for Miranda IM

Copyright:
© 2006-2010 DeathAxe, Yasnovidyashii, Merlin, K. Romanov, Kreol

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#pragma once

typedef struct TPropSheet	PS, *LPPS;

struct CPsHdr;
class CPsTree;

/***********************************************************************************************************
 * Tree item
 ***********************************************************************************************************/

class CPsTreeItem 
{
	int               _idDlg = 0;     // resource id of the property page
	HINSTANCE         _hInst = 0;     // instance handle of the owning plugin dll
	CUserInfoPageDlg *_pDialog = 0;   // pointer to a page dialog
	HWND              _hWnd = 0;      // window handle for the property page if shown jet
	uint32_t          _dwFlags = 0;   // some flags
	int               _iPosition = 0; // initiating position if custom (used for sorting)
	MCONTACT          _hContact = 0;  // contact the page is accociated with (may be a meta subcontact if details dialog is shown for a meta contact)
	const char*       _pszProto = 0;  // protocol the page is accociated with (is the contact's protocol if _hContact is not NULL)
	const char*       _pszPrefix = 0; // pointer to the dialog owning contact's protocol
	INT_PTR           _initParam = 0;
					      
	HTREEITEM         _hItem = 0;     // handle to the treeview item if visible (NULL if this item is hidden)
	CPsTreeItem*      _pParent = 0;   // owning tree item
	int               _iImage = -1;   // index of treeview item's image
	uint8_t           _bState = 0;    // initial state of this treeitem
	char*             _pszName = 0;   // original name, given by plugin (not customized)
	wchar_t*          _ptszLabel = 0; // string to setting in db holding information about this treeitem

	LPCSTR GlobalName();

	int Icon(HIMAGELIST hIml, USERINFOPAGE *uip, bool bInitIconsOnly);
	int ItemLabel(bool bReadDBValue);
	int Name(const wchar_t *pszTitle, bool bIsUnicode);
	HICON	ProtoIcon();

public:
	CPsTreeItem();
	~CPsTreeItem();

	int Create(CPsHdr* pPsh, USERINFOPAGE *uip);
	void Rename(const LPTSTR pszLabel);

	__inline LPSTR Name() const { return _pszName; }
	__inline LPCSTR Proto() const { return _pszProto; }
	__inline LPTSTR Label() const { return _ptszLabel; }
	__inline MCONTACT hContact() const { return _hContact; }

	__inline HWND Wnd() const { return _hWnd; }
	__inline int DlgId() const { return _idDlg; }
	__inline HINSTANCE Inst() const { return _hInst; }
	__inline CUserInfoPageDlg* Dialog() const { return _pDialog; }

	__inline int Image() const { return _iImage; }
	__inline int Pos() const { return _iPosition; }
	__inline uint8_t State() const { return _bState; }
	__inline HTREEITEM Hti() const { return _hItem; }
	__inline void Hti(HTREEITEM hti) { _hItem = hti; }
	__inline CPsTreeItem* Parent() const { return _pParent; }
	__inline void Parent(CPsTreeItem *pParent) { _pParent = pParent; }

	__inline uint32_t Flags() const { return _dwFlags; }
	__inline void Flags(uint32_t dwFlags) { _dwFlags = dwFlags; }
	__inline void AddFlags(uint32_t dwFlags) { _dwFlags |= dwFlags; }
	__inline void RemoveFlags(uint32_t dwFlags) { _dwFlags &= ~dwFlags; }

	uint8_t HasName(const LPCSTR pszName) const;

	LPCSTR PropertyKey(LPCSTR pszProperty);
	LPCSTR GlobalPropertyKey(LPCSTR pszProperty);
	LPCSTR IconKey();

	LPSTR ParentItemName();
	HWND CreateWnd(LPPS pPs);
	
	uint16_t DBSaveItemState(LPCSTR pszGroup, int iItemPosition, UINT iState, uint32_t dwFlags);

	// notification handlers
	void OnInfoChanged();
	void OnPageIconsChanged();
	void OnIconsChanged(CPsTree *pTree);
};


/***********************************************************************************************************
 * Tree control
 ***********************************************************************************************************/

#define MAX_TINAME			64

// internal setting strings
#define SET_LASTITEM		"LastItem"
#define SET_ITEM_LABEL		"label"
#define SET_ITEM_GROUP		"group"
#define SET_ITEM_STATE		"state"
#define SET_ITEM_POS		"pos"
#define TREE_ROOTITEM		"<ROOT>"

// treeview states
#define DBTVIS_INVISIBLE	0
#define DBTVIS_NORMAL		1
#define DBTVIS_EXPANDED		2

// flags for the treeview
#define PSTVF_SORTTREE		0x00010000
#define PSTVF_GROUPS		0x00020000
#define PSTVF_LABEL_CHANGED	0x00040000
#define PSTVF_POS_CHANGED	0x00080000
#define PSTVF_STATE_CHANGED	0x00100000
#define PSTVF_INITICONS		0x00200000		// flag that indicates the AddPage handler to load only basic stuff

class CPsTree
{
	OBJLIST<CPsTreeItem> _pages;

	HWND _hWndTree = nullptr;
	HIMAGELIST _hImages = nullptr;
	int _curItem = -1;
	uint32_t _dwFlags = 0;
	HWND _hLabelEdit = nullptr;
	HTREEITEM _hDragItem = nullptr;
	bool _isDragging = false;
	LPPS _pPs = nullptr;

	uint16_t	SaveItemsState(LPCSTR pszGroup, HTREEITEM hRootItem, int& iItem);

public:
	CPsTree(LPPS pPs);
	~CPsTree();
	
	__inline void BeginDrag(HTREEITEM hDragItem) { _isDragging = true; _hDragItem = hDragItem; }
	__inline void EndDrag() { _isDragging = false; _hDragItem = nullptr; }
	__inline bool IsDragging() const { return _isDragging; }
	__inline HTREEITEM DragItem() const { return _hDragItem; }

	__inline uint32_t Flags() const { return _dwFlags; }
	__inline void Flags(uint32_t dwFlags) { _dwFlags = dwFlags; }
	__inline void AddFlags(uint32_t dwFlags) { _dwFlags |= dwFlags; }
	__inline void RemoveFlags(uint32_t dwFlags) { _dwFlags &= ~dwFlags; }

	__inline int NumItems() const { return _pages.getCount(); }
	__inline HWND Window() const { return _hWndTree; }
	__inline HIMAGELIST ImageList() const { return _hImages; }
	__inline uint8_t IsIndexValid(const int index) const { return (index >= 0 && index < _pages.getCount()); }
	
	__inline CPsTreeItem* TreeItem(int index) const { return (IsIndexValid(index) ? &_pages[index] : nullptr); };
	__inline HTREEITEM TreeItemHandle(int index) const { return (IsIndexValid(index) ? _pages[index].Hti() : nullptr); };

	__inline int CurrentItemIndex() const { return _curItem; };
	__inline CPsTreeItem* CurrentItem() const { return TreeItem(CurrentItemIndex()); };

	CPsTreeItem* AddDummyItem(const char *pszGroup);
	uint8_t Create(HWND hWndTree, CPsHdr *pPsh);
	uint8_t InitTreeItems(LPWORD needWidth);
	void Remove(HINSTANCE);

	void HideItem(const int iPageIndex);
	HTREEITEM ShowItem(CPsTreeItem *pti, LPWORD needWidth);

	HTREEITEM MoveItem(HTREEITEM hItem, HTREEITEM hInsertAfter, uint8_t bAsChild = FALSE);
	void SaveState();
	void DBResetState();

	int FindItemIndexByHandle(HTREEITEM hItem);
	int FindItemIndexByName(LPCSTR pszName);

	CPsTreeItem *FindItemByName(LPCSTR pszName);
	CPsTreeItem *FindItemByHandle(HTREEITEM hItem);
	HTREEITEM    FindItemHandleByName(LPCSTR pszName);
	CPsTreeItem *FindItemByResource(HINSTANCE hInst, int idDlg);

	int  BeginLabelEdit(HTREEITEM hItem);
	int  EndLabelEdit(const uint8_t bSave);
	void PopupMenu();

	void OnIconsChanged();
	uint8_t OnInfoChanged();
	uint8_t OnSelChanging();
	void OnSelChanged(LPNMTREEVIEW lpnmtv);
	void OnCancel();
	int  OnApply();
};

/***********************************************************************************************************
 * common stuff
 ***********************************************************************************************************/

// internal flags for the PSP structure
#define PSPF_CHANGED            4096
#define PSPF_PROTOPREPENDED     8192 // the first token of the title is the protocol

#define PSF_PROTOPAGESONLY        64 // load only contact's protocol pages
#define PSF_PROTOPAGESONLY_INIT  128

class CPsUpload;

struct CPsHdr
{
	MCONTACT _hContact = 0;    // handle to the owning contact
	LPCSTR   _pszProto = 0;    // owning contact's protocol 
	LPCSTR   _pszPrefix = 0;   // name prefix for treeitem settings
	CPsTreeItem** _pPages = 0; // the pages
	uint16_t     _numPages = 0;    // number of pages
	uint32_t    _dwFlags = 0;     // some option flags
	HIMAGELIST _hImages = 0;   // the imagelist with all tree item icons
	LIST<wchar_t> _ignore;     // list of skipped items when adding metasubcontacts pages
	int      _nSubContact = 0; // index of a current subcontact

	CPsHdr();
	~CPsHdr();
	
	void Free_pPages();
};

struct TAckInfo 
{
	MCONTACT hContact;
	LPINT acks;
	int count;
};

struct TPropSheet 
{
	// dialogs owner
	MCONTACT	hContact;
	char pszProto[MAXMODULELABELLENGTH];

	HANDLE hProtoAckEvent;  // eventhook for protocol acks
	HANDLE hSettingChanged; // eventhook searching for changed contact information
	HANDLE hIconsChanged;   // eventhook for changed icons in icolib
	HANDLE hModuleUnloaded; // eventhook for unloading modules

	HFONT hCaptionFont;
	HFONT hBoldFont;
	RECT rcDisplay;
	uint8_t updateAnimFrame;
	CHAR szUpdating[64];
	uint32_t dwFlags;

	TAckInfo	*infosUpdated;
	int nSubContacts;
	
	// controls
	HWND hDlg;
	CPsTree *pTree;
	CPsUpload *pUpload;
};

void DlgContactInfoInitTreeIcons();
void DlgContactInfoLoadModule();
void DlgContactInfoUnLoadModule();