summaryrefslogtreecommitdiff
path: root/plugins/FavContacts/src/favlist.h
blob: 588731662b0c9458fd60a030dac158a21e5ee7ba (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
#ifndef favlist_h__
#define favlist_h__

struct TContactInfo
{
private:
	MCONTACT hContact;
	uint32_t status;
	wchar_t *name;
	wchar_t *group;
	bool bManual;
	float fRate;

public:
	TContactInfo(MCONTACT _hContact, bool _bManual, float _fRate = 0) :
		hContact(_hContact),
		bManual(_bManual),
		fRate(_fRate)
	{
		name = mir_wstrdup(Clist_GetContactDisplayName(hContact));

		if (g_Options.bUseGroups)
			group = db_get_wsa(hContact, "CList", "Group", TranslateT("<no group>"));
		else
			group = mir_wstrdup(TranslateT("Favorite Contacts"));

		status = db_get_w(hContact, Proto_GetBaseAccountName(hContact), "Status", ID_STATUS_OFFLINE);
	}

	~TContactInfo()
	{
		mir_free(name);
		mir_free(group);
	}

	MCONTACT getHandle() const
	{
		return hContact;
	}

	wchar_t *getGroup() const
	{
		return group;
	}

	static int cmp(const TContactInfo *p1, const TContactInfo *p2)
	{
		if (p1->bManual && !p2->bManual) return -1;
		if (!p1->bManual && p2->bManual) return 1;

		if (!p1->bManual)
		{
			if (p1->fRate > p2->fRate) return -1;
			if (p1->fRate < p2->fRate) return 1;
		}

		int res = 0;
		if (res = mir_wstrcmp(p1->group, p2->group)) return res;
		if (res = mir_wstrcmp(p1->name, p2->name)) return res;
		return 0;
	}
};

class TFavContacts : public LIST < TContactInfo >
{
private:
	int nGroups;
	wchar_t *prevGroup;
	MDatabaseCommon *db;

	int addContact(MCONTACT hContact, bool bManual)
	{
		DBCachedContact *cc = db->getCache()->GetCachedContact(hContact);
		if (cc == nullptr)
			return 0;

		if (db_mc_isEnabled()) {
			if (cc->IsSub()) // skip subcontacts if MC is enabled
				return 0;
		}
		else if (cc->IsMeta()) // skip metacontacts if MC is not enabled
			return 0;

		TContactInfo *info = new TContactInfo(hContact, bManual);
		insert(info);
		wchar_t *group = info->getGroup();
		if (prevGroup && mir_wstrcmp(prevGroup, group))
			++nGroups;
		prevGroup = group;
		return 1;
	}

public:
	TFavContacts() : LIST<TContactInfo>(5, TContactInfo::cmp)
	{
		db = db_get_current();
	}

	~TFavContacts()
	{
		for (auto &it : *this)
			delete it;
	}

	__forceinline int groupCount() const { return nGroups; }

	void build()
	{
		prevGroup = nullptr;

		nGroups = 1;

		for (auto &hContact : Contacts())
			if (g_plugin.getByte(hContact, "IsFavourite", 0))
				addContact(hContact, true);

		int nRecent = 0;
		for (int i = 0; nRecent < g_Options.wMaxRecent; ++i) {
			MCONTACT hContact = g_contactCache->get(i);
			if (!hContact)
				break;
			
			if (!g_plugin.getByte(hContact, "IsFavourite", 0))
				nRecent += addContact(hContact, false);
		}
	}
};

#endif // favlist_h__