diff options
author | watcherhd <watcherhd@e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb> | 2011-04-21 14:14:52 +0000 |
---|---|---|
committer | watcherhd <watcherhd@e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb> | 2011-04-21 14:14:52 +0000 |
commit | cb4a46e7fbe62d788e66ed6121c717a2d22a4d7c (patch) | |
tree | 30df260fdc5a1b5a7049c2f8cac8b7ef17513d6d /custom_status_list/cslist.c | |
parent | 19b6f534d2e784a1e120bf52c4aa07004798f473 (diff) |
svn.miranda.im is moving to a new home!
git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@7 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb
Diffstat (limited to 'custom_status_list/cslist.c')
-rw-r--r-- | custom_status_list/cslist.c | 1246 |
1 files changed, 1246 insertions, 0 deletions
diff --git a/custom_status_list/cslist.c b/custom_status_list/cslist.c new file mode 100644 index 0000000..6a1bb84 --- /dev/null +++ b/custom_status_list/cslist.c @@ -0,0 +1,1246 @@ +/* ########################################################################## 80
+
+ Custom Status List
+ __________________
+
+ Custom Status List plugin for Miranda-IM (www.miranda-im.org)
+ Follower of Custom Status History List by HANAX
+ Copyright 2006,2007 HANAX
+ Copyright 2007,2008 jarvis
+
+ 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.
+
+ ----------------------------------------------------------------------------
+
+ File name : $URL$
+ Revision : $Rev$
+ Last change on : $Date$
+ Last change by : $Author$
+
+ ----------------------------------------------------------------------------
+
+
+ DESCRIPTION:
+
+ Offers List of your Custom Statuses.
+
+ ----------------------------------------------------------------------------
+
+
+ HISTORY:
+
+ TODO
+ ----
+ - duplicities detection (during Import, adding, ..)
+ - stage 2 of code revision
+ - save window positions
+ - resetting custom status on when selected users log in
+ - exactly, CSList-like system
+ - optionally set Away/NA/DND/Occ
+ - saving dialog positions
+ - all TODOs listed in this source x)
+ - feature requests maybe ..
+
+ 0.0.0.18 - fixing trip :)
+ --------
+ - icon selector shows only icons, that are supported by installed ICQ plugin
+ - fixed memory leak and possible crash when modifying status and then importing 0 DB entries (helpItem not nulled)
+ - merged Add/Modify processes together :)
+ - Unicode build, finally :)
+
+ 0.0.0.17 - I become to be useful :)
+ --------
+ - CSList menu item can be placed elsewhere, also instead of Xstatus menu (currently ICQ eternity/PlusPlus++ mod only)
+ - importing statuses from database (ICQ key)
+ - list sorting (Procedure + calls)
+ - dialog openable only once :)
+ - new icons by inducti0n :)
+ - no more infinite width when adding x-message
+ - new Options dialog
+
+ 0.0.0.16 - rework
+ --------
+ - code redesigned
+ - fix for Windows Vista crash (free) and ANSI Windows crash (init extended controls)
+ - preimplementation for new features that will come (favourites, ...)
+
+ 0.0.0.15 - make me nice
+ --------
+ - stage 1 of code revision
+ - Options dialog (in development) :)
+ - IcoLib group renamed to CSLIST_MODULE_LONG_NAME
+ - status titles in Add/Modify ComboBox were strangely corrected x)
+ - possibility to turn off "Release Notes" dialog
+
+ 0.0.0.14 - will you use me? :)
+ --------
+ - new lines in message input creatable via Enter
+ - NULLED XSTATUS now available :)
+
+ 0.0.0.13 - oooops x))
+ --------
+ - hotfix for Miranda cores < 0.7
+ - CSList appears in Main Menu
+ - fixed icons not loaded when IcoLib is missing
+
+ 0.0.0.12 - goin' my way now x)
+ --------
+ - DB saving method/format slightly modified
+ [+] multi-line messages now working
+ [-] LOST compatibility with HANAX's plugin (but is auto-imported if exists)
+ NOTE: I think "importing-only" of older releases will stay,
+ I have many Feature Requests that would need changing
+ DB format anyway, so this problem looks solved x)
+ - "Release notes" dialog on first run
+ - Updater support
+
+ 0.0.0.11 - will this work? x)
+ --------
+ - some similar procedures merged together :P
+ - another procedures more generalized 8)
+ - separated Add/Modify dialog finally in use :)
+ [+] solves some bahaviour problems x)
+
+ 0.0.0.10 - ohhh, basics ]:)
+ --------
+ - icons support - complete xstatus service :)
+ [+] no more static angry ;) :D
+ - iconized buttons - supporting IcoLib :)
+ - better method for DB entry format - old was little.."dizzy" x) :D
+ - TEMPORARILY DISABLED modifying of items - needs some fixes x))
+
+ 0.0.0.9 - working a little? O:)
+ -------
+ - enhanced List Control behaviour (selecting, deselecting, editation, adding)
+ - LOADING from + SAVING to DB!
+ [+] my parser is also compatible with HANAX plugin's DB entries ;)
+
+ 0.0.0.8 - behaviour testing :o)
+ -------
+ - setting status by double-clicking list item
+ - much better procedures, debugging, better exceptions, dialog behaviour
+
+ 0.0.0.7 - crash testing :o)
+ -------
+ - basic functions coding
+
+ 0.0.0.6 - resource testing
+ -------
+ - basic resources modeling
+
+
+// ############################ INCLUDES & DEFINITIONS ###################### */
+
+#include "cslist.h"
+
+
+// ############################### MAIN ########################################
+
+BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) {
+ hInst = hinstDLL;
+ return TRUE;
+}
+
+
+// ########################### MIM MENU COMMAND ################################
+
+static int PluginMenuCommand( WPARAM wParam, LPARAM lParam ) {
+ if ( !opened )
+ DialogBox( hInst, MAKEINTRESOURCE( IDD_CSLIST ), NULL, ( DLGPROC )CSListProc );
+ else if ( opened == 1 )
+ {
+ opened++;
+ MessageBox( NULL, L"Some instance of Custom Status List is already opened.", L"Custom Status List", MB_OK );
+ opened--;
+ }
+ return 0;
+}
+
+
+// ############################# PLUGIN INFO ###################################
+
+__declspec( dllexport ) PLUGININFOEX* MirandaPluginInfoEx( DWORD mirandaVersion ) {
+ gMirandaVersion = mirandaVersion;
+ return &pluginInfoEx;
+}
+
+__declspec( dllexport ) PLUGININFO* MirandaPluginInfo( DWORD mirandaVersion ) {
+ gMirandaVersion = mirandaVersion;
+ return &pluginInfo;
+}
+
+
+// ############################# INTERFACES ####################################
+
+__declspec( dllexport ) const MUUID* MirandaPluginInterfaces( void ) {
+ return interfaces;
+}
+
+
+// ############################### LOADER ######################################
+
+int __declspec( dllexport ) Load( PLUGINLINK *link ) {
+ pluginLink = link;
+
+ { // are we running under Unicode core?
+ char szVer[MAX_PATH];
+
+ CallService( MS_SYSTEM_GETVERSIONTEXT, MAX_PATH, ( LPARAM )szVer );
+ _strlwr( szVer ); // make sure it is lowercase
+ gbUnicodeCore = ( strstr( szVer, "unicode" ) != NULL );
+ if ( !gbUnicodeCore )
+ {
+ pluginInfoEx.flags = 0;
+ pluginInfo.flags = 0;
+ }
+ }
+
+ hSvcShowList = CreateServiceFunction( MS_CSLIST_SHOWLIST, PluginMenuCommand );
+
+ cslist_init_icons();
+
+ if ( DBGetContactSettingByte( NULL, "ICQ", "XStatusEnabled", 1 ) )
+ { // if xstatuses are enabled, declare, if we can use status menu or main menu only
+ if ( bStatusMenu = ServiceExists( MS_CLIST_ADDSTATUSMENUITEM ) )
+ hHookMenuBuild = HookEvent( ME_CLIST_PREBUILDSTATUSMENU, cslist_init_menu_item );
+ else
+ cslist_init_menu_item( 0, 0 );
+ }
+
+ hHookOnPluginsLoaded = HookEvent( ME_SYSTEM_MODULESLOADED, onPluginsLoaded );
+ hHookOnOptionsInit = HookEvent( ME_OPT_INITIALISE, onOptionsInit );
+ { // Katy's easter-egg :))
+ hHookOnKatynkaIsLoggedIn = HookEvent( ME_DB_CONTACT_SETTINGCHANGED, cslist_KatysEasterEgg );
+ }
+ { // fix for ANSI Windows - Add and Modify dialogs not loaded when clicking - troubles with not loaded ComboBoxEx
+ INITCOMMONCONTROLSEX icc;
+ icc.dwSize = sizeof( icc );
+ icc.dwICC = ICC_USEREX_CLASSES;
+ InitCommonControlsEx( &icc );
+ }
+ return 0;
+}
+
+
+// ############################## UNLOADER #####################################
+
+int __declspec( dllexport ) Unload( void ) {
+ int i;
+ // unhooking, unservicing & unhandling
+ UnhookEvent( hHookMenuBuild );
+ UnhookEvent( hHookOnPluginsLoaded );
+ UnhookEvent( hHookOnOptionsInit );
+ UnhookEvent( hHookOnKatynkaIsLoggedIn );
+ DestroyServiceFunction( hSvcShowList );
+ for ( i = 0; i < SIZEOF( cslforms ); i++ )
+ cslforms[i].hIcoLibItem = NULL;
+ hList = NULL;
+ hXCombo = NULL;
+ hIml = NULL;
+ hDlg = NULL;
+ return 0;
+}
+
+
+// ############################# AFTER-LOADER ##################################
+
+static int onPluginsLoaded( WPARAM wparam, LPARAM lparam )
+{
+ // updater section - needs optimalization x)
+ if( ServiceExists( MS_UPDATE_REGISTER ) )
+ {
+ static Update upd = { 0 };
+
+//#if defined( _UNICODE )
+ static char szCurrentVersion[30];
+ static char *szVersionUrl = CSLIST_UPD_VERURL;
+ static char *szUpdateUrl = CSLIST_UPD_UPDURL;
+ // todo: complete FL updating
+ static char *szFLVersionUrl = CSLIST_UPD_FLVERURL;
+ static char *szFLUpdateurl = CSLIST_UPD_FLUPDURL;
+//#endif
+ static char *szPrefix = CSLIST_UPD_SZPREFIX;
+
+ upd.cbSize = sizeof( upd );
+ upd.szComponentName = pluginInfo.shortName;
+ if ( gMirandaVersion < PLUGIN_MAKE_VERSION( 0, 7, 0, 0 ) )
+ upd.pbVersion = ( BYTE * )CreateVersionStringPlugin( ( PLUGININFO * )&pluginInfo, szCurrentVersion ); // updater support for < 0.7 core
+ else
+ upd.pbVersion = ( BYTE * )CreateVersionStringPluginEx( ( PLUGININFOEX * )&pluginInfoEx, szCurrentVersion );
+ upd.cpbVersion = strlen( ( char * )upd.pbVersion );
+ //upd.szVersionURL = szFLVersionUrl;
+ //upd.szUpdateURL = szFLUpdateurl;
+//#if defined( _UNICODE )
+ upd.pbVersionPrefix = ( BYTE * )CSLIST_UPD_SZPREFIX;
+//#endif
+ upd.cpbVersionPrefix = strlen( ( char * )upd.pbVersionPrefix );
+
+ upd.szBetaUpdateURL = szUpdateUrl;
+ upd.szBetaVersionURL = szVersionUrl;
+ upd.pbVersion = szCurrentVersion;
+ upd.cpbVersion = lstrlenA( szCurrentVersion );
+ upd.pbBetaVersionPrefix = ( BYTE * )szPrefix;
+ upd.cpbBetaVersionPrefix = strlen( ( char * )upd.pbBetaVersionPrefix );
+
+ CallService( MS_UPDATE_REGISTER, 0, ( LPARAM )&upd );
+ }
+ // 0.8+ hotkeys service
+ if ( ServiceExists( MS_HOTKEY_REGISTER ) )
+ {
+ HOTKEYDESC hotkey = { 0 };
+ hotkey.cbSize = sizeof( hotkey );
+ hotkey.pszName = MS_CSLIST_SHOWLIST;
+ hotkey.pszDescription = "Show Custom Status List";
+ hotkey.pszSection = "Status";
+ hotkey.pszService = MS_CSLIST_SHOWLIST;
+ hotkey.DefHotKey = MAKEWORD( 'L', HOTKEYF_CONTROL | HOTKEYF_SHIFT );
+ CallService( MS_HOTKEY_REGISTER, 0, ( LPARAM )&hotkey );
+ }
+ // modern toolbar
+ if ( ServiceExists( MS_TB_ADDBUTTON ) )
+ {
+ TBButton button = { 0 };
+ SKINICONDESC sid = { 0 };
+ TCHAR szFile[MAX_PATH];
+ GetModuleFileName( hInst, szFile, MAX_PATH );
+
+ sid.cbSize = sizeof( sid );
+ sid.flags = SIDF_ALL_TCHAR;
+ sid.ptszSection = L"ToolBar";
+ sid.ptszDefaultFile = ( TCHAR * )szFile;
+ sid.cx = sid.cy = 16;
+
+ sid.pszName = "CSList_TB_Icon";
+ sid.ptszDescription = L"Custom Status List";
+ sid.iDefaultIndex = -IDI_CSLIST;
+ hMainIcon = CallService( MS_SKIN2_ADDICON, 0, ( LPARAM )&sid );
+
+ button.cbSize = sizeof( button );
+ button.pszButtonID = MS_CSLIST_SHOWLIST;
+ button.pszTooltipUp = button.pszTooltipDn = button.pszButtonName = CSLIST_MODULE_LONG_NAME;
+ button.pszServiceName = MS_CSLIST_SHOWLIST;
+ button.defPos = 200;
+ button.tbbFlags = TBBF_SHOWTOOLTIP | TBBF_VISIBLE;
+ button.hPrimaryIconHandle = ( HANDLE )hMainIcon;
+ button.hSecondaryIconHandle = button.hPrimaryIconHandle;
+ CallService( MS_TB_ADDBUTTON, 0, ( LPARAM )&button );
+ }
+ // release notes dialog
+ {
+ int relnotes, showit;
+ relnotes = DBGetContactSettingWord( NULL, CSLIST_MODULE_SHORT_NAME, "RelNotes", 0 );
+ showit = DBGetContactSettingByte( NULL, CSLIST_MODULE_SHORT_NAME, "ShowRelNotes", 1 );
+ if ( relnotes != CSLIST_RELNOTES && showit )
+ DialogBox( hInst, MAKEINTRESOURCE(IDD_RELNOTES), NULL, ( DLGPROC )RelNotesProc );
+ }
+ { // take care of DB entries
+ // not needed :) current structure allows to write them into DB when it's needed :)
+ }
+ return 0;
+}
+
+
+// ############################# OPTIONS LOADER ##############################
+
+int onOptionsInit( WPARAM wparam, LPARAM lparam )
+{
+ OPTIONSDIALOGPAGE odp = { 0 };
+
+ odp.cbSize = sizeof( odp );
+ odp.position = 955000000;
+ odp.hInstance = hInst;
+ odp.pszTemplate = MAKEINTRESOURCEA( IDD_OPTIONS );
+ odp.ptszTitle = TranslateTS( ( TCHAR * )CSLIST_MODULE_LONG_NAME );
+ odp.pfnDlgProc = CSListOptionsProc;
+ odp.ptszGroup = TranslateTS( ( TCHAR * )"Status" );
+ odp.flags = ODPF_BOLDGROUPS;
+
+ CallService( MS_OPT_ADDPAGE, wparam, ( LPARAM )&odp );
+ return 0;
+}
+
+
+// #############################################################################
+// #############################################################################
+// #############################################################################
+// #############################################################################
+// ############################# MAIN PROCEDURE ################################
+// #############################################################################
+// #############################################################################
+// #############################################################################
+
+INT_PTR CALLBACK CSListProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
+{
+ NMHDR* pnmh = 0;
+ hDlg = hwndDlg;
+ switch ( uMsg )
+ {
+ case WM_NOTIFY: // some notifying message is sent
+ {
+ if ( wParam == IDC_CSLIST ) {
+ pnmh = ( NMHDR * )lParam; // TODO : optimize? maybe cleaner solution is possible (switching lParam)
+ // ######################## DBLCLICKING THE LIST ###############################
+ if ( pnmh->code == NM_DBLCLK ) {
+ cslist_set_status( hwndDlg );
+ //cslist_clear_selection();
+ goto savenexit; // stick #1 - edit: not needed ;) so TODO
+ // EndDialog( hwndDlg, LOWORD( wParam ) ); // OPTIONALLY: end dialog when ListItem is DblClk'd?
+ }
+ // #################### CLICKING TO SORT THE LIST ##############################
+ else if ( pnmh->code == LVN_COLUMNCLICK && pnmh->idFrom == IDC_CSLIST ) {
+ cslist_sort_list();
+ }
+ // ######################## CLICKING THE LIST ##################################
+ else {
+ iSelect = SendMessage( hList, LVM_GETNEXTITEM, -1, LVNI_FOCUSED | LVNI_SELECTED ); // set which row is selected (cannot be only focused, but fully selected - second param ;))
+ if ( iSelect == -1 ) // if no selection
+ flag = 0;
+ else
+ flag = 1;
+ EnableWindow( GetDlgItem( hDlg, IDC_MODIFY ), flag );
+ EnableWindow( GetDlgItem( hDlg, IDC_REMOVE ), flag );
+ break;
+ }
+ }
+ }
+ break;
+// ################## INITIALIZING MAIN DIALOG #################################
+ case WM_INITDIALOG:
+ {
+ int i;
+ char szTemp[MAX_PATH + 128];
+
+ opened = 1; // instance opened
+ // ..................................................... creating the list
+ hList = GetDlgItem( hwndDlg, IDC_CSLIST );
+ memset( &LvCol, 0, sizeof( LvCol ) );
+ hIml = ImageList_Create( 16, 16, IsWinVerXPPlus() ? ILC_COLOR32 | ILC_MASK : ILC_COLOR16 | ILC_MASK, 37, 1 );
+ if ( hIml ) {
+ for ( i = 0; i < 37; i++ )
+ {
+ null_snprintf( szTemp, sizeof( szTemp ), "%s_%s%d", "ICQ", "xstatus", i );
+ ImageList_AddIcon( hIml, ( HANDLE )CallService( MS_SKIN2_GETICON, 0, ( LPARAM )szTemp ) );
+ }
+ ListView_SetImageList( hList, hIml, LVSIL_SMALL );
+ }
+ LvCol.mask = LVCF_TEXT | LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM;
+ LvCol.fmt = LVCFMT_LEFT;
+ LvCol.cx = 0x00;
+ LvCol.pszText = L"";
+ LvCol.cx = 0x16;
+ //ListView_SetExtendedListViewStyle( hList, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP );
+ ListView_SetExtendedListViewStyleEx( hList, 0, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP | LVS_EX_INFOTIP );
+ SendMessage( hList, LVM_INSERTCOLUMN , 0, ( LPARAM )&LvCol );
+ LvCol.pszText = TranslateT( "Title" );
+ LvCol.cx = 0x64;
+ SendMessage( hList, LVM_INSERTCOLUMN, 1, ( LPARAM )&LvCol );
+ LvCol.pszText = TranslateT( "Message" );
+ LvCol.cx = 0xa8;
+ SendMessage( hList, LVM_INSERTCOLUMN, 2, ( LPARAM )&LvCol );
+ memset( &LvItem, 0, sizeof( LvItem ) );
+
+ // ................................................ load + sort list items
+ cslist_initialize_list_content( hwndDlg );
+ cslist_sort_list();
+
+ // ............................................. creating iconized buttons
+ for ( i = 0; i < SIZEOF( cslforms ); i++ )
+ {
+ if ( cslforms[i].idc < 0 )
+ continue;
+ SendDlgItemMessage( hwndDlg, cslforms[i].idc, BM_SETIMAGE, IMAGE_ICON, ( LPARAM )LoadIconExEx( cslforms[i].iconIcoLib, cslforms[i].iconNoIcoLib ) );
+ SendDlgItemMessage( hwndDlg, cslforms[i].idc, BUTTONSETASFLATBTN, 0, 0 ); //maybe set as BUTTONSETDEFAULT?
+ SendDlgItemMessage( hwndDlg, cslforms[i].idc, BUTTONADDTOOLTIP, ( WPARAM )TranslateTS( cslforms[i].title ), BATF_TCHAR );
+ }
+ SetWindowText( hwndDlg, TranslateT( "Custom Status List" ) );
+ }
+ break;
+// ######################## COMMANDS ###########################################
+ case WM_COMMAND:
+ switch ( LOWORD( wParam ) )
+ {
+ //case IDC_CSLIST: TODO: deselection
+// ------------------------- EXITING THE LIST ----------------------------------
+savenexit: // stick #1
+ case IDC_NOCHNG: // save, no status change and close
+ case IDCANCEL: // save, no status change and close
+ case IDOK: // not used
+ case IDC_APPLY: // save, set selected and close
+ case IDC_EXIT: // save, set nulled status and close
+ if ( ( LOWORD( wParam ) ) == IDC_APPLY ) //set selected status
+ cslist_set_status( hwndDlg );
+ else if ( ( LOWORD( wParam ) ) == IDC_EXIT )
+ { // set null status
+ ICQ_CUSTOM_STATUS helpStatus;
+ int icon = 0;
+ char* title = "";
+ char* message = "";
+ helpStatus.cbSize = sizeof( ICQ_CUSTOM_STATUS );
+ helpStatus.flags = CSSF_MASK_STATUS | CSSF_MASK_NAME | CSSF_MASK_MESSAGE;
+ helpStatus.status = &icon;
+ helpStatus.ptszName = ( TCHAR * )title;
+ helpStatus.ptszMessage = ( TCHAR * )message;
+ CallService( PS_ICQ_SETCUSTOMSTATUSEX, 0, ( LPARAM )&helpStatus );
+ }
+ flag = 0;
+ iSelect = -1;
+ if ( bChanged ) cslist_save_list_content( hwndDlg );
+ ListView_DeleteAllItems( hList );
+ bChanged = 0;
+ opened = 0; // closing instance
+ EndDialog( hwndDlg, LOWORD( wParam ) );
+ break;
+// -------------------------- OPTIONS BUTTON -----------------------------------
+ case IDC_OPTS:
+ DialogBox( hInst, MAKEINTRESOURCE( IDD_OPTIONS ), hwndDlg, ( DLGPROC )CSListOptionsProc );
+ break;
+// --------------------- ADDING/MODIFYING ITEM --------------------------------
+ case IDC_MODIFY:
+ action = 1;
+ case IDC_ADD:
+ {
+ DialogBox( hInst, MAKEINTRESOURCE( IDD_ADDMODIFY ), hwndDlg, ( DLGPROC )CSListAddModifyProc );
+ if ( AMResult == 1 )
+ {
+ if ( action == 1 )
+ {
+ ModifiedPos = iSelect;
+ cslist_modify_item();
+ ModifiedPos = -1;
+ }
+ else
+ {
+ cslist_add_item();
+ }
+ AMResult = 0;
+ bChanged = 1;
+ }
+ action = 0;
+ cslist_clear_help_item();
+ cslist_sort_list();
+ }
+ break;
+// ----------------- REMOVING ITEM FROM THE LIST -------------------------------
+ case IDC_REMOVE:
+ {
+ cslist_remove_item();
+ bChanged = 1;
+ }
+ break;
+ case IDC_IMPORT:
+ cslist_import_statuses_from_icq();
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+// #############################################################################
+// ########################### END OF MAIN PROCEDURE ###########################
+// #############################################################################
+// #############################################################################
+// ########################## ADD/MODIFY DLG PROCEDURE #########################
+// #############################################################################
+
+INT_PTR CALLBACK CSListAddModifyProc( HWND hwndAMDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
+{
+ switch ( uMsg )
+ {
+ case WM_INITDIALOG:
+ {
+ // .........................................creating comboboxex for xicons
+ // TODO: changing statics and dialog title in order of action :)
+ int i, maxCount;
+ if ( action ^ 1 ) // action == 1
+ {
+ SetWindowText( hwndAMDlg, TranslateT( "Add new item" ) );
+ SetDlgItemText( hwndAMDlg, IDC_AM_OK, TranslateT( "Add" ) );
+ }
+ else
+ {
+ SetWindowText( hwndAMDlg, TranslateT( "Modify selected item" ) );
+ SetDlgItemText( hwndAMDlg, IDC_AM_OK, TranslateT( "Modify" ) );
+ }
+ SetDlgItemText( hwndAMDlg, IDC_AM_CN, TranslateT( "Cancel" ) );
+ SetDlgItemText( hwndAMDlg, IDC_ST_XICON, TranslateT( "Icon:" ) );
+ SetDlgItemText( hwndAMDlg, IDC_ST_XTITLE, TranslateT( "Title:" ) );
+ SetDlgItemText( hwndAMDlg, IDC_ST_XMESSAGE, TranslateT( "Message:" ) );
+
+ hXCombo = GetDlgItem( hwndAMDlg, IDC_CB_ICON );
+ SendMessage( hXCombo, CBEM_SETIMAGELIST, 0, ( LPARAM )hIml );
+ ZeroMemory( &CbItem, sizeof( CbItem ) );
+
+ if ( DBGetContactSettingByte( NULL, "ICQ", "NonStandartXstatus", 0 ) )
+ maxCount = SIZEOF( xstatuses );
+ else
+ maxCount = 32;
+ for ( i = 0; i < maxCount; i++ )
+ {
+ CbItem.mask = CBEIF_IMAGE | CBEIF_TEXT | CBEIF_SELECTEDIMAGE;
+ CbItem.pszText = TranslateTS( xstatuses[i].xname );
+ CbItem.iImage = i; // or xstatuses[i].xnum? x)
+ CbItem.iItem = i;
+ CbItem.iSelectedImage = i;
+ SendMessage( hXCombo, CBEM_INSERTITEM, 0, ( LPARAM )&CbItem );
+ }
+ SendMessage( hXCombo, CB_SETCURSEL, 0, 0 ); // first zero sets selection to top
+ if ( action == 1 ) // modifying
+ {
+ // get values from selection..
+ LvItem.iItem = iSelect;
+ LvItem.iSubItem = 0;
+ ListView_GetItem( hList, &LvItem );
+ ListView_GetItemText( hList, iSelect, 1, helpItem.ItemTitle, CSLIST_XTITLE_LIMIT );
+ ListView_GetItemText( hList, iSelect, 2, helpItem.ItemMessage, CSLIST_XMESSAGE_LIMIT );
+ // ..and send them to edit controls
+ SendMessage( hXCombo, CB_SETCURSEL, LvItem.iImage, 0 );
+ SetDlgItemText( hwndAMDlg, IDC_XTITLE, helpItem.ItemTitle );
+ SetDlgItemText( hwndAMDlg, IDC_XMESSAGE, helpItem.ItemMessage );
+ }
+ }
+ break;
+ case WM_COMMAND:
+ {
+ switch ( LOWORD( wParam ) )
+ {
+ case IDC_XTITLE:
+ if ( ( HIWORD( wParam ) == EN_CHANGE ) )
+ {
+ if ( GetWindowTextLength( GetDlgItem( hwndAMDlg, IDC_XTITLE ) ) > CSLIST_XTITLE_LIMIT )
+ SendDlgItemMessage( hwndAMDlg, IDC_XTITLE, WM_APP, ( WPARAM )Translate( "Warning" ), ( LPARAM )Translate( "This field do not accept string longer than 64 characters. String will be truncated." ) );
+ else
+ SendDlgItemMessage( hwndAMDlg, IDC_XTITLE, WM_APP, 0, 0 );
+ }
+ break;
+ case IDC_XMESSAGE:
+ if ( ( HIWORD( wParam ) == EN_CHANGE ) )
+ {
+ if ( GetWindowTextLength( GetDlgItem( hwndAMDlg, IDC_XMESSAGE ) ) > CSLIST_XMESSAGE_LIMIT )
+ SendDlgItemMessage( hwndAMDlg, IDC_XMESSAGE, WM_APP, ( WPARAM )Translate( "Warning" ), ( LPARAM )Translate( "This field do not accept string longer than 2048 characters. String will be truncated." ) );
+ else
+ SendDlgItemMessage( hwndAMDlg, IDC_XMESSAGE, WM_APP, 0, 0 );
+ }
+ break;
+ case IDOK:
+ case IDC_AM_OK:
+ cslist_AM_set_help_item( hwndAMDlg );
+ AMResult = 1;
+ EndDialog( hwndAMDlg, LOWORD( wParam ) );
+ break;
+ case IDCANCEL:
+ case IDC_AM_CN:
+ AMResult = 0;
+ EndDialog( hwndAMDlg, LOWORD( wParam ) );
+ break;
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
+
+// #############################################################################
+// ####################### END OF ADD/MODIFY DLG PROCEDURE #####################
+// #############################################################################
+// ############################ OPTIONS DLG PROCEDURE ##########################
+// #############################################################################
+
+BOOL CALLBACK CSListOptionsProc( HWND hwndOptsDlg, UINT msg, WPARAM wparam, LPARAM lparam )
+{
+ // WORD flags = DBGetContactSettingWord( NULL, MODULENAME, "flags", default_flags );
+ // EnableWindow( GetDlgItem( hwndOptsDlg, IDC_PLACE_GLOBAL ), 1 );
+ // IsDlgButtonChecked( hwndRNDlg, IDC_SHOWIT )
+ // CheckDlgButton(hwndDlg, IDC_META, DBGetContactSettingByte(NULL,"CLC","Meta",SETTING_USEMETAICON_DEFAULT) ? BST_CHECKED : BST_UNCHECKED); /// by FYR
+
+ switch ( msg )
+ {
+ case WM_INITDIALOG:
+ {
+ int hideCS = DBGetContactSettingByte( NULL, CSLIST_MODULE_SHORT_NAME, "hideCS", 0 );
+ int place = DBGetContactSettingByte( NULL, CSLIST_MODULE_SHORT_NAME, "placement", 11 );
+ CheckDlgButton( hwndOptsDlg, IDC_HIDE_CSMENU, hideCS ? BST_CHECKED : BST_UNCHECKED );
+ switch ( place ) {
+ case 0:
+ case 1:
+ case 11:
+ case 12:
+ CheckDlgButton( hwndOptsDlg, IDC_PLACE_GLOBAL, 1 );
+ EnableWindow( GetDlgItem( hwndOptsDlg, IDC_PLACE_GLOBAL_TOP ), 1 );
+ EnableWindow( GetDlgItem( hwndOptsDlg, IDC_PLACE_GLOBAL_BOTTOM ), 1 );
+ break;
+ case 2:
+ CheckDlgButton( hwndOptsDlg, IDC_PLACE_ICQ_STATUS, 1 );
+ break;
+ case 3:
+ CheckDlgButton( hwndOptsDlg, IDC_PLACE_MAIN, 1 );
+ break;
+ }
+ switch ( place ) {
+ case 0:
+ case 1:
+ case 11 :
+ CheckDlgButton( hwndOptsDlg, IDC_PLACE_GLOBAL_TOP, 1 );
+ break;
+ case 12 :
+ CheckDlgButton( hwndOptsDlg, IDC_PLACE_GLOBAL_BOTTOM, 1 );
+ break;
+ }
+ }
+ break;
+
+ case WM_COMMAND:
+ {
+ switch ( LOWORD( wparam ) )
+ {
+ case IDC_PLACE_GLOBAL:
+ EnableWindow( GetDlgItem( hwndOptsDlg, IDC_PLACE_GLOBAL_TOP ), 1 );
+ EnableWindow( GetDlgItem( hwndOptsDlg, IDC_PLACE_GLOBAL_BOTTOM ), 1 );
+ break;
+ case IDC_PLACE_ICQ_STATUS:
+ case IDC_PLACE_MAIN:
+ EnableWindow( GetDlgItem( hwndOptsDlg, IDC_PLACE_GLOBAL_TOP ), 0 );
+ EnableWindow( GetDlgItem( hwndOptsDlg, IDC_PLACE_GLOBAL_BOTTOM ), 0 );
+ break;
+ case IDOK:
+ case IDCANCEL:
+ {
+ int place, hideCS;
+ hideCS = IsDlgButtonChecked( hwndOptsDlg, IDC_HIDE_CSMENU );
+ DBWriteContactSettingByte( NULL, CSLIST_MODULE_SHORT_NAME, "hideCS", hideCS );
+ if( IsDlgButtonChecked( hwndOptsDlg, IDC_PLACE_GLOBAL ) )
+ {
+ if ( IsDlgButtonChecked( hwndOptsDlg, IDC_PLACE_GLOBAL_TOP ) )
+ place = 11;
+ else if ( IsDlgButtonChecked( hwndOptsDlg, IDC_PLACE_GLOBAL_BOTTOM ) )
+ place = 12;
+ else
+ place = 11;
+ }
+ else if ( IsDlgButtonChecked( hwndOptsDlg, IDC_PLACE_ICQ_STATUS ) )
+ place = 2;
+ else if ( IsDlgButtonChecked( hwndOptsDlg, IDC_PLACE_MAIN ) )
+ place = 3;
+ if ( place != DBGetContactSettingByte( NULL, CSLIST_MODULE_SHORT_NAME, "placement", 0 ) )
+ DBWriteContactSettingByte( NULL, CSLIST_MODULE_SHORT_NAME, "placement", place );
+ }
+ EndDialog( hwndOptsDlg, LOWORD( wparam ) );
+ break;
+ }
+ }
+ break;
+ }
+ return 0;
+}
+
+
+// #############################################################################
+// ######################## END OF OPTIONS DLG PROCEDURE #######################
+// #############################################################################
+// ############################# LIST SORT PROCEDURE ###########################
+// #############################################################################
+
+static int CALLBACK CSListSortProc( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort )
+{
+ LVITEM first, second;
+
+ first.mask = LVIF_IMAGE;
+ first.iItem = lParam1;
+ first.iSubItem = lParamSort;
+
+ second.mask = LVIF_IMAGE;
+ second.iItem = lParam2;
+ second.iSubItem = lParamSort;
+
+ ListView_GetItem( hList, &first );
+ ListView_GetItem( hList, &second );
+
+ if ( first.iImage > second.iImage ) return 1;
+ else if ( first.iImage < second.iImage ) return -1;
+ else return 0;
+}
+
+
+// #############################################################################
+// ########################## END OF LIST SORT PROCEDURE #######################
+// #############################################################################
+// ######################## RELEASE NOTES DIALOG PROCEDURE #####################
+// #############################################################################
+
+INT_PTR CALLBACK RelNotesProc( HWND hwndRNDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
+{
+ switch ( uMsg )
+ {
+ case WM_INITDIALOG:
+ {
+ SetDlgItemText( hwndRNDlg, IDC_TXHTEXT, rnthanks );
+ }
+ break;
+ case WM_COMMAND:
+ {
+ switch ( LOWORD( wParam ) )
+ {
+ case IDOK:
+ case IDCANCEL:
+ {
+ int showit;
+ showit = IsDlgButtonChecked( hwndRNDlg, IDC_SHOWIT ) ? 1 : 0;
+ DBWriteContactSettingByte( NULL, CSLIST_MODULE_SHORT_NAME, "ShowRelNotes", !showit );
+ DBWriteContactSettingWord( NULL, CSLIST_MODULE_SHORT_NAME, "RelNotes", CSLIST_RELNOTES );
+ EndDialog( hwndRNDlg, LOWORD( wParam ) );
+ }
+ break;
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
+
+// #############################################################################
+// #################### END OF RELEASE NOTES DIALOG PROCEDURE ##################
+// #############################################################################
+
+// ############################# HELP FUNCTIONS ################################
+
+int null_snprintf( char *buffer, size_t count, const char* fmt, ... ) // deprecated? O_o
+{
+ va_list va;
+ int len;
+
+ ZeroMemory( buffer, count );
+ va_start( va, fmt );
+ len = mir_vsnprintf( buffer, count - 1, fmt, va );
+ va_end( va );
+ return len;
+}
+
+static int cslist_init_menu_item( WPARAM wParam, LPARAM lParam )
+{
+ CLISTMENUITEM mi = { 0 };
+ int miPlacement = 3;
+ if ( hHookMenuBuild != NULL )
+ miPlacement = DBGetContactSettingByte( NULL, CSLIST_MODULE_SHORT_NAME, "placement", 11 );
+ ZeroMemory( &mi, sizeof( mi ) );
+ mi.cbSize = sizeof( mi );
+ mi.position = -0x7FFFFFFF; // top
+ mi.flags = 0;
+ mi.hIcon = LoadIconExEx( "csl_icon", IDI_CSLIST );
+ mi.ptszName = TranslateTS( ( TCHAR * )"Custom Status List..." );
+ mi.pszService = "CSList/ShowList";
+ mi.pszContactOwner = "ICQ";
+ if ( miPlacement == 12 ) mi.position = 2000040000; // bottom
+ else if ( miPlacement == 2 ) {
+ int protoCount;
+ PROTOCOLDESCRIPTOR** pdesc;
+ CallService(MS_PROTO_ENUMPROTOCOLS,(WPARAM)&protoCount,(LPARAM)&pdesc);
+ if ( protoCount > 1 ) mi.ptszPopupName = ( TCHAR * )"ICQ";
+ }
+ switch ( miPlacement ) {
+ case 0 : // obsolete I think :))
+ case 1 :
+ case 11:
+ case 12:
+ case 2:
+ if( DBGetContactSettingByte( NULL, CSLIST_MODULE_SHORT_NAME, "hideCS", 0 ) )
+ {
+ mi.position = 00000001; // when hiding CSMenu, move to its place
+ mi.ptszName = TranslateTS( ( TCHAR * )"Custom status" );
+ }
+ CallService( MS_CLIST_ADDSTATUSMENUITEM, 0, ( LPARAM )&mi );
+ break;
+ case 3: // add to main menu
+ CallService( MS_CLIST_ADDMAINMENUITEM, 0, ( LPARAM )&mi );
+ break;
+ //case 2: // add to tray menu
+ // CallService( "CList/AddTrayMenuItem", 0, ( LPARAM )&mi );
+ // break;
+ }
+ return 0;
+}
+
+// dialog box ANSI or Unicode?
+
+
+// ################## COMMANDS OF CSLIST #######################################
+
+int cslist_add_item()
+{ // final adding with helpItem
+ int iItem;
+
+// -------------------------------------------------------- define list style --
+ if ( ModifiedPos >= 0 )
+ iItem = ModifiedPos;
+ else
+ iItem = SendMessage( hList, LVM_GETITEMCOUNT, 0, 0 );
+ memset( &LvItem, 0, sizeof( LvItem ) );
+ LvItem.mask = LVIF_TEXT | LVIF_IMAGE;
+
+ LvItem.cchTextMax = 256;
+ LvItem.iItem = iItem;
+// -------------------------------------------------------------------- first --
+ LvItem.iSubItem = 0;
+ LvItem.iImage = helpItem.ItemIcon; // use selected xicon
+
+ SendMessage( hList, LVM_INSERTITEM, 0, ( LPARAM )&LvItem );
+// ------------------------------------------------------------------- second --
+
+ LvItem.iSubItem = 1;
+ LvItem.pszText = helpItem.ItemTitle;
+ SendMessage( hList, LVM_SETITEM, 0, ( LPARAM )&LvItem );
+// -------------------------------------------------------------------- third --
+ LvItem.iSubItem = 2;
+ LvItem.pszText = helpItem.ItemMessage;
+ SendMessage( hList, LVM_SETITEM, 0, ( LPARAM )&LvItem );
+// --------------------------------------------------------------------- end ---
+ cslist_clear_selection();
+ return 0;
+}
+
+int cslist_modify_item()
+{
+ if ( ModifiedPos < 0 )
+ return FALSE;
+ memset( &LvItem, 0, sizeof( LvItem ) );
+ LvItem.mask = LVIF_TEXT | LVIF_IMAGE;
+ LvItem.cchTextMax = 256;
+ LvItem.iItem = ModifiedPos;
+ LvItem.iSubItem = 0;
+ LvItem.iImage = helpItem.ItemIcon;
+ SendMessage( hList, LVM_SETITEM, 0, ( LPARAM )&LvItem );
+ LvItem.iSubItem = 1;
+ LvItem.pszText = helpItem.ItemTitle;
+ SendMessage( hList, LVM_SETITEM, 0, ( LPARAM )&LvItem );
+ LvItem.iSubItem = 2;
+ LvItem.pszText = helpItem.ItemMessage;
+ SendMessage( hList, LVM_SETITEM, 0, ( LPARAM )&LvItem );
+ return TRUE;
+}
+
+int cslist_remove_item()
+{
+ if ( flag ) SendMessage( hList, LVM_DELETEITEM, iSelect, 0 );
+ cslist_clear_selection();
+ return 0;
+}
+
+int cslist_AM_set_help_item(HWND hwndAMDlg)
+{
+ // get and set helpItem xicon
+ ZeroMemory( &CbItem, sizeof( CbItem ) );
+ CbItem.mask = CBEIF_IMAGE | CBEIF_TEXT;
+ CbItem.iItem = SendDlgItemMessage( hwndAMDlg, IDC_CB_ICON, CB_GETCURSEL, 0, 0 );
+ SendDlgItemMessage( hwndAMDlg, IDC_CB_ICON, CBEM_GETITEM, 0, ( LPARAM )&CbItem );
+ helpItem.ItemIcon = CbItem.iImage;
+
+ GetDlgItemText( hwndAMDlg, IDC_XTITLE, helpItem.ItemTitle, CSLIST_XTITLE_LIMIT ); // set helpItem xtitle
+ GetDlgItemText( hwndAMDlg, IDC_XMESSAGE, helpItem.ItemMessage, CSLIST_XMESSAGE_LIMIT ); // set helpItem xmessage
+ return 0;
+}
+
+
+// ################## SERVICES FOR CSLIST ######################################
+
+void cslist_clear_selection() {
+ flag = 0;
+ iSelect = -1;
+ SendMessage( hList, LVM_SETITEMSTATE, -1, 0 );
+ //SendMessage( hList, LVM_GETNEXTITEM, -1, LVNI_FOCUSED | LVNI_SELECTED );
+}
+
+void cslist_clear_help_item() {
+ ZeroMemory( &helpItem, sizeof( helpItem ) );
+}
+
+void cslist_sort_list() {
+ ListView_SortItemsEx( hList, CSListSortProc, (LPARAM)0 );
+}
+
+void cslist_import_statuses_from_icq() {
+ int i, result;
+ result = MessageBox( hDlg, L"Do you want to delete those DB entries after Import?", L"Custom Status List", MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION );
+ for ( i = 0; i < 37; i++ )
+ {
+ DBVARIANT dbv = { 0 };
+ char bufName[64], bufMsg[64];
+ cslist_clear_help_item( );
+ mir_snprintf( bufName, 32, "XStatus%luName", i );
+ mir_snprintf( bufMsg, 32, "XStatus%luMsg", i );
+ helpItem.ItemIcon = i - 1;
+ DBGetContactSettingTString( NULL, "ICQ", bufName, &dbv );
+ lstrcpy( helpItem.ItemTitle, dbv.ptszVal );
+ DBGetContactSettingTString( NULL, "ICQ", bufMsg, &dbv );
+ lstrcpy( helpItem.ItemMessage, dbv.ptszVal );
+ if ( lstrlen( helpItem.ItemTitle ) || lstrlen( helpItem.ItemMessage ) )
+ cslist_add_item();
+ if ( result == IDYES )
+ {
+ DBDeleteContactSetting( NULL, "ICQ", bufName );
+ DBDeleteContactSetting( NULL, "ICQ", bufMsg );
+ }
+ }
+ cslist_sort_list();
+ bChanged = 1;
+}
+
+int cslist_KatysEasterEgg( WPARAM wParam, LPARAM lParam )
+{
+ DBCONTACTWRITESETTING *cws = ( DBCONTACTWRITESETTING* )lParam;
+ if ( ( HANDLE )wParam == NULL || lstrcmpA( cws->szSetting, "Status" ) )
+ return 0;
+ if ( ( DBGetContactSettingDword( ( HANDLE )wParam, "ICQ", "UIN", 0 ) == 0x1831BA1A ) &&
+ ( DBGetContactSettingWord( ( HANDLE )wParam, "UserOnline", "OldStatus2", 0 ) == ID_STATUS_OFFLINE ) &&
+ ( cws->value.wVal > ID_STATUS_OFFLINE ) )
+ {
+ ICQ_CUSTOM_STATUS helpStatus;
+ int icon = 0;
+ char * title = "";
+ char * message = "";
+ helpStatus.cbSize = sizeof( ICQ_CUSTOM_STATUS );
+ helpStatus.flags = CSSF_MASK_STATUS | CSSF_MASK_NAME | CSSF_MASK_MESSAGE;
+ helpStatus.status = &icon;
+ helpStatus.ptszName = ( TCHAR * )title;
+ helpStatus.ptszMessage = ( TCHAR * )message;
+ CallService( PS_ICQ_SETCUSTOMSTATUSEX, 0, ( LPARAM )&helpStatus );
+ }
+ return 0;
+}
+
+// ################## DB - LOAD AND SAVE #######################################
+
+int cslist_initialize_list_content( HWND hwndDlg )
+{
+ // get DB string, parse to statuses, add by helpItem
+ DBVARIANT dbv = { DBVT_TCHAR };
+ int parseResult;
+ int dbLoadResult;
+ const TCHAR* rowDelim = L""; // new line
+ TCHAR *row = NULL;
+
+ dbLoadResult = DBGetContactSettingTString( NULL, CSLIST_MODULE_SHORT_NAME, "listhistory", &dbv );
+ if ( dbv.ptszVal )
+ {
+ row = tcstok( dbv.ptszVal, rowDelim );
+ while( row != NULL ) {
+ // process current row..
+ parseResult = cslist_parse_row( row );
+ // ..add item..
+ if ( parseResult == TRUE ) cslist_add_item();
+ // ..and go to the other, while some remains
+ row = tcstok( NULL, rowDelim );
+ }
+ }
+ //free( rowDelim );
+ //free( row );
+ return 0;
+}
+
+int cslist_parse_row( TCHAR *row ) // parse + helpItem
+{
+ int pIconInt;
+ TCHAR pIcon[4], pTitle[CSLIST_XTITLE_LIMIT+2], pMsg[CSLIST_XMESSAGE_LIMIT+2], pFav[4];
+
+#if defined( _UNICODE )
+ if ( swscanf( row, L"%2[^]%64[^]%2048[^]%2[^]", &pIcon, &pTitle, &pMsg, &pFav ) == 4 ) // PLEASE!! x) use DEFs xO
+#else
+ if ( sscanf( row, "%2[^]%64[^]%2048[^]%2[^]", pIcon, pTitle, pMsg, pFav ) == 4 ) // PLEASE!! x) use DEFs xO
+#endif
+ {
+#if defined( _UNICODE )
+ pIconInt = _wtoi( pIcon );
+#else
+ pIconInt = atoi( pIcon );
+#endif
+ helpItem.ItemIcon = pIconInt;
+ lstrcpy( helpItem.ItemTitle, pTitle );
+ lstrcpy( helpItem.ItemMessage, pMsg );
+ }
+#if defined( _UNICODE )
+ else if ( swscanf( row, L"%2[^]%2048[^]%2[^]", &pIcon, &pMsg, &pFav ) == 3 )
+#else
+ else if ( sscanf( row, "%2[^]%2048[^]%2[^]", pIcon, pMsg, pFav ) == 3 )
+#endif
+ {
+#if defined( _UNICODE )
+ pIconInt = _wtoi( pIcon );
+#else
+ pIconInt = atoi( pIcon );
+#endif
+ helpItem.ItemIcon = pIconInt;
+ lstrcpy( helpItem.ItemTitle, L"" );
+ lstrcpy( helpItem.ItemMessage, pMsg );
+ }
+#if defined( _UNICODE )
+ else if ( swscanf( row, L"%2[^]%64[^]%2[^]", &pIcon, &pTitle, &pFav ) == 3 )
+#else
+ else if ( sscanf( row, "%2[^]%64[^]%2[^]", pIcon, pTitle, pFav ) == 3 )
+#endif
+ {
+#if defined( _UNICODE )
+ pIconInt = _wtoi( pIcon );
+#else
+ pIconInt = atoi( pIcon );
+#endif
+ helpItem.ItemIcon = pIconInt;
+ lstrcpy( helpItem.ItemTitle, pTitle );
+ lstrcpy( helpItem.ItemMessage, L"" );
+ }
+//#if defined( _UNICODE )
+// else if( swscanf( row, L"%2[^]%2[^]", &pIcon, &pFav ) == 2 )
+//#else
+// else if( sscanf( row, "%2[^]%2[^]", pIcon, pFav ) == 2 )
+//#endif
+// {
+//#if defined( _UNICODE )
+// pIconInt = _wtoi( pIcon );
+//#else
+// pIconInt = atoi( pIcon );
+//#endif
+// helpItem.ItemIcon = pIconInt;
+// lstrcpy( helpItem.ItemTitle, "" );
+// lstrcpy( helpItem.ItemMessage, "" );
+// } // why allow empty xstatuses? O_o
+ else {
+ //free(row);
+ //free(pIcon);
+ //free(pTitle);
+ //free(pMsg);
+ //free(pFav);
+ return FALSE;
+ }
+ //free(row);
+ //free(pIcon);
+ //free(pTitle);
+ //free(pMsg);
+ //free(pFav);
+ return TRUE;
+}
+
+
+int cslist_save_list_content( HWND hwndDlg )
+{
+ TCHAR cImageToString[64];
+ int i = 0;
+ LPTSTR dbString = { 0 };
+ TCHAR dbStringTmp[65536];
+ lstrcpy( dbStringTmp, L"" ); // set to empty - caused "dizzy" string begin x) O_o
+ lstrcpy( cImageToString, L"" );
+ for ( i = 0; i < ListView_GetItemCount( hList ); i++ )
+ {
+ // insert xint to string
+ LvItem.iItem = i;
+ LvItem.iSubItem = 0;
+ ListView_GetItem( hList, &LvItem );
+ tcprintf( cImageToString, 8, L"%d", LvItem.iImage );
+ lstrcat( dbStringTmp, cImageToString );
+ lstrcpy( cImageToString, L"" );
+ lstrcat( dbStringTmp, L"" );
+ ListView_GetItemText( hList, i, 1, helpItem.ItemTitle, CSLIST_XTITLE_LIMIT );
+ if ( wcslen( helpItem.ItemTitle ) > 0 ) lstrcat( dbStringTmp, helpItem.ItemTitle );
+ lstrcat( dbStringTmp, L"" );
+ ListView_GetItemText( hList, i, 2, helpItem.ItemMessage, CSLIST_XMESSAGE_LIMIT );
+ if ( wcslen( helpItem.ItemMessage ) > 0 ) lstrcat( dbStringTmp, helpItem.ItemMessage );
+ lstrcat( dbStringTmp, L"0" );
+ }
+ dbString = dbStringTmp;
+ // save to DB
+ DBWriteContactSettingTString( NULL, CSLIST_MODULE_SHORT_NAME, "listhistory", dbString );
+ free( dbString );
+ free( dbStringTmp );
+ lstrcpy( helpItem.ItemTitle, L"" );
+ lstrcpy( helpItem.ItemMessage, L"" );
+ return 0;
+}
+
+
+// ######################### CREATING DIALOG ###################################
+
+int cslist_set_status( HWND hwndDlg )
+{
+ ICQ_CUSTOM_STATUS helpStatus;
+ memset( &helpStatus, 0, sizeof( helpStatus ) );
+ helpStatus.cbSize = sizeof( ICQ_CUSTOM_STATUS );
+ helpStatus.flags = CSSF_MASK_STATUS | CSSF_MASK_NAME | CSSF_MASK_MESSAGE | CSSF_UNICODE;
+ iSelect = SendMessage( hList, LVM_GETNEXTITEM, -1, LVNI_FOCUSED | LVNI_SELECTED ); // set which row is selected
+ if ( iSelect == -1 ) // no status selected
+ flag = 0;
+ else
+ { // else get values from selection
+ LvItem.iItem = iSelect;
+ LvItem.iSubItem = 0;
+ ListView_GetItem( hList, &LvItem );
+ helpItem.ItemIcon = LvItem.iImage; // TODO: get xicon int and set ..
+ ListView_GetItemText( hList, iSelect, 1, helpItem.ItemTitle, CSLIST_XTITLE_LIMIT );
+ ListView_GetItemText( hList, iSelect, 2, helpItem.ItemMessage, CSLIST_XMESSAGE_LIMIT );
+ // ..and set xstatus
+ helpItem.ItemIcon++; // need revision of redirected xstatus numbers xo)
+ helpStatus.status = &helpItem.ItemIcon;
+ helpStatus.ptszName = helpItem.ItemTitle;
+ helpStatus.ptszMessage = helpItem.ItemMessage;
+ CallService( PS_ICQ_SETCUSTOMSTATUSEX, 0, ( LPARAM )&helpStatus ); // f**king function, 4 hours of thinking xDD
+ // ..and clean helper + selection
+ cslist_clear_selection();
+ }
+ return 0;
+}
+
+void cslist_init_icons( void )
+{
+ int i;
+ SKINICONDESC sid = { 0 };
+ char szFile[MAX_PATH];
+ GetModuleFileNameA( hInst, szFile, MAX_PATH );
+
+ sid.cbSize = sizeof( SKINICONDESC );
+ sid.ptszDefaultFile = ( TCHAR * )szFile;
+ sid.cx = sid.cy = 16;
+ sid.ptszSection = TranslateTS( CSLIST_MODULE_LONG_NAME );
+
+ for ( i = 0; i < SIZEOF( cslforms ); i++ )
+ {
+ char szSettingName[64];
+ mir_snprintf( szSettingName, sizeof( szSettingName ), "%s_%s", CSLIST_MODULE_SHORT_NAME, cslforms[i].iconIcoLib );
+ sid.pszName = szSettingName;
+ sid.ptszDescription = TranslateTS( cslforms[i].szDescr );
+ sid.iDefaultIndex = -cslforms[i].iconNoIcoLib;
+ cslforms[i].hIcoLibItem = ( HANDLE )CallService( MS_SKIN2_ADDICON, 0, ( LPARAM )&sid );
+ }
+}
+
+
+// ######################### OTHER FUNCTIONS ###################################
+
+HICON LoadIconExEx( const char* IcoLibName, int NonIcoLibIcon )
+{
+ if ( ServiceExists( MS_SKIN2_GETICON ) ) {
+ char szSettingName[64];
+ mir_snprintf( szSettingName, sizeof( szSettingName ), "%s_%s", CSLIST_MODULE_SHORT_NAME, IcoLibName );
+ return ( HICON )CallService( MS_SKIN2_GETICON, 0, ( LPARAM )szSettingName );
+ }
+ else
+ return ( HICON )LoadImage( hInst, MAKEINTRESOURCE( NonIcoLibIcon ), IMAGE_ICON, 0, 0, 0 );
+}
+
+
+/* ########################################################################## 80
+
+ Custom Status List
+ __________________
+
+ by jarvis
+
+// ############################################################ 2008/01/28 ## */
|