diff options
-rw-r--r-- | plugins/CSList/src/cslist.cpp | 2085 |
1 files changed, 1042 insertions, 1043 deletions
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<CSWindow> 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<CSWindow> 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; +} |