From db2ec6c60fc50ea7a66a9d782b1af1017df596ca Mon Sep 17 00:00:00 2001 From: Rozhuk Ivan Date: Wed, 26 Nov 2014 01:08:07 +0000 Subject: CSList code cleanup git-svn-id: http://svn.miranda-ng.org/main/trunk@11078 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/CSList/src/cslist.cpp | 2085 ++++++++++++++++++++--------------------- 1 file changed, 1042 insertions(+), 1043 deletions(-) (limited to 'plugins') diff --git a/plugins/CSList/src/cslist.cpp b/plugins/CSList/src/cslist.cpp index 645850d5e6..de5baa57a5 100644 --- a/plugins/CSList/src/cslist.cpp +++ b/plugins/CSList/src/cslist.cpp @@ -1,1043 +1,1042 @@ -/* ======================================================================== - - Custom Status List - __________________ - - Custom Status List plugin for Miranda-IM (www.miranda-im.org) - Follower of Custom Status History List by HANAX - Copyright © 2006-2008 HANAX - Copyright © 2007-2009 jarvis - Occasionally rewritten in 2012 by George Hazan - - 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. - ======================================================================== */ - -#include "cslist.h" -#include "strpos.h" - -CLIST_INTERFACE *pcli; -int hLangpack; -HINSTANCE g_hInst; - -static LIST arWindows(3, HandleKeySortT); - -PLUGININFOEX pluginInfoEx = -{ - sizeof(PLUGININFOEX), - __PLUGIN_NAME, - PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), - __DESCRIPTION, - __AUTHOR, - __AUTHOREMAIL, - __COPYRIGHT, - __AUTHORWEB, - UNICODE_AWARE, - // {C8CC7414-6507-4AF6-925A-83C1D2F7BE8C} - {0xc8cc7414, 0x6507, 0x4af6, {0x92, 0x5a, 0x83, 0xc1, 0xd2, 0xf7, 0xbe, 0x8c}} -}; - -// ====[ MAIN ]=============================================================== - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - g_hInst = hinstDLL; - return TRUE; -} - -// ====[ PLUGIN INFO ]======================================================== - -extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD) -{ - return &pluginInfoEx; -} - -// ====[ LOADER ]============================================================= - -static int OnDbChanged(WPARAM hContact, LPARAM lparam) -{ - DBCONTACTWRITESETTING *cws = ( DBCONTACTWRITESETTING* )lparam; - - // if user changes his UIN or JID on any account - if (hContact == NULL) { - INT_PTR szUniqueID = CallProtoService(cws->szModule, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); - if (szUniqueID != CALLSERVICE_NOTFOUND && !lstrcmpA(cws->szSetting, (char*)szUniqueID)) - pcli->pfnReloadProtoMenus(); - } - return 0; -} - -static int OnInitOptions(WPARAM wparam, LPARAM lparam) -{ - OPTIONSDIALOGPAGE odp = { sizeof(odp) }; - odp.position = 955000000; - odp.hInstance = g_hInst; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); - odp.pszTitle = MODULENAME; - odp.pfnDlgProc = CSOptionsProc; - odp.pszGroup = LPGEN("Status"); - odp.flags = ODPF_BOLDGROUPS; - Options_AddPage(wparam, &odp); - return 0; -} - -static int OnCreateMenuItems(WPARAM, LPARAM) -{ - int protoCount; - PROTOACCOUNT** pdesc; - ProtoEnumAccounts(&protoCount, &pdesc); - - for (int i = 0; i < protoCount; i++) - if ( ProtoServiceExists(pdesc[i]->szModuleName, PS_SETCUSTOMSTATUSEX)) - addProtoStatusMenuItem(pdesc[i]->szModuleName); - - return 0; -} - -static int OnPreshutdown(WPARAM wparam, LPARAM lparam) -{ - for (int i=0; i < arWindows.getCount(); i++) - DestroyWindow(arWindows[i]->m_handle); - return 0; -} - -extern "C" __declspec(dllexport) int Load() -{ - mir_getLP(&pluginInfoEx); - mir_getCLI(); - - // support for ComboBoxEx - INITCOMMONCONTROLSEX icc; - icc.dwSize = sizeof(icc); - icc.dwICC = ICC_USEREX_CLASSES; - InitCommonControlsEx(&icc); - - // init icons - TCHAR tszFile[MAX_PATH]; - GetModuleFileName( g_hInst, tszFile, MAX_PATH ); - - SKINICONDESC sid = { sizeof(sid) }; - sid.ptszDefaultFile = tszFile; - sid.flags = SIDF_ALL_TCHAR; - sid.cx = sid.cy = 16; - sid.ptszSection = _T(MODULENAME); - - for (int i=0; i < SIZEOF(forms); i++) { - char szSettingName[64]; - mir_snprintf(szSettingName, SIZEOF(szSettingName), "%s_%s", MODNAME, forms[i].pszIconIcoLib); - - sid.pszName = szSettingName; - sid.ptszDescription = forms[i].ptszDescr; - sid.iDefaultIndex = -forms[i].iconNoIcoLib; - forms[i].hIcoLibItem = Skin_AddIcon(&sid); - } - - HookEvent(ME_OPT_INITIALISE, OnInitOptions); - HookEvent(ME_DB_CONTACT_SETTINGCHANGED, OnDbChanged); - HookEvent(ME_CLIST_PREBUILDSTATUSMENU, OnCreateMenuItems); - HookEvent(ME_SYSTEM_PRESHUTDOWN, OnPreshutdown); - - // if we load a plugin dynamically, it will work, otherwise fail - OnCreateMenuItems(0, 0); - return 0; -} - -// ====[ UNLOADER ]=========================================================== - -extern "C" __declspec(dllexport) int Unload() -{ - return 0; -} - -// ====[ FUN ]================================================================ - -void RegisterHotkeys(char buf[200], TCHAR* accName, int Number) -{ - HOTKEYDESC hotkey = { sizeof(hotkey) }; - hotkey.dwFlags = HKD_TCHAR; - hotkey.pszName = buf; - hotkey.ptszDescription = accName; - hotkey.ptszSection = LPGENT("Custom Status List"); - hotkey.pszService = buf; - hotkey.DefHotKey = HOTKEYCODE( HOTKEYF_CONTROL | HOTKEYF_SHIFT, '0' + Number); - Hotkey_Register(&hotkey); -} - -void SetStatus(WORD code, StatusItem* item, char *szAccName) -{ - if ( code == IDCLOSE ) - return; - - PROTOACCOUNT* pdescr = (PROTOACCOUNT*)CallService(MS_PROTO_GETACCOUNT, 0, (LPARAM)szAccName); - if (pdescr == NULL) - return; - - if ( !ProtoServiceExists(szAccName, PS_SETCUSTOMSTATUSEX)) - return; - - int statusToSet; - - CUSTOM_STATUS ics = { sizeof(CUSTOM_STATUS) }; - ics.flags = CSSF_MASK_STATUS | CSSF_MASK_NAME | CSSF_MASK_MESSAGE | CSSF_TCHAR; - - if (code == IDC_CANCEL) { - statusToSet = 0; - ics.ptszName = _T(""); - ics.ptszMessage = _T(""); - } - else if (code == IDOK && item != NULL) { - statusToSet = item->m_iIcon+1; - ics.ptszName = variables_parsedup(item->m_tszTitle, NULL, NULL); - ics.ptszMessage = variables_parsedup(item->m_tszMessage, NULL, NULL); - } - else return; - - ics.status = &statusToSet; - ProtoCallService(szAccName, PS_SETCUSTOMSTATUSEX, 0, (LPARAM)&ics); -} - -INT_PTR showList(WPARAM wparam, LPARAM lparam, LPARAM param) -{ - char* szProto = (char*)param; - for (int i=0; i < arWindows.getCount(); i++) { - CSWindow *p = arWindows[i]; - if ( !strcmp(szProto, p->m_protoName)) { - ShowWindow(p->m_handle, SW_SHOW); - SetForegroundWindow(p->m_handle); - return 1; - } - } - - CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_CSLIST), NULL, CSWindowProc, (LPARAM)new CSWindow(szProto)); - return 0; -} - -void addProtoStatusMenuItem(char *protoName) -{ - PROTOACCOUNT *pdescr = ProtoGetAccount(protoName); - if (pdescr == NULL) - return; - - HGENMENU hRoot = MO_GetProtoRootMenu(pdescr->szModuleName); - if (hRoot == NULL) - return; - - char buf[200]; - mir_snprintf(buf, SIZEOF(buf), "CSList/ShowList/%s", protoName); - if ( !ServiceExists(buf)) - CreateServiceFunctionParam(buf, showList, (LPARAM)protoName); - - CLISTMENUITEM mi = { sizeof(mi) }; - mi.flags = CMIF_CHILDPOPUP | CMIF_TCHAR; - mi.icolibItem = forms[0].hIcoLibItem; - mi.ptszName = _T(MODULENAME); - mi.position = 2000040000; - mi.pszService = buf; - mi.hParentMenu = hRoot; - Menu_AddStatusMenuItem(&mi); - - RegisterHotkeys(buf, pdescr->tszAccountName, pdescr->iOrder); -} - -/////////////////////////////////////////////////////////////////////////////// - -void importCustomStatuses(CSWindow* csw, int result) -{ - DBVARIANT dbv; - char bufTitle[32], bufMessage[32], *protoName = csw->m_protoName; - - for (int i = 0; i < csw->m_statusCount; i++) { - StatusItem* si = new StatusItem(); - si->m_iIcon = i-1; - - mir_snprintf(bufTitle, 32, "XStatus%dName", i); - if ( !db_get_ts( NULL, protoName, bufTitle, &dbv )) { - lstrcpy(si->m_tszTitle, dbv.ptszVal); - db_free(&dbv); - } - else si->m_tszTitle[0] = 0; - - mir_snprintf(bufMessage, 32, "XStatus%dMsg", i); - if ( !db_get_ts( NULL, protoName, bufMessage, &dbv )) { - lstrcpy(si->m_tszMessage, dbv.ptszVal); - db_free(&dbv); - } - else si->m_tszMessage[0] = 0; - - if (si->m_tszTitle[0] || si->m_tszMessage[0]) { - csw->m_itemslist->m_list->add(si); - csw->m_bSomethingChanged = TRUE; - } - else delete si; - - if (result == IDYES) { - db_unset(NULL, protoName, bufTitle); - db_unset(NULL, protoName, bufMessage); - } - } - csw->m_listview->reinitItems(csw->m_itemslist->m_list->getListHead()); -} - -/////////////////////////////////////////////////////////////////////////////// -// CSWindow class - -CSWindow::CSWindow(char *protoName) -{ - m_protoName = protoName; - m_handle = NULL; - m_bExtraIcons = getByte( "AllowExtraIcons", DEFAULT_ALLOW_EXTRA_ICONS ); - m_itemslist = new CSItemsList(m_protoName); - m_listview = NULL; - m_addModifyDlg = NULL; - m_bSomethingChanged = FALSE; - m_filterString = NULL; -} - -void __fastcall SAFE_FREE(void** p) -{ - if (*p) - { - free(*p); - *p = NULL; - } -} - -CSWindow::~CSWindow() -{ - delete m_itemslist; - SAFE_FREE(( void** )&m_filterString ); -} - -void CSWindow::initIcons() -{ - PROTOACCOUNT *pdescr = ProtoGetAccount(m_protoName); - if (pdescr == NULL) - return; - - char *szUniqueID = (char*)CallProtoService(m_protoName, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); - if (szUniqueID == NULL) - return; - - DBVARIANT dbv; - if ( db_get(NULL, pdescr->szModuleName, szUniqueID, &dbv)) - return; - db_free(&dbv); - - WPARAM iNumStatuses = 0; - CUSTOM_STATUS cs = { sizeof(cs) }; - cs.flags = CSSF_STATUSES_COUNT; - cs.wParam = &iNumStatuses; - if ( CallProtoService(pdescr->szModuleName, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&cs) != 0) - return; - - m_statusCount = (int)iNumStatuses; - if (NULL == (m_icons = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, m_statusCount, 0))) - return; - - for (int i=1; i <= m_statusCount; i++) { - HICON hIcon = (HICON)CallProtoService(pdescr->szModuleName, PS_GETCUSTOMSTATUSICON, i, 0); - if (hIcon) { - ImageList_AddIcon(m_icons, hIcon); - DestroyIcon(hIcon); - } - } -} - -void CSWindow::deinitIcons() -{ - ImageList_Destroy( m_icons ); -} - -void CSWindow::initButtons() -{ - for (int i = 0; i < SIZEOF(forms); i++) { - if ( forms[i].idc < 0 ) - continue; - - SendDlgItemMessage( m_handle, forms[i].idc, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Skin_GetIconByHandle(forms[i].hIcoLibItem)); - SendDlgItemMessage( m_handle, forms[i].idc, BUTTONSETASFLATBTN, TRUE, 0 ); //maybe set as BUTTONSETDEFAULT? - SendDlgItemMessage( m_handle, forms[i].idc, BUTTONADDTOOLTIP, (WPARAM )TranslateTS(forms[i].ptszTitle), BATF_TCHAR ); - } -} - -void CSWindow::loadWindowPosition() -{ - if (getByte("RememberWindowPosition", DEFAULT_REMEMBER_WINDOW_POSITION)) - Utils_RestoreWindowPosition(m_handle, NULL, MODNAME, "Position"); -} - -void CSWindow::toggleEmptyListMessage() -{ - HWND hwnd = GetDlgItem( m_handle, IDC_NO_ITEMS ); - ShowWindow( hwnd, ( ListView_GetItemCount( m_listview->m_handle ) > 0 ) ? FALSE : TRUE ); - SetForegroundWindow( hwnd ); - hwnd = GetDlgItem( m_handle, IDC_ADD_SAMPLE ); - ShowWindow( hwnd, ( ListView_GetItemCount( m_listview->m_handle ) > 0 ) ? FALSE : TRUE ); - SetForegroundWindow( hwnd ); -} - -BOOL CSWindow::itemPassedFilter( ListItem< StatusItem >* li ) -{ - TCHAR filter[MAX_PATH]; - GetDlgItemText( m_handle, IDC_FILTER_FIELD, filter, MAX_PATH ); - - if ( lstrlen( filter )) - { - TCHAR title[EXTRASTATUS_TITLE_LIMIT], message[EXTRASTATUS_MESSAGE_LIMIT]; - lstrcpy( title, li->m_item->m_tszTitle ); lstrcpy( message, li->m_item->m_tszMessage ); - if ( strpos( _tcslwr( title ), _tcslwr( filter )) == -1 ) - if ( strpos( _tcslwr( message ), _tcslwr( filter )) == -1 ) - return FALSE; - } - - return TRUE; -} - -void CSWindow::toggleFilter() -{ - HWND hFilter = GetDlgItem( m_handle, IDC_FILTER_FIELD ); - BOOL isEnabled = !IsWindowEnabled( hFilter ) ? TRUE : FALSE; // ! = + isEnabled = !isEnabled in one - EnableWindow( hFilter, isEnabled ); - ShowWindow( hFilter, isEnabled ); - CheckDlgButton( m_handle, IDC_FILTER, isEnabled ); - SetForegroundWindow( hFilter ); - if ( isEnabled ) - SetFocus( hFilter ); - else - { - TCHAR filterText[255]; - GetDlgItemText(m_handle, IDC_FILTER_FIELD, filterText, SIZEOF(filterText)); - if (filterText[0] != 0) - SetDlgItemText( m_handle, IDC_FILTER_FIELD, TEXT( "")); - } -} - -BOOL CSWindow::toggleButtons() -{ - int selection = ListView_GetSelectedItemMacro( m_listview->m_handle ); - BOOL validSelection = ( selection >= 0 && ( unsigned int )selection < m_itemslist->m_list->getCount()) ? TRUE : FALSE; - BOOL filterEnabled = IsWindowVisible( GetDlgItem( m_handle, IDC_FILTER_FIELD )); - BOOL somethingChanged = m_bSomethingChanged; - - EnableWindow( GetDlgItem( m_handle, IDC_ADD ), !filterEnabled ); - EnableWindow( GetDlgItem( m_handle, IDC_MODIFY ), validSelection && !filterEnabled ); - EnableWindow( GetDlgItem( m_handle, IDC_REMOVE ), validSelection && !filterEnabled ); - EnableWindow( GetDlgItem( m_handle, IDC_FAVOURITE ), validSelection && !filterEnabled ); - EnableWindow( GetDlgItem( m_handle, IDC_UNDO ), somethingChanged && !filterEnabled ); - EnableWindow( GetDlgItem( m_handle, IDC_IMPORT ), !filterEnabled ); - EnableWindow( GetDlgItem( m_handle, IDOK ), validSelection ); - - return validSelection; -} - -/////////////////////////////////////////////////////////////////////////////// -// CSAMWindow class - add form window - -CSAMWindow::CSAMWindow( WORD action, CSWindow* parent ) -{ - m_action = action; - m_parent = parent; - m_bChanged = FALSE; - m_hCombo = m_hMessage = NULL; - - if ( m_action == IDC_ADD ) - m_item = new StatusItem(); - else - m_item = new StatusItem( *m_parent->m_itemslist->m_list->get( m_parent->m_listview->getPositionInList()) ); -} - -CSAMWindow::~CSAMWindow() -{ - if ( !m_bChanged ) - delete m_item; -} - -void CSAMWindow::exec() -{ - DialogBoxParam( g_hInst, MAKEINTRESOURCE( IDD_ADDMODIFY ), NULL, CSAMWindowProc, (LPARAM)this ); -} - - -void CSAMWindow::setCombo() -{ - PROTOACCOUNT *pdescr = ProtoGetAccount(m_parent->m_protoName); - if (pdescr == NULL) - return; - - char *szUniqueID = (char*)CallProtoService(pdescr->szModuleName, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); - if (szUniqueID == NULL) - return; - - DBVARIANT dbv; - if ( db_get(NULL, pdescr->szModuleName, szUniqueID, &dbv)) - return; - db_free(&dbv); - - WPARAM iStatus; - TCHAR tszName[100]; - CUSTOM_STATUS cs = { sizeof(cs) }; - cs.flags = CSSF_MASK_NAME | CSSF_DEFAULT_NAME | CSSF_TCHAR; - cs.ptszName = tszName; - cs.wParam = &iStatus; - - SendMessage( m_hCombo, CBEM_SETIMAGELIST, 0, (LPARAM)m_parent->m_icons); - for (int i=1; i <= m_parent->m_statusCount; i++) { - iStatus = i; - if ( CallProtoService(pdescr->szModuleName, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&cs) != 0) - continue; - - COMBOBOXEXITEM cbi = { 0 }; - cbi.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE; - cbi.iItem = -1; - cbi.iImage = cbi.iSelectedImage = i-1; - cbi.pszText = TranslateTS(tszName); - SendMessage( m_hCombo, CBEM_INSERTITEM, 0, (LPARAM)&cbi ); - } - SendMessage( m_hCombo, CB_SETCURSEL, 0, 0 ); // first 0 sets selection to top -} - -void CSAMWindow::fillDialog() -{ - if (m_action == IDC_ADD) { - SetWindowText(m_handle, TranslateT("Add new item")); - SetDlgItemText(m_handle, IDOK, TranslateT("Add")); - } - else { - SetWindowText(m_handle, TranslateT("Modify item")); - SetDlgItemText(m_handle, IDOK, TranslateT("Modify")); - } - - SendMessage(m_hCombo, CB_SETCURSEL, m_item->m_iIcon, 0); - SetDlgItemText(m_handle, IDC_MESSAGE, m_item->m_tszMessage); -} - -void CSAMWindow::checkFieldLimit( WORD action, WORD item ) -{ - BOOL type = ( item == IDC_MESSAGE ) ? TRUE : FALSE; - unsigned int limit = type ? EXTRASTATUS_MESSAGE_LIMIT : EXTRASTATUS_TITLE_LIMIT; - - if ( action == EN_CHANGE ) - { - TCHAR* ptszInputText = (TCHAR*)mir_alloc((limit + 8) * sizeof(TCHAR)); - - GetDlgItemText( m_handle, item, ptszInputText, limit + 8 ); - - if ( _tcslen( ptszInputText ) > limit ) - { -#if ( WINVER >= 0x501 ) - TCHAR tszPopupTip[MAX_PATH]; - EDITBALLOONTIP ebt = { 0 }; - ebt.cbStruct = sizeof(ebt); - ebt.pszTitle = TranslateT("Warning"); - mir_sntprintf(tszPopupTip, SIZEOF(tszPopupTip), TranslateT("This field doesn't accept string longer than %d characters. The string will be truncated."), limit); - ebt.pszText = tszPopupTip; - ebt.ttiIcon = TTI_WARNING; - SendMessage( GetDlgItem( m_handle, item ), EM_SHOWBALLOONTIP, 0, (LPARAM)&ebt ); -#endif - TCHAR* ptszOutputText = (TCHAR*)mir_alloc((limit + 1) * sizeof(TCHAR)); - GetDlgItemText( m_handle, item, ptszOutputText, limit + 1 ); - SetDlgItemText( m_handle, item, ptszOutputText ); - mir_free( ptszOutputText ); - } - mir_free( ptszInputText ); - } -} - -void CSAMWindow::checkItemValidity() -{ - COMBOBOXEXITEM cbi = { 0 }; - cbi.mask = CBEIF_IMAGE; - cbi.iItem = SendDlgItemMessage(m_handle, IDC_COMBO, CB_GETCURSEL, 0, 0); - SendDlgItemMessage( m_handle, IDC_COMBO, CBEM_GETITEM, 0, (LPARAM)&cbi ); - - if (m_item->m_iIcon != cbi.iImage) - m_item->m_iIcon = cbi.iImage, m_bChanged = TRUE; - - TCHAR tszInputMessage[EXTRASTATUS_MESSAGE_LIMIT]; - - GetDlgItemText( m_handle, IDC_MESSAGE, tszInputMessage, EXTRASTATUS_MESSAGE_LIMIT ); - - PROTOACCOUNT* pdescr = (PROTOACCOUNT*)CallService(MS_PROTO_GETACCOUNT, 0, (LPARAM)m_parent->m_protoName); - if (pdescr == NULL) - return; - - WPARAM i = SendMessage(m_hCombo, CB_GETCURSEL, 0, 0)+1; - TCHAR tszTitle[100]; - - CUSTOM_STATUS cs = { sizeof(cs) }; - cs.flags = CSSF_MASK_NAME | CSSF_DEFAULT_NAME | CSSF_TCHAR; - cs.ptszName = tszTitle; - cs.wParam = &i; - if ( CallProtoService(pdescr->szModuleName, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&cs) == 0) - lstrcpyn(m_item->m_tszTitle, TranslateTS(tszTitle), SIZEOF(m_item->m_tszTitle)); - - if ( lstrcmp(m_item->m_tszMessage, tszInputMessage)) - lstrcpy( m_item->m_tszMessage, tszInputMessage), m_bChanged = true; -} - -CSListView::CSListView(HWND hwnd, CSWindow* parent) -{ - m_handle = hwnd; - m_parent = parent; - -#if (_WIN32_WINNT >= 0x501) - LVGROUP lg = { 0 }; - lg.cbSize = sizeof(LVGROUP); - lg.mask = LVGF_HEADER | LVGF_GROUPID; - - lg.pszHeader = TranslateT("Favorites"); - lg.iGroupId = 0; - ListView_InsertGroup( m_handle, -1, &lg ); - - lg.pszHeader = TranslateT("Regular statuses"); - lg.iGroupId = 1; - ListView_InsertGroup( m_handle, -1, &lg ); - ListView_EnableGroupView( m_handle, TRUE ); -#endif - - LVCOLUMN lvc = { 0 }; - lvc.mask = LVCF_TEXT | LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM; - lvc.fmt = LVCFMT_LEFT; - lvc.cx = 0x00; - lvc.pszText = TEXT( ""); - lvc.cx = 0x16; - SendMessage( m_handle, LVM_INSERTCOLUMN, 0, (LPARAM)&lvc ); - lvc.pszText = TranslateT("Title"); - lvc.cx = 0x64; - SendMessage( m_handle, LVM_INSERTCOLUMN, 1, (LPARAM)&lvc ); - lvc.pszText = TranslateT("Message"); - lvc.cx = 0xa8; - SendMessage( m_handle, LVM_INSERTCOLUMN, 2, (LPARAM)&lvc ); - -#if (_WIN32_IE >= 0x0400) - ListView_SetExtendedListViewStyleEx( m_handle, 0, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP | LVS_EX_INFOTIP ); -#endif - ListView_SetImageList(m_handle, m_parent->m_icons, LVSIL_SMALL); -} - -void CSListView::addItem( StatusItem* item, int itemNumber ) -{ - LVITEM lvi = { 0 }; - lvi.mask = LVIF_IMAGE | LVIF_GROUPID | LVIF_PARAM; - lvi.cchTextMax = 256; - lvi.iItem = ListView_GetItemCount( m_handle ); - lvi.lParam = itemNumber; - lvi.iGroupId = item->m_bFavourite ? 0 : 1; - - // first column - lvi.iSubItem = 0; - lvi.iImage = item->m_iIcon; // use selected xicon - SendMessage( m_handle, LVM_INSERTITEM, 0, (LPARAM)&lvi ); - - // second column - lvi.mask = LVIF_TEXT; - lvi.iSubItem = 1; - lvi.pszText = item->m_tszTitle; - SendMessage( m_handle, LVM_SETITEM, 0, (LPARAM)&lvi ); - - // third column - lvi.iSubItem = 2; - lvi.pszText = item->m_tszMessage; - SendMessage( m_handle, LVM_SETITEM, 0, (LPARAM)&lvi ); -} - -void CSListView::initItems( ListItem< StatusItem >* items ) -{ - ListItem< StatusItem >* help = items; - for ( int i = 0; help != NULL; help = help->m_next, i++ ) - if (m_parent->itemPassedFilter( help )) - addItem( help->m_item, i ); -} - -void CSListView::reinitItems( ListItem< StatusItem >* items ) -{ - EnableWindow(m_handle, FALSE); - removeItems(); - initItems(items); - EnableWindow(m_handle, TRUE); -} - -void CSListView::removeItems() -{ - ListView_DeleteAllItems( m_handle ); -} - -int CSListView::getPositionInList() -{ - LVITEM lvi = { 0 }; - lvi.iItem = ListView_GetSelectedItemMacro(m_parent->m_listview->m_handle); - lvi.iSubItem = 0; - lvi.mask = LVIF_PARAM; - ListView_GetItem(m_parent->m_listview->m_handle, &lvi); - return lvi.lParam; -} - -void CSListView::setFullFocusedSelection( int selection ) -{ - ListView_SetItemState( m_handle, -1, 0, LVIS_SELECTED ); - ListView_EnsureVisible( m_handle, selection, FALSE ); - ListView_SetItemState( m_handle, selection, LVIS_SELECTED, LVIS_SELECTED ); - ListView_SetItemState( m_handle, selection, LVIS_FOCUSED , LVIS_FOCUSED ); - SetFocus( m_handle ); -} - -// ====[ LIST MANAGEMENT ]==================================================== - -CSItemsList::CSItemsList(char *protoName) -{ - m_list = new List< StatusItem >(compareItems); - loadItems(protoName); -} - -CSItemsList::~CSItemsList() -{ - delete m_list; -} - -int CSItemsList::compareItems( const StatusItem* p1, const StatusItem* p2 ) -{ - int favRes = 0, icoRes = 0, ttlRes = 0, msgRes = 0; - - if ( p1->m_bFavourite < p2->m_bFavourite ) - favRes = 1; - else if ( p1->m_bFavourite > p2->m_bFavourite ) - favRes = -1; - - int result; - if ( p1->m_iIcon > p2->m_iIcon ) - icoRes = 1; - else if ( p1->m_iIcon < p2->m_iIcon ) - icoRes = -1; - - result = lstrcmp(p1->m_tszTitle, p2->m_tszTitle); - ttlRes = result; - - result = lstrcmp(p1->m_tszMessage, p2->m_tszMessage); - msgRes = result; - - if ( !icoRes && !ttlRes && !msgRes) - return 0; - - if (favRes != 0) - return favRes; - if (icoRes != 0) - return icoRes; - if (ttlRes != 0) - return ttlRes; - if (msgRes != 0) - return msgRes; - - return 0; -} - -void CSItemsList::loadItems(char *protoName) -{ - char dbSetting[32]; - mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_ItemsCount", protoName); - unsigned int itemsCount = getWord(dbSetting, DEFAULT_ITEMS_COUNT); - - for (unsigned int i = 1; i <= itemsCount; i++) { - StatusItem* item = new StatusItem(); - DBVARIANT dbv; - mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dIcon", protoName, i); - item->m_iIcon = getByte(dbSetting, DEFAULT_ITEM_ICON); - - mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dTitle", protoName, i); - if ( !getTString(dbSetting, &dbv)) { - lstrcpy(item->m_tszTitle, dbv.ptszVal); - db_free(&dbv); - } - else item->m_tszTitle[0] = 0; - - mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dMessage", protoName, i); - if ( !getTString(dbSetting, &dbv)) { - lstrcpy(item->m_tszMessage, dbv.ptszVal); - db_free(&dbv); - } - else item->m_tszMessage[0] = 0; - - mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dFavourite", protoName, i); - item->m_bFavourite = (BOOL)getByte(dbSetting, DEFAULT_ITEM_IS_FAVOURITE); - - m_list->add(item); - } -} - - -void CSItemsList::saveItems(char *protoName) -{ - unsigned int i; - char dbSetting[32]; - mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_ItemsCount", protoName); - unsigned int oldItemsCount = getWord(dbSetting, DEFAULT_ITEMS_COUNT); - - for (i = 1; i <= m_list->getCount(); i++) - { - StatusItem* item = m_list->get( i - 1 ); - mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dIcon", protoName, i); - setByte(dbSetting, item->m_iIcon); - mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dTitle", protoName, i); - setTString(dbSetting, item->m_tszTitle); - mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dMessage", protoName, i); - setTString(dbSetting, item->m_tszMessage); - mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dFavourite", protoName, i); - setByte(dbSetting, item->m_bFavourite); - } - - mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_ItemsCount", protoName); - setWord(dbSetting, m_list->getCount()); - - for ( ; i <= oldItemsCount; i++) - { - mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dIcon", protoName, i); - deleteSetting(dbSetting); - mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dTitle", protoName, i); - deleteSetting(dbSetting); - mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dMessage", protoName, i); - deleteSetting(dbSetting); - mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dFavourite", protoName, i); - deleteSetting(dbSetting); - } -} - - -// ====[ PROCEDURES ]========================================================= - -INT_PTR CALLBACK CSWindowProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) -{ - CSWindow* csw = ( CSWindow* )GetWindowLongPtr( hwnd, GWLP_USERDATA ); - - switch ( message ) { - case WM_INITDIALOG: - TranslateDialogDefault(hwnd); - - csw = (CSWindow*)lparam; - arWindows.insert(csw); - SetWindowLongPtr(hwnd, GWLP_USERDATA, lparam); - - csw->m_handle = hwnd; - csw->initIcons(); - csw->initButtons(); - csw->m_listview = new CSListView( GetDlgItem( hwnd, IDC_CSLIST ), csw); - csw->m_listview->initItems(csw->m_itemslist->m_list->getListHead()); - csw->toggleButtons(); - csw->toggleEmptyListMessage(); - csw->loadWindowPosition(); - SetWindowText(hwnd, TranslateT(MODULENAME)); - return TRUE; - - case WM_COMMAND: - switch ( LOWORD( wparam )) { - case IDC_MODIFY: - case IDC_ADD: - csw->m_addModifyDlg = new CSAMWindow( LOWORD( wparam ), csw ); - csw->m_addModifyDlg->exec(); - if ( csw->m_addModifyDlg->m_bChanged ) { - if ( LOWORD( wparam ) == IDC_MODIFY ) - csw->m_itemslist->m_list->remove( csw->m_listview->getPositionInList()); - - int selection = csw->m_itemslist->m_list->add( csw->m_addModifyDlg->m_item ); - csw->m_bSomethingChanged = TRUE; - csw->m_listview->reinitItems( csw->m_itemslist->m_list->getListHead()); - csw->m_listview->setFullFocusedSelection( selection ); - csw->toggleButtons(); - csw->toggleEmptyListMessage(); - } - delete csw->m_addModifyDlg; - break; - - case IDC_REMOVE: - if ( getByte( "ConfirmDeletion", DEFAULT_PLUGIN_CONFIRM_ITEMS_DELETION )) - if ( MessageBox( hwnd, TranslateT("Do you really want to delete selected item?"), TranslateT(MODULENAME), MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION ) == IDNO ) - break; - - csw->m_itemslist->m_list->remove( csw->m_listview->getPositionInList()); - csw->m_bSomethingChanged = TRUE; - csw->m_listview->reinitItems( csw->m_itemslist->m_list->getListHead()); - csw->toggleButtons(); - csw->toggleEmptyListMessage(); - break; - - case IDC_FAVOURITE: - { - int selection = csw->m_listview->getPositionInList(); - StatusItem* f = new StatusItem( *csw->m_itemslist->m_list->get( selection )); - f->m_bFavourite = ! f->m_bFavourite; - csw->m_itemslist->m_list->remove( selection ); - selection = csw->m_itemslist->m_list->add( f ); - csw->m_bSomethingChanged = TRUE; - csw->m_listview->reinitItems( csw->m_itemslist->m_list->getListHead()); - csw->m_listview->setFullFocusedSelection( selection ); - csw->toggleButtons(); - } - break; - - case IDC_UNDO: - csw->m_itemslist->m_list->destroy(); - csw->m_itemslist->loadItems(csw->m_protoName); - csw->m_bSomethingChanged = FALSE; - csw->m_listview->reinitItems( csw->m_itemslist->m_list->getListHead()); - csw->toggleButtons(); - csw->toggleEmptyListMessage(); - break; - - case IDC_IMPORT: - { - int result = getByte( "DeleteAfterImport", DEFAULT_PLUGIN_DELETE_AFTER_IMPORT ); - if (result == TRUE) - result = IDYES; - else { - result = MessageBox( hwnd, - TranslateT("Do you want old database entries to be deleted after Import?"), - TranslateT(MODULENAME), MB_YESNOCANCEL | MB_DEFBUTTON2 | MB_ICONQUESTION ); - if ( result == IDCANCEL ) - break; - } - - importCustomStatuses(csw, result); - csw->m_bSomethingChanged = TRUE; - csw->toggleButtons(); - csw->toggleEmptyListMessage(); - } - break; - - case IDC_FILTER: - csw->toggleFilter(); - csw->toggleButtons(); - break; - - case IDC_FILTER_FIELD: - if ( HIWORD( wparam ) == EN_CHANGE ) - csw->m_listview->reinitItems( csw->m_itemslist->m_list->getListHead()); - break; - - case IDCLOSE: // close and save, no custom status - case IDCANCEL: // close and save, no custom status - case IDC_CANCEL: // close and save, cancel custom status - case IDOK: // close and save, set selected custom status - if ( LOWORD( wparam ) == IDOK && csw->toggleButtons()) - SetStatus(IDOK, csw->m_itemslist->m_list->get(csw->m_listview->getPositionInList()), csw->m_protoName); - if ( LOWORD( wparam ) == IDC_CANCEL ) - SetStatus(IDC_CANCEL, NULL, csw->m_protoName); - if ( csw->m_bSomethingChanged ) - if (csw->m_itemslist!=NULL) - csw->m_itemslist->saveItems(csw->m_protoName); - csw->saveWindowPosition(csw->m_handle); - EndDialog(hwnd, FALSE); - break; - } - return FALSE; - - case WM_NOTIFY: - if ( wparam == IDC_CSLIST ) { - NMHDR* pnmh = ( NMHDR* )lparam; - switch ( pnmh->code ) { - case NM_DBLCLK: - PostMessage( hwnd, WM_COMMAND, IDOK, 0L ); - break; - - case LVN_ITEMCHANGED: - case NM_CLICK: - csw->toggleButtons(); - break; - } - } - return FALSE; - - case WM_CTLCOLORSTATIC: - SetTextColor(( HDC )wparam, RGB( 174, 174, 174 )); - if (((HWND)lparam == GetDlgItem(hwnd, IDC_NO_ITEMS)) || ((HWND)lparam == GetDlgItem(hwnd, IDC_ADD_SAMPLE))) - return ( BOOL )GetStockObject( WHITE_BRUSH ); - return FALSE; - - case WM_DESTROY: - SetWindowLongPtr(hwnd, GWLP_USERDATA, 0); - arWindows.remove(csw); - delete csw->m_listview; - csw->deinitIcons(); - delete csw; - break; - } - return FALSE; -} - -INT_PTR CALLBACK CSAMWindowProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) -{ - CSAMWindow* csamw = ( CSAMWindow* )GetWindowLongPtr( hwnd, GWLP_USERDATA ); - - switch ( message ) { - case WM_INITDIALOG: - csamw = ( CSAMWindow* )lparam; - SetWindowLongPtr( hwnd, GWLP_USERDATA, lparam ); - csamw->m_handle = hwnd; - EnableWindow( csamw->m_parent->m_handle, FALSE ); - csamw->m_hCombo = GetDlgItem( hwnd, IDC_COMBO ); - csamw->m_hMessage = GetDlgItem( hwnd, IDC_MESSAGE ); - csamw->setCombo(); - csamw->fillDialog(); - TranslateDialogDefault(hwnd); - break; - - case WM_COMMAND: - switch ( LOWORD( wparam )) { - case IDC_MESSAGE: - csamw->checkFieldLimit( HIWORD( wparam ), LOWORD( wparam )); - break; - - case IDOK: - csamw->checkItemValidity(); - - case IDCANCEL: - EnableWindow(csamw->m_parent->m_handle, TRUE); - EndDialog(hwnd, LOWORD(wparam)); - break; - } - break; - } - return FALSE; -} - - -INT_PTR CALLBACK CSOptionsProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) -{ - switch ( message ) { - case WM_INITDIALOG: - TranslateDialogDefault(hwnd); - CheckDlgButton( hwnd, IDC_CONFIRM_DELETION, - getByte( "ConfirmDeletion", DEFAULT_PLUGIN_CONFIRM_ITEMS_DELETION ) ? - BST_CHECKED : BST_UNCHECKED ); - - CheckDlgButton( hwnd, IDC_DELETE_AFTER_IMPORT, - getByte( "DeleteAfterImport", DEFAULT_PLUGIN_DELETE_AFTER_IMPORT ) ? - BST_CHECKED : BST_UNCHECKED ); - - CheckDlgButton( hwnd, IDC_REMEMBER_POSITION, - getByte( "RememberWindowPosition", DEFAULT_REMEMBER_WINDOW_POSITION ) ? - BST_CHECKED : BST_UNCHECKED ); - return TRUE; - - case WM_NOTIFY: - switch ((( LPNMHDR )lparam )->code ) { - case PSN_APPLY: - setByte( "ConfirmDeletion", IsDlgButtonChecked( hwnd, IDC_CONFIRM_DELETION ) ? 1 : 0 ); - setByte( "DeleteAfterImport", IsDlgButtonChecked( hwnd, IDC_DELETE_AFTER_IMPORT ) ? 1 : 0 ); - setByte( "RememberWindowPosition", IsDlgButtonChecked( hwnd, IDC_REMEMBER_POSITION ) ? 1 : 0 ); - - pcli->pfnReloadProtoMenus(); - break; - } - return TRUE; - } - return FALSE; -} +/* ======================================================================== + + Custom Status List + __________________ + + Custom Status List plugin for Miranda-IM (www.miranda-im.org) + Follower of Custom Status History List by HANAX + Copyright © 2006-2008 HANAX + Copyright © 2007-2009 jarvis + Occasionally rewritten in 2012 by George Hazan + + 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. + ======================================================================== */ + +#include "cslist.h" +#include "strpos.h" + +CLIST_INTERFACE *pcli; +int hLangpack; +HINSTANCE g_hInst; + +static LIST arWindows(3, HandleKeySortT); + +PLUGININFOEX pluginInfoEx = +{ + sizeof(PLUGININFOEX), + __PLUGIN_NAME, + PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), + __DESCRIPTION, + __AUTHOR, + __AUTHOREMAIL, + __COPYRIGHT, + __AUTHORWEB, + UNICODE_AWARE, + // {C8CC7414-6507-4AF6-925A-83C1D2F7BE8C} + {0xc8cc7414, 0x6507, 0x4af6, {0x92, 0x5a, 0x83, 0xc1, 0xd2, 0xf7, 0xbe, 0x8c}} +}; + +// ====[ MAIN ]=============================================================== + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + g_hInst = hinstDLL; + return TRUE; +} + +// ====[ PLUGIN INFO ]======================================================== + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD) +{ + return &pluginInfoEx; +} + +// ====[ LOADER ]============================================================= + +static int OnDbChanged(WPARAM hContact, LPARAM lparam) +{ + DBCONTACTWRITESETTING *cws = ( DBCONTACTWRITESETTING* )lparam; + + // if user changes his UIN or JID on any account + if (hContact == NULL) { + INT_PTR szUniqueID = CallProtoService(cws->szModule, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); + if (szUniqueID != CALLSERVICE_NOTFOUND && !lstrcmpA(cws->szSetting, (char*)szUniqueID)) + pcli->pfnReloadProtoMenus(); + } + return 0; +} + +static int OnInitOptions(WPARAM wparam, LPARAM lparam) +{ + OPTIONSDIALOGPAGE odp = { sizeof(odp) }; + odp.position = 955000000; + odp.hInstance = g_hInst; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); + odp.pszTitle = MODULENAME; + odp.pfnDlgProc = CSOptionsProc; + odp.pszGroup = LPGEN("Status"); + odp.flags = ODPF_BOLDGROUPS; + Options_AddPage(wparam, &odp); + return 0; +} + +static int OnCreateMenuItems(WPARAM, LPARAM) +{ + int protoCount; + PROTOACCOUNT** pdesc; + ProtoEnumAccounts(&protoCount, &pdesc); + + for (int i = 0; i < protoCount; i++) + if ( ProtoServiceExists(pdesc[i]->szModuleName, PS_SETCUSTOMSTATUSEX)) + addProtoStatusMenuItem(pdesc[i]->szModuleName); + + return 0; +} + +static int OnPreshutdown(WPARAM wparam, LPARAM lparam) +{ + for (int i=0; i < arWindows.getCount(); i++) + DestroyWindow(arWindows[i]->m_handle); + return 0; +} + +extern "C" __declspec(dllexport) int Load() +{ + mir_getLP(&pluginInfoEx); + mir_getCLI(); + + // support for ComboBoxEx + INITCOMMONCONTROLSEX icc; + icc.dwSize = sizeof(icc); + icc.dwICC = ICC_USEREX_CLASSES; + InitCommonControlsEx(&icc); + + // init icons + TCHAR tszFile[MAX_PATH]; + GetModuleFileName( g_hInst, tszFile, MAX_PATH ); + + SKINICONDESC sid = { sizeof(sid) }; + sid.ptszDefaultFile = tszFile; + sid.flags = SIDF_ALL_TCHAR; + sid.cx = sid.cy = 16; + sid.ptszSection = _T(MODULENAME); + + for (int i=0; i < SIZEOF(forms); i++) { + char szSettingName[64]; + mir_snprintf(szSettingName, SIZEOF(szSettingName), "%s_%s", MODNAME, forms[i].pszIconIcoLib); + + sid.pszName = szSettingName; + sid.ptszDescription = forms[i].ptszDescr; + sid.iDefaultIndex = -forms[i].iconNoIcoLib; + forms[i].hIcoLibItem = Skin_AddIcon(&sid); + } + + HookEvent(ME_OPT_INITIALISE, OnInitOptions); + HookEvent(ME_DB_CONTACT_SETTINGCHANGED, OnDbChanged); + HookEvent(ME_CLIST_PREBUILDSTATUSMENU, OnCreateMenuItems); + HookEvent(ME_SYSTEM_PRESHUTDOWN, OnPreshutdown); + + // if we load a plugin dynamically, it will work, otherwise fail + OnCreateMenuItems(0, 0); + return 0; +} + +// ====[ UNLOADER ]=========================================================== + +extern "C" __declspec(dllexport) int Unload() +{ + return 0; +} + +// ====[ FUN ]================================================================ + +void RegisterHotkeys(char buf[200], TCHAR* accName, int Number) +{ + HOTKEYDESC hotkey = { sizeof(hotkey) }; + hotkey.dwFlags = HKD_TCHAR; + hotkey.pszName = buf; + hotkey.ptszDescription = accName; + hotkey.ptszSection = LPGENT("Custom Status List"); + hotkey.pszService = buf; + hotkey.DefHotKey = HOTKEYCODE( HOTKEYF_CONTROL | HOTKEYF_SHIFT, '0' + Number); + Hotkey_Register(&hotkey); +} + +void SetStatus(WORD code, StatusItem* item, char *szAccName) +{ + if ( code == IDCLOSE ) + return; + + PROTOACCOUNT* pdescr = (PROTOACCOUNT*)CallService(MS_PROTO_GETACCOUNT, 0, (LPARAM)szAccName); + if (pdescr == NULL) + return; + + if ( !ProtoServiceExists(szAccName, PS_SETCUSTOMSTATUSEX)) + return; + + int statusToSet; + + CUSTOM_STATUS ics = { sizeof(CUSTOM_STATUS) }; + ics.flags = CSSF_MASK_STATUS | CSSF_MASK_NAME | CSSF_MASK_MESSAGE | CSSF_TCHAR; + + if (code == IDC_CANCEL) { + statusToSet = 0; + ics.ptszName = _T(""); + ics.ptszMessage = _T(""); + } + else if (code == IDOK && item != NULL) { + statusToSet = item->m_iIcon+1; + ics.ptszName = variables_parsedup(item->m_tszTitle, NULL, NULL); + ics.ptszMessage = variables_parsedup(item->m_tszMessage, NULL, NULL); + } + else return; + + ics.status = &statusToSet; + ProtoCallService(szAccName, PS_SETCUSTOMSTATUSEX, 0, (LPARAM)&ics); +} + +INT_PTR showList(WPARAM wparam, LPARAM lparam, LPARAM param) +{ + char* szProto = (char*)param; + for (int i=0; i < arWindows.getCount(); i++) { + CSWindow *p = arWindows[i]; + if ( !strcmp(szProto, p->m_protoName)) { + ShowWindow(p->m_handle, SW_SHOW); + SetForegroundWindow(p->m_handle); + return 1; + } + } + + CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_CSLIST), NULL, CSWindowProc, (LPARAM)new CSWindow(szProto)); + return 0; +} + +void addProtoStatusMenuItem(char *protoName) +{ + PROTOACCOUNT *pdescr = ProtoGetAccount(protoName); + if (pdescr == NULL) + return; + + HGENMENU hRoot = MO_GetProtoRootMenu(pdescr->szModuleName); + if (hRoot == NULL) + return; + + char buf[200]; + mir_snprintf(buf, SIZEOF(buf), "CSList/ShowList/%s", protoName); + if ( !ServiceExists(buf)) + CreateServiceFunctionParam(buf, showList, (LPARAM)protoName); + + CLISTMENUITEM mi = { sizeof(mi) }; + mi.flags = CMIF_CHILDPOPUP | CMIF_TCHAR; + mi.icolibItem = forms[0].hIcoLibItem; + mi.ptszName = _T(MODULENAME); + mi.position = 2000040000; + mi.pszService = buf; + mi.hParentMenu = hRoot; + Menu_AddStatusMenuItem(&mi); + + RegisterHotkeys(buf, pdescr->tszAccountName, pdescr->iOrder); +} + +/////////////////////////////////////////////////////////////////////////////// + +void importCustomStatuses(CSWindow* csw, int result) +{ + DBVARIANT dbv; + char bufTitle[32], bufMessage[32], *protoName = csw->m_protoName; + + for (int i = 0; i < csw->m_statusCount; i++) { + StatusItem* si = new StatusItem(); + si->m_iIcon = i-1; + + mir_snprintf(bufTitle, 32, "XStatus%dName", i); + if ( !db_get_ts( NULL, protoName, bufTitle, &dbv )) { + lstrcpy(si->m_tszTitle, dbv.ptszVal); + db_free(&dbv); + } + else si->m_tszTitle[0] = 0; + + mir_snprintf(bufMessage, 32, "XStatus%dMsg", i); + if ( !db_get_ts( NULL, protoName, bufMessage, &dbv )) { + lstrcpy(si->m_tszMessage, dbv.ptszVal); + db_free(&dbv); + } + else si->m_tszMessage[0] = 0; + + if (si->m_tszTitle[0] || si->m_tszMessage[0]) { + csw->m_itemslist->m_list->add(si); + csw->m_bSomethingChanged = TRUE; + } + else delete si; + + if (result == IDYES) { + db_unset(NULL, protoName, bufTitle); + db_unset(NULL, protoName, bufMessage); + } + } + csw->m_listview->reinitItems(csw->m_itemslist->m_list->getListHead()); +} + +/////////////////////////////////////////////////////////////////////////////// +// CSWindow class + +CSWindow::CSWindow(char *protoName) +{ + m_protoName = protoName; + m_handle = NULL; + m_bExtraIcons = getByte( "AllowExtraIcons", DEFAULT_ALLOW_EXTRA_ICONS ); + m_itemslist = new CSItemsList(m_protoName); + m_listview = NULL; + m_addModifyDlg = NULL; + m_bSomethingChanged = FALSE; + m_filterString = NULL; +} + +void __fastcall SAFE_FREE(void** p) +{ + if (*p) + { + free(*p); + *p = NULL; + } +} + +CSWindow::~CSWindow() +{ + delete m_itemslist; + SAFE_FREE(( void** )&m_filterString ); +} + +void CSWindow::initIcons() +{ + PROTOACCOUNT *pdescr = ProtoGetAccount(m_protoName); + if (pdescr == NULL) + return; + + char *szUniqueID = (char*)CallProtoService(m_protoName, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); + if (szUniqueID == NULL) + return; + + DBVARIANT dbv; + if ( db_get(NULL, pdescr->szModuleName, szUniqueID, &dbv)) + return; + db_free(&dbv); + + WPARAM iNumStatuses = 0; + CUSTOM_STATUS cs = { sizeof(cs) }; + cs.flags = CSSF_STATUSES_COUNT; + cs.wParam = &iNumStatuses; + if ( CallProtoService(pdescr->szModuleName, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&cs) != 0) + return; + + m_statusCount = (int)iNumStatuses; + if (NULL == (m_icons = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, m_statusCount, 0))) + return; + + for (int i=1; i <= m_statusCount; i++) { + HICON hIcon = (HICON)CallProtoService(pdescr->szModuleName, PS_GETCUSTOMSTATUSICON, i, 0); + if (hIcon) { + ImageList_AddIcon(m_icons, hIcon); + DestroyIcon(hIcon); + } + } +} + +void CSWindow::deinitIcons() +{ + ImageList_Destroy( m_icons ); +} + +void CSWindow::initButtons() +{ + for (int i = 0; i < SIZEOF(forms); i++) { + if ( forms[i].idc < 0 ) + continue; + + SendDlgItemMessage( m_handle, forms[i].idc, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Skin_GetIconByHandle(forms[i].hIcoLibItem)); + SendDlgItemMessage( m_handle, forms[i].idc, BUTTONSETASFLATBTN, TRUE, 0 ); //maybe set as BUTTONSETDEFAULT? + SendDlgItemMessage( m_handle, forms[i].idc, BUTTONADDTOOLTIP, (WPARAM )TranslateTS(forms[i].ptszTitle), BATF_TCHAR ); + } +} + +void CSWindow::loadWindowPosition() +{ + if (getByte("RememberWindowPosition", DEFAULT_REMEMBER_WINDOW_POSITION)) + Utils_RestoreWindowPosition(m_handle, NULL, MODNAME, "Position"); +} + +void CSWindow::toggleEmptyListMessage() +{ + HWND hwnd = GetDlgItem( m_handle, IDC_NO_ITEMS ); + ShowWindow( hwnd, ( ListView_GetItemCount( m_listview->m_handle ) > 0 ) ? FALSE : TRUE ); + SetForegroundWindow( hwnd ); + hwnd = GetDlgItem( m_handle, IDC_ADD_SAMPLE ); + ShowWindow( hwnd, ( ListView_GetItemCount( m_listview->m_handle ) > 0 ) ? FALSE : TRUE ); + SetForegroundWindow( hwnd ); +} + +BOOL CSWindow::itemPassedFilter( ListItem< StatusItem >* li ) +{ + TCHAR filter[MAX_PATH]; + GetDlgItemText( m_handle, IDC_FILTER_FIELD, filter, MAX_PATH ); + + if ( lstrlen( filter )) + { + TCHAR title[EXTRASTATUS_TITLE_LIMIT], message[EXTRASTATUS_MESSAGE_LIMIT]; + lstrcpy( title, li->m_item->m_tszTitle ); lstrcpy( message, li->m_item->m_tszMessage ); + if ( strpos( _tcslwr( title ), _tcslwr( filter )) == -1 ) + if ( strpos( _tcslwr( message ), _tcslwr( filter )) == -1 ) + return FALSE; + } + + return TRUE; +} + +void CSWindow::toggleFilter() +{ + HWND hFilter = GetDlgItem( m_handle, IDC_FILTER_FIELD ); + BOOL isEnabled = !IsWindowEnabled( hFilter ) ? TRUE : FALSE; // ! = + isEnabled = !isEnabled in one + EnableWindow( hFilter, isEnabled ); + ShowWindow( hFilter, isEnabled ); + CheckDlgButton( m_handle, IDC_FILTER, isEnabled ); + SetForegroundWindow( hFilter ); + if ( isEnabled ) + SetFocus( hFilter ); + else + { + TCHAR filterText[255]; + GetDlgItemText(m_handle, IDC_FILTER_FIELD, filterText, SIZEOF(filterText)); + if (filterText[0] != 0) + SetDlgItemText( m_handle, IDC_FILTER_FIELD, TEXT( "")); + } +} + +BOOL CSWindow::toggleButtons() +{ + int selection = ListView_GetSelectedItemMacro( m_listview->m_handle ); + BOOL validSelection = ( selection >= 0 && ( unsigned int )selection < m_itemslist->m_list->getCount()) ? TRUE : FALSE; + BOOL filterEnabled = IsWindowVisible( GetDlgItem( m_handle, IDC_FILTER_FIELD )); + BOOL somethingChanged = m_bSomethingChanged; + + EnableWindow( GetDlgItem( m_handle, IDC_ADD ), !filterEnabled ); + EnableWindow( GetDlgItem( m_handle, IDC_MODIFY ), validSelection && !filterEnabled ); + EnableWindow( GetDlgItem( m_handle, IDC_REMOVE ), validSelection && !filterEnabled ); + EnableWindow( GetDlgItem( m_handle, IDC_FAVOURITE ), validSelection && !filterEnabled ); + EnableWindow( GetDlgItem( m_handle, IDC_UNDO ), somethingChanged && !filterEnabled ); + EnableWindow( GetDlgItem( m_handle, IDC_IMPORT ), !filterEnabled ); + EnableWindow( GetDlgItem( m_handle, IDOK ), validSelection ); + + return validSelection; +} + +/////////////////////////////////////////////////////////////////////////////// +// CSAMWindow class - add form window + +CSAMWindow::CSAMWindow( WORD action, CSWindow* parent ) +{ + m_action = action; + m_parent = parent; + m_bChanged = FALSE; + m_hCombo = m_hMessage = NULL; + + if ( m_action == IDC_ADD ) + m_item = new StatusItem(); + else + m_item = new StatusItem( *m_parent->m_itemslist->m_list->get( m_parent->m_listview->getPositionInList()) ); +} + +CSAMWindow::~CSAMWindow() +{ + if ( !m_bChanged ) + delete m_item; +} + +void CSAMWindow::exec() +{ + DialogBoxParam( g_hInst, MAKEINTRESOURCE( IDD_ADDMODIFY ), NULL, CSAMWindowProc, (LPARAM)this ); +} + + +void CSAMWindow::setCombo() +{ + PROTOACCOUNT *pdescr = ProtoGetAccount(m_parent->m_protoName); + if (pdescr == NULL) + return; + + char *szUniqueID = (char*)CallProtoService(pdescr->szModuleName, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); + if (szUniqueID == NULL) + return; + + DBVARIANT dbv; + if ( db_get(NULL, pdescr->szModuleName, szUniqueID, &dbv)) + return; + db_free(&dbv); + + WPARAM iStatus; + TCHAR tszName[100]; + CUSTOM_STATUS cs = { sizeof(cs) }; + cs.flags = CSSF_MASK_NAME | CSSF_DEFAULT_NAME | CSSF_TCHAR; + cs.ptszName = tszName; + cs.wParam = &iStatus; + + SendMessage( m_hCombo, CBEM_SETIMAGELIST, 0, (LPARAM)m_parent->m_icons); + for (int i=1; i <= m_parent->m_statusCount; i++) { + iStatus = i; + if ( CallProtoService(pdescr->szModuleName, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&cs) != 0) + continue; + + COMBOBOXEXITEM cbi = { 0 }; + cbi.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE; + cbi.iItem = -1; + cbi.iImage = cbi.iSelectedImage = i-1; + cbi.pszText = TranslateTS(tszName); + SendMessage( m_hCombo, CBEM_INSERTITEM, 0, (LPARAM)&cbi ); + } + SendMessage( m_hCombo, CB_SETCURSEL, 0, 0 ); // first 0 sets selection to top +} + +void CSAMWindow::fillDialog() +{ + if (m_action == IDC_ADD) { + SetWindowText(m_handle, TranslateT("Add new item")); + SetDlgItemText(m_handle, IDOK, TranslateT("Add")); + } + else { + SetWindowText(m_handle, TranslateT("Modify item")); + SetDlgItemText(m_handle, IDOK, TranslateT("Modify")); + } + + SendMessage(m_hCombo, CB_SETCURSEL, m_item->m_iIcon, 0); + SetDlgItemText(m_handle, IDC_MESSAGE, m_item->m_tszMessage); +} + +void CSAMWindow::checkFieldLimit( WORD action, WORD item ) +{ + BOOL type = ( item == IDC_MESSAGE ) ? TRUE : FALSE; + unsigned int limit = type ? EXTRASTATUS_MESSAGE_LIMIT : EXTRASTATUS_TITLE_LIMIT; + + if ( action == EN_CHANGE ) + { + TCHAR* ptszInputText = (TCHAR*)mir_alloc((limit + 8) * sizeof(TCHAR)); + + GetDlgItemText( m_handle, item, ptszInputText, limit + 8 ); + + if ( _tcslen( ptszInputText ) > limit ) + { +#if ( WINVER >= 0x501 ) + TCHAR tszPopupTip[MAX_PATH]; + EDITBALLOONTIP ebt = { 0 }; + ebt.cbStruct = sizeof(ebt); + ebt.pszTitle = TranslateT("Warning"); + mir_sntprintf(tszPopupTip, SIZEOF(tszPopupTip), TranslateT("This field doesn't accept string longer than %d characters. The string will be truncated."), limit); + ebt.pszText = tszPopupTip; + ebt.ttiIcon = TTI_WARNING; + SendMessage( GetDlgItem( m_handle, item ), EM_SHOWBALLOONTIP, 0, (LPARAM)&ebt ); +#endif + TCHAR* ptszOutputText = (TCHAR*)mir_alloc((limit + 1) * sizeof(TCHAR)); + GetDlgItemText( m_handle, item, ptszOutputText, limit + 1 ); + SetDlgItemText( m_handle, item, ptszOutputText ); + mir_free( ptszOutputText ); + } + mir_free( ptszInputText ); + } +} + +void CSAMWindow::checkItemValidity() +{ + COMBOBOXEXITEM cbi = { 0 }; + cbi.mask = CBEIF_IMAGE; + cbi.iItem = SendDlgItemMessage(m_handle, IDC_COMBO, CB_GETCURSEL, 0, 0); + SendDlgItemMessage( m_handle, IDC_COMBO, CBEM_GETITEM, 0, (LPARAM)&cbi ); + + if (m_item->m_iIcon != cbi.iImage) + m_item->m_iIcon = cbi.iImage, m_bChanged = TRUE; + + TCHAR tszInputMessage[EXTRASTATUS_MESSAGE_LIMIT]; + + GetDlgItemText( m_handle, IDC_MESSAGE, tszInputMessage, EXTRASTATUS_MESSAGE_LIMIT ); + + PROTOACCOUNT* pdescr = (PROTOACCOUNT*)CallService(MS_PROTO_GETACCOUNT, 0, (LPARAM)m_parent->m_protoName); + if (pdescr == NULL) + return; + + WPARAM i = SendMessage(m_hCombo, CB_GETCURSEL, 0, 0)+1; + TCHAR tszTitle[100]; + + CUSTOM_STATUS cs = { sizeof(cs) }; + cs.flags = CSSF_MASK_NAME | CSSF_DEFAULT_NAME | CSSF_TCHAR; + cs.ptszName = tszTitle; + cs.wParam = &i; + if ( CallProtoService(pdescr->szModuleName, PS_GETCUSTOMSTATUSEX, 0, (LPARAM)&cs) == 0) + lstrcpyn(m_item->m_tszTitle, TranslateTS(tszTitle), SIZEOF(m_item->m_tszTitle)); + + if ( lstrcmp(m_item->m_tszMessage, tszInputMessage)) + lstrcpy( m_item->m_tszMessage, tszInputMessage), m_bChanged = true; +} + +CSListView::CSListView(HWND hwnd, CSWindow* parent) +{ + m_handle = hwnd; + m_parent = parent; + +#if (_WIN32_WINNT >= 0x501) + LVGROUP lg = { 0 }; + lg.cbSize = sizeof(LVGROUP); + lg.mask = LVGF_HEADER | LVGF_GROUPID; + + lg.pszHeader = TranslateT("Favorites"); + lg.iGroupId = 0; + ListView_InsertGroup( m_handle, -1, &lg ); + + lg.pszHeader = TranslateT("Regular statuses"); + lg.iGroupId = 1; + ListView_InsertGroup( m_handle, -1, &lg ); + ListView_EnableGroupView( m_handle, TRUE ); +#endif + + LVCOLUMN lvc = { 0 }; + lvc.mask = LVCF_TEXT | LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM; + lvc.fmt = LVCFMT_LEFT; + lvc.cx = 0x00; + lvc.pszText = TEXT( ""); + lvc.cx = 0x16; + SendMessage( m_handle, LVM_INSERTCOLUMN, 0, (LPARAM)&lvc ); + lvc.pszText = TranslateT("Title"); + lvc.cx = 0x64; + SendMessage( m_handle, LVM_INSERTCOLUMN, 1, (LPARAM)&lvc ); + lvc.pszText = TranslateT("Message"); + lvc.cx = 0xa8; + SendMessage( m_handle, LVM_INSERTCOLUMN, 2, (LPARAM)&lvc ); + +#if (_WIN32_IE >= 0x0400) + ListView_SetExtendedListViewStyleEx( m_handle, 0, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP | LVS_EX_INFOTIP ); +#endif + ListView_SetImageList(m_handle, m_parent->m_icons, LVSIL_SMALL); +} + +void CSListView::addItem( StatusItem* item, int itemNumber ) +{ + LVITEM lvi = { 0 }; + lvi.mask = LVIF_IMAGE | LVIF_GROUPID | LVIF_PARAM; + lvi.cchTextMax = 256; + lvi.iItem = ListView_GetItemCount( m_handle ); + lvi.lParam = itemNumber; + lvi.iGroupId = item->m_bFavourite ? 0 : 1; + + // first column + lvi.iSubItem = 0; + lvi.iImage = item->m_iIcon; // use selected xicon + SendMessage( m_handle, LVM_INSERTITEM, 0, (LPARAM)&lvi ); + + // second column + lvi.mask = LVIF_TEXT; + lvi.iSubItem = 1; + lvi.pszText = item->m_tszTitle; + SendMessage( m_handle, LVM_SETITEM, 0, (LPARAM)&lvi ); + + // third column + lvi.iSubItem = 2; + lvi.pszText = item->m_tszMessage; + SendMessage( m_handle, LVM_SETITEM, 0, (LPARAM)&lvi ); +} + +void CSListView::initItems( ListItem< StatusItem >* items ) +{ + ListItem< StatusItem >* help = items; + for ( int i = 0; help != NULL; help = help->m_next, i++ ) + if (m_parent->itemPassedFilter( help )) + addItem( help->m_item, i ); +} + +void CSListView::reinitItems( ListItem< StatusItem >* items ) +{ + EnableWindow(m_handle, FALSE); + removeItems(); + initItems(items); + EnableWindow(m_handle, TRUE); +} + +void CSListView::removeItems() +{ + ListView_DeleteAllItems( m_handle ); +} + +int CSListView::getPositionInList() +{ + LVITEM lvi = { 0 }; + lvi.iItem = ListView_GetSelectedItemMacro(m_parent->m_listview->m_handle); + lvi.iSubItem = 0; + lvi.mask = LVIF_PARAM; + ListView_GetItem(m_parent->m_listview->m_handle, &lvi); + return lvi.lParam; +} + +void CSListView::setFullFocusedSelection( int selection ) +{ + ListView_SetItemState( m_handle, -1, 0, LVIS_SELECTED ); + ListView_EnsureVisible( m_handle, selection, FALSE ); + ListView_SetItemState( m_handle, selection, LVIS_SELECTED, LVIS_SELECTED ); + ListView_SetItemState( m_handle, selection, LVIS_FOCUSED , LVIS_FOCUSED ); + SetFocus( m_handle ); +} + +// ====[ LIST MANAGEMENT ]==================================================== + +CSItemsList::CSItemsList(char *protoName) +{ + m_list = new List< StatusItem >(compareItems); + loadItems(protoName); +} + +CSItemsList::~CSItemsList() +{ + delete m_list; +} + +int CSItemsList::compareItems( const StatusItem* p1, const StatusItem* p2 ) +{ + int favRes = 0, icoRes = 0, ttlRes = 0, msgRes = 0; + + if ( p1->m_bFavourite < p2->m_bFavourite ) + favRes = 1; + else if ( p1->m_bFavourite > p2->m_bFavourite ) + favRes = -1; + + int result; + if ( p1->m_iIcon > p2->m_iIcon ) + icoRes = 1; + else if ( p1->m_iIcon < p2->m_iIcon ) + icoRes = -1; + + result = lstrcmp(p1->m_tszTitle, p2->m_tszTitle); + ttlRes = result; + + result = lstrcmp(p1->m_tszMessage, p2->m_tszMessage); + msgRes = result; + + if ( !icoRes && !ttlRes && !msgRes) + return 0; + + if (favRes != 0) + return favRes; + if (icoRes != 0) + return icoRes; + if (ttlRes != 0) + return ttlRes; + if (msgRes != 0) + return msgRes; + + return 0; +} + +void CSItemsList::loadItems(char *protoName) +{ + char dbSetting[32]; + mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_ItemsCount", protoName); + unsigned int itemsCount = getWord(dbSetting, DEFAULT_ITEMS_COUNT); + + for (unsigned int i = 1; i <= itemsCount; i++) { + StatusItem* item = new StatusItem(); + DBVARIANT dbv; + mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dIcon", protoName, i); + item->m_iIcon = getByte(dbSetting, DEFAULT_ITEM_ICON); + + mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dTitle", protoName, i); + if ( !getTString(dbSetting, &dbv)) { + lstrcpy(item->m_tszTitle, dbv.ptszVal); + db_free(&dbv); + } + else item->m_tszTitle[0] = 0; + + mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dMessage", protoName, i); + if ( !getTString(dbSetting, &dbv)) { + lstrcpy(item->m_tszMessage, dbv.ptszVal); + db_free(&dbv); + } + else item->m_tszMessage[0] = 0; + + mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dFavourite", protoName, i); + item->m_bFavourite = (BOOL)getByte(dbSetting, DEFAULT_ITEM_IS_FAVOURITE); + + m_list->add(item); + } +} + + +void CSItemsList::saveItems(char *protoName) +{ + unsigned int i; + char dbSetting[32]; + mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_ItemsCount", protoName); + unsigned int oldItemsCount = getWord(dbSetting, DEFAULT_ITEMS_COUNT); + + for (i = 1; i <= m_list->getCount(); i++) + { + StatusItem* item = m_list->get( i - 1 ); + mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dIcon", protoName, i); + setByte(dbSetting, item->m_iIcon); + mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dTitle", protoName, i); + setTString(dbSetting, item->m_tszTitle); + mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dMessage", protoName, i); + setTString(dbSetting, item->m_tszMessage); + mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dFavourite", protoName, i); + setByte(dbSetting, item->m_bFavourite); + } + + mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_ItemsCount", protoName); + setWord(dbSetting, m_list->getCount()); + + for ( ; i <= oldItemsCount; i++) + { + mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dIcon", protoName, i); + deleteSetting(dbSetting); + mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dTitle", protoName, i); + deleteSetting(dbSetting); + mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dMessage", protoName, i); + deleteSetting(dbSetting); + mir_snprintf(dbSetting, SIZEOF(dbSetting), "%s_Item%dFavourite", protoName, i); + deleteSetting(dbSetting); + } +} + + +// ====[ PROCEDURES ]========================================================= + +INT_PTR CALLBACK CSWindowProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) +{ + CSWindow* csw = ( CSWindow* )GetWindowLongPtr( hwnd, GWLP_USERDATA ); + + switch ( message ) { + case WM_INITDIALOG: + TranslateDialogDefault(hwnd); + + csw = (CSWindow*)lparam; + arWindows.insert(csw); + SetWindowLongPtr(hwnd, GWLP_USERDATA, lparam); + + csw->m_handle = hwnd; + csw->initIcons(); + csw->initButtons(); + csw->m_listview = new CSListView( GetDlgItem( hwnd, IDC_CSLIST ), csw); + csw->m_listview->initItems(csw->m_itemslist->m_list->getListHead()); + csw->toggleButtons(); + csw->toggleEmptyListMessage(); + csw->loadWindowPosition(); + SetWindowText(hwnd, TranslateT(MODULENAME)); + return TRUE; + + case WM_COMMAND: + switch ( LOWORD( wparam )) { + case IDC_MODIFY: + case IDC_ADD: + csw->m_addModifyDlg = new CSAMWindow( LOWORD( wparam ), csw ); + csw->m_addModifyDlg->exec(); + if ( csw->m_addModifyDlg->m_bChanged ) { + if ( LOWORD( wparam ) == IDC_MODIFY ) + csw->m_itemslist->m_list->remove( csw->m_listview->getPositionInList()); + + int selection = csw->m_itemslist->m_list->add( csw->m_addModifyDlg->m_item ); + csw->m_bSomethingChanged = TRUE; + csw->m_listview->reinitItems( csw->m_itemslist->m_list->getListHead()); + csw->m_listview->setFullFocusedSelection( selection ); + csw->toggleButtons(); + csw->toggleEmptyListMessage(); + } + delete csw->m_addModifyDlg; + break; + + case IDC_REMOVE: + if ( getByte( "ConfirmDeletion", DEFAULT_PLUGIN_CONFIRM_ITEMS_DELETION )) + if ( MessageBox( hwnd, TranslateT("Do you really want to delete selected item?"), TranslateT(MODULENAME), MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION ) == IDNO ) + break; + + csw->m_itemslist->m_list->remove( csw->m_listview->getPositionInList()); + csw->m_bSomethingChanged = TRUE; + csw->m_listview->reinitItems( csw->m_itemslist->m_list->getListHead()); + csw->toggleButtons(); + csw->toggleEmptyListMessage(); + break; + + case IDC_FAVOURITE: + { + int selection = csw->m_listview->getPositionInList(); + StatusItem* f = new StatusItem( *csw->m_itemslist->m_list->get( selection )); + f->m_bFavourite = ! f->m_bFavourite; + csw->m_itemslist->m_list->remove( selection ); + selection = csw->m_itemslist->m_list->add( f ); + csw->m_bSomethingChanged = TRUE; + csw->m_listview->reinitItems( csw->m_itemslist->m_list->getListHead()); + csw->m_listview->setFullFocusedSelection( selection ); + csw->toggleButtons(); + } + break; + + case IDC_UNDO: + csw->m_itemslist->m_list->destroy(); + csw->m_itemslist->loadItems(csw->m_protoName); + csw->m_bSomethingChanged = FALSE; + csw->m_listview->reinitItems( csw->m_itemslist->m_list->getListHead()); + csw->toggleButtons(); + csw->toggleEmptyListMessage(); + break; + + case IDC_IMPORT: + { + int result = getByte( "DeleteAfterImport", DEFAULT_PLUGIN_DELETE_AFTER_IMPORT ); + if (result == TRUE) + result = IDYES; + else { + result = MessageBox( hwnd, + TranslateT("Do you want old database entries to be deleted after Import?"), + TranslateT(MODULENAME), MB_YESNOCANCEL | MB_DEFBUTTON2 | MB_ICONQUESTION ); + if ( result == IDCANCEL ) + break; + } + + importCustomStatuses(csw, result); + csw->m_bSomethingChanged = TRUE; + csw->toggleButtons(); + csw->toggleEmptyListMessage(); + } + break; + + case IDC_FILTER: + csw->toggleFilter(); + csw->toggleButtons(); + break; + + case IDC_FILTER_FIELD: + if ( HIWORD( wparam ) == EN_CHANGE ) + csw->m_listview->reinitItems( csw->m_itemslist->m_list->getListHead()); + break; + + case IDCLOSE: // close and save, no custom status + case IDCANCEL: // close and save, no custom status + case IDC_CANCEL: // close and save, cancel custom status + case IDOK: // close and save, set selected custom status + if ( LOWORD( wparam ) == IDOK && csw->toggleButtons()) + SetStatus(IDOK, csw->m_itemslist->m_list->get(csw->m_listview->getPositionInList()), csw->m_protoName); + if ( LOWORD( wparam ) == IDC_CANCEL ) + SetStatus(IDC_CANCEL, NULL, csw->m_protoName); + if ( csw->m_bSomethingChanged ) + csw->m_itemslist->saveItems(csw->m_protoName); + csw->saveWindowPosition(csw->m_handle); + EndDialog(hwnd, FALSE); + break; + } + return FALSE; + + case WM_NOTIFY: + if ( wparam == IDC_CSLIST ) { + NMHDR* pnmh = ( NMHDR* )lparam; + switch ( pnmh->code ) { + case NM_DBLCLK: + PostMessage( hwnd, WM_COMMAND, IDOK, 0L ); + break; + + case LVN_ITEMCHANGED: + case NM_CLICK: + csw->toggleButtons(); + break; + } + } + return FALSE; + + case WM_CTLCOLORSTATIC: + SetTextColor(( HDC )wparam, RGB( 174, 174, 174 )); + if (((HWND)lparam == GetDlgItem(hwnd, IDC_NO_ITEMS)) || ((HWND)lparam == GetDlgItem(hwnd, IDC_ADD_SAMPLE))) + return ( BOOL )GetStockObject( WHITE_BRUSH ); + return FALSE; + + case WM_DESTROY: + SetWindowLongPtr(hwnd, GWLP_USERDATA, 0); + arWindows.remove(csw); + delete csw->m_listview; + csw->deinitIcons(); + delete csw; + break; + } + return FALSE; +} + +INT_PTR CALLBACK CSAMWindowProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) +{ + CSAMWindow* csamw = ( CSAMWindow* )GetWindowLongPtr( hwnd, GWLP_USERDATA ); + + switch ( message ) { + case WM_INITDIALOG: + csamw = ( CSAMWindow* )lparam; + SetWindowLongPtr( hwnd, GWLP_USERDATA, lparam ); + csamw->m_handle = hwnd; + EnableWindow( csamw->m_parent->m_handle, FALSE ); + csamw->m_hCombo = GetDlgItem( hwnd, IDC_COMBO ); + csamw->m_hMessage = GetDlgItem( hwnd, IDC_MESSAGE ); + csamw->setCombo(); + csamw->fillDialog(); + TranslateDialogDefault(hwnd); + break; + + case WM_COMMAND: + switch ( LOWORD( wparam )) { + case IDC_MESSAGE: + csamw->checkFieldLimit( HIWORD( wparam ), LOWORD( wparam )); + break; + + case IDOK: + csamw->checkItemValidity(); + + case IDCANCEL: + EnableWindow(csamw->m_parent->m_handle, TRUE); + EndDialog(hwnd, LOWORD(wparam)); + break; + } + break; + } + return FALSE; +} + + +INT_PTR CALLBACK CSOptionsProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) +{ + switch ( message ) { + case WM_INITDIALOG: + TranslateDialogDefault(hwnd); + CheckDlgButton( hwnd, IDC_CONFIRM_DELETION, + getByte( "ConfirmDeletion", DEFAULT_PLUGIN_CONFIRM_ITEMS_DELETION ) ? + BST_CHECKED : BST_UNCHECKED ); + + CheckDlgButton( hwnd, IDC_DELETE_AFTER_IMPORT, + getByte( "DeleteAfterImport", DEFAULT_PLUGIN_DELETE_AFTER_IMPORT ) ? + BST_CHECKED : BST_UNCHECKED ); + + CheckDlgButton( hwnd, IDC_REMEMBER_POSITION, + getByte( "RememberWindowPosition", DEFAULT_REMEMBER_WINDOW_POSITION ) ? + BST_CHECKED : BST_UNCHECKED ); + return TRUE; + + case WM_NOTIFY: + switch ((( LPNMHDR )lparam )->code ) { + case PSN_APPLY: + setByte( "ConfirmDeletion", IsDlgButtonChecked( hwnd, IDC_CONFIRM_DELETION ) ? 1 : 0 ); + setByte( "DeleteAfterImport", IsDlgButtonChecked( hwnd, IDC_DELETE_AFTER_IMPORT ) ? 1 : 0 ); + setByte( "RememberWindowPosition", IsDlgButtonChecked( hwnd, IDC_REMEMBER_POSITION ) ? 1 : 0 ); + + pcli->pfnReloadProtoMenus(); + break; + } + return TRUE; + } + return FALSE; +} -- cgit v1.2.3