summaryrefslogtreecommitdiff
path: root/plugins/UserInfoEx
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2022-06-15 15:34:07 +0300
committerGeorge Hazan <ghazan@miranda.im>2022-06-15 15:34:07 +0300
commitc5be633b829e83a308eb9537e67d3318ec86b084 (patch)
tree21896374fc7aa27f9df1b65336f6abaa3914c069 /plugins/UserInfoEx
parent65171c0d60c0846affe796b9e22d4f005ef82bee (diff)
UInfoEx:
- fix for custom page trees; - random crash fix; - code cleaning
Diffstat (limited to 'plugins/UserInfoEx')
-rw-r--r--plugins/UserInfoEx/src/classPsTree.cpp76
-rw-r--r--plugins/UserInfoEx/src/classPsTreeItem.cpp145
-rw-r--r--plugins/UserInfoEx/src/dlg_propsheet.cpp2
-rw-r--r--plugins/UserInfoEx/src/dlg_propsheet.h26
-rw-r--r--plugins/UserInfoEx/src/psp_base.cpp1
-rw-r--r--plugins/UserInfoEx/src/psp_profile.cpp610
-rw-r--r--plugins/UserInfoEx/src/version.h2
7 files changed, 397 insertions, 465 deletions
diff --git a/plugins/UserInfoEx/src/classPsTree.cpp b/plugins/UserInfoEx/src/classPsTree.cpp
index 3b486b8955..b31247fe1d 100644
--- a/plugins/UserInfoEx/src/classPsTree.cpp
+++ b/plugins/UserInfoEx/src/classPsTree.cpp
@@ -51,8 +51,7 @@ CPsTree::CPsTree(LPPS pPs) :
**/
CPsTree::~CPsTree()
{
- if (_hLabelEdit)
- {
+ if (_hLabelEdit) {
DestroyWindow(_hLabelEdit);
_hLabelEdit = nullptr;
}
@@ -105,10 +104,10 @@ uint8_t CPsTree::Create(HWND hWndTree, CPsHdr* pPsh)
* return: index of the new item or -1 if failed to add
**/
-int CPsTree::AddDummyItem(LPCSTR pszGroup)
+CPsTreeItem* CPsTree::AddDummyItem(const char *pszGroup)
{
if (!mir_strcmpi(pszGroup, TREE_ROOTITEM))
- return -1;
+ return nullptr;
CPsHdr psh;
psh._hContact = _pPs->hContact;
@@ -118,12 +117,13 @@ int CPsTree::AddDummyItem(LPCSTR pszGroup)
USERINFOPAGE uip = {};
uip.flags = ODPF_UNICODE;
uip.szTitle.w = mir_utf8decodeW(pszGroup);
+ uip.pPlugin = &g_plugin;
auto *p = new CPsTreeItem();
p->Create(&psh, &uip);
_pages.insert(p);
- return _pages.indexOf(&p);
+ return p;
}
void CPsTree::Remove(HINSTANCE hInst)
@@ -171,16 +171,17 @@ uint8_t CPsTree::InitTreeItems(LPWORD needWidth)
SetWindowLongPtr(_hWndTree, GWL_STYLE, GetWindowLongPtr(_hWndTree, GWL_STYLE) | TVS_HASBUTTONS);
// init the iParent member for all the items
- for (auto &it : _pages) {
- LPSTR pszGroup = it->ParentItemName();
+ for (int i = 0; i < _pages.getCount(); i++) {
+ auto &it = _pages[i];
+ char *pszGroup = it.ParentItemName();
if (pszGroup != nullptr) {
- int iParent = FindItemIndexByName(pszGroup);
+ auto *pParent = FindItemByName(pszGroup);
// need to add an empty parent item
- if (iParent == -1)
- iParent = AddDummyItem(pszGroup);
+ if (pParent == nullptr)
+ pParent = AddDummyItem(pszGroup);
- it->Parent(iParent);
+ it.Parent(pParent);
mir_free(pszGroup);
}
}
@@ -192,7 +193,7 @@ uint8_t CPsTree::InitTreeItems(LPWORD needWidth)
ShowWindow(_hWndTree, SW_HIDE);
for (auto &it : _pages)
if (it->State() != DBTVIS_INVISIBLE)
- ShowItem(_pages.indexOf(&it), needWidth);
+ ShowItem(it, needWidth);
ShowWindow(_hWndTree, SW_SHOW);
return TRUE;
@@ -335,52 +336,45 @@ void CPsTree::HideItem(const int iPageIndex)
* needWidth - gives and takes the width, the treeview must have to show all items properly
* return: TRUE if item was added successfully, FALSE otherwise
**/
-HTREEITEM CPsTree::ShowItem(const int iPageIndex, LPWORD needWidth)
+HTREEITEM CPsTree::ShowItem(CPsTreeItem *pti, LPWORD needWidth)
{
TVINSERTSTRUCT tvii;
- CPsTreeItem *pti;
// check parameters
- if (!_hWndTree ||
- !IsIndexValid(iPageIndex) ||
- !(pti = &_pages[iPageIndex]) ||
- !pti->Name() ||
- !pti->Label())
- {
+ if (!_hWndTree || !pti->Name() || !pti->Label()) {
MsgErr(GetParent(_hWndTree), LPGENW("Due to a parameter error, one of the treeitems can't be added!"));
return nullptr;
}
+
// item is visible at the moment
- if ((tvii.itemex.hItem = pti->Hti()) == nullptr)
- {
- RECT rc;
- const int iParent = pti->Parent();
+ if ((tvii.itemex.hItem = pti->Hti()) == nullptr) {
+ auto *pParent = pti->Parent();
// init the rest of the treeitem
- tvii.hParent = IsIndexValid(iParent) ? ShowItem(iParent, needWidth) : nullptr;
- tvii.hInsertAfter = (_dwFlags & PSTVF_SORTTREE) ? TVI_SORT : TVI_LAST;
- tvii.itemex.mask = TVIF_TEXT|TVIF_PARAM|TVIF_STATE;
- tvii.itemex.pszText = pti->Label();
- tvii.itemex.state = pti->State() == DBTVIS_EXPANDED ? TVIS_EXPANDED : 0;
- tvii.itemex.stateMask = TVIS_EXPANDED;
- tvii.itemex.lParam = iPageIndex;
+ tvii.hParent = (pParent) ? ShowItem(pParent, needWidth) : nullptr;
+ tvii.hInsertAfter = (_dwFlags & PSTVF_SORTTREE) ? TVI_SORT : TVI_LAST;
+ tvii.itemex.mask = TVIF_TEXT | TVIF_PARAM | TVIF_STATE;
+ tvii.itemex.pszText = pti->Label();
+ tvii.itemex.state = pti->State() == DBTVIS_EXPANDED ? TVIS_EXPANDED : 0;
+ tvii.itemex.stateMask = TVIS_EXPANDED;
+ tvii.itemex.lParam = _pages.indexOf(pti);
+
// set images
if ((tvii.itemex.iImage = tvii.itemex.iSelectedImage = pti->Image()) != -1)
- {
- tvii.itemex.mask |= TVIF_IMAGE|TVIF_SELECTEDIMAGE;
- }
+ tvii.itemex.mask |= TVIF_IMAGE | TVIF_SELECTEDIMAGE;
+
// insert item into tree if set visible
- if ((tvii.itemex.hItem = TreeView_InsertItem(_hWndTree, &tvii)) == nullptr)
- {
+ if ((tvii.itemex.hItem = TreeView_InsertItem(_hWndTree, &tvii)) == nullptr) {
MsgErr(GetParent(_hWndTree), LPGENW("A fatal error occurred on adding a property sheet page!\nDialog creation aborted!"));
return nullptr;
}
+
pti->Hti(tvii.itemex.hItem);
+
// calculate width of treeview
+ RECT rc;
if (needWidth && TreeView_GetItemRect(_hWndTree, pti->Hti(), &rc, TRUE) && rc.right > *needWidth)
- {
*needWidth = (uint16_t)rc.right;
- }
}
return tvii.itemex.hItem;
}
@@ -457,7 +451,7 @@ HTREEITEM CPsTree::MoveItem(HTREEITEM hItem, HTREEITEM hInsertAfter, uint8_t bAs
// update handle pointer in the page structure
pItem.Hti(hNewItem);
// get the index of the parent
- pItem.Parent(FindItemIndexByHandle(tvis.hParent));
+ pItem.Parent(FindItemByHandle(tvis.hParent));
// move children
hInsertAfter = hNewItem;
while (hChild = TreeView_GetChild(_hWndTree, hItem))
@@ -524,7 +518,7 @@ void CPsTree::SaveState()
if (!it->Hti()) {
LPSTR pszGroup;
- if (!IsIndexValid(it->Parent()) || !(pszGroup = _pages[it->Parent()].Name()))
+ if (!it->Parent() || !(pszGroup = it->Parent()->Name()))
pszGroup = TREE_ROOTITEM;
numErrors += it->DBSaveItemState(pszGroup, iItem++, DBTVIS_INVISIBLE, _dwFlags);
}
@@ -775,7 +769,7 @@ void CPsTree::PopupMenu()
DBResetState();
break;
default: // show a hidden item
- if ((iItem -= 100) >= 0 && ShowItem(iItem, nullptr))
+ if ((iItem -= 100) >= 0 && ShowItem(&_pages[iItem], nullptr))
AddFlags(PSTVF_STATE_CHANGED | PSTVF_POS_CHANGED);
break;
}
diff --git a/plugins/UserInfoEx/src/classPsTreeItem.cpp b/plugins/UserInfoEx/src/classPsTreeItem.cpp
index 189d9fd9a1..d7971444cd 100644
--- a/plugins/UserInfoEx/src/classPsTreeItem.cpp
+++ b/plugins/UserInfoEx/src/classPsTreeItem.cpp
@@ -159,19 +159,16 @@ LPSTR CPsTreeItem::ParentItemName()
* bIsUnicode - if TRUE the title is unicode
* return: 0 on success, 1 to 4 indicating the failed operation
**/
-int CPsTreeItem::Name(LPTSTR ptszTitle, const uint8_t bIsUnicode)
+int CPsTreeItem::Name(const wchar_t *ptszTitle, bool bIsUnicode)
{
// convert title to utf8
_pszName = (bIsUnicode) ? mir_utf8encodeW((LPWSTR)ptszTitle) : mir_utf8encode((LPSTR)ptszTitle);
- if (_pszName)
- {
+ if (_pszName) {
// convert disallowed characters
- for (uint32_t i = 0; _pszName[i] != 0; i++)
- {
- switch (_pszName[i])
- {
- case '{': _pszName[i] = '('; break;
- case '}': _pszName[i] = ')'; break;
+ for (uint32_t i = 0; _pszName[i] != 0; i++) {
+ switch (_pszName[i]) {
+ case '{': _pszName[i] = '('; break;
+ case '}': _pszName[i] = ')'; break;
}
}
}
@@ -225,28 +222,21 @@ void CPsTreeItem::Rename(const LPTSTR pszLabel)
* param: pszName - uniquely identifiing string for a propertypage encoded with utf8 (e.g.: {group\item})
* return: Label in a newly allocated piece of memory
**/
-int CPsTreeItem::ItemLabel(const uint8_t bReadDBValue)
+int CPsTreeItem::ItemLabel(bool bReadDBValue)
{
- DBVARIANT dbv;
-
- // clear existing
- if (_ptszLabel)
- mir_free(_ptszLabel);
-
// try to get custom label from database
+ DBVARIANT dbv;
if (!bReadDBValue || DB::Setting::GetWString(0, MODULENAME, GlobalPropertyKey(SET_ITEM_LABEL), &dbv) || (_ptszLabel = dbv.pwszVal) == nullptr) {
// extract the name
- LPSTR pszName = mir_strrchr(_pszName, '\\');
+ char *pszName = mir_strrchr(_pszName, '\\');
if (pszName && pszName[1])
pszName++;
else
pszName = _pszName;
- LPTSTR ptszLabel = mir_utf8decodeW(pszName);
- if (ptszLabel) {
- _ptszLabel = mir_wstrdup(TranslateW(ptszLabel));
- mir_free(ptszLabel);
- }
+ ptrW ptszLabel(mir_utf8decodeW(pszName));
+ if (ptszLabel)
+ replaceStrW(_ptszLabel, TranslateW(ptszLabel));
}
// return nonezero if label is invalid
return _ptszLabel == nullptr;
@@ -287,7 +277,7 @@ HICON CPsTreeItem::ProtoIcon()
* hDefaultIcon - default icon to use
* return: nothing
**/
-int CPsTreeItem::Icon(HIMAGELIST hIml, USERINFOPAGE *uip, uint8_t bInitIconsOnly)
+int CPsTreeItem::Icon(HIMAGELIST hIml, USERINFOPAGE *uip, bool bInitIconsOnly)
{
// check parameter
if (!_pszName || !uip)
@@ -366,68 +356,65 @@ int CPsTreeItem::Icon(HIMAGELIST hIml, USERINFOPAGE *uip, uint8_t bInitIconsOnly
* odp - USERINFOPAGE structure with the information about the page to add
* return: 0 on success, 1 on failure
**/
-int CPsTreeItem::Create(CPsHdr* pPsh, USERINFOPAGE *uip)
+int CPsTreeItem::Create(CPsHdr *pPsh, USERINFOPAGE *uip)
{
- int err;
- wchar_t szTitle[ MAXSETTING ];
-
// check parameter
- if (pPsh && uip && PtrIsValid(uip->pPlugin)) {
- // instance value
- _hInst = uip->pPlugin->getInst();
- _dwFlags = uip->flags;
- _initParam = uip->dwInitParam;
-
- // init page owning contact
- _hContact = pPsh->_hContact;
- _pszProto = mir_strdup(pPsh->_pszProto);
-
- // global settings prefix for current contact (is dialog owning contact's protocol by default)
- _pszPrefix = (pPsh->_pszPrefix) ? pPsh->_pszPrefix : "Owner";
-
- if (pPsh->_dwFlags & PSF_PROTOPAGESONLY) {
- if (_dwFlags & ODPF_USERINFOTAB)
- mir_snwprintf(szTitle, L"%s %d\\%s", uip->szTitle.w, pPsh->_nSubContact+1, uip->szGroup.w);
- else
- mir_snwprintf(szTitle, L"%s %d", uip->szTitle.w, pPsh->_nSubContact+1);
- }
- else {
- if (_dwFlags & ODPF_USERINFOTAB)
- mir_snwprintf(szTitle, L"%s\\%s", uip->szTitle.w, uip->szGroup.w);
- else
- mir_wstrcpy(szTitle, uip->szTitle.w);
- }
- // set the unique utf8 encoded name for the item
- if (err = Name(szTitle, (_dwFlags & ODPF_UNICODE) == ODPF_UNICODE))
- MsgErr(nullptr, LPGENW("Creating unique name for a page failed with %d and error code %d"), err, GetLastError());
+ if (!pPsh || !uip || !PtrIsValid(uip->pPlugin))
+ return 1;
- // read label from database or create it
- else if (err = ItemLabel(TRUE))
- MsgErr(nullptr, LPGENW("Creating the label for a page failed with %d and error code %d"), err, GetLastError());
+ // instance value
+ _hInst = uip->pPlugin->getInst();
+ _dwFlags = uip->flags;
+ _initParam = uip->dwInitParam;
- else {
- // load icon for the item
- Icon(pPsh->_hImages, uip, (pPsh->_dwFlags & PSTVF_INITICONS) == PSTVF_INITICONS);
-
- // the rest is not needed if only icons are loaded
- if (pPsh->_dwFlags & PSTVF_INITICONS)
- return 0;
-
- // load custom order
- if (!(pPsh->_dwFlags & PSTVF_SORTTREE)) {
- _iPosition = g_plugin.getByte(PropertyKey(SET_ITEM_POS), uip->position);
- if ((_iPosition < 0) || (_iPosition > 0x800000A))
- _iPosition = 0;
- }
- // read visibility state
- _bState = g_plugin.getByte(PropertyKey(SET_ITEM_STATE), DBTVIS_EXPANDED);
+ // init page owning contact
+ _hContact = pPsh->_hContact;
+ _pszProto = mir_strdup(pPsh->_pszProto);
- // fetch dialog
- _pDialog = uip->pDialog;
- return 0;
- }
+ // global settings prefix for current contact (is dialog owning contact's protocol by default)
+ _pszPrefix = (pPsh->_pszPrefix) ? pPsh->_pszPrefix : "Owner";
+
+ CMStringW wszTitle;
+ if (_dwFlags & ODPF_USERINFOTAB) {
+ wszTitle.Append(uip->szGroup.w);
+ wszTitle.AppendChar('\\');
+ }
+
+ wszTitle.Append(uip->szTitle.w);
+ if (pPsh->_dwFlags & PSF_PROTOPAGESONLY)
+ wszTitle.AppendFormat(L" %d", pPsh->_nSubContact + 1);
+
+ // set the unique utf8 encoded name for the item
+ if (int err = Name(wszTitle, (_dwFlags & ODPF_UNICODE) == ODPF_UNICODE)) {
+ MsgErr(nullptr, LPGENW("Creating unique name for a page failed with %d and error code %d"), err, GetLastError());
+ return 1;
+ }
+
+ // read label from database or create it
+ if (int err = ItemLabel(TRUE)) {
+ MsgErr(nullptr, LPGENW("Creating the label for a page failed with %d and error code %d"), err, GetLastError());
+ return 1;
}
- return 1;
+
+ // load icon for the item
+ Icon(pPsh->_hImages, uip, (pPsh->_dwFlags & PSTVF_INITICONS) == PSTVF_INITICONS);
+
+ // the rest is not needed if only icons are loaded
+ if (pPsh->_dwFlags & PSTVF_INITICONS)
+ return 0;
+
+ // load custom order
+ if (!(pPsh->_dwFlags & PSTVF_SORTTREE)) {
+ _iPosition = g_plugin.getByte(PropertyKey(SET_ITEM_POS), uip->position);
+ if ((_iPosition < 0) || (_iPosition > 0x800000A))
+ _iPosition = 0;
+ }
+ // read visibility state
+ _bState = g_plugin.getByte(PropertyKey(SET_ITEM_STATE), DBTVIS_EXPANDED);
+
+ // fetch dialog
+ _pDialog = uip->pDialog;
+ return 0;
}
/**
diff --git a/plugins/UserInfoEx/src/dlg_propsheet.cpp b/plugins/UserInfoEx/src/dlg_propsheet.cpp
index e254162217..cdfcb19319 100644
--- a/plugins/UserInfoEx/src/dlg_propsheet.cpp
+++ b/plugins/UserInfoEx/src/dlg_propsheet.cpp
@@ -335,7 +335,7 @@ static INT_PTR AddPage(WPARAM wParam, LPARAM lParam)
CPsTreeItem *pNew = new CPsTreeItem();
if (pNew) {
if (pNew->Create(pPsh, uip)) {
- MIR_DELETE(pNew);
+ delete pNew;
return 1;
}
diff --git a/plugins/UserInfoEx/src/dlg_propsheet.h b/plugins/UserInfoEx/src/dlg_propsheet.h
index 615c98102b..824fa48868 100644
--- a/plugins/UserInfoEx/src/dlg_propsheet.h
+++ b/plugins/UserInfoEx/src/dlg_propsheet.h
@@ -39,22 +39,22 @@ class CPsTreeItem
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)
- LPCSTR _pszProto = 0; // protocol the page is accociated with (is the contact's protocol if _hContact is not NULL)
- LPCSTR _pszPrefix = 0; // pointer to the dialog owning contact's protocol
+ 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)
- int _iParent = -1; // index of the owning tree item
+ CPsTreeItem* _pParent = 0; // owning tree item
int _iImage = -1; // index of treeview item's image
uint8_t _bState = 0; // initial state of this treeitem
- LPSTR _pszName = 0; // original name, given by plugin (not customized)
- LPTSTR _ptszLabel= 0; // string to setting in db holding information about 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();
+ LPCSTR GlobalName();
- int Icon(HIMAGELIST hIml, USERINFOPAGE *uip, uint8_t bInitIconsOnly);
- int ItemLabel(const uint8_t bReadDBValue);
- int Name(LPTSTR pszTitle, const uint8_t bIsUnicode);
+ int Icon(HIMAGELIST hIml, USERINFOPAGE *uip, bool bInitIconsOnly);
+ int ItemLabel(bool bReadDBValue);
+ int Name(const wchar_t *pszTitle, bool bIsUnicode);
HICON ProtoIcon();
public:
@@ -79,8 +79,8 @@ public:
__inline uint8_t State() const { return _bState; }
__inline HTREEITEM Hti() const { return _hItem; }
__inline void Hti(HTREEITEM hti) { _hItem = hti; }
- __inline int Parent() const { return _iParent; }
- __inline void Parent(const int iParent) { _iParent = iParent; }
+ __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; }
@@ -172,13 +172,13 @@ public:
__inline int CurrentItemIndex() const { return _curItem; };
__inline CPsTreeItem* CurrentItem() const { return TreeItem(CurrentItemIndex()); };
- int AddDummyItem(LPCSTR pszGroup);
+ 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(const int iPageIndex, LPWORD needWidth);
+ HTREEITEM ShowItem(CPsTreeItem *pti, LPWORD needWidth);
HTREEITEM MoveItem(HTREEITEM hItem, HTREEITEM hInsertAfter, uint8_t bAsChild = FALSE);
void SaveState();
diff --git a/plugins/UserInfoEx/src/psp_base.cpp b/plugins/UserInfoEx/src/psp_base.cpp
index 0737807bcc..fe05560a4b 100644
--- a/plugins/UserInfoEx/src/psp_base.cpp
+++ b/plugins/UserInfoEx/src/psp_base.cpp
@@ -33,6 +33,7 @@ PSPBaseDlg::PSPBaseDlg(int idDialog) :
CUserInfoPageDlg(g_plugin, idDialog),
m_ctrlList(nullptr)
{
+ m_bFixedSize = true;
}
bool PSPBaseDlg::OnInitDialog()
diff --git a/plugins/UserInfoEx/src/psp_profile.cpp b/plugins/UserInfoEx/src/psp_profile.cpp
index 38ee787e90..78acc56f4d 100644
--- a/plugins/UserInfoEx/src/psp_profile.cpp
+++ b/plugins/UserInfoEx/src/psp_profile.cpp
@@ -198,13 +198,12 @@ static void ProfileList_Clear(HWND hList)
**/
static int ProfileList_EndLabelEdit(LPLISTCTRL pList, uint8_t bSave)
{
- HWND hEdit;
-
// check if labeledit is enabled
- if (!PtrIsValid(pList) || !pList->hList || !pList->labelEdit.hEdit)
+ if (!pList->hList || !pList->labelEdit.hEdit)
return 1;
+
// set hEdit NULL to indicate the endlabeledit call and prevent other calls
- hEdit = pList->labelEdit.hEdit;
+ HWND hEdit = pList->labelEdit.hEdit;
pList->labelEdit.hEdit = nullptr;
if (bSave != FALSE && pList->labelEdit.pItem) {
@@ -257,11 +256,6 @@ static int ProfileList_EndLabelEdit(LPLISTCTRL pList, uint8_t bSave)
return 0;
}
-static int ProfileList_EndLabelEdit(HWND hList, uint8_t bSave)
-{
- return ProfileList_EndLabelEdit((LPLISTCTRL)GetUserData(hList), bSave);
-}
-
/**
* name: ProfileList_BeginLabelEdit
* desc: create an edit control to edit the label of the selected item
@@ -272,16 +266,10 @@ static int ProfileList_EndLabelEdit(HWND hList, uint8_t bSave)
**/
static HWND ProfileList_BeginLabelEdit(LPLISTCTRL pList, int iItem, int iSubItem)
{
- LVITEM lvi;
- LPLCITEM pItem;
- MCONTACT m_hContact;
- RECT rcList;
-
- if (!PtrIsValid(pList))
- return nullptr;
if (pList->labelEdit.hEdit)
ProfileList_EndLabelEdit(pList, FALSE);
+ LVITEM lvi;
lvi.mask = LVIF_PARAM | LVIF_STATE;
lvi.stateMask = 0xFFFFFFFF;
lvi.iItem = iItem;
@@ -290,12 +278,13 @@ static HWND ProfileList_BeginLabelEdit(LPLISTCTRL pList, int iItem, int iSubItem
if (!ListView_GetItem(pList->hList, &lvi))
return nullptr;
- pItem = (LPLCITEM)lvi.lParam;
+ LPLCITEM pItem = (LPLCITEM)lvi.lParam;
- PSGetContact(GetParent(pList->hList), m_hContact);
+ MCONTACT hContact;
+ PSGetContact(GetParent(pList->hList), hContact);
// do not edit deviders or protocol based contact information
- if (!(lvi.state & LVIS_SELECTED) || !PtrIsValid(pItem) || (m_hContact && (pItem->wFlags & CTRLF_HASPROTO)))
+ if (!(lvi.state & LVIS_SELECTED) || !PtrIsValid(pItem) || (hContact && (pItem->wFlags & CTRLF_HASPROTO)))
return nullptr;
ListView_EnsureVisible(pList->hList, iItem, FALSE);
@@ -307,6 +296,8 @@ static HWND ProfileList_BeginLabelEdit(LPLISTCTRL pList, int iItem, int iSubItem
ListView_GetSubItemRect(pList->hList, iItem, 1, LVIR_BOUNDS, &rc2);
pList->labelEdit.rcCombo.right = rc2.left;
}
+
+ RECT rcList;
GetClientRect(pList->hList, &rcList);
pList->labelEdit.rcCombo.right = min(pList->labelEdit.rcCombo.right, rcList.right);
pList->labelEdit.rcCombo.left = max(pList->labelEdit.rcCombo.left, rcList.left);
@@ -358,19 +349,6 @@ static HWND ProfileList_BeginLabelEdit(LPLISTCTRL pList, int iItem, int iSubItem
}
/**
- * name: ProfileList_BeginLabelEdit
- * desc: create an edit control to edit the label of the selected item
- * param: hList - handle to listview control
- * iItem - item index
- * iSubItem - subitem (column) index
- * return: handle to the edit control
- **/
-static HWND ProfileList_BeginLabelEdit(HWND hList, int iItem, int iSubItem)
-{
- return ProfileList_BeginLabelEdit((LPLISTCTRL)GetUserData(hList), iItem, iSubItem);
-}
-
-/**
* name: ProfileList_GetInsertIndex
* desc: finds index to add the new item to and adds an devider if necessary
* param: hList - handle to listcontrol to search for the index in
@@ -412,148 +390,6 @@ static int ProfileList_GetInsertIndex(HWND hList, LPTSTR pszGroup)
}
/**
- * name: ProfileList_AddNewItem
- * desc: Ask's user for a type and adds new item to the list view
- * param: pList - pointer to the listview's data structure
- * pszList - database settings string, that identifies this category
- *
- * return: TRUE or FALSE
- **/
-static uint8_t ProfileList_AddNewItem(HWND hDlg, LPLISTCTRL pList, const PROFILEENTRY *pEntry)
-{
- LPLCITEM pItem;
- LVITEM lvi;
- MCONTACT m_hContact;
-
- if (PtrIsValid(pList) && (pItem = (LPLCITEM)mir_alloc(sizeof(LCITEM)))) {
- PSGetContact(hDlg, m_hContact);
- pItem->nType = CTRL_LIST_ITEM;
- pItem->wFlags = m_hContact ? CTRLF_HASCUSTOM : 0;
- pItem->iListItem = 0;
- pItem->pszText[0] = nullptr;
- pItem->pszText[1] = nullptr;
- // get category list
- pEntry->GetList((WPARAM)&pItem->idstrListCount, (LPARAM)&pItem->idstrList);
-
- lvi.mask = LVIF_PARAM | LVIF_STATE;
- lvi.stateMask = 0xFFFFFFFF;
- lvi.state = LVIS_FOCUSED | LVIS_SELECTED;
- lvi.iItem = ProfileList_GetInsertIndex(pList->hList, pEntry->szGroup);
- lvi.iSubItem = 0;
- lvi.lParam = (LPARAM)pItem;
- if ((lvi.iItem = ListView_InsertItem(pList->hList, &lvi)) >= 0) {
- ProfileList_BeginLabelEdit(pList, lvi.iItem, 0);
- return TRUE;
- }
- mir_free(pItem);
- MsgErr(hDlg, LPGENW("Sorry, but there is a problem with adding a new item of type \"%s\""), pEntry->szGroup);
- }
- return FALSE;
-}
-
-/**
- * name: ProfileList_AddItemlistFromDB
- * desc: reads an zero based indexed szList from the database of hContacts pszModule and fills a hList
- * param: hList - HANDLE to the list to fill with two columns
- * iItem - index of new listviewitem
- * iImage - image to draw from a imagelist associated with the listview
- * m_hContact - handle to the contact, whose information are read
- * pszModule - the module the information are stored in
- * szCatFormat - name of a database setting that holds the categorytext
- * szValFormat - name of a database setting that holds the valuetext
- * wFlags - flags to set for a new allocated item
- *
- * return number of added rows or -1 if listview's changed flag is set
- **/
-static int ProfileList_AddItemlistFromDB(
- LPLISTCTRL pList,
- int &iItem,
- LPIDSTRLIST idList,
- UINT nList,
- MCONTACT m_hContact,
- LPCSTR pszModule,
- LPCSTR szCatFormat,
- LPCSTR szValFormat,
- uint16_t wFlags)
-{
- DBVARIANT dbvVal, dbvCat;
- LPLCITEM pItem;
- LVITEM lvi;
- UINT i, j = 0;
- CHAR pszSetting[MAXSETTING];
-
- lvi.iSubItem = 0;
- lvi.mask = LVIF_PARAM;
-
- for (i = 0, lvi.iItem = iItem; ; i++) {
- // read the setting from db
- mir_snprintf(pszSetting, szValFormat, i);
- if (DB::Setting::GetWString(m_hContact, pszModule, pszSetting, &dbvVal))
- break;
- if (dbvVal.type != DBVT_WCHAR)
- continue;
- mir_snprintf(pszSetting, szCatFormat, i);
- DB::Setting::GetAString(m_hContact, pszModule, pszSetting, &dbvCat);
- // create the itemobject
- if (!(pItem = (LPLCITEM)mir_alloc(sizeof(LCITEM)))) {
- db_free(&dbvCat);
- db_free(&dbvVal);
- break;
- }
- // fill item struct
- pItem->nType = CTRL_LIST_ITEM;
- pItem->idstrList = idList;
- pItem->idstrListCount = nList;
- pItem->iListItem = 0;
- pItem->pszText[0] = nullptr;
- pItem->pszText[1] = dbvVal.pwszVal;
- pItem->wFlags = wFlags;
- lvi.lParam = (LPARAM)pItem;
-
- // get id-str-list-item for the category string
- if (idList != nullptr) {
- for (j = 0; j < nList; j++) {
- switch (dbvCat.type) {
- case DBVT_BYTE:
- if (dbvCat.bVal != (uint8_t)idList[j].nID)
- continue;
- break;
- case DBVT_WORD:
- if (dbvCat.wVal != (uint16_t)idList[j].nID)
- continue;
- break;
- case DBVT_DWORD:
- if (dbvCat.dVal != (uint32_t)idList[j].nID)
- continue;
- break;
- case DBVT_ASCIIZ:
- if (mir_strcmp(dbvCat.pszVal, idList[j].pszText))
- continue;
- break;
- }
- pItem->iListItem = j;
- break;
- }
- }
- // item not found in the predefined category list?
- if ((idList == nullptr || j == nList) && dbvCat.type == DBVT_ASCIIZ) {
- pItem->pszText[0] = mir_a2u(dbvCat.pszVal);
- db_free(&dbvCat);
- }
- if ((lvi.iItem = ListView_InsertItem(pList->hList, &lvi)) < 0) {
- mir_free(pItem);
- db_free(&dbvCat);
- db_free(&dbvVal);
- break;
- }
- lvi.iItem++;
- dbvCat.type = dbvVal.type = DBVT_DELETED;
- }
- iItem = lvi.iItem;
- return i;
-}
-
-/**
* name: ProfileList_DropdownProc
* desc: procedure to catch messages for a listbox control for my own combobox
* param: hwnd - handle to the listview control's window
@@ -613,7 +449,7 @@ static LRESULT CALLBACK ProfileList_DropdownProc(HWND hwnd, UINT msg, WPARAM wPa
else
pList->labelEdit.dropDown.iItem = -1;
- ProfileList_EndLabelEdit(pList->hList, TRUE);
+ ProfileList_EndLabelEdit(pList, TRUE);
return 0;
}
case WM_KILLFOCUS:
@@ -654,24 +490,20 @@ static LRESULT CALLBACK ProfileList_LabelEditProc(HWND hwnd, UINT msg, WPARAM wP
SendMessage(pList->hList, WM_COMMAND, MAKEWPARAM(BTN_EDIT, BN_CLICKED), (LPARAM)pList->labelEdit.hBtn);
return 0;
case VK_RETURN:
- {
- uint8_t bEditNext;
- int iItem;
-
- if (GetWindowLongPtr(hwnd, GWL_STYLE) & ES_WANTRETURN && !(GetKeyState(VK_CONTROL) & 0x8000))
- break;
- if (PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))) {
- bEditNext = !pList->labelEdit.iSubItem && !ProfileList_GetItemText(pList->hList, pList->labelEdit.iItem, 1, nullptr, NULL);
- iItem = pList->labelEdit.iItem;
- ProfileList_EndLabelEdit(pList->hList, TRUE);
- if (bEditNext) ProfileList_BeginLabelEdit(pList->hList, pList->labelEdit.iItem, 1);
- }
- return 0;
+ if (GetWindowLongPtr(hwnd, GWL_STYLE) & ES_WANTRETURN && !(GetKeyState(VK_CONTROL) & 0x8000))
+ break;
+
+ if (PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))) {
+ bool bEditNext = !pList->labelEdit.iSubItem && !ProfileList_GetItemText(pList->hList, pList->labelEdit.iItem, 1, nullptr, NULL);
+ ProfileList_EndLabelEdit(pList, TRUE);
+ if (bEditNext)
+ ProfileList_BeginLabelEdit(pList, pList->labelEdit.iItem, 1);
}
+ return 0;
+
case VK_TAB:
if (PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))) {
LVITEM lvi;
-
lvi.mask = LVIF_STATE;
lvi.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
lvi.iItem = pList->labelEdit.iItem;
@@ -679,11 +511,9 @@ static LRESULT CALLBACK ProfileList_LabelEditProc(HWND hwnd, UINT msg, WPARAM wP
if (!pList->labelEdit.iSubItem) {
lvi.iSubItem = 1;
lvi.state = LVIS_FOCUSED | LVIS_SELECTED;
- ProfileList_EndLabelEdit(pList->hList, TRUE);
+ ProfileList_EndLabelEdit(pList, TRUE);
}
else {
- UINT iSubItem = 0;
-
lvi.iSubItem = 0;
lvi.state = 0;
@@ -694,11 +524,10 @@ static LRESULT CALLBACK ProfileList_LabelEditProc(HWND hwnd, UINT msg, WPARAM wP
return 0;
// search for next valid list item (skip deviders)
- lvi.iSubItem = iSubItem;
+ lvi.iSubItem = 0;
lvi.mask = LVIF_PARAM;
do {
lvi.iItem++;
-
if (lvi.iItem == -1 || !ListView_GetItem(pList->hList, &lvi))
return 0;
}
@@ -710,26 +539,27 @@ static LRESULT CALLBACK ProfileList_LabelEditProc(HWND hwnd, UINT msg, WPARAM wP
if (!ListView_SetItem(pList->hList, &lvi))
return 0;
}
- ProfileList_BeginLabelEdit(pList->hList, lvi.iItem, lvi.iSubItem);
+ ProfileList_BeginLabelEdit(pList, lvi.iItem, lvi.iSubItem);
return 0;
}
return 1;
}
break;
+
case WM_GETDLGCODE:
return DLGC_WANTALLKEYS | mir_callNextSubclass(hwnd, ProfileList_LabelEditProc, msg, wParam, lParam);
+
case WM_KILLFOCUS:
- {
- HWND hwndFocus = GetFocus();
+ HWND hwndFocus = GetFocus();
- if (PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))
- && hwndFocus != pList->labelEdit.dropDown.hDrop
- && hwndFocus != pList->labelEdit.hEdit
- && hwndFocus != pList->labelEdit.hBtn)
- ProfileList_EndLabelEdit(pList, hwndFocus == pList->hList);
- return 0;
- }
+ if (PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))
+ && hwndFocus != pList->labelEdit.dropDown.hDrop
+ && hwndFocus != pList->labelEdit.hEdit
+ && hwndFocus != pList->labelEdit.hBtn)
+ ProfileList_EndLabelEdit(pList, hwndFocus == pList->hList);
+ return 0;
}
+
return mir_callNextSubclass(hwnd, ProfileList_LabelEditProc, msg, wParam, lParam);
}
@@ -744,7 +574,7 @@ static LRESULT CALLBACK ProfileList_LabelEditProc(HWND hwnd, UINT msg, WPARAM wP
**/
static LRESULT CALLBACK ProfileList_SubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
- LPLISTCTRL pList;
+ LPLISTCTRL pList = (LPLISTCTRL)GetUserData(hwnd);
LVHITTESTINFO hi;
switch (msg) {
@@ -758,13 +588,13 @@ static LRESULT CALLBACK ProfileList_SubclassProc(HWND hwnd, UINT msg, WPARAM wPa
nCurSel = ListView_GetSelectionMark(hwnd);
if (nCurSel == -1)
break;
- ProfileList_BeginLabelEdit(hwnd, nCurSel, 0);
+ ProfileList_BeginLabelEdit(pList, nCurSel, 0);
return 0;
case VK_F3:
nCurSel = ListView_GetSelectionMark(hwnd);
if (nCurSel == -1)
break;
- ProfileList_BeginLabelEdit(hwnd, nCurSel, 1);
+ ProfileList_BeginLabelEdit(pList, nCurSel, 1);
return 0;
case VK_UP:
case VK_DOWN:
@@ -796,10 +626,11 @@ static LRESULT CALLBACK ProfileList_SubclassProc(HWND hwnd, UINT msg, WPARAM wPa
ListView_SetSelectionMark(hwnd, lvi.iItem);
return 0;
}
- break;
}
+ break;
+
case WM_MOUSEMOVE:
- if (PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd))) {
+ if (PtrIsValid(pList)) {
RECT rchWnd, rcItem;
SIZE textSize;
@@ -872,13 +703,12 @@ static LRESULT CALLBACK ProfileList_SubclassProc(HWND hwnd, UINT msg, WPARAM wPa
}
return 0;
- // begin label edit
- case WM_LBUTTONDBLCLK:
+ case WM_LBUTTONDBLCLK: // begin label edit
{
hi.pt.x = GET_X_LPARAM(lParam);
hi.pt.y = GET_Y_LPARAM(lParam);
if (ListView_SubItemHitTest(hwnd, &hi))
- ProfileList_BeginLabelEdit(hwnd, hi.iItem, hi.iSubItem);
+ ProfileList_BeginLabelEdit(pList, hi.iItem, hi.iSubItem);
return TRUE;
}
@@ -902,75 +732,72 @@ static LRESULT CALLBACK ProfileList_SubclassProc(HWND hwnd, UINT msg, WPARAM wPa
switch (LOWORD(wParam)) {
// show dropdown menu for category list
case BTN_EDIT:
- {
- int i;
- wchar_t szEdit[MAX_PATH];
-
- if (!PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd)))
- break;
- GetWindowText(pList->labelEdit.hEdit, szEdit, _countof(szEdit));
-
- // need to create the dropdown list?
- if (pList->labelEdit.dropDown.hDrop == nullptr) {
- const int listHeight = 120;
- RECT rc, rcList;
- int add;
-
- // dropdown rect
- GetClientRect(pList->hList, &rcList);
- rc.left = pList->labelEdit.rcCombo.left;
- rc.right = pList->labelEdit.rcCombo.right + pList->labelEdit.rcCombo.bottom - pList->labelEdit.rcCombo.top;
-
- if (rcList.bottom < pList->labelEdit.rcCombo.bottom + listHeight) {
- rc.bottom = pList->labelEdit.rcCombo.bottom - 7; // don't ask me why!
- rc.top = rc.bottom - listHeight;
- }
- else {
- rc.top = pList->labelEdit.rcCombo.bottom;
- rc.bottom = rc.top + listHeight;
- }
+ int i;
+ wchar_t szEdit[MAX_PATH];
- pList->labelEdit.dropDown.hDrop = CreateWindowEx(0, L"LISTBOX", nullptr,
- WS_CHILD | WS_BORDER | WS_VSCROLL | LBS_COMBOBOX | LBS_HASSTRINGS,
- rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
- hwnd, nullptr, g_plugin.getInst(), nullptr);
- if (!pList->labelEdit.dropDown.hDrop)
- return FALSE;
- SetUserData(pList->labelEdit.dropDown.hDrop, pList);
- mir_subclassWindow(pList->labelEdit.dropDown.hDrop, ProfileList_DropdownProc);
- SetWindowLongPtr(pList->labelEdit.dropDown.hDrop, GWLP_ID, LIST_DROPDOWN);
- SendMessage(pList->labelEdit.dropDown.hDrop, WM_SETFONT, (WPARAM)SendMessage(GetParent(pList->hList), WM_GETFONT, 0, 0), 0);
-
- // add items
- for (i = 0; i < pList->labelEdit.pItem->idstrListCount; i++) {
- add = ListBox_AddString(pList->labelEdit.dropDown.hDrop, pList->labelEdit.pItem->idstrList[i].ptszTranslated);
- ListBox_SetItemData(pList->labelEdit.dropDown.hDrop, add, pList->labelEdit.pItem->idstrList + i);
- if (!mir_wstrcmp(szEdit, pList->labelEdit.pItem->idstrList[i].ptszTranslated))
- ListBox_SetCurSel(pList->labelEdit.dropDown.hDrop, add);
- }
+ if (!PtrIsValid(pList = (LPLISTCTRL)GetUserData(hwnd)))
+ break;
+ GetWindowText(pList->labelEdit.hEdit, szEdit, _countof(szEdit));
+
+ // need to create the dropdown list?
+ if (pList->labelEdit.dropDown.hDrop == nullptr) {
+ const int listHeight = 120;
+ RECT rc, rcList;
+ int add;
+
+ // dropdown rect
+ GetClientRect(pList->hList, &rcList);
+ rc.left = pList->labelEdit.rcCombo.left;
+ rc.right = pList->labelEdit.rcCombo.right + pList->labelEdit.rcCombo.bottom - pList->labelEdit.rcCombo.top;
+
+ if (rcList.bottom < pList->labelEdit.rcCombo.bottom + listHeight) {
+ rc.bottom = pList->labelEdit.rcCombo.bottom - 7; // don't ask me why!
+ rc.top = rc.bottom - listHeight;
}
else {
- LPIDSTRLIST lpidList;
-
- i = 0;
- while (PtrIsValid(lpidList = (LPIDSTRLIST)ListBox_GetItemData(pList->labelEdit.dropDown.hDrop, i))) {
- if (!mir_wstrcmp(szEdit, lpidList->ptszTranslated)) {
- ListBox_SetCurSel(pList->labelEdit.dropDown.hDrop, i);
- break;
- }
- i++;
- }
- if (i == pList->labelEdit.pItem->idstrListCount)
- ListBox_SetCurSel(pList->labelEdit.dropDown.hDrop, -1);
+ rc.top = pList->labelEdit.rcCombo.bottom;
+ rc.bottom = rc.top + listHeight;
}
- if (IsWindowVisible(pList->labelEdit.dropDown.hDrop)) {
- SetFocus(pList->labelEdit.hEdit);
+
+ pList->labelEdit.dropDown.hDrop = CreateWindowEx(0, L"LISTBOX", nullptr,
+ WS_CHILD | WS_BORDER | WS_VSCROLL | LBS_COMBOBOX | LBS_HASSTRINGS,
+ rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
+ hwnd, nullptr, g_plugin.getInst(), nullptr);
+ if (!pList->labelEdit.dropDown.hDrop)
+ return FALSE;
+ SetUserData(pList->labelEdit.dropDown.hDrop, pList);
+ mir_subclassWindow(pList->labelEdit.dropDown.hDrop, ProfileList_DropdownProc);
+ SetWindowLongPtr(pList->labelEdit.dropDown.hDrop, GWLP_ID, LIST_DROPDOWN);
+ SendMessage(pList->labelEdit.dropDown.hDrop, WM_SETFONT, (WPARAM)SendMessage(GetParent(pList->hList), WM_GETFONT, 0, 0), 0);
+
+ // add items
+ for (i = 0; i < pList->labelEdit.pItem->idstrListCount; i++) {
+ add = ListBox_AddString(pList->labelEdit.dropDown.hDrop, pList->labelEdit.pItem->idstrList[i].ptszTranslated);
+ ListBox_SetItemData(pList->labelEdit.dropDown.hDrop, add, pList->labelEdit.pItem->idstrList + i);
+ if (!mir_wstrcmp(szEdit, pList->labelEdit.pItem->idstrList[i].ptszTranslated))
+ ListBox_SetCurSel(pList->labelEdit.dropDown.hDrop, add);
}
- else {
- ShowWindow(pList->labelEdit.dropDown.hDrop, SW_SHOW);
- //SetFocus(pList->labelEdit.dropDown.hDrop);
+ }
+ else {
+ LPIDSTRLIST lpidList;
+
+ i = 0;
+ while (PtrIsValid(lpidList = (LPIDSTRLIST)ListBox_GetItemData(pList->labelEdit.dropDown.hDrop, i))) {
+ if (!mir_wstrcmp(szEdit, lpidList->ptszTranslated)) {
+ ListBox_SetCurSel(pList->labelEdit.dropDown.hDrop, i);
+ break;
+ }
+ i++;
}
- break;
+ if (i == pList->labelEdit.pItem->idstrListCount)
+ ListBox_SetCurSel(pList->labelEdit.dropDown.hDrop, -1);
+ }
+ if (IsWindowVisible(pList->labelEdit.dropDown.hDrop)) {
+ SetFocus(pList->labelEdit.hEdit);
+ }
+ else {
+ ShowWindow(pList->labelEdit.dropDown.hDrop, SW_SHOW);
+ //SetFocus(pList->labelEdit.dropDown.hDrop);
}
}
break;
@@ -1017,61 +844,187 @@ static LRESULT CALLBACK ProfileList_SubclassProc(HWND hwnd, UINT msg, WPARAM wPa
* return: 0 or 1
**/
-struct PSPContactProfileDlg : public PSPBaseDlg
+class PSPContactProfileDlg : public PSPBaseDlg
{
+ CCtrlListView m_list;
+
+ /**
+ * name: ProfileList_AddItemlistFromDB
+ * desc: reads an zero based indexed szList from the database of hContacts pszModule and fills a hList
+ * param: iItem - index of new listviewitem
+ * iImage - image to draw from a imagelist associated with the listview
+ * hContact - handle to the contact, whose information are read
+ * pszModule - the module the information are stored in
+ * szCatFormat - name of a database setting that holds the categorytext
+ * szValFormat - name of a database setting that holds the valuetext
+ * wFlags - flags to set for a new allocated item
+ *
+ * return number of added rows or -1 if listview's changed flag is set
+ **/
+
+ int ProfileList_AddItemlistFromDB(
+ int &iItem,
+ LPIDSTRLIST idList,
+ int nList,
+ MCONTACT hContact,
+ LPCSTR pszModule,
+ LPCSTR szCatFormat,
+ LPCSTR szValFormat,
+ uint16_t wFlags)
+ {
+ DBVARIANT dbvVal, dbvCat;
+ CHAR pszSetting[MAXSETTING];
+
+ LVITEM lvi;
+ lvi.iSubItem = 0;
+ lvi.mask = LVIF_PARAM;
+ lvi.iItem = iItem;
+
+ int i;
+ for (i = 0; ; i++) {
+ // read the setting from db
+ mir_snprintf(pszSetting, szValFormat, i);
+ if (DB::Setting::GetWString(hContact, pszModule, pszSetting, &dbvVal))
+ break;
+ if (dbvVal.type != DBVT_WCHAR)
+ continue;
+ mir_snprintf(pszSetting, szCatFormat, i);
+ DB::Setting::GetAString(hContact, pszModule, pszSetting, &dbvCat);
+
+ // create the item object
+ LPLCITEM pItem = (LPLCITEM)mir_alloc(sizeof(LCITEM));
+ pItem->nType = CTRL_LIST_ITEM;
+ pItem->idstrList = idList;
+ pItem->idstrListCount = nList;
+ pItem->iListItem = 0;
+ pItem->pszText[0] = nullptr;
+ pItem->pszText[1] = dbvVal.pwszVal;
+ pItem->wFlags = wFlags;
+ lvi.lParam = (LPARAM)pItem;
+
+ // get id-str-list-item for the category string
+ int j = 0;
+ if (idList != nullptr) {
+ for (j = 0; j < nList; j++) {
+ switch (dbvCat.type) {
+ case DBVT_BYTE:
+ if (dbvCat.bVal != (uint8_t)idList[j].nID)
+ continue;
+ break;
+ case DBVT_WORD:
+ if (dbvCat.wVal != (uint16_t)idList[j].nID)
+ continue;
+ break;
+ case DBVT_DWORD:
+ if (dbvCat.dVal != (uint32_t)idList[j].nID)
+ continue;
+ break;
+ case DBVT_ASCIIZ:
+ if (mir_strcmp(dbvCat.pszVal, idList[j].pszText))
+ continue;
+ break;
+ }
+ pItem->iListItem = j;
+ break;
+ }
+ }
+ // item not found in the predefined category list?
+ if ((idList == nullptr || j == nList) && dbvCat.type == DBVT_ASCIIZ) {
+ pItem->pszText[0] = mir_a2u(dbvCat.pszVal);
+ db_free(&dbvCat);
+ }
+ if ((lvi.iItem = m_list.InsertItem(&lvi)) < 0) {
+ mir_free(pItem);
+ db_free(&dbvCat);
+ db_free(&dbvVal);
+ break;
+ }
+ lvi.iItem++;
+ dbvCat.type = dbvVal.type = DBVT_DELETED;
+ }
+ iItem = lvi.iItem;
+ return i;
+ }
+
+ bool ProfileList_AddNewItem(const PROFILEENTRY *pEntry)
+ {
+ LPLCITEM pItem = (LPLCITEM)mir_alloc(sizeof(LCITEM));
+ pItem->nType = CTRL_LIST_ITEM;
+ pItem->wFlags = m_hContact ? CTRLF_HASCUSTOM : 0;
+ pItem->iListItem = 0;
+ pItem->pszText[0] = nullptr;
+ pItem->pszText[1] = nullptr;
+ // get category list
+ pEntry->GetList((WPARAM)&pItem->idstrListCount, (LPARAM)&pItem->idstrList);
+
+ LVITEM lvi;
+ lvi.mask = LVIF_PARAM | LVIF_STATE;
+ lvi.stateMask = 0xFFFFFFFF;
+ lvi.state = LVIS_FOCUSED | LVIS_SELECTED;
+ lvi.iItem = ProfileList_GetInsertIndex(m_list.GetHwnd(), pEntry->szGroup);
+ lvi.iSubItem = 0;
+ lvi.lParam = (LPARAM)pItem;
+ if ((lvi.iItem = m_list.InsertItem(&lvi)) >= 0) {
+ ProfileList_BeginLabelEdit(pList, lvi.iItem, 0);
+ return true;
+ }
+
+ mir_free(pItem);
+ MsgErr(m_hwnd, LPGENW("Sorry, but there is a problem with adding a new item of type \"%s\""), pEntry->szGroup);
+ return false;
+ }
+
+public:
PSPContactProfileDlg() :
- PSPBaseDlg(IDD_CONTACT_PROFILE)
- {}
+ PSPBaseDlg(IDD_CONTACT_PROFILE),
+ m_list(this, LIST_PROFILE)
+ {
+ pList = (LPLISTCTRL)mir_calloc(sizeof(LISTCTRL));
+ }
- HWND hList;
LPLISTCTRL pList;
bool OnInitDialog() override
{
- LVCOLUMN lvc;
- RECT rc;
- LOGFONT lf;
- HFONT hFont;
-
- hList = GetDlgItem(m_hwnd, LIST_PROFILE);
- if (!hList || !(pList = (LPLISTCTRL)mir_calloc(sizeof(LISTCTRL))))
- return FALSE;
-
Ctrl_InitTextColours();
// init info structure
- pList->hList = hList;
+ pList->hList = m_list.GetHwnd();
pList->nType = CTRL_LIST_PROFILE;
memset(&pList->labelEdit, 0, sizeof(pList->labelEdit));
- SetUserData(hList, pList);
+ SetUserData(m_list.GetHwnd(), pList);
// set new window procedure
- mir_subclassWindow(hList, ProfileList_SubclassProc);
+ mir_subclassWindow(m_list.GetHwnd(), ProfileList_SubclassProc);
// remove static edge in aero mode
if (IsAeroMode())
- SetWindowLongPtr(hList, GWL_EXSTYLE, GetWindowLongPtr(hList, GWL_EXSTYLE) & ~WS_EX_STATICEDGE);
+ SetWindowLongPtr(m_list.GetHwnd(), GWL_EXSTYLE, GetWindowLongPtr(m_list.GetHwnd(), GWL_EXSTYLE) & ~WS_EX_STATICEDGE);
// insert columns into the listboxes
- ListView_SetExtendedListViewStyle(hList, LVS_EX_FULLROWSELECT);
+ m_list.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT);
+ HFONT hFont;
PSGetBoldFont(m_hwnd, hFont);
SendDlgItemMessage(m_hwnd, IDC_PAGETITLE, WM_SETFONT, (WPARAM)hFont, 0);
// set listfont
- pList->hFont = (HFONT)SendMessage(hList, WM_GETFONT, 0, 0);
+ pList->hFont = (HFONT)m_list.SendMsg(WM_GETFONT, 0, 0);
pList->wFlags |= LVF_EDITLABEL;
+
+ LOGFONT lf;
GetObject(pList->hFont, sizeof(lf), &lf);
lf.lfHeight -= 6;
hFont = CreateFontIndirect(&lf);
- SendMessage(hList, WM_SETFONT, (WPARAM)hFont, 0);
+ m_list.SendMsg(WM_SETFONT, (WPARAM)hFont, 0);
- GetClientRect(hList, &rc);
+ RECT rc;
+ GetClientRect(m_list.GetHwnd(), &rc);
rc.right -= GetSystemMetrics(SM_CXVSCROLL);
// initiate the tooltips
pList->hTip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, nullptr, WS_POPUP | TTS_BALLOON | TTS_NOPREFIX | TTS_ALWAYSTIP,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hList, nullptr, g_plugin.getInst(), nullptr);
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, m_list.GetHwnd(), nullptr, g_plugin.getInst(), nullptr);
if (pList->hTip) {
SetWindowPos(pList->hTip, HWND_TOPMOST, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
@@ -1081,18 +1034,19 @@ struct PSPContactProfileDlg : public PSPBaseDlg
ti.cbSize = sizeof(TOOLINFO);
ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS | TTF_TRANSPARENT;
ti.hinst = g_plugin.getInst();
- ti.hwnd = hList;
- ti.uId = (UINT_PTR)hList;
+ ti.hwnd = m_list.GetHwnd();
+ ti.uId = (UINT_PTR)m_list.GetHwnd();
SendMessage(pList->hTip, TTM_ADDTOOL, NULL, (LPARAM)&ti);
SendMessage(pList->hTip, TTM_ACTIVATE, FALSE, (LPARAM)&ti);
}
// insert columns into the listboxes
+ LVCOLUMN lvc;
lvc.mask = LVCF_WIDTH;
lvc.cx = rc.right / 8 * 3;
- ListView_InsertColumn(hList, 0, &lvc);
+ m_list.InsertColumn(0, &lvc);
lvc.cx = rc.right / 8 * 5;
- ListView_InsertColumn(hList, 1, &lvc);
+ m_list.InsertColumn(1, &lvc);
return true;
}
@@ -1116,7 +1070,7 @@ struct PSPContactProfileDlg : public PSPBaseDlg
lvi.pszText = szGroup;
lvi.cchTextMax = _countof(szGroup);
- for (iItem = lvi.iItem = lvi.iSubItem = 0; ListView_GetItem(hList, &lvi); lvi.iItem++) {
+ for (iItem = lvi.iItem = lvi.iSubItem = 0; m_list.GetItem(&lvi); lvi.iItem++) {
if (!PtrIsValid(pItem = (LPLCITEM)lvi.lParam)) {
// delete reluctant items
if (iFmt < _countof(pFmt)) {
@@ -1153,7 +1107,7 @@ struct PSPContactProfileDlg : public PSPBaseDlg
// redraw the item if required
if (pItem->wFlags & CTRLF_CHANGED) {
pItem->wFlags &= ~CTRLF_CHANGED;
- ListView_RedrawItems(hList, lvi.iItem, lvi.iItem);
+ m_list.RedrawItems(lvi.iItem, lvi.iItem);
}
iItem++;
}
@@ -1172,20 +1126,18 @@ struct PSPContactProfileDlg : public PSPBaseDlg
bool OnRefresh() override
{
- LPCSTR pszProto;
- uint8_t msgResult = 0;
- LPIDSTRLIST idList;
- UINT nList;
- uint8_t i;
int iItem = 0, iGrp = 0, numProtoItems, numUserItems;
+ LPCSTR pszProto;
if (!(pList->wFlags & CTRLF_CHANGED) && PSGetBaseProto(m_hwnd, pszProto) && *pszProto != 0) {
- ProfileList_Clear(hList);
+ ProfileList_Clear(m_list.GetHwnd());
// insert the past information
- for (i = 0; i < 3; i++) {
+ for (int i = 0; i < 3; i++) {
+ int nList;
+ LPIDSTRLIST idList;
pFmt[i].GetList((WPARAM)&nList, (LPARAM)&idList);
- if ((numProtoItems = ProfileList_AddItemlistFromDB(pList, iItem, idList, nList, m_hContact, pszProto, pFmt[i].szCatFmt, pFmt[i].szValFmt, CTRLF_HASPROTO)) < 0)
+ if ((numProtoItems = ProfileList_AddItemlistFromDB(iItem, idList, nList, m_hContact, pszProto, pFmt[i].szCatFmt, pFmt[i].szValFmt, CTRLF_HASPROTO)) < 0)
return false;
// scan all basic protocols for the subcontacts
@@ -1195,7 +1147,7 @@ struct PSPContactProfileDlg : public PSPBaseDlg
LPCSTR pszSubBaseProto;
if ((hDefContact = db_mc_getSub(m_hContact, iDefault)) && (pszSubBaseProto = Proto_GetBaseAccountName(hDefContact))) {
- if ((numProtoItems += ProfileList_AddItemlistFromDB(pList, iItem, idList, nList, hDefContact, pszSubBaseProto, pFmt[i].szCatFmt, pFmt[i].szValFmt, CTRLF_HASMETA | CTRLF_HASPROTO)) < 0)
+ if ((numProtoItems += ProfileList_AddItemlistFromDB(iItem, idList, nList, hDefContact, pszSubBaseProto, pFmt[i].szCatFmt, pFmt[i].szValFmt, CTRLF_HASMETA | CTRLF_HASPROTO)) < 0)
return false;
// copy the missing settings from the other subcontacts
@@ -1207,17 +1159,16 @@ struct PSPContactProfileDlg : public PSPBaseDlg
continue;
if (!(pszSubBaseProto = Proto_GetBaseAccountName(hSubContact)))
continue;
- if ((numProtoItems += ProfileList_AddItemlistFromDB(pList, iItem, idList, nList, hSubContact, pszSubBaseProto, pFmt[i].szCatFmt, pFmt[i].szValFmt, CTRLF_HASMETA | CTRLF_HASPROTO)) < 0)
+ if ((numProtoItems += ProfileList_AddItemlistFromDB(iItem, idList, nList, hSubContact, pszSubBaseProto, pFmt[i].szCatFmt, pFmt[i].szValFmt, CTRLF_HASMETA | CTRLF_HASPROTO)) < 0)
return false;
}
}
}
- if ((numUserItems = ProfileList_AddItemlistFromDB(pList, iItem, idList, nList, m_hContact, USERINFO, pFmt[i].szCatFmt, pFmt[i].szValFmt, CTRLF_HASCUSTOM)) < 0)
+ if ((numUserItems = ProfileList_AddItemlistFromDB(iItem, idList, nList, m_hContact, USERINFO, pFmt[i].szCatFmt, pFmt[i].szValFmt, CTRLF_HASCUSTOM)) < 0)
return false;
if (numUserItems || numProtoItems) {
- msgResult = PSP_CHANGED;
- ProfileList_AddGroup(hList, pFmt[i].szGroup, iGrp);
+ ProfileList_AddGroup(m_list.GetHwnd(), pFmt[i].szGroup, iGrp);
iGrp = ++iItem;
}
}
@@ -1242,7 +1193,7 @@ struct PSPContactProfileDlg : public PSPBaseDlg
// some account data may have changed so reread database
switch (((LPNMHDR)lParam)->code) {
case PSN_KILLACTIVE: // user swiches to another propertysheetpage
- ProfileList_EndLabelEdit(hList, TRUE);
+ ProfileList_EndLabelEdit(pList, TRUE);
break;
}
break;
@@ -1306,8 +1257,8 @@ struct PSPContactProfileDlg : public PSPBaseDlg
return 0;
case LVN_GETDISPINFO:
- if (pList->labelEdit.iTopIndex != ListView_GetTopIndex(hList))
- ProfileList_EndLabelEdit(((LPNMHDR)lParam)->hwndFrom, FALSE);
+ if (pList->labelEdit.iTopIndex != m_list.GetTopIndex())
+ ProfileList_EndLabelEdit(pList, FALSE);
break;
case NM_CUSTOMDRAW:
@@ -1389,28 +1340,27 @@ struct PSPContactProfileDlg : public PSPBaseDlg
case WM_COMMAND:
switch (LOWORD(wParam)) {
case BTN_ADD_intEREST:
- return ProfileList_AddNewItem(m_hwnd, (LPLISTCTRL)GetUserData(hList), &pFmt[2]);
+ return ProfileList_AddNewItem(&pFmt[2]);
case BTN_ADD_AFFLIATION:
- return ProfileList_AddNewItem(m_hwnd, (LPLISTCTRL)GetUserData(hList), &pFmt[1]);
+ return ProfileList_AddNewItem(&pFmt[1]);
case BTN_ADD_PAST:
- return ProfileList_AddNewItem(m_hwnd, (LPLISTCTRL)GetUserData(hList), &pFmt[0]);
+ return ProfileList_AddNewItem(&pFmt[0]);
case BTN_EDIT_CAT:
- ProfileList_BeginLabelEdit(hList, ListView_GetSelectionMark(hList), 0);
+ ProfileList_BeginLabelEdit(pList, m_list.GetSelectionMark(), 0);
break;
case BTN_EDIT_VAL:
- ProfileList_BeginLabelEdit(hList, ListView_GetSelectionMark(hList), 1);
+ ProfileList_BeginLabelEdit(pList, m_list.GetSelectionMark(), 1);
break;
case BTN_DEL:
if (IDYES == MsgBox(m_hwnd, MB_YESNO | MB_ICON_QUESTION, LPGENW("Question"), LPGENW("Delete an entry"), LPGENW("Do you really want to delete this entry?"))) {
- int iItem = ListView_GetSelectionMark(hList);
- ProfileList_DeleteItem(hList, iItem);
+ int iItem = m_list.GetSelectionMark();
+ ProfileList_DeleteItem(m_list.GetHwnd(), iItem);
- if (PtrIsValid(pList))
- pList->wFlags |= CTRLF_CHANGED;
+ pList->wFlags |= CTRLF_CHANGED;
SendMessage(GetParent(m_hwnd), PSM_CHANGED, NULL, NULL);
// check if to delete any devider
- if (!ProfileList_GetItemData(hList, iItem--) && !ProfileList_GetItemData(hList, iItem))
- ListView_DeleteItem(hList, iItem);
+ if (!ProfileList_GetItemData(m_list.GetHwnd(), iItem--) && !ProfileList_GetItemData(m_list.GetHwnd(), iItem))
+ m_list.DeleteItem(iItem);
}
break;
}
diff --git a/plugins/UserInfoEx/src/version.h b/plugins/UserInfoEx/src/version.h
index 798e0d7831..191d376c3e 100644
--- a/plugins/UserInfoEx/src/version.h
+++ b/plugins/UserInfoEx/src/version.h
@@ -1,7 +1,7 @@
#define __MAJOR_VERSION 0
#define __MINOR_VERSION 9
#define __RELEASE_NUM 0
-#define __BUILD_NUM 2
+#define __BUILD_NUM 3
#include <stdver.h>