/* 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; // resource id of the property page LPDLGTEMPLATE _pTemplate; // locked template for the property page HINSTANCE _hInst; // instance handle of the owning plugin dll DLGPROC _pfnDlgProc; // dialog procedure for the property page HWND _hWnd; // window handle for the property page if shown jet DWORD _dwFlags; // some flags int _iPosition; // initiating position if custom (used for sorting) LPARAM _initParam; MCONTACT _hContact; // contact the page is accociated with (may be a meta subcontact if details dialog is shown for a meta contact) LPCSTR _pszProto; // protocol the page is accociated with (is the contact's protocol if _hContact is not NULL) LPCSTR _pszPrefix; // pointer to the dialog owning contact's protocol HTREEITEM _hItem; // handle to the treeview item if visible (NULL if this item is hidden) int _iParent; // index of the owning tree item int _iImage; // index of treeview item's image BYTE _bState; // initial state of this treeitem LPSTR _pszName; // original name, given by plugin (not customized) LPTSTR _ptszLabel; // string to setting in db holding information about this treeitem LPCSTR GlobalName(); int Icon(HIMAGELIST hIml, OPTIONSDIALOGPAGE *odp, BYTE bInitIconsOnly); int ItemLabel(const BYTE bReadDBValue); int Name(LPTSTR pszTitle, const BYTE bIsUnicode); HICON ProtoIcon(); public: CPsTreeItem(); ~CPsTreeItem(); int Create(CPsHdr* pPsh, OPTIONSDIALOGPAGE *odp); 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 int Image() const { return _iImage; }; __inline int Pos() const { return _iPosition; }; __inline BYTE 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 DWORD Flags() const { return _dwFlags; }; __inline void Flags(DWORD dwFlags) { _dwFlags = dwFlags; }; __inline void AddFlags(DWORD dwFlags) { _dwFlags |= dwFlags; }; __inline void RemoveFlags(DWORD dwFlags) { _dwFlags &= ~dwFlags; }; BYTE HasName(const LPCSTR pszName) const; LPCSTR PropertyKey(LPCSTR pszProperty); LPCSTR GlobalPropertyKey(LPCSTR pszProperty); LPCSTR IconKey(); LPSTR ParentItemName(); HWND CreateWnd(LPPS pPs); WORD DBSaveItemState(LPCSTR pszGroup, int iItemPosition, UINT iState, DWORD 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 "" // 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 _pages; HWND _hWndTree = nullptr; HIMAGELIST _hImages = nullptr; int _curItem = -1; DWORD _dwFlags = 0; HWND _hLabelEdit = nullptr; HTREEITEM _hDragItem = nullptr; bool _isDragging = false; LPPS _pPs = nullptr; WORD 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 DWORD Flags() const { return _dwFlags; } __inline void Flags(DWORD dwFlags) { _dwFlags = dwFlags; } __inline void AddFlags(DWORD dwFlags) { _dwFlags |= dwFlags; } __inline void RemoveFlags(DWORD dwFlags) { _dwFlags &= ~dwFlags; } __inline int NumItems() const { return _pages.getCount(); } __inline HWND Window() const { return _hWndTree; } __inline HIMAGELIST ImageList() const { return _hImages; } __inline BYTE 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()); }; int AddDummyItem(LPCSTR pszGroup); BYTE Create(HWND hWndTree, CPsHdr *pPsh); BYTE InitTreeItems(LPWORD needWidth); void Remove(HINSTANCE); void HideItem(const int iPageIndex); HTREEITEM ShowItem(const int iPageIndex, LPWORD needWidth); HTREEITEM MoveItem(HTREEITEM hItem, HTREEITEM hInsertAfter, BYTE 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 BYTE bSave); void PopupMenu(); void OnIconsChanged(); BYTE OnInfoChanged(); BYTE 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 WORD _numPages = 0; // number of pages DWORD _dwFlags = 0; // some option flags HIMAGELIST _hImages = 0; // the imagelist with all tree item icons LIST _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; BYTE updateAnimFrame; CHAR szUpdating[64]; DWORD dwFlags; TAckInfo *infosUpdated; int nSubContacts; // controls HWND hDlg; CPsTree *pTree; CPsUpload *pUpload; }; void DlgContactInfoInitTreeIcons(); void DlgContactInfoLoadModule(); void DlgContactInfoUnLoadModule();