diff options
Diffstat (limited to 'plugins/QuickSearch')
20 files changed, 5702 insertions, 0 deletions
diff --git a/plugins/QuickSearch/ico/default.ico b/plugins/QuickSearch/ico/default.ico Binary files differnew file mode 100644 index 0000000000..4cd27f0623 --- /dev/null +++ b/plugins/QuickSearch/ico/default.ico diff --git a/plugins/QuickSearch/ico/delete.ico b/plugins/QuickSearch/ico/delete.ico Binary files differnew file mode 100644 index 0000000000..07fee6c512 --- /dev/null +++ b/plugins/QuickSearch/ico/delete.ico diff --git a/plugins/QuickSearch/ico/down.ico b/plugins/QuickSearch/ico/down.ico Binary files differnew file mode 100644 index 0000000000..d4fdb83bbf --- /dev/null +++ b/plugins/QuickSearch/ico/down.ico diff --git a/plugins/QuickSearch/ico/female.ico b/plugins/QuickSearch/ico/female.ico Binary files differnew file mode 100644 index 0000000000..fe1cbd2bce --- /dev/null +++ b/plugins/QuickSearch/ico/female.ico diff --git a/plugins/QuickSearch/ico/item.ico b/plugins/QuickSearch/ico/item.ico Binary files differnew file mode 100644 index 0000000000..80c3802c09 --- /dev/null +++ b/plugins/QuickSearch/ico/item.ico diff --git a/plugins/QuickSearch/ico/male.ico b/plugins/QuickSearch/ico/male.ico Binary files differnew file mode 100644 index 0000000000..ebd0420554 --- /dev/null +++ b/plugins/QuickSearch/ico/male.ico diff --git a/plugins/QuickSearch/ico/new.ico b/plugins/QuickSearch/ico/new.ico Binary files differnew file mode 100644 index 0000000000..ac80adb26e --- /dev/null +++ b/plugins/QuickSearch/ico/new.ico diff --git a/plugins/QuickSearch/ico/qs.ico b/plugins/QuickSearch/ico/qs.ico Binary files differnew file mode 100644 index 0000000000..415a0bccd7 --- /dev/null +++ b/plugins/QuickSearch/ico/qs.ico diff --git a/plugins/QuickSearch/ico/reload.ico b/plugins/QuickSearch/ico/reload.ico Binary files differnew file mode 100644 index 0000000000..dc070c5083 --- /dev/null +++ b/plugins/QuickSearch/ico/reload.ico diff --git a/plugins/QuickSearch/ico/up.ico b/plugins/QuickSearch/ico/up.ico Binary files differnew file mode 100644 index 0000000000..56fde31eda --- /dev/null +++ b/plugins/QuickSearch/ico/up.ico diff --git a/plugins/QuickSearch/make.bat b/plugins/QuickSearch/make.bat new file mode 100644 index 0000000000..36de9c338c --- /dev/null +++ b/plugins/QuickSearch/make.bat @@ -0,0 +1,17 @@ +@echo off
+set myopts=-dMiranda
+set dprname=quicksearch.dpr
+
+..\delphi\brcc32.exe qs.rc -foqs.res
+
+if /i '%1' == 'fpc' (
+ ..\FPC\bin\fpc.exe %myopts% %dprname% %2 %3 %4 %5 %6 %7 %8 %9
+) else if /i '%1' == 'fpc64' (
+ ..\FPC\bin64\ppcrossx64.exe %myopts% %dprname% %2 %3 %4 %5 %6 %7 %8 %9
+) else if /i '%1' == 'xe2' (
+ ..\XE2\BIN\dcc32.exe %myopts% %dprname% %2 %3 %4 %5 %6 %7 %8 %9
+) else if /i '%1' == 'xe64' (
+ ..\XE2\BIN\dcc64.exe %myopts% %dprname% %2 %3 %4 %5 %6 %7 %8 %9
+) else (
+ ..\delphi\dcc32 %myopts% %dprname% %1 %2 %3 %4 %5 %6 %7 %8 %9
+)
diff --git a/plugins/QuickSearch/qs.rc b/plugins/QuickSearch/qs.rc new file mode 100644 index 0000000000..d22a32c57d --- /dev/null +++ b/plugins/QuickSearch/qs.rc @@ -0,0 +1,178 @@ +#include "resource.inc"
+
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+
+IDD_FRAME DIALOGEX 0, 0, 114, 16, 0
+STYLE DS_SETFONT | WS_CHILD | DS_FIXEDSYS | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0
+{
+ PUSHBUTTON "*", IDC_FRAME_OPEN, 2, 2, 12, 12
+ EDITTEXT IDC_FRAME_EDIT, 16, 2, 62, 12
+ PUSHBUTTON "<", IDC_FRAME_PREV, 80, 2, 15, 12
+ PUSHBUTTON ">", IDC_FRAME_NEXT, 97, 2, 15, 12
+}
+
+IDD_SCRIPT DIALOGEX 0, 0, 256, 82, 0
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_VISIBLE | WS_THICKFRAME
+CAPTION "Script Editor"
+//EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0
+{
+ EDITTEXT IDC_EDIT_SCRIPT , 4, 4, 248, 56,
+ ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL
+ PUSHBUTTON "&OK" , IDOK , 106, 64, 46, 14
+ PUSHBUTTON "&Help" , IDHELP , 156, 64, 46, 14
+ PUSHBUTTON "C&ancel", IDCANCEL , 206, 64, 46, 14
+}
+
+IDD_DIALOG1 DIALOGEX 40, 40, 314, 240
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE | WS_BORDER
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "Ms Shell Dlg",0,0
+{
+ CONTROL "New" ,IDC_NEW ,"MButtonClass",WS_TABSTOP,216, 46,16,16,$18000000
+ CONTROL "Save" ,IDC_SETITEM,"MButtonClass",WS_TABSTOP,216, 64,16,16,$18000000
+ CONTROL "Up" ,IDC_UP ,"MButtonClass",WS_TABSTOP,216, 82,16,16,$18000000
+ CONTROL "Down" ,IDC_DN ,"MButtonClass",WS_TABSTOP,216,100,16,16,$18000000
+ CONTROL "Delete" ,IDC_DELETE ,"MButtonClass",WS_TABSTOP,216,118,16,16,$18000000
+ CONTROL "Default",IDC_DEFAULT,"MButtonClass",WS_TABSTOP,216,136,16,16,$18000000
+ CONTROL "Reload" ,IDC_RELOAD ,"MButtonClass",WS_TABSTOP,216, 2,16,16,$18000000
+
+ CONTROL "List2",IDC_LIST,"SysListView32",LVS_REPORT |
+ LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER |
+ WS_BORDER | WS_TABSTOP,0,2,213,150
+
+ CTEXT "Settings",-1 ,234, 2,77,12, SS_CENTERIMAGE
+ CONTROL "", -1, "STATIC", SS_ETCHEDHORZ, 234, 14, 77, 2
+
+ LTEXT "Title:",-1 ,236, 16,75,12, SS_CENTERIMAGE
+ EDITTEXT IDC_E_TITLE ,234, 28,77,14, ES_AUTOHSCROLL | WS_TABSTOP
+
+ LTEXT "Type:",-1 ,236, 44,75,12, SS_CENTERIMAGE
+ COMBOBOX IDC_C_VARTYPE ,234, 56,77,110, CBS_DROPDOWNLIST |
+ CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+
+ LTEXT "InfoType:",IDC_STAT_VARTYPE,236, 72,75,12, SS_CENTERIMAGE
+ COMBOBOX IDC_C_CNFTYPE ,234, 84,77,150, CBS_DROPDOWNLIST |
+ CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_C_RESULT ,234, 84,77,80, CBS_DROPDOWNLIST |
+ CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "Script",IDC_SCRIPT, 234, 84, 77, 12
+
+ LTEXT "Service:",IDC_STAT_SERVICE ,236,100,75,12, SS_CENTERIMAGE
+ LTEXT "Module:" ,IDC_STAT_MODULE ,236,100,75,12, SS_CENTERIMAGE
+ EDITTEXT IDC_E_MODULE ,234,112,77,14, ES_AUTOHSCROLL | WS_TABSTOP
+
+ LTEXT "wParam:",IDC_STAT_WPAR ,236,128,75,12, SS_CENTERIMAGE
+ LTEXT "Setting:",IDC_STAT_SETTING ,236,128,75,12, SS_CENTERIMAGE
+ EDITTEXT IDC_E_VAR ,234,140,77,14, ES_AUTOHSCROLL | WS_TABSTOP
+
+ LTEXT "wParam type:",-1,236,156,75,12, SS_CENTERIMAGE
+ COMBOBOX IDC_C_WPAR ,234,168,77,80, CBS_DROPDOWNLIST |
+ CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+
+ LTEXT "lParam:",-1,236,184,75,12, SS_CENTERIMAGE
+ EDITTEXT IDC_E_LPAR ,234,196,77,14, ES_AUTOHSCROLL | WS_TABSTOP
+
+ LTEXT "lParam type:",-1 ,236,212,75,12, SS_CENTERIMAGE
+ COMBOBOX IDC_C_LPAR ,234,224,77,80, CBS_DROPDOWNLIST |
+ CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+
+ CONTROL "Sort by Status",IDC_CH_SORTSTATUS,"Button",
+ BS_MULTILINE | BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,5,166,109,10
+ CONTROL "Only Users in List",IDC_CH_SHOWONLYUSERS,"Button",
+ BS_MULTILINE | BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,5,178,109,10
+ CONTROL "Auto Close mode",IDC_CH_AUTOCLOSE,"Button",
+ BS_MULTILINE | BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,5,190,109,10
+ CONTROL "Draw Grid",IDC_CH_DRAWGRID,"Button",
+ BS_MULTILINE | BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,5,202,109,10
+ CONTROL "Show Client Icons",IDC_CH_SHOWCLIENTICONS,"Button",
+ BS_MULTILINE | BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,5,214,109,10
+ CONTROL "Save search pattern",IDC_CH_SAVEPATTERN,"Button",
+ BS_MULTILINE | BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,5,226,109,10
+ GROUPBOX "",-1,0,154,116,84
+
+ CONTROL "Item in Main Menu",IDC_CH_SHOWINMENU,"Button",
+ BS_MULTILINE | BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,121,166,109,10
+ CONTROL "Button on TopToolBar",IDC_CH_ADDTOTOPTOOLBAR,"Button",
+ BS_MULTILINE | BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,121,178,109,10
+ CONTROL "Tool Window Style",IDC_CH_USETOOLSTYLE,"Button",
+ BS_MULTILINE | BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,121,190,109,10
+ CONTROL "Copy line to CSV",IDC_CH_SINGLECSV,"Button",
+ BS_MULTILINE | BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,121,202,109,10
+ CONTROL "CSV with headers",IDC_CH_EXPORTHEADERS,"Button",
+ BS_MULTILINE | BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,121,214,109,10
+ CONTROL "Skip minimized columns",IDC_CH_SKIPMINIMIZED,"Button",
+ BS_MULTILINE | BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,121,226,109,10
+ GROUPBOX "",-1,118,154,114,84
+ GROUPBOX "Additional Options",-1,0,154,232,84
+}
+
+IDI_QS ICON DISCARDABLE "ico\qs.ico"
+
+IDI_NEW ICON DISCARDABLE "ico\new.ico"
+IDI_ITEM ICON DISCARDABLE "ico\item.ico"
+IDI_UP ICON DISCARDABLE "ico\up.ico"
+IDI_DOWN ICON DISCARDABLE "ico\down.ico"
+IDI_DELETE ICON DISCARDABLE "ico\delete.ico"
+IDI_DEFAULT ICON DISCARDABLE "ico\default.ico"
+IDI_RELOAD ICON DISCARDABLE "ico\reload.ico"
+
+IDI_MALE ICON DISCARDABLE "ico\male.ico"
+IDI_FEMALE ICON DISCARDABLE "ico\female.ico"
+
+IDD_MAIN DIALOGEX 40, 40, 520, 240
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CAPTION | WS_VISIBLE | WS_BORDER | WS_SYSMENU |
+ WS_DLGFRAME | WS_OVERLAPPED | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_THICKFRAME
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "Ms Shell Dlg",0,0
+{
+ EDITTEXT IDC_E_SEARCHTEXT, 180,8,276,14, WS_TABSTOP// | ES_LOWERCASE
+ PUSHBUTTON "Close" , IDCANCEL , 462, 0,52,14, WS_TABSTOP
+ PUSHBUTTON "Refresh", IDC_REFRESH, 462,16,52,14, WS_TABSTOP
+
+ CONTROL "Show Offline contacts",IDC_CH_SHOWOFFLINE,"Button",
+ BS_AUTOCHECKBOX | BS_FLAT | BS_MULTILINE | BS_VCENTER | WS_TABSTOP,2,0,96,20
+ CONTROL "Colorize",IDC_CH_COLORIZE,"Button",
+ BS_AUTOCHECKBOX | BS_FLAT | BS_MULTILINE | BS_VCENTER | WS_TABSTOP,2,20,96,10
+// LTEXT "Search for:",-1, 4,4,52,14, SS_CENTERIMAGE
+ COMBOBOX IDC_CB_PROTOCOLS,100,8,76,80, CBS_DROPDOWNLIST |
+ CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+ CONTROL "", IDC_LIST, "SysListView32", WS_BORDER | WS_TABSTOP | // LVS_SHAREIMAGELISTS | // LVS_EX_SUBITEMIMAGES |
+ LVS_SHOWSELALWAYS | LVS_REPORT | LVS_NOLABELWRAP,
+ 2, 32, 516, 194 //, WS_EX_CONTROLPARENT
+
+ CONTROL "", IDC_STATUSBAR, "msctls_statusbar32",
+ CCS_BOTTOM | 0x0900, // SBT_TOOLTIPS | SBARS_SIZEGRIP
+ 0,226,520,14
+}
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,4,1,18
+ PRODUCTVERSION 0,8,0,0
+ FILEFLAGSMASK $3F
+ FILEOS 4
+ FILETYPE 2
+ FILESUBTYPE 0
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "CompanyName",""
+ VALUE "Comments", "Plugin to quick search for nickname, firstname, lastname, email, uin in your contact list"0
+ VALUE "FileDescription", "Quick info search plugin for Miranda NG"0
+ VALUE "FileVersion", "1, 4, 1, 18 "0
+ VALUE "InternalName", "QuickSearchMod"0
+ VALUE "OriginalFilename", "quicksearch.dll"0
+ VALUE "ProductName", "QuickSearchMod Dynamic Link Library (DLL)"0
+ VALUE "ProductVersion", "0, 8, 0, 0 "0
+ VALUE "SpecialBuild", "2.07.2010 "0
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation",0,1200
+ END
+END
diff --git a/plugins/QuickSearch/qs.res b/plugins/QuickSearch/qs.res Binary files differnew file mode 100644 index 0000000000..891c078829 --- /dev/null +++ b/plugins/QuickSearch/qs.res diff --git a/plugins/QuickSearch/quicksearch.dpr b/plugins/QuickSearch/quicksearch.dpr new file mode 100644 index 0000000000..699472b7b1 --- /dev/null +++ b/plugins/QuickSearch/quicksearch.dpr @@ -0,0 +1,244 @@ +{$include compilers.inc}
+{$IFDEF COMPILER_16_UP}
+ {$WEAKLINKRTTI ON}
+ {.$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
+{$ENDIF}
+{$IMAGEBASE $13100000}
+library quicksearch;
+
+{$R qs.res}
+
+uses
+// FastMM4,
+ Windows,
+ Messages,
+ m_api,
+ sr_optdialog,
+ sr_global,
+ sr_window,
+ sr_frame,
+ mirutils,
+ common;
+
+var
+ opthook:cardinal;
+ onloadhook:cardinal;
+ onstatus,
+ ondelete,
+// onaccount,
+ onadd:cardinal;
+ servshow:cardinal;
+
+const
+ icohook:THANDLE = 0;
+
+function MirandaPluginInfoEx(mirandaVersion:DWORD):PPLUGININFOEX; cdecl;
+begin
+ result:=@PluginInfo;
+ PluginInfo.cbSize :=SizeOf(TPLUGININFOEX);
+ PluginInfo.shortName :='Quick Search Mod';
+ PluginInfo.version :=$01040112;
+ PluginInfo.description:=
+ 'This Plugin allow you to quick search for nickname,'+
+ 'firstname, lastname, email, uin in your contact list.'+
+ 'And now you may add any setting to display - for example'+
+ 'users version of miranda,group or city.';
+ PluginInfo.author :='Awkward, based on Bethoven sources';
+ PluginInfo.authorEmail:='panda75@bk.ru; awk1975@ya.ru';
+ PluginInfo.copyright :='(c) 2004,2005 Bethoven; 2006-2012 Awkward';
+ PluginInfo.homepage :='http://code.google.com/p/delphi-miranda-plugins/';
+ PluginInfo.flags :=UNICODE_AWARE;
+ PluginInfo.uuid :=MIID_QUICKSEARCH;
+end;
+
+function OnTTBLoaded(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+begin
+ addtotoolbar;
+ result:=0;
+end;
+
+function IconChanged(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+var
+ mi:TCListMenuItem;
+ ttb:TTBButton;
+begin
+ result:=0;
+ FillChar(mi,SizeOf(mi),0);
+ mi.cbSize:=sizeof(mi);
+ mi.flags :=CMIM_ICON;
+
+ mi.hIcon:=CallService(MS_SKIN2_GETICON,0,tlparam(QS_QS));
+ CallService(MS_CLIST_MODIFYMENUITEM,MainMenuItem,tlparam(@mi));
+
+// toptoolbar
+ if ServiceExists(MS_TTB_GETBUTTONOPTIONS)<>0 then
+ begin
+ CallService(MS_TTB_GETBUTTONOPTIONS,(hTTBButton shl 16)+TTBO_ALLDATA,TLPARAM(@ttb));
+ ttb.hIconUp:=CallService(MS_SKIN2_GETICON,0,TLPARAM(QS_QS));
+ ttb.hIconDn:=ttb.hIconUp;
+ CallService(MS_TTB_SETBUTTONOPTIONS,(hTTBButton shl 16)+TTBO_ALLDATA,TLPARAM(@ttb));
+ end;
+
+end;
+
+procedure RegisterIcons;
+var
+ sid:TSKINICONDESC;
+begin
+ FillChar(sid,SizeOf(TSKINICONDESC),0);
+ sid.cbSize :=SizeOf(TSKINICONDESC);
+ sid.cx :=16;
+ sid.cy :=16;
+ sid.szSection.a:=qs_module;
+
+ sid.hDefaultIcon :=LoadImage(hInstance,MAKEINTRESOURCE(IDI_QS),IMAGE_ICON,16,16,0);
+ sid.pszName :=QS_QS;
+ sid.szDescription.a:=qs_name;
+ Skin_AddIcon(@sid);
+ DestroyIcon(sid.hDefaultIcon);
+
+ sid.hDefaultIcon :=LoadImage(hInstance,MAKEINTRESOURCE(IDI_NEW),IMAGE_ICON,16,16,0);
+ sid.pszName :=QS_NEW;
+ sid.szDescription.a:='New Column';
+ Skin_AddIcon(@sid);
+ DestroyIcon(sid.hDefaultIcon);
+
+ sid.hDefaultIcon :=LoadImage(hInstance,MAKEINTRESOURCE(IDI_ITEM),IMAGE_ICON,16,16,0);
+ sid.pszName :=QS_ITEM;
+ sid.szDescription.a:='Save Column';
+ Skin_AddIcon(@sid);
+ DestroyIcon(sid.hDefaultIcon);
+
+ sid.hDefaultIcon :=LoadImage(hInstance,MAKEINTRESOURCE(IDI_UP),IMAGE_ICON,16,16,0);
+ sid.pszName :=QS_UP;
+ sid.szDescription.a:='Column Up';
+ Skin_AddIcon(@sid);
+ DestroyIcon(sid.hDefaultIcon);
+
+ sid.hDefaultIcon :=LoadImage(hInstance,MAKEINTRESOURCE(IDI_DOWN),IMAGE_ICON,16,16,0);
+ sid.pszName :=QS_DOWN;
+ sid.szDescription.a:='Column Down';
+ Skin_AddIcon(@sid);
+ DestroyIcon(sid.hDefaultIcon);
+
+ sid.hDefaultIcon :=LoadImage(hInstance,MAKEINTRESOURCE(IDI_DELETE),IMAGE_ICON,16,16,0);
+ sid.pszName :=QS_DELETE;
+ sid.szDescription.a:='Delete Column';
+ Skin_AddIcon(@sid);
+ DestroyIcon(sid.hDefaultIcon);
+
+ sid.hDefaultIcon :=LoadImage(hInstance,MAKEINTRESOURCE(IDI_DEFAULT),IMAGE_ICON,16,16,0);
+ sid.pszName :=QS_DEFAULT;
+ sid.szDescription.a:='Default';
+ Skin_AddIcon(@sid);
+ DestroyIcon(sid.hDefaultIcon);
+
+ sid.hDefaultIcon :=LoadImage(hInstance,MAKEINTRESOURCE(IDI_RELOAD),IMAGE_ICON,16,16,0);
+ sid.pszName :=QS_RELOAD;
+ sid.szDescription.a:='Reload';
+ Skin_AddIcon(@sid);
+ DestroyIcon(sid.hDefaultIcon);
+
+ sid.hDefaultIcon :=LoadImage(hInstance,MAKEINTRESOURCE(IDI_MALE),IMAGE_ICON,16,16,0);
+ sid.pszName :=QS_MALE;
+ sid.szDescription.a:='Male';
+ Skin_AddIcon(@sid);
+ DestroyIcon(sid.hDefaultIcon);
+
+ sid.hDefaultIcon :=LoadImage(hInstance,MAKEINTRESOURCE(IDI_FEMALE),IMAGE_ICON,16,16,0);
+ sid.pszName :=QS_FEMALE;
+ sid.szDescription.a:='Female';
+ Skin_AddIcon(@sid);
+ DestroyIcon(sid.hDefaultIcon);
+
+ icohook:=HookEvent(ME_SKIN2_ICONSCHANGED,@IconChanged);
+end;
+
+function OnOptInitialise(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+var
+ odp:TOPTIONSDIALOGPAGE;
+begin
+ ZeroMemory(@odp,sizeof(odp));
+ odp.cbSize :=SizeOf(odp); //for 0.6+ compatibility
+ odp.Position :=900003000;
+ odp.hInstance :=hInstance;
+ odp.pszTemplate:=PAnsiChar(IDD_DIALOG1);
+ odp.szTitle.a :=qs_name;
+ odp.szGroup.a :='Contact List';
+ odp.pfnDlgProc :=@sr_optdialog.DlgProcOptions;
+ odp.flags :=ODPF_BOLDGROUPS;
+ Options_AddPage(wParam,@odp);
+// CallService(MS_OPT_ADDPAGE,wParam,tlparam(@odp));
+ Result:=0;
+end;
+
+function OpenSearchWindow(wParam:WPARAM;lParam:LPARAM):int_ptr;cdecl;
+begin
+ result:=0;
+ if not opened then
+ OpenSrWindow(pointer(wParam),lParam)
+ else
+ BringToFront;
+end;
+
+function OnModulesLoaded(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+begin
+ UnhookEvent(onloadhook);
+
+ CallService(MS_DBEDIT_REGISTERSINGLEMODULE,twparam(qs_module),0);
+
+ RegisterIcons;
+ RegisterColors;
+
+ servshow:=CreateServiceFunction(QS_SHOWSERVICE,@OpenSearchWindow);
+ AddRemoveMenuItemToMainMenu;
+
+ reghotkeys;
+
+ onadd :=HookEvent(ME_DB_CONTACT_ADDED ,@OnContactAdded);
+ ondelete :=HookEvent(ME_DB_CONTACT_DELETED ,@OnContactDeleted);
+ onstatus :=HookEvent(ME_CLIST_CONTACTICONCHANGED,@OnStatusChanged);
+// onaccount:=HookEvent(ME_PROTO_ACCLISTCHANGED ,@OnAccountChanged);
+ HookEvent(ME_TTB_MODULELOADED,@OnTTBLoaded);
+
+ CreateFrame(0);
+ Result:=0;
+end;
+
+function Load():Integer;cdecl;
+begin
+ Result:=0;
+ Langpack_register;
+ opthook :=HookEvent(ME_OPT_INITIALISE ,@OnOptInitialise);
+ onloadhook:=HookEvent(ME_SYSTEM_MODULESLOADED,@OnModulesLoaded);
+ loadopt_db(true);
+end;
+
+function Unload:Integer;cdecl;
+begin
+ result:=0;
+ removetoolbar; //??
+ DestroyFrame;
+
+ DestroyServiceFunction(servshow);
+ UnhookEvent(opthook);
+ UnhookEvent(onadd);
+ UnhookEvent(ondelete);
+ UnhookEvent(onstatus);
+// UnhookEvent(onaccount);
+ if icohook<>0 then
+ UnhookEvent(icohook);
+
+// unreghotkeys;
+
+ CloseSrWindow;
+
+ clear_columns;
+end;
+
+exports
+ Load, Unload,
+ MirandaPluginInfoEx;
+
+begin
+end.
diff --git a/plugins/QuickSearch/quicksearch_history.txt b/plugins/QuickSearch/quicksearch_history.txt new file mode 100644 index 0000000000..17cfce6852 --- /dev/null +++ b/plugins/QuickSearch/quicksearch_history.txt @@ -0,0 +1,110 @@ +Service:
+ wParam: 0, or pattern string
+ lParam: 0 - wParam has unicode string;
+ 1 - Ansi String (only Unicode plugin version)
+ 2 - wParam is contact handle to select (not realized)
+ service:"QuickSearch_PLUGIN/Show"
+
+History:
+
+1.4.1.19 ()
+ FastMM4 memory manager used (not native Delphi or miranda)
+ Fixed some Memory leaks
+1.4.1.18 (2 jul 2010)
+ Doubleclick/Enter on contact set as Clist doubleclick action
+ Group list sorted now
+ Fixed main window Refresh action (F5 and button)
+ Added frame button to open Main QS window
+1.4.1.17 (5 may 2010)
+ Added contact list frame
+ Fixed columns sort
+ Added right click on columns header processing
+ Filter applying just for visible columns now
+ Added tooltip for hidden columns info
+ Added several User Info fields
+ Added button and hotkey F5 to refresh content of main window
+ Partial code refactoring
+ Fixed again info showing in window with hidden columns
+1.4.0.16 (16 jul 2009)
+ Fixed info showing in window with hidden columns
+1.4.0.15 (13 jul 2009)
+ Fixed empty line for hidden contacts and contacts of disabled accounts
+1.4.0.14 (11 jul 2009)
+ Added checkbox for hide columns from showing
+1.4.0.13 (10 jul 2009)
+ Added context menu item to combine selected contacts to metacontact
+ Added new column type for metacontacts
+ Added colorization for metacontacts
+1.4.0.12 (jun 2009)
+ Fixed fields drawing in options dialog
+ Added colorisation for not-in-list contacts and on switched off or deleted accounts
+ Fixes for Statusbar
+ Fixes for Show/hide offline contacts
+1.4.0.11 (13 mar 2009)
+ Added column type "Variables script"
+ Added translation to column types
+ Fixed Show/hide offline contacts behaviour
+ Fixed one of unicode localization bugs
+ Fixed contact copying to Clipboard
+1.4.0.10 (19 oct 2008)
+ Some fixes
+ Some WinAPI/Delphi functions replaced by handmaked
+ Added support for Miranda core hotkeys (ver 8.0+)
+ Added:Drag&Drop (realtime) QS list column reordering
+ In option:list scrolling to newly added items
+ Added ANSI code part
+ Fixed: empty LastEvent field was at top of event list
+1.4.0.9 (11 sep 2008)
+ Fixed: Can crashed with content filter
+ Maked list filling faster
+ Changed: maximum column amount changing dynamically now
+ Source changed: AnsiChar replaced by AnsiChar
+ Removed some codeparts for Miranda v0.5 compatibility
+ Fixed: wrong QS window width resizing
+1.4.0.8 (28 aug 2008)
+ Fixed crash while adding contact with opened QS window
+1.4.0.7 (21 jul 2008)
+ Added icons for XStatus
+ Fixed unicode filter
+ Added internal caching
+(29 oct 2007)
+ Added tooltips for IM-client and gender columns
+ Changed QS window icon assign code
+ Changed group of contacts delete code
+ Added filter groups in "" (start quote must be first AnsiChar or after space)
+(19 may 2007)
+ Added option to save text search pattern
+1.4.0.6 (09 mar 2007)
+ Added: Option to skip 'minimized' columns while copying to Clipboard
+ Fixed: Abort context menu move contacts to first group in list
+ Ctrl-C (or &Copy context menu command) copying info with TAB separated fields
+ Added: new miranda API support
+1.4.0.5 (21 jan 2007)
+ Fixed: Contact menu do not execute action when Auto close mode is ON
+ Fixed: Gender icon not shown when icolib not installed
+ Partially solved problem with large system fonts
+ Fixed: changed menu/toolbar icon was not set at start
+ Added Gender reading from UserInfo, not only protocol
+1.4.0.4 (22 dec 2006)
+ Added Male/Female icon and special gender processing
+ Letters and BackSpace works in the list
+ Ctrl-C in list copying contact info to Clipboard
+ Added StatusBar
+ Slightly modified Option page
+ Added option to disable client icon
+ Added Updater support
+ Added IcoLib support
+1.4.0.3 (18 dec 2006)
+ Service was advanced
+ Fixed: Enter on edit field removes contact from group
+1.4.0.2 (17 dec 2006)
+ Added option to show/hide offline contacts
+ Added "Stay on top" option to sysmenu
+ Fixed: context menu shown only one time
+1.4.0.1 (17 dec 2006)
+ Fixed: Options not shown in Miranda before 0.6 version
+ Small code and interface changes
+ First item in list now focused automatically
+ Fixed: search pattern work only with small characters
+1.4.0.0 (14 dec 2006)
+ Initial release
\ No newline at end of file diff --git a/plugins/QuickSearch/resource.inc b/plugins/QuickSearch/resource.inc new file mode 100644 index 0000000000..d31773d79e --- /dev/null +++ b/plugins/QuickSearch/resource.inc @@ -0,0 +1,76 @@ +const
+ IDD_DIALOG1 = 101;
+ IDD_MAIN = 102;
+ IDD_SCRIPT = 103;
+ IDD_FRAME = 104;
+
+ IDI_QS = 107;
+
+ IDI_NEW = 110;
+ IDI_ITEM = 111;
+ IDI_UP = 112;
+ IDI_DOWN = 113;
+ IDI_DELETE = 114;
+ IDI_DEFAULT = 115;
+ IDI_RELOAD = 116;
+
+ IDI_MALE = 120;
+ IDI_FEMALE = 121;
+
+ IDC_FRAME_EDIT = 1025;
+ IDC_FRAME_PREV = 1026;
+ IDC_FRAME_NEXT = 1027;
+ IDC_FRAME_OPEN = 1028;
+
+ IDC_NEW = 1001;
+ IDC_DELETE = 1002;
+ IDC_UP = 1003;
+ IDC_DN = 1004;
+ IDC_DEFAULT = 1005;
+ IDC_SETITEM = 1006;
+ IDC_RELOAD = 1007;
+
+ IDC_E_TITLE = 1010;
+ IDC_E_MODULE = 1011;
+ IDC_E_VAR = 1012;
+ IDC_E_LPAR = 1013;
+ IDC_HOTKEYGLOB = 1014;
+ IDC_HOTKEYLOC = 1015;
+ IDC_HKGROUP = 1016;
+ IDC_STAT_GLOBAL = 1017;
+ IDC_STAT_LOCAL = 1018;
+ IDC_LIST = 1020;
+ IDC_C_VARTYPE = 1021;
+ IDC_C_CNFTYPE = 1022;
+ IDC_CB_MAIN = 1023;
+ IDC_C_WPAR = 1024;
+ IDC_C_LPAR = 1025;
+ IDC_C_RESULT = 1026;
+ IDC_CH_SORTSTATUS = 1030;
+ IDC_CH_SHOWINMENU = 1031;
+ IDC_CH_SHOWONLYUSERS = 1032;
+ IDC_CH_ADDTOTOPTOOLBAR = 1033;
+ IDC_CH_AUTOCLOSE = 1034;
+ IDC_CH_USETOOLSTYLE = 1035;
+ IDC_CH_HOOKCHANGES = 1036;
+ IDC_CH_DRAWGRID = 1037;
+ IDC_CH_SHOWCLIENTICONS = 1038;
+ IDC_STAT_SERVICE = 1040;
+ IDC_STAT_MODULE = 1041;
+ IDC_STAT_WPAR = 1042;
+ IDC_STAT_SETTING = 1043;
+ IDC_CH_SINGLECSV = 1044;
+ IDC_CH_EXPORTHEADERS = 1045;
+ IDC_CH_SKIPMINIMIZED = 1046;
+ IDC_CH_SAVEPATTERN = 1047;
+ IDC_STAT_VARTYPE = 1048;
+ IDC_SCRIPT = 1049;
+
+ IDC_E_SEARCHTEXT = 1001;
+ IDC_CH_SHOWOFFLINE = 1031;
+ IDC_CH_COLORIZE = 1032;
+ IDC_REFRESH = 1033;
+ IDC_STATUSBAR = 1034;
+ IDC_CB_PROTOCOLS = 1035;
+
+ IDC_EDIT_SCRIPT = 1025;
diff --git a/plugins/QuickSearch/sr_frame.pas b/plugins/QuickSearch/sr_frame.pas new file mode 100644 index 0000000000..bf3e576554 --- /dev/null +++ b/plugins/QuickSearch/sr_frame.pas @@ -0,0 +1,343 @@ +unit sr_frame;
+
+interface
+
+uses windows;
+
+procedure CreateFrame(parent:HWND);
+procedure DestroyFrame;
+
+implementation
+
+uses commctrl,Messages,m_api,common,wrapper,mirutils,sr_global;
+
+{.$include resource.inc}
+
+const
+ frm_back:pAnsiChar = 'Frame background';
+const
+ FrameWnd:HWND = 0;
+ FrameId:integer = -1;
+ OldEditProc:pointer=nil;
+ pattern:pWideChar=nil;
+ current: THANDLE = 0;
+var
+ colorhook:THANDLE;
+ hbr:HBRUSH;
+ frm_bkg:TCOLORREF;
+
+function CheckContact(wnd:HWND; hContact:THANDLE):THANDLE;
+var
+ buf:array [0..127] of WideChar;
+begin
+ result:=0;
+
+ SendMessage(wnd,CLM_GETITEMTEXT,hContact,lparam(@buf));
+
+ if StrPosW(CharLowerW(@buf),pattern)<>nil then
+ result:=hContact;
+end;
+
+function GetNextContact(wnd:HWND; root,hContact:THANDLE; direction,skip:integer):THANDLE;
+var
+ tmp:THANDLE;
+// buf:array [0..127] of WideChar;
+begin
+ result:=0;
+ repeat
+
+ if skip=0 then
+ begin
+ case SendMessage(wnd,CLM_GETITEMTYPE,hContact,0) of
+ CLCIT_GROUP: begin
+ if SendMessage(wnd,CLM_GETEXPAND,hContact,0)=CLE_EXPAND then // expanded only
+ begin
+ tmp:=SendMessage(wnd,CLM_GETNEXTITEM,CLGN_CHILD,hContact);
+ if tmp<>0 then
+ begin
+ hContact:=tmp;
+ if direction=CLGN_PREVIOUS then
+ begin // set on last contact in group
+ repeat
+ tmp:=SendMessage(wnd,CLM_GETNEXTITEM,CLGN_NEXT,hContact);
+ if tmp<>0 then
+ hContact:=tmp
+ else
+ break;
+ until false;
+ end;
+ continue;
+ end;
+ end;
+ end;
+ CLCIT_CONTACT: begin
+ result:=CheckContact(wnd,hContact);
+ if result<>0 then
+ break;
+ end;
+ else // CLCIT_INVALID for example
+ break;
+ end;
+ end
+ else
+ skip:=0;
+
+ if hContact=HCONTACT_ISGROUP then
+// if (hContact=root) and (direction=CLGN_PREVIOUS) then // 1st group, no need to process "root=clist"
+ break;
+
+ tmp:=SendMessage(wnd,CLM_GETNEXTITEM,direction,hContact);
+ if tmp=0 then
+ begin
+ hContact:=SendMessage(wnd,CLM_GETNEXTITEM,CLGN_PARENT,hContact);
+ // not here but where group insert
+ skip:=1;
+ continue;
+ // hContact:=SendMessage(wnd,CLM_GETNEXTITEM,direction,hContact);
+ if hContact=0 then
+ break;
+ end
+ else
+ hContact:=tmp;
+ until false;
+end;
+
+function SearchContact(direction:integer;skip:integer=1):integer;
+var
+ root,hContact:THANDLE;
+ wnd:HWND;
+begin
+ result:=0;
+ if (pattern=nil) or (pattern^=#0) then
+ begin
+ current:=0; // next seach - from start
+ exit; // pattern empty
+ end;
+
+ wnd:=CallService(MS_CLUI_GETHWNDTREE,0,0);
+
+ root:=SendMessage(wnd,CLM_GETNEXTITEM,CLGN_ROOT,0);
+ if current=0 then
+ hContact:=root
+ else
+ hContact:=current;
+
+ result:=GetNextContact(wnd,root,hContact,direction,skip);
+
+ if result<>0 then
+ SetCListSelContact(result);
+end;
+
+function NewEditProc(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+begin
+// result:=0;
+ case hMessage of
+ WM_CHAR: if wParam=27 then
+ begin
+ // clear edit field
+ SendMessage(Dialog,WM_SETTEXT,0,0);
+ // go to top?
+ current:=0;
+ end;
+
+ WM_KEYDOWN: begin
+ case wParam of
+ VK_PRIOR,VK_UP: begin
+ current:=SearchContact(CLGN_PREVIOUS);
+ end;
+ VK_NEXT,VK_DOWN: begin
+ current:=SearchContact(CLGN_NEXT);
+ end;
+ end;
+ end;
+ end;
+ result:=CallWindowProc(OldEditProc,Dialog,hMessage,wParam,lParam);
+end;
+
+function QSDlgResizer(Dialog:HWND;lParam:LPARAM;urc:PUTILRESIZECONTROL):int; cdecl;
+begin
+ case urc^.wId of
+ IDC_FRAME_OPEN: result:=RD_ANCHORX_LEFT or RD_ANCHORY_CENTRE;
+ IDC_FRAME_EDIT: result:=RD_ANCHORX_WIDTH or RD_ANCHORY_CENTRE;
+ IDC_FRAME_PREV: result:=RD_ANCHORX_RIGHT or RD_ANCHORY_CENTRE;
+ IDC_FRAME_NEXT: result:=RD_ANCHORX_RIGHT or RD_ANCHORY_CENTRE;
+ else
+ result:=0;
+ end;
+end;
+
+function QSFrameProc(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+var
+ urd:TUTILRESIZEDIALOG;
+ tmp:THANDLE;
+ rc:TRECT;
+ ti:TTOOLINFOW;
+ hwndTooltip:HWND;
+begin
+ result:=0;
+ case hMessage of
+ WM_DESTROY: begin
+ DeleteObject(hbr);
+ end;
+
+ WM_INITDIALOG: begin
+ OldEditProc:=pointer(SetWindowLongPtrW(GetDlgItem(Dialog,IDC_FRAME_EDIT),
+ GWL_WNDPROC,LONG_PTR(@NewEditProc)));
+
+ hwndTooltip:=CreateWindowW(TOOLTIPS_CLASS,nil,TTS_ALWAYSTIP,
+ integer(CW_USEDEFAULT),integer(CW_USEDEFAULT),
+ integer(CW_USEDEFAULT),integer(CW_USEDEFAULT),
+ Dialog,0,hInstance,nil);
+
+ FillChar(ti,SizeOf(ti),0);
+ ti.cbSize :=sizeof(TOOLINFO);
+ ti.uFlags :=TTF_IDISHWND or TTF_SUBCLASS;
+ ti.hwnd :=Dialog;
+ ti.hinst :=hInstance;
+ ti.uId :=GetDlgItem(Dialog,IDC_FRAME_PREV);
+
+ ti.lpszText:=pWideChar(TranslateW('Previous item'));
+ SendMessage(hwndTooltip,TTM_ADDTOOLW,0,tlparam(@ti));
+ ti.uId :=GetDlgItem(Dialog,IDC_FRAME_NEXT);
+ ti.lpszText:=pWideChar(TranslateW('Next item'));
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,tlparam(@ti));
+ ti.uId :=GetDlgItem(Dialog,IDC_FRAME_OPEN);
+ ti.lpszText:=pWideChar(TranslateW('Open main window'));
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,tlparam(@ti));
+ end;
+
+ WM_SIZE: begin
+ FillChar(urd,SizeOf(TUTILRESIZEDIALOG),0);
+ urd.cbSize :=SizeOf(urd);
+ urd.hwndDlg :=Dialog;
+ urd.hInstance :=hInstance;
+ urd.lpTemplate:=MAKEINTRESOURCEA(IDD_FRAME);
+ urd.lParam :=0;
+ urd.pfnResizer:=@QSDlgResizer;
+ CallService(MS_UTILS_RESIZEDIALOG,0,tlparam(@urd));
+ end;
+
+ WM_ERASEBKGND: begin
+ GetClientRect(Dialog,rc);
+ FillRect(wParam,rc,hbr);
+ result:=1;
+ end;
+
+ WM_COMMAND: begin
+ case wParam shr 16 of
+ EN_CHANGE: begin
+ mFreeMem(pattern);
+ pattern:=GetDlgText(Dialog,IDC_FRAME_EDIT);
+ if pattern<>nil then
+ CharLowerW(pattern);
+
+ tmp:=SearchContact(CLGN_NEXT,0);
+ if tmp=0 then
+ tmp:=SearchContact(CLGN_PREVIOUS,0);
+ current:=tmp;
+ end;
+
+ BN_CLICKED: begin
+ tmp:=0;
+ case loword(wParam) of
+ IDC_FRAME_PREV: tmp:=SearchContact(CLGN_PREVIOUS);
+ IDC_FRAME_NEXT: tmp:=SearchContact(CLGN_NEXT);
+ IDC_FRAME_OPEN: CallService(QS_SHOWSERVICE,twparam(pattern),0);
+ end;
+ if tmp<>0 then current:=tmp;
+ end;
+ end;
+ end;
+
+ else
+ result:=DefWindowProc(Dialog,hMessage,wParam,lParam);
+ end;
+end;
+
+function ColorReload(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+var
+ cid:TColourID;
+begin
+ result:=0;
+ cid.cbSize:=SizeOf(cid);
+ StrCopy(cid.group,'QuickSearch');
+ StrCopy(cid.name ,frm_back);
+ frm_bkg:=CallService(MS_COLOUR_GETA,twparam(@cid),0);
+ DeleteObject(hbr);
+ hbr:=CreateSolidBrush(frm_bkg);
+
+ RedrawWindow(FrameWnd,nil,0,RDW_ERASE);
+end;
+
+procedure CreateFrame(parent:HWND);
+var
+ Frame:TCLISTFrame;
+ wnd:HWND;
+ tmp:cardinal;
+ tr:TRECT;
+ cid:TColourID;
+begin
+ if ServiceExists(MS_CLIST_FRAMES_ADDFRAME)=0 then
+ exit;
+ if parent=0 then
+ parent:=CallService(MS_CLUI_GETHWND,0,0);
+
+ if FrameWnd=0 then
+ FrameWnd:=CreateDialog(hInstance,MAKEINTRESOURCE(IDD_FRAME),parent,@QSFrameProc);
+
+ if FrameWnd<>0 then
+ begin
+ GetWindowRect(FrameWnd,tr);
+ FillChar(Frame,SizeOf(Frame),0);
+ with Frame do
+ begin
+ cbSize :=SizeOf(Frame);
+ hWnd :=FrameWnd;
+ hIcon :=0;
+ align :=alTop;
+ height :=tr.bottom-tr.top+2;
+ Flags :=F_VISIBLE or F_NOBORDER or F_UNICODE;
+ name.w :='Quick search';
+ TBName.w:='Quick search';
+ end;
+
+ FrameId:=CallService(MS_CLIST_FRAMES_ADDFRAME,wparam(@Frame),0);
+ if FrameId>=0 then
+ begin
+ CallService(MS_CLIST_FRAMES_UPDATEFRAME,FrameId, FU_FMPOS);
+
+ wnd:=CallService(MS_CLUI_GETHWND{MS_CLUI_GETHWNDTREE},0,0);
+ tmp:=SendMessage(wnd,CLM_GETEXSTYLE,0,0);
+ SendMessage(wnd,CLM_SETEXSTYLE,tmp or CLS_EX_SHOWSELALWAYS,0);
+
+ cid.cbSize:=SizeOf(cid);
+ cid.flags :=0;
+ StrCopy(cid.group,'QuickSearch');
+ StrCopy(cid.dbSettingsGroup,qs_module);
+
+ StrCopy(cid.name ,frm_back);
+ StrCopy(cid.setting,'frame_back');
+ cid.defcolour:=COLOR_3DFACE;
+ cid.order :=0;
+ ColourRegister(@cid);
+
+ colorhook:=HookEvent(ME_COLOUR_RELOAD,@ColorReload);
+ ColorReload(0,0);
+ end;
+ end;
+end;
+
+procedure DestroyFrame;
+begin
+ if FrameId>=0 then
+ begin
+ UnhookEvent(colorhook);
+ CallService(MS_CLIST_FRAMES_REMOVEFRAME,FrameId,0);
+ FrameId:=-1;
+ end;
+ DestroyWindow(FrameWnd);
+ FrameWnd:=0;
+ mFreeMem(pattern);
+end;
+
+end.
diff --git a/plugins/QuickSearch/sr_global.pas b/plugins/QuickSearch/sr_global.pas new file mode 100644 index 0000000000..cd9e1d826e --- /dev/null +++ b/plugins/QuickSearch/sr_global.pas @@ -0,0 +1,750 @@ +unit sr_global;
+
+interface
+uses windows,messages,commctrl,m_api,dbsettings,mirutils;
+
+const
+ // for QS window only
+ IDM_STAYONTOP = WM_USER+1;
+ WM_MYADDCONTACT = WM_USER+2;
+ WM_MYDELETECONTACT = WM_USER+3;
+
+ WM_MYSHOWHIDEITEM = WM_USER + 4;
+ WM_MYMOVEITEM = WM_USER + 5;
+const
+ wcUp = 1;
+ wcDown = 2;
+ wcHide = 3;
+ wcShow = 4;
+ wcDelete = 5;
+ wcInsert = 6;
+ wcChange = 7;
+ wcRefresh = 8;
+
+const
+ opened:boolean = false;
+const
+ QS_QS :PAnsiChar = 'QS_QS';
+ QS_NEW :PAnsiChar = 'QS_New';
+ QS_ITEM :PAnsiChar = 'QS_Item';
+ QS_UP :PAnsiChar = 'QS_Up';
+ QS_DOWN :PAnsiChar = 'QS_Down';
+ QS_DELETE :PAnsiChar = 'QS_Delete';
+ QS_DEFAULT:PAnsiChar = 'QS_Default';
+ QS_RELOAD :PAnsiChar = 'QS_Reload';
+ QS_MALE :PAnsiChar = 'QS_Male';
+ QS_FEMALE :PAnsiChar = 'QS_Female';
+const
+ qs_module :PAnsiChar = 'QuickSearch';
+ qs_name :PAnsiChar = 'Quick Search';
+ QS_SHOWSERVICE:PAnsiChar = 'QuickSearch_PLUGIN/Show';
+
+const
+ StatusSort = 1000;
+
+const
+ ptNumber = 0;
+ ptInteger = 1;
+ ptString = 2;
+ ptUnicode = 3;
+ ptCurrent = 4;
+
+const //types
+ ST_BYTE = 0;
+ ST_WORD = 1;
+ ST_INT = 2;
+ ST_STRING = 3;
+ ST_IP = 4;
+ ST_LASTSEEN = 5;
+ ST_CONTACTINFO = 6;
+ ST_LASTEVENT = 7;
+ ST_TIMESTAMP = 8;
+ ST_SERVICE = 9;
+ ST_SCRIPT = 10;
+ ST_METACONTACT = 11;
+
+ ST_MAXTYPE = 11;
+
+const
+ COL_ON = $0001; // Show column
+ COL_INIT = $0002; // No need to update
+ COL_XSTATUS = $0100;
+ COL_GENDER = $0200;
+ COL_CLIENT = $0400;
+
+{$include resource.inc}
+
+type
+ tserviceparam = record
+ case _type:word of
+ 0: (n:dword);
+ 1: (i:integer);
+ 2: (a:PAnsiChar);
+ 3: (w:PWideChar);
+ end;
+type
+ tcolumnitem=record
+ title :PWideChar;
+ module_name :PAnsiChar;
+ width :dword;
+ setting_type :dword; // ST_* constants
+ setting_cnftype:dword; // pt* constants
+ wparam :tserviceparam;
+ lparam :tserviceparam;
+ flags :dword; // COL_* constants
+ end;
+ tcolumnarray = array of tcolumnitem;
+ tqsopt=record
+ grrect :TRECT;
+ columns :tcolumnarray;//array of tcolumnitem;
+ numcolumns :integer;
+ columnsort :integer;
+ ascendsort :boolean;
+ sortbystatus :boolean;
+ drawgrid :boolean;
+ showinmenu :boolean;
+ showonlyinlist :boolean;
+ showintoptoolbar:boolean;
+ usetoolstyle :boolean;
+ closeafteraction:boolean;
+ stayontop :boolean;
+ showoffline :boolean;
+ showclienticons :boolean;
+ exportheaders :boolean;
+ singlecsv :boolean;
+ skipminimized :boolean;
+ savepattern :boolean;
+ colorize :boolean;
+ end;
+
+procedure reghotkeys;
+procedure unreghotkeys;
+
+procedure saveopt_wnd;
+procedure saveopt_db;
+procedure loadopt_db(full:boolean);
+procedure clear_columns;
+function new_column(after:integer=-1):integer;
+procedure delete_column(pos:integer);
+procedure loaddefaultcolumns;
+
+procedure AddRemoveMenuItemToMainMenu;
+procedure addtotoolbar;
+procedure removetoolbar;
+
+var
+ qsopt:tqsopt;
+
+const
+ MainMenuItem:integer=0;
+ hTTBButton :thandle=0;
+
+implementation
+
+uses common;
+
+const
+ HKN_GLOBAL:PAnsiChar = 'QS_Global';
+const
+ so_mbottom :PAnsiChar = 'mbottom';
+ so_mright :PAnsiChar = 'mright';
+ so_mtop :PAnsiChar = 'mtop';
+ so_mleft :PAnsiChar = 'mleft';
+ so_columnsort :PAnsiChar = 'columnsort';
+ so_sortbystatus :PAnsiChar = 'sortbystatus';
+ so_ascendsort :PAnsiChar = 'ascendsort';
+ so_showonlyinlist :PAnsiChar = 'showonlyinlist';
+ so_dontusetoolstyle:PAnsiChar = 'dontusetoolstyle';
+ so_showinmenu :PAnsiChar = 'showinmenu';
+ so_showintoptoolbar:PAnsiChar = 'showintoptoolbar';
+ so_closeafteraction:PAnsiChar = 'closeafteraction';
+ so_exportheaders :PAnsiChar = 'exportheaders';
+ so_singlecsv :PAnsiChar = 'singlecsv';
+ so_savepattern :PAnsiChar = 'savepattern';
+ so_numcolumns :PAnsiChar = 'numcolumns';
+ so_item :PAnsiChar = 'item';
+ so_drawgrid :PAnsiChar = 'drawgrid';
+ so_stayontop :PAnsiChar = 'stayontop';
+ so_showclienticons :PAnsiChar = 'showclienticons';
+ so_skipminimized :PAnsiChar = 'skipminimized';
+ so_showoffline :PAnsiChar = 'showoffline';
+ so_colorize :PAnsiChar = 'colorize';
+
+ so__title :PAnsiChar = '_title';
+ so__setting_type :PAnsiChar = '_setting_type';
+ so__setting_cnftype:PAnsiChar = '_setting_cnftype';
+ so__module_name :PAnsiChar = '_module_name';
+ so__wparam_type :PAnsiChar = '_wparam_type';
+ so__lparam_type :PAnsiChar = '_lparam_type';
+ so__wparam :PAnsiChar = '_wparam';
+ so__lparam :PAnsiChar = '_lparam';
+ so__width :PAnsiChar = '_width';
+ so__flags :PAnsiChar = '_flags';
+
+procedure reghotkeys;
+var
+ hkrec:HOTKEYDESC;
+begin
+ FillChar(hkrec,SizeOf(hkrec),0);
+ with hkrec do
+ begin
+ cbSize :=HOTKEYDESC_SIZE_V1;
+ pszName :=HKN_GLOBAL;
+ pszDescription.a:='QuickSearch window hotkey';
+ pszSection.a :=qs_name;
+ pszService :=QS_SHOWSERVICE;
+ DefHotKey :=(HOTKEYF_ALT shl 8) or VK_F3;
+ end;
+ CallService(MS_HOTKEY_REGISTER,0,lparam(@hkrec));
+end;
+
+procedure unreghotkeys;
+begin
+ CallService(MS_HOTKEY_UNREGISTER,0,lparam(HKN_GLOBAL));
+end;
+
+procedure removetoolbar;
+begin
+ if hTTBButton<>0 then
+ begin
+ if ServiceExists(MS_TTB_REMOVEBUTTON)>0 then
+ begin
+ CallService(MS_TTB_REMOVEBUTTON,WPARAM(hTTBButton),0);
+ hTTBButton:=0;
+ end;
+ end;
+end;
+
+procedure addtotoolbar;
+var
+ ttbopt:TTBButton;
+begin
+ removetoolbar;
+
+ if qsopt.showintoptoolbar then
+ begin
+ if ServiceExists(MS_TTB_ADDBUTTON)>0 then
+ begin
+ ZeroMemory(@ttbopt,sizeof(ttbopt));
+ ttbopt.cbSize :=sizeof(ttbopt);
+ ttbopt.pszService:=QS_SHOWSERVICE;
+ ttbopt.hIconUp :=CallService(MS_SKIN2_GETICON,0,lparam(QS_QS));
+ ttbopt.hIconDn :=ttbopt.hIconUp;
+ ttbopt.dwFlags :=TTBBF_VISIBLE;
+ ttbopt.name :=qs_module;
+ hTTBButton:=TopToolbar_AddButton(@ttbopt);
+ if hTTBButton=THANDLE(-1) then
+ hTTBButton:=0;
+ end;
+ end;
+end;
+
+procedure AddRemoveMenuItemToMainMenu;
+var
+ cmi:TCLISTMENUITEM;
+begin
+ if qsopt.showinmenu then
+ begin
+ if MainMenuItem<>0 then exit;
+ ZeroMemory(@cmi,sizeof(cmi));
+ cmi.cbSize :=sizeof(cmi) ;
+ cmi.szName.a :=qs_name;
+ cmi.position :=500050000;
+// cmi.pszPopupName:=nil;
+// cmi.flags :=0;
+ cmi.pszService :=QS_SHOWSERVICE;
+ cmi.hIcon :=CallService(MS_SKIN2_GETICON,0,lparam(QS_QS));
+ MainMenuItem :=Menu_AddMainMenuItem(@cmi);
+ end
+ else
+ begin
+ if (MainMenuItem<>0) and
+ (ServiceExists(MS_CLIST_REMOVEMAINMENUITEM)<>0) then
+ begin
+ CallService(MS_CLIST_REMOVEMAINMENUITEM,MainMenuItem,0);
+ MainMenuItem:=0;
+ end;
+ end;
+end;
+
+// -------- column functions ---------
+
+procedure clear_column(num:integer);
+begin
+ with qsopt.columns[num] do
+ begin
+ mFreeMem(title);
+ if setting_type<>ST_CONTACTINFO then
+ begin
+ mFreeMem(module_name);
+ if setting_type<>ST_SERVICE then
+ mFreeMem(wparam.a)
+ else
+ begin
+ if (wparam._type=ptString) or (wparam._type=ptUnicode) then mFreeMem(wparam.a);
+ if (lparam._type=ptString) or (lparam._type=ptUnicode) then mFreeMem(lparam.a);
+ end;
+ end;
+ end;
+end;
+
+procedure clear_columns;
+var
+ i:integer;
+begin
+ for i:=0 to qsopt.numcolumns-1 do
+ clear_column(i);
+ FillChar(qsopt.columns[0],Length(qsopt.columns),0);
+ qsopt.numcolumns:=0;
+end;
+
+procedure delete_column(pos:integer);
+begin
+ if (pos>=0) and (qsopt.numcolumns>0) then
+ begin
+ dec(qsopt.numcolumns);
+ clear_column(pos);
+ move(qsopt.columns[pos+1],qsopt.columns[pos],(qsopt.numcolumns-pos)*sizeof(tcolumnitem));
+ SetLength(qsopt.columns,qsopt.numcolumns);
+ end;
+end;
+
+function new_column(after:integer=-1):integer;
+begin
+ SetLength(qsopt.columns,qsopt.numcolumns+1);
+ FillChar(qsopt.columns[qsopt.numcolumns],SizeOf(tcolumnitem),0);
+ with qsopt.columns[qsopt.numcolumns] do
+ begin
+ StrDupW(title,'New column');
+ width:=64;
+ flags:=COL_ON;
+ end;
+ result:=qsopt.numcolumns;
+ inc(qsopt.numcolumns);
+end;
+
+procedure MakeTitle(var title; name:pAnsiChar);
+begin
+ FastAnsiToWide(name,pWideChar(title));
+end;
+
+procedure loaddefaultcolumns;
+begin
+ clear_columns;
+ qsopt.numcolumns:=15;
+ SetLength(qsopt.columns ,qsopt.numcolumns);
+ FillChar(qsopt.columns[0],qsopt.numcolumns*SizeOf(tcolumnitem),0);
+
+ // protocol
+ with qsopt.columns[0] do
+ begin
+ MakeTitle(title,'Protocol');
+ StrDup (module_name,MS_PROTO_GETCONTACTBASEPROTO);
+ width :=82;
+ setting_type :=ST_SERVICE;
+ setting_cnftype:=ptString;
+ wparam._type :=ptCurrent;
+ lparam._type :=ptNumber;
+ lparam.n :=0;
+ flags :=COL_ON;
+ end;
+
+ with qsopt.columns[1] do
+ begin
+ MakeTitle(title,'Real Protocol');
+ StrDup(module_name,'Protocol');
+ StrDup(wparam.a ,'p');
+ width :=82;
+ setting_type :=ST_STRING;
+ flags :=0;
+ end;
+
+ //gender
+ with qsopt.columns[2] do
+ begin
+ MakeTitle(title,'Gender');
+ width :=20;
+ setting_type :=ST_CONTACTINFO;
+ setting_cnftype:=CNF_GENDER;
+ flags :=COL_ON;
+ end;
+
+ //uin
+ with qsopt.columns[3] do
+ begin
+ MakeTitle(title,'UserID');
+ width :=80;
+ setting_type :=ST_CONTACTINFO;
+ setting_cnftype:=CNF_UNIQUEID;
+ flags :=COL_ON;
+ end;
+
+ //username(displayname)
+ with qsopt.columns[4] do
+ begin
+ MakeTitle(title,'Nickname');
+ StrDup(module_name,MS_CLIST_GETCONTACTDISPLAYNAME);
+ width :=76;
+ setting_type :=ST_SERVICE;
+ setting_cnftype:=ptUnicode;
+ wparam._type :=ptCurrent;
+ lparam._type :=ptNumber;
+ lparam.n :=2; // 0 for ANSI
+ flags :=COL_ON;
+ end;
+
+ //firstname
+ with qsopt.columns[5] do
+ begin
+ MakeTitle(title,'First name');
+ width :=68;
+ setting_type :=ST_CONTACTINFO;
+ setting_cnftype:=CNF_FIRSTNAME;
+ flags :=COL_ON;
+ end;
+
+ //lastname
+ with qsopt.columns[6] do
+ begin
+ MakeTitle(title,'Last name');
+ width :=66;
+ setting_type :=ST_CONTACTINFO;
+ setting_cnftype:=CNF_LASTNAME;
+ flags :=COL_ON;
+ end;
+
+ //group
+ with qsopt.columns[7] do
+ begin
+ MakeTitle(title,'Group');
+ width :=80;
+ StrDup(module_name,'CList');
+ StrDup(wparam.a ,'Group');
+ setting_type :=ST_STRING;
+ flags :=COL_ON;
+ end;
+
+ //email
+ with qsopt.columns[8] do
+ begin
+ MakeTitle(title,'E-mail');
+ width :=116;
+ setting_type :=ST_CONTACTINFO;
+ setting_cnftype:=CNF_EMAIL;
+ flags :=COL_ON;
+ end;
+
+ //miranda version
+ with qsopt.columns[9] do
+ begin
+ MakeTitle(title,'ClientID');
+ StrDup(wparam.a,'MirVer');
+ width :=60;
+ setting_type:=ST_STRING;
+ flags :=COL_ON;
+ end;
+
+ //IP version
+ with qsopt.columns[10] do
+ begin
+ MakeTitle(title,'Ext IP');
+ StrDup(module_name,'ICQ');
+ StrDup(wparam.a ,'IP');
+ width :=100;
+ setting_type:=ST_IP;
+ flags :=0;
+ end;
+
+ //LastSeen
+ with qsopt.columns[11] do
+ begin
+ MakeTitle(title,'LastSeen');
+ StrDup(module_name,'SeenModule');
+ width :=116;
+ setting_type:=ST_LASTSEEN;
+ flags :=0;
+ end;
+
+ //last event
+ with qsopt.columns[12] do
+ begin
+ MakeTitle(title,'Last Event');
+ width :=100;
+ setting_type:=ST_LASTEVENT;
+ flags :=0;
+ end;
+
+ //online since
+ with qsopt.columns[13] do
+ begin
+ MakeTitle(title,'Online since');
+ StrDup(module_name,'ICQ');
+ StrDup(wparam.a ,'LogonTS');
+ width :=100;
+ setting_type:=ST_TIMESTAMP;
+ flags :=0;
+ end;
+
+ //metacontacts
+ with qsopt.columns[14] do
+ begin
+ MakeTitle(title,'Metacontact');
+ width :=50;
+ setting_type:=ST_METACONTACT;
+ flags :=0;
+ end;
+end;
+
+// -------- save/load settings ---------
+
+procedure WriteInt(setting:PAnsiChar;value:int);
+begin
+ DBWriteDword(0,qs_module,setting,value)
+end;
+procedure WriteWord(setting:PAnsiChar;value:word);
+begin
+ DBWriteWord(0,qs_module,setting,value)
+end;
+procedure WriteStr(setting:PAnsiChar;value:PAnsiChar);
+begin
+ DBWriteString(0,qs_module,setting,value)
+end;
+procedure WriteUnicode(setting:PAnsiChar;value:PWideChar);
+begin
+ DBWriteUnicode(0,qs_module,setting,value)
+end;
+procedure WriteBool(setting:PAnsiChar;value:bool);
+begin
+ DBWriteByte(0,qs_module,setting,ord(value))
+end;
+
+procedure saveopt_wnd;
+var
+ i:integer;
+ buf:array [0..127] of AnsiChar;
+ p,pp:PAnsiChar;
+begin
+ WriteInt (so_mbottom ,qsopt.grrect.bottom);
+ WriteInt (so_mright ,qsopt.grrect.right);
+ WriteInt (so_mtop ,qsopt.grrect.top);
+ WriteInt (so_mleft ,qsopt.grrect.left);
+
+ WriteBool(so_showoffline,qsopt.showoffline);
+ WriteBool(so_colorize ,qsopt.colorize);
+
+ WriteInt (so_columnsort ,qsopt.columnsort);
+
+ pp:=StrCopyE(buf,so_item);
+ for i:=0 to qsopt.numcolumns-1 do
+ begin
+ p:=StrEnd(IntToStr(pp,i));
+ with qsopt.columns[i] do
+ begin
+ StrCopy(p,so__flags); WriteInt (buf,flags);
+ StrCopy(p,so__width); WriteWord(buf,width);
+ end;
+ end;
+end;
+
+{
+ "fast" writing"
+ order array - if column order only changed
+ column flags - if checkboxes changed only
+}
+procedure saveopt_db;
+var
+ i:integer;
+ buf:array [0..127] of AnsiChar;
+ p,pp:PAnsiChar;
+begin
+ WriteWord(so_numcolumns ,qsopt.numcolumns);
+
+ WriteBool(so_sortbystatus ,qsopt.sortbystatus);
+ WriteBool(so_showinmenu ,qsopt.showinmenu);
+// WriteInt (so_columnsort ,qsopt.columnsort);
+ WriteBool(so_ascendsort ,qsopt.ascendsort);
+ WriteBool(so_showonlyinlist ,qsopt.showonlyinlist);
+
+ WriteBool(so_showintoptoolbar,qsopt.showintoptoolbar);
+ WriteBool(so_dontusetoolstyle,not qsopt.usetoolstyle);
+ WriteBool(so_closeafteraction,qsopt.closeafteraction);
+ WriteBool(so_drawgrid ,qsopt.drawgrid);
+ WriteBool(so_stayontop ,qsopt.stayontop);
+ WriteBool(so_showclienticons ,qsopt.showclienticons);
+ WriteBool(so_exportheaders ,qsopt.exportheaders);
+ WriteBool(so_singlecsv ,qsopt.singlecsv);
+ WriteBool(so_skipminimized ,qsopt.skipminimized);
+ WriteBool(so_savepattern ,qsopt.savepattern);
+
+ pp:=StrCopyE(buf,so_item);
+ for i:=0 to qsopt.numcolumns-1 do
+ begin
+ p:=StrEnd(IntToStr(pp,i));
+ with qsopt.columns[i] do
+ begin
+ StrCopy(p,so__title);
+ WriteUnicode(buf,title);
+ case setting_type of
+ ST_SCRIPT: begin
+ StrCopy(p,so__wparam);
+ WriteUnicode(buf,wparam.w);
+ end;
+ ST_CONTACTINFO: begin
+ StrCopy(p,so__setting_cnftype); WriteWord(buf,setting_cnftype);
+ end;
+ ST_SERVICE: begin
+ StrCopy(p,so__module_name ); WriteStr (buf,module_name);
+ StrCopy(p,so__setting_cnftype); WriteWord(buf,setting_cnftype);
+ StrCopy(p,so__wparam_type ); WriteWord(buf,wparam._type);
+ StrCopy(p,so__lparam_type ); WriteWord(buf,lparam._type);
+ StrCopy(p,so__wparam);
+ case wparam._type of
+ ptNumber,
+ ptInteger: WriteInt (buf,wparam.n);
+ ptString : WriteStr (buf,wparam.a);
+ ptUnicode: WriteUnicode(buf,wparam.w);
+ end;
+ StrCopy(p,so__lparam);
+ case lparam._type of
+ ptNumber,
+ ptInteger: WriteInt (buf,lparam.n);
+ ptString : WriteStr (buf,lparam.a);
+ ptUnicode: WriteUnicode(buf,lparam.w);
+ end;
+ end;
+ else
+ StrCopy(p,so__module_name); WriteStr(buf,module_name);
+ StrCopy(p,so__wparam ); WriteStr(buf,wparam.a);
+ end;
+ StrCopy(p,so__setting_type); WriteWord(buf,setting_type);
+ StrCopy(p,so__flags ); WriteInt (buf,flags);
+ StrCopy(p,so__width ); WriteWord(buf,width);
+ end;
+ end;
+end;
+
+function GetInt(setting:PAnsiChar;default:integer):integer;
+begin
+ result:=DBReadDWord(0,qs_module,setting,default);
+end;
+function GetWord(setting:PAnsiChar;default:word):word;
+begin
+ result:=DBReadWord(0,qs_module,setting,default);
+end;
+function GetBool(setting:PAnsiChar;default:bool):bool;
+begin
+ result:=bool(DBReadByte(0,qs_module,setting,integer(default)));
+end;
+function GetStr(setting:PAnsiChar):PAnsiChar;
+begin
+ result:=DBReadString(0,qs_module,setting,nil);
+end;
+function GetUnicode(setting:PAnsiChar):PWideChar;
+begin
+ result:=DBReadUnicode(0,qs_module,setting,nil);
+end;
+
+{
+ if "fast"writing enabled
+ fill columns accordingly comumn order array
+}
+procedure loadopt_db(full:boolean);
+var
+ i:integer;
+ buf:array [0..127] of AnsiChar;
+ p,pp:PAnsiChar;
+begin
+ if full then
+ begin
+ zeromemory(@qsopt,sizeof(qsopt));
+
+ qsopt.grrect.bottom:=GetInt(so_mbottom,240);
+ qsopt.grrect.right :=GetInt(so_mright,550);
+ qsopt.grrect.top :=GetInt(so_mtop,0);
+ qsopt.grrect.left :=GetInt(so_mleft,0);
+
+ qsopt.columnsort :=GetInt (so_columnsort,StatusSort);
+ qsopt.sortbystatus :=GetBool(so_sortbystatus,true);
+ qsopt.ascendsort :=GetBool(so_ascendsort ,true);
+
+ qsopt.showonlyinlist :=GetBool(so_showonlyinlist ,false);
+ qsopt.usetoolstyle :=not GetBool(so_dontusetoolstyle,false);
+ qsopt.showinmenu :=GetBool(so_showinmenu ,true);
+ qsopt.showintoptoolbar:=GetBool(so_showintoptoolbar,true);
+ qsopt.closeafteraction:=GetBool(so_closeafteraction,false);
+ qsopt.drawgrid :=GetBool(so_drawgrid ,true);
+ qsopt.stayontop :=GetBool(so_stayontop ,false);
+ qsopt.singlecsv :=GetBool(so_singlecsv ,false);
+ qsopt.exportheaders :=GetBool(so_exportheaders ,false);
+ qsopt.showoffline :=GetBool(so_showoffline ,true);
+ qsopt.skipminimized :=GetBool(so_skipminimized ,true);
+ qsopt.savepattern :=GetBool(so_savepattern ,true);
+ qsopt.colorize :=GetBool(so_colorize ,true);
+
+ if ServiceExists(MS_FP_GETCLIENTICON)<>0 then
+ qsopt.showclienticons:=GetBool(so_showclienticons,true)
+ else
+ qsopt.showclienticons:=false;
+ end
+ else
+ clear_columns;
+
+ qsopt.numcolumns:=GetWord(so_numcolumns,0);
+ if qsopt.numcolumns=0 then
+ begin
+ loaddefaultcolumns;
+ saveopt_db;
+ end
+ else
+ begin
+ pp:=StrCopyE(buf,so_item);
+ SetLength(qsopt.columns,qsopt.numcolumns);
+ FillChar(qsopt.columns[0],SizeOf(tcolumnitem)*qsopt.numcolumns,0);
+ for i:=0 to qsopt.numcolumns-1 do
+ begin
+ p:=StrEnd(IntToStr(pp,i));
+ with qsopt.columns[i] do
+ begin
+ StrCopy(p,so__title);
+ title:=GetUnicode(buf);
+ StrCopy(p,so__setting_type); setting_type:=GetWord(buf,0);
+ case setting_type of
+ ST_SCRIPT: begin
+ StrCopy(p,so__wparam);
+ wparam.w:=GetUnicode(buf);
+ end;
+ ST_CONTACTINFO: begin
+ StrCopy(p,so__setting_cnftype); setting_cnftype:=GetWord(buf,0);
+ end;
+ ST_SERVICE: begin
+ StrCopy(p,so__setting_cnftype); setting_cnftype:=GetWord(buf,0);
+ StrCopy(p,so__module_name); module_name :=GetStr(buf);
+ StrCopy(p,so__wparam_type); wparam._type:=GetWord(buf,0);
+ StrCopy(p,so__lparam_type); lparam._type:=GetWord(buf,0);
+ StrCopy(p,so__wparam);
+ case wparam._type of
+ ptNumber,
+ ptInteger: wparam.n:=GetInt(buf,0);
+ ptString : wparam.a:=GetStr(buf);
+ ptUnicode: wparam.w:=GetUnicode(buf);
+ end;
+ StrCopy(p,so__lparam);
+ case lparam._type of
+ ptNumber,
+ ptInteger: lparam.n:=GetInt(buf,0);
+ ptString : lparam.a:=GetStr(buf);
+ ptUnicode: lparam.w:=GetUnicode(buf);
+ end;
+ end;
+ else
+ StrCopy(p,so__module_name); module_name:=GetStr(buf);
+ StrCopy(p,so__wparam ); wparam.a :=GetStr(buf);
+ end;
+ StrCopy(p,so__width); width:=GetWord(buf,20);
+ StrCopy(p,so__flags); flags:=GetInt (buf,COL_ON);
+ end;
+ end;
+ end;
+end;
+
+end.
diff --git a/plugins/QuickSearch/sr_optdialog.pas b/plugins/QuickSearch/sr_optdialog.pas new file mode 100644 index 0000000000..7e7e711532 --- /dev/null +++ b/plugins/QuickSearch/sr_optdialog.pas @@ -0,0 +1,1041 @@ +unit sr_optdialog;
+
+interface
+uses windows;
+
+{.$include resource.inc}
+
+procedure OptChangeColumns(code:integer;column,data:integer);
+function DlgProcOptions(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+
+const
+ maindlg:HWND = 0;
+
+implementation
+
+uses messages,commctrl,sr_global,m_api,common,mirutils,wrapper,sr_window;
+
+var
+ OldListProc:pointer;
+const
+ curscript:pointer=nil;
+
+const
+ stByte :PAnsiChar = 'Byte';
+ stWord :PAnsiChar = 'Word';
+ stInt :PAnsiChar = 'Int';
+ stString :PAnsiChar = 'String';
+ stLastSeen :PAnsiChar = 'LastSeen';
+ stIP :PAnsiChar = 'IP';
+ stContactInfo:PAnsiChar = 'ContactInfo';
+ stLastEvent :PAnsiChar = 'LastEvent';
+ stTimeStamp :PAnsiChar = 'TimeStamp';
+ stService :PAnsiChar = 'Service';
+ stScript :PAnsiChar = 'Script';
+ stMetacontact:PAnsiChar = 'Metacontact';
+
+const
+ cnFirstName = 'FIRSTNAME' ;
+ cnLastName = 'LASTNAME' ;
+ cnNick = 'NICK' ;
+ cnCustomNick = 'CUSTOMNICK';
+ cnEmail = 'EMAIL' ;
+ cnCity = 'CITY' ;
+ cnState = 'STATE' ;
+ cnCountry = 'COUNTRY' ;
+ cnPhone = 'PHONE' ;
+ cnHomepage = 'HOMEPAGE' ;
+ cnAbout = 'ABOUT' ;
+ cnGender = 'GENDER' ;
+ cnAge = 'AGE' ;
+ cnFirstLast = 'FIRSTLAST' ;
+ cnUniqueID = 'UNIQUEID' ;
+ cnFax = 'FAX' ;
+ cnCellular = 'CELLULAR' ;
+ cnTimezone = 'TIMEZONE' ;
+ cnMyNotes = 'MYNOTES' ;
+ cnBirthday = 'BIRTHDAY' ;
+ cnBirthMonth = 'BIRTHMONTH';
+ cnBirthYear = 'BIRTHYEAR' ;
+ cnZIP = 'ZIP' ;
+ cnStreet = 'STREET' ;
+ cnLanguage1 = 'LANGUAGE1' ;
+ cnLanguage2 = 'LANGUAGE2' ;
+ cnLanguage3 = 'LANGUAGE3' ;
+ cnCoName = 'CONAME' ;
+
+const
+ strNotSelected = 'Not Selected';
+
+const
+ MaxControls = 13;
+ aIdElement:array [0..MaxControls-1] of integer = (
+ IDC_SCRIPT, IDC_STAT_VARTYPE, IDC_C_CNFTYPE, IDC_C_RESULT,
+ IDC_STAT_SERVICE, IDC_STAT_MODULE, IDC_E_MODULE,
+ IDC_STAT_WPAR, IDC_STAT_SETTING, IDC_E_VAR,
+ IDC_C_WPAR, IDC_E_LPAR, IDC_C_LPAR);
+
+ aShowElement:array [0..ST_MAXTYPE,0..MaxControls-1] of byte = (
+{ST_BYTE } ($00, $80, $80, $00, $00, $81, $81, $00, $81, $81, $80, $80, $80),
+{ST_WORD } ($00, $80, $80, $00, $00, $81, $81, $00, $81, $81, $80, $80, $80),
+{ST_INT } ($00, $80, $80, $00, $00, $81, $81, $00, $81, $81, $80, $80, $80),
+{ST_STRING } ($00, $80, $80, $00, $00, $81, $81, $00, $81, $81, $80, $80, $80),
+{ST_IP } ($00, $80, $80, $00, $00, $81, $81, $00, $81, $81, $80, $80, $80),
+{ST_LASTSEEN } ($00, $80, $80, $00, $00, $81, $81, $00, $81, $81, $80, $80, $80),
+{ST_CONTACTINFO} ($00, $81, $81, $00, $00, $80, $80, $00, $80, $80, $80, $80, $80),
+{ST_LASTEVENT } ($00, $80, $80, $00, $00, $80, $80, $00, $80, $80, $80, $80, $80),
+{ST_TIMESTAMP } ($00, $80, $80, $00, $00, $81, $81, $00, $81, $81, $80, $80, $80),
+{ST_SERVICE } ($00, $80, $00, $81, $81, $00, $81, $81, $00, $81, $81, $81, $81),
+{ST_SCRIPT } ($81, $00, $00, $00, $00, $80, $80, $00, $80, $80, $80, $80, $80),
+{ST_METACONTACT} ($00, $80, $80, $00, $00, $80, $80, $00, $80, $80, $80, $80, $80));
+
+procedure SetupControls(Dialog:HWND; aType:integer);
+var
+ i,j: cardinal;
+ wnd:HWND;
+begin
+ for i:=0 to MaxControls-1 do
+ begin
+ j :=aShowElement[aType][i];
+ wnd:=GetDlgItem(Dialog,aIdElement[i]);
+ EnableWindow(wnd,odd(j));
+ if shortint(j)<0 then
+ j:=SW_SHOW
+ else
+ j:=SW_HIDE;
+ ShowWindow(wnd,j);
+ end;
+end;
+
+function settype2str(settype:integer):pointer;
+var
+ tmp:array [0..127] of WideChar;
+begin
+ case settype of
+// ST_BYTE: result:=stByte;
+ ST_WORD: result:=stWord;
+ ST_INT: result:=stInt;
+ ST_STRING: result:=stString;
+ ST_LASTSEEN: result:=stLastSeen;
+ ST_IP: result:=stIP;
+ ST_CONTACTINFO: result:=stContactInfo;
+ ST_LASTEVENT: result:=stLastEvent;
+ ST_TIMESTAMP: result:=stTimeStamp;
+ ST_SERVICE: result:=stService;
+ ST_SCRIPT: result:=stScript;
+ ST_METACONTACT: result:=stMetacontact;
+ else
+ result:=stByte;
+ end;
+
+ FastAnsiToWideBuf(result,tmp);
+ StrDupW(pWideChar(result),TranslateW(tmp));
+end;
+
+function setcnftype2str(settype:integer):PWideChar;
+var
+ res:pWideChar;
+begin
+ case settype of
+// CNF_FIRSTNAME: result:=translate(cnFirstName);
+ CNF_LASTNAME: res:=cnLastName ;
+ CNF_NICK: res:=cnNick ;
+ CNF_CUSTOMNICK: res:=cnCustomNick;
+ CNF_EMAIL: res:=cnEmail ;
+ CNF_CITY: res:=cnCity ;
+ CNF_STATE: res:=cnState ;
+ CNF_COUNTRY: res:=cnCountry ;
+ CNF_PHONE: res:=cnPhone ;
+ CNF_HOMEPAGE: res:=cnHomepage ;
+ CNF_ABOUT: res:=cnAbout ;
+ CNF_GENDER: res:=cnGender ;
+ CNF_AGE: res:=cnAge ;
+ CNF_FIRSTLAST: res:=cnFirstLast ;
+ CNF_UNIQUEID: res:=cnUniqueID ;
+
+ CNF_FAX: res:=cnFax ;
+ CNF_CELLULAR: res:=cnCellular ;
+ CNF_TIMEZONE: res:=cnTimezone ;
+ CNF_MYNOTES: res:=cnMyNotes ;
+ CNF_BIRTHDAY: res:=cnBirthday ;
+ CNF_BIRTHMONTH: res:=cnBirthMonth;
+ CNF_BIRTHYEAR: res:=cnBirthYear ;
+ CNF_STREET: res:=cnStreet ;
+ CNF_ZIP: res:=cnZIP ;
+ CNF_LANGUAGE1: res:=cnLanguage1 ;
+ CNF_LANGUAGE2: res:=cnLanguage2 ;
+ CNF_LANGUAGE3: res:=cnLanguage3 ;
+ CNF_CONAME: res:=cnCoName ;
+ else
+ res:=cnFirstName;
+ end;
+ result:=TranslateW(res);
+end;
+
+procedure addcolumn(handle:hwnd;width:word;title:PAnsiChar);
+var
+ lvcol:LV_COLUMNW;
+ buf:array [0..127] of WideChar;
+begin
+ lvcol.mask:=LVCF_TEXT or LVCF_WIDTH;
+ lvcol.cx :=width;
+ lvcol.pszText:=TranslateW(FastAnsiToWideBuf(title,buf));
+ SendMessageW(handle,LVM_INSERTCOLUMNW,0,lparam(@lvcol));
+end;
+
+function getselecteditem(list:hwnd):integer;
+begin
+ result:=SendMessage(list,LVM_GETNEXTITEM,-1,LVNI_FOCUSED);
+end;
+
+function savecuritem(Dialog:hwnd):integer;
+var
+ listhwnd:hwnd;
+ selitem:integer;
+
+ procedure GetText(id,subpos:integer;var dst:PAnsiChar); overload;
+ var
+ tpc:array [0..1023] of AnsiChar;
+ begin
+ GetDlgItemTextA(Dialog,id,tpc,SizeOf(tpc));
+ mFreeMem(dst);
+ StrDup(dst,tpc);
+ LV_SetItem(listhwnd,dst,selitem,subpos);
+ end;
+
+ // now for Title only
+ procedure GetText(id,subpos:integer;var dst:PWideChar); overload;
+ var
+ tpc:array [0..1023] of WideChar;
+ begin
+ GetDlgItemTextW(Dialog,id,@tpc,SizeOf(tpc) div SizeOf(WideChar));
+ mFreeMem(dst);
+ StrDupW(dst,@tpc);
+ LV_SetItemW(listhwnd,dst,selitem,subpos);
+ end;
+
+ procedure setparam(var param:tserviceparam;cb,id:integer);
+ var
+ z:bool;
+ tpc:array [0..1023] of WideChar;
+ begin
+ param._type:=SendDlgItemMessage(Dialog,cb,CB_GETCURSEL,0,0);
+ case param._type of
+ ptNumber: param.n:=GetDlgItemInt(Dialog,id,z,false);
+ ptInteger: param.i:=GetDlgItemInt(Dialog,id,z,true);
+ ptString: begin
+ GetDlgItemTextA(Dialog,id,@tpc,SizeOf(tpc));
+ StrDup(param.a,@tpc);
+ end;
+ ptUnicode: begin
+ GetDlgItemTextW(Dialog,id,@tpc,SizeOf(tpc) div SizeOf(WideChar));
+ StrDupW(param.w,@tpc);
+ end;
+ end;
+ end;
+
+var
+ tpc :array [0..127] of WideChar;
+ tmpwnd:HWND;
+ oldtype,i:integer;
+ column:integer;
+begin
+ listhwnd:=GetDlgItem(Dialog,IDC_LIST);
+ selitem:=getselecteditem(listhwnd);
+//!! column:=LV_GetLParam(listhwnd,selitem);
+ column:=selitem;
+ result:=selitem;
+ if (selitem>=0) and (selitem<qsopt.numcolumns) then
+ begin
+ with qsopt.columns[column] do
+ begin
+ flags:=0;
+
+ if ListView_GetCheckState(listhwnd,selitem)=BST_CHECKED then
+ flags:=flags or COL_ON;
+
+ oldtype:=setting_type;
+
+ tmpwnd:=GetDlgItem(Dialog,IDC_C_VARTYPE);
+
+ setting_type:=SendMessage(tmpwnd,CB_GETITEMDATA,
+ SendMessage(tmpwnd,CB_GETCURSEL,0,0),0);
+
+ GetText(IDC_E_TITLE,1,title);
+
+ case oldtype of
+ ST_SCRIPT: begin
+ mFreeMem(wparam.a);
+ end;
+ ST_SERVICE: begin
+ if (wparam._type=ptString) or (wparam._type=ptUnicode) then mFreeMem(wparam.a);
+ if (lparam._type=ptString) or (lparam._type=ptUnicode) then mFreeMem(lparam.a);
+ end;
+ else
+ mFreeMem(wparam.a);
+ end;
+
+ case setting_type of
+ ST_METACONTACT: begin
+ LV_SetItemW(listhwnd,TranslateW('Metacontact'),selitem,2);
+ end;
+
+ ST_SCRIPT: begin
+ StrDupW(wparam.w,curscript);
+ LV_SetItemW(listhwnd,TranslateW('Script'),selitem,2);
+ end;
+
+ ST_CONTACTINFO: begin
+ FillChar(tpc,SizeOf(tpc),0);
+ tmpwnd:=GetDlgItem(Dialog,IDC_C_CNFTYPE);
+
+ i:=SendMessage(tmpwnd,CB_GETCURSEL,0,0);
+ setting_cnftype:=SendMessage(tmpwnd,CB_GETITEMDATA,i,0);
+
+ SendMessageW(tmpwnd,CB_GETLBTEXT,i,tlparam(@tpc));
+ LV_SetItemW(listhwnd,tpc,selitem,2);
+ end;
+
+ ST_SERVICE: begin
+ GetText(IDC_E_MODULE,3,module_name);
+ LV_SetItemW(listhwnd,TranslateW('Service'),selitem,2);
+//!! setitem(listhwnd,selitem,3,module_name);
+
+ setting_cnftype:=SendDlgItemMessage(Dialog,IDC_C_RESULT,CB_GETCURSEL,0,0);
+ setparam(wparam,IDC_C_WPAR,IDC_E_VAR);
+ setparam(lparam,IDC_C_LPAR,IDC_E_LPAR);
+ end;
+ else
+ GetText(IDC_E_MODULE,2,module_name);
+ GetText(IDC_E_VAR ,3,wparam.a)
+ end;
+ end;
+ end;
+end;
+
+procedure disable_elem(Dialog:hwnd;id:cardinal);
+begin
+ EnableWindow(GetDlgItem(Dialog,id),FALSE);
+end;
+
+procedure enable_elem(Dialog:hwnd;id:cardinal);
+begin
+ EnableWindow(GetDlgItem(Dialog,id),TRUE);
+end;
+
+procedure CheckDirection(Dialog:HWND;item:integer);
+begin
+ if item=0 then
+ disable_elem(Dialog,IDC_UP)
+ else
+ enable_elem(Dialog,IDC_UP);
+
+ if item=(qsopt.numcolumns-1) then
+ disable_elem(Dialog,IDC_DN)
+ else
+ enable_elem(Dialog,IDC_DN);
+end;
+
+procedure displcurinfo(Dialog:hwnd;column:integer);
+
+ procedure set_elem(const param:tserviceparam;cb,id:integer);
+ begin
+ SendDlgItemMessage(Dialog,cb,CB_SETCURSEL,param._type,0);
+ case param._type of
+ ptNumber: SetDlgItemInt (Dialog,id,param.n,false);
+ ptInteger: SetDlgItemInt (Dialog,id,param.i,true);
+ ptString: SetDlgItemTextA(Dialog,id,param.a);
+ ptUnicode: SetDlgItemTextW(Dialog,id,param.w);
+ else
+ SetDlgItemTextA(Dialog,id,'');
+ end;
+ EnableWindow(GetDlgItem(Dialog,id),param._type<>ptCurrent);
+ end;
+
+var
+ v:PWideChar;
+ i:int_ptr;
+ selpos:integer;
+begin
+ CheckDirection(Dialog,column);
+
+ selpos:=column;
+ if (selpos>=0) and (selpos<qsopt.numcolumns) then
+ begin
+ enable_elem(Dialog,IDC_E_TITLE);
+ enable_elem(Dialog,IDC_C_VARTYPE);
+ enable_elem(Dialog,IDC_DELETE);
+// enable_elem(Dialog,IDC_SETITEM);
+
+ with qsopt.columns[column] do
+ begin
+ SetupControls(Dialog,setting_type);
+ case setting_type of
+ ST_SCRIPT: begin
+ mFreeMem(curscript);
+ StrDupW(pWideChar(curscript),wparam.w);
+ end;
+ ST_SERVICE: begin
+ SendDlgItemMessage(Dialog,IDC_C_RESULT,CB_SETCURSEL,setting_cnftype,0);
+ SetDlgItemTextA(Dialog,IDC_E_MODULE,module_name);
+ set_elem(wparam,IDC_C_WPAR,IDC_E_VAR);
+ set_elem(lparam,IDC_C_LPAR,IDC_E_LPAR);
+ end;
+ ST_CONTACTINFO: begin
+ i:=int_ptr(setcnftype2str(setting_cnftype));
+ SendDlgItemMessageW(Dialog,IDC_C_CNFTYPE,CB_SELECTSTRING,twparam(-1),i);
+ end;
+ else
+ SetDlgItemTextA(Dialog,IDC_E_MODULE,module_name);
+ SetDlgItemTextA(Dialog,IDC_E_VAR,wparam.a);
+ end;
+
+ v:=settype2str(setting_type);
+ SetDlgItemTextW(Dialog,IDC_E_TITLE,title);
+ SendDlgItemMessageW(Dialog,IDC_C_VARTYPE,CB_SELECTSTRING,twparam(-1),tlparam(v));
+ mFreeMem(v);
+ end;
+ end
+ else
+ begin
+ disable_elem(Dialog,IDC_E_TITLE);
+ disable_elem(Dialog,IDC_C_VARTYPE);
+ disable_elem(Dialog,IDC_DELETE);
+ disable_elem(Dialog,IDC_SETITEM);
+
+ v:=TranslateW(strNotSelected);
+ SetDlgItemTextW(Dialog,IDC_E_TITLE ,v);
+ SetDlgItemTextW(Dialog,IDC_E_MODULE,v);
+ SetDlgItemTextW(Dialog,IDC_E_VAR ,v);
+ SetDlgItemTextW(Dialog,IDC_E_LPAR ,v);
+ SendDlgItemMessageW(Dialog,IDC_C_VARTYPE,CB_SELECTSTRING,twparam(-1),tlparam(v));
+ SendDlgItemMessageW(Dialog,IDC_C_CNFTYPE,CB_SELECTSTRING,twparam(-1),tlparam(v));
+ end;
+end;
+
+function add_column(list:HWND;i:integer):integer;
+var
+ li:LV_ITEMA;
+begin
+ result:=i;
+ zeromemory(@li,sizeof(li));
+ li.mask :=LVIF_PARAM;
+ li.lParam:=i;
+ li.iItem :=i;
+ SendMessage(list,LVM_INSERTITEM,0,lparam(@li));
+
+ with qsopt.columns[i] do
+ begin
+ ListView_SetCheckState(list,i,(flags and COL_ON)<>0);
+ LV_SetItemW(list,title,i,1);
+ case setting_type of
+ ST_METACONTACT: begin
+ LV_SetItemW(list,TranslateW('Metacontact'),i,2);
+ end;
+
+ ST_CONTACTINFO: begin
+ LV_SetItemW(list,setcnftype2str(setting_cnftype),i,2)
+ end;
+
+ ST_SCRIPT: begin
+ LV_SetItemW(list,TranslateW('Script'),i,2);
+ end;
+
+ ST_SERVICE: begin
+ LV_SetItemW(list,TranslateW('Service'),i,2);
+ LV_SetItem(list,module_name,i,3);
+ end;
+ else
+ LV_SetItem(list,module_name,i,2);
+ LV_SetItem(list,wparam.a,i,3);
+ end;
+ end;
+end;
+
+procedure update_list(list:hwnd);
+var
+ i:integer;
+begin
+ ListView_DeleteAllItems(list);
+ ListView_SetItemCount(list,qsopt.numcolumns);
+
+ for i:=0 to qsopt.numcolumns-1 do
+ begin
+ add_column(list,i);
+ end;
+//!! SortColumns(list);
+ ListView_SetItemState(list,0,LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+end;
+
+procedure addresulttypes(list:integer);
+begin
+ SendMessageW(list,CB_INSERTSTRING,ptNumber ,lparam(TranslateW('number value' )));
+ SendMessageW(list,CB_INSERTSTRING,ptInteger,lparam(TranslateW('integer value' )));
+ SendMessageW(list,CB_INSERTSTRING,ptString ,lparam(TranslateW('ANSI string' )));
+ SendMessageW(list,CB_INSERTSTRING,ptUnicode,lparam(TranslateW('Unicode string')));
+ SendMessage(list,CB_SETCURSEL,0,0);
+end;
+
+procedure addparamtypes(list:integer);
+begin
+ addresulttypes(list);
+ SendMessageW(list,CB_INSERTSTRING,ptCurrent,lparam(TranslateW('current contact')));
+end;
+
+procedure AddVal(list:HWND;param:integer);
+var
+ i:integer;
+ v:pointer;
+begin
+ v:=settype2str(param);
+ i:=SendMessageW(list,CB_ADDSTRING,0,lparam(v));
+ mFreeMem(v);
+ SendMessage(list,CB_SETITEMDATA,i,param);
+end;
+
+procedure addsettypes(list:hwnd);
+begin
+ AddVal(list,ST_BYTE);
+ AddVal(list,ST_WORD);
+ AddVal(list,ST_INT);
+ AddVal(list,ST_STRING);
+ AddVal(list,ST_LASTSEEN);
+ AddVal(list,ST_IP);
+ AddVal(list,ST_CONTACTINFO);
+ AddVal(list,ST_LASTEVENT);
+ AddVal(list,ST_TIMESTAMP);
+ AddVal(list,ST_SERVICE);
+ AddVal(list,ST_SCRIPT);
+ AddVal(list,ST_METACONTACT);
+ SendMessage(list,CB_SETCURSEL,0,0);
+end;
+
+procedure AddCnf(list:HWND;param:integer);
+begin
+ SendMessage(list,CB_SETITEMDATA,
+ SendMessageW(list,CB_ADDSTRING,0,lparam(setcnftype2str(param))),
+ param);
+// mFreeMem(str);
+end;
+
+procedure addsetcnftypes(list:hwnd);
+begin
+ AddCnf(list,CNF_FIRSTNAME);
+ AddCnf(list,CNF_LASTNAME);
+ AddCnf(list,CNF_NICK);
+ AddCnf(list,CNF_CUSTOMNICK);
+ AddCnf(list,CNF_EMAIL);
+ AddCnf(list,CNF_CITY);
+ AddCnf(list,CNF_STATE);
+ AddCnf(list,CNF_COUNTRY);
+ AddCnf(list,CNF_PHONE);
+ AddCnf(list,CNF_HOMEPAGE);
+ AddCnf(list,CNF_ABOUT);
+ AddCnf(list,CNF_GENDER);
+ AddCnf(list,CNF_AGE);
+ AddCnf(list,CNF_FIRSTLAST);
+ AddCnf(list,CNF_UNIQUEID);
+
+ AddCnf(list,CNF_FAX);
+ AddCnf(list,CNF_CELLULAR);
+ AddCnf(list,CNF_TIMEZONE);
+ AddCnf(list,CNF_MYNOTES);
+ AddCnf(list,CNF_BIRTHDAY);
+ AddCnf(list,CNF_BIRTHMONTH);
+ AddCnf(list,CNF_BIRTHYEAR);
+ AddCnf(list,CNF_STREET);
+ AddCnf(list,CNF_ZIP);
+ AddCnf(list,CNF_LANGUAGE1);
+ AddCnf(list,CNF_LANGUAGE2);
+ AddCnf(list,CNF_LANGUAGE3);
+ AddCnf(list,CNF_CONAME);
+
+ SendMessage(list,CB_SETCURSEL,0,0);
+end;
+
+procedure _GetIcon(idc:integer;ico:PAnsiChar);
+begin
+ SetButtonIcon(GetDlgItem(maindlg,idc),ico);
+end;
+
+function IconChanged(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+begin
+ result:=0;
+ _GetIcon(IDC_NEW ,QS_NEW);
+ _GetIcon(IDC_SETITEM,QS_ITEM);
+ _GetIcon(IDC_UP ,QS_UP);
+ _GetIcon(IDC_DN ,QS_DOWN);
+ _GetIcon(IDC_DELETE ,QS_DELETE);
+ _GetIcon(IDC_DEFAULT,QS_DEFAULT);
+ _GetIcon(IDC_RELOAD ,QS_RELOAD);
+end;
+
+function ScriptEdit(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+var
+ tmp:pointer;
+ vhi:TVARHELPINFO;
+begin
+ result:=0;
+ case hMessage of
+
+ WM_INITDIALOG: begin
+ TranslateDialogDefault(Dialog);
+ SetDlgItemTextW(Dialog,IDC_EDIT_SCRIPT,pWideChar(lParam));
+ end;
+
+ WM_COMMAND: begin
+ case wParam shr 16 of
+ BN_CLICKED: begin
+ case loword(wParam) of
+ IDHELP: SendMessage(Dialog,WM_HELP,0,0);
+ IDOK: begin
+ tmp:=GetDlgText(Dialog,IDC_EDIT_SCRIPT);
+ EndDialog(Dialog,tlparam(tmp));
+ end;
+ IDCANCEL: begin // clear result / restore old value
+ EndDialog(Dialog,0);
+ end;
+ end;
+ end;
+ end;
+ end;
+
+ WM_HELP: begin
+ FillChar(vhi,SizeOf(vhi),0);
+ with vhi do
+ begin
+ cbSize:=SizeOf(vhi);
+ flags:=VHF_NOINPUTDLG;
+ end;
+ CallService(MS_VARS_SHOWHELPEX,Dialog,tlparam(@vhi));
+ end;
+ end;
+end;
+
+function NewListProc(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):integer; stdcall;
+begin
+ result:=0;
+ if hMessage=WM_KEYDOWN then
+ begin
+ case wParam of
+ VK_INSERT: begin
+ PostMessage(GetParent(Dialog),WM_COMMAND,(BN_CLICKED shl 16)+IDC_NEW,0);
+ exit;
+ end;
+ VK_DELETE: begin
+ PostMessage(GetParent(Dialog),WM_COMMAND,(BN_CLICKED shl 16)+IDC_DELETE,0);
+ exit;
+ end;
+ VK_UP: begin
+ if (GetKeyState(VK_CONTROL) and $8000)<>0 then
+ begin
+ PostMessage(GetParent(Dialog),WM_COMMAND,(BN_CLICKED shl 16)+IDC_UP,0);
+ exit;
+ end;
+ end;
+ VK_DOWN: begin
+ if (GetKeyState(VK_CONTROL) and $8000)<>0 then
+ begin
+ PostMessage(GetParent(Dialog),WM_COMMAND,(BN_CLICKED shl 16)+IDC_DN,0);
+ exit;
+ end;
+ end;
+ end;
+ end;
+ result:=CallWindowProc(OldListProc,Dialog,hMessage,wParam,lParam);
+end;
+
+function DlgProcOptions(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+const
+ InitDlg:bool = true;
+ hook:THANDLE = 0;
+var
+// tpc:array [0..255] of AnsiChar;
+ itemsel:integer;
+ tmpwnd:HWND;
+ tmpbool:bool;
+ i:integer;
+// ti:TTOOLINFOW;
+// hwndTooltip:HWND;
+ hNew :hwnd;
+ hItem :hwnd;
+ hUp :hwnd;
+ hDown :hwnd;
+ hDelete :hwnd;
+ hDefault:hwnd;
+ hReload :hwnd;
+ listhwnd:hwnd;
+ tmpcol:tcolumnitem;
+begin
+ result:=0;
+
+ case hMessage of
+ WM_DESTROY: begin
+ // if closed by Cancel, with changes but without apply
+ loadopt_db(false); //!!!!
+ WndChangeColumns(wcRefresh);
+
+ mFreeMem(curscript);
+ if hook<>0 then
+ UnhookEvent(hook);
+ maindlg:=0;
+ end;
+
+ WM_INITDIALOG: begin
+ InitDlg:=true;
+ listhwnd:=GetDlgItem(Dialog,IDC_LIST);
+
+ SendMessageW(listhwnd,LVM_SETEXTENDEDLISTVIEWSTYLE,0,
+ SendMessageW(listhwnd,LVM_GETEXTENDEDLISTVIEWSTYLE,0,0) or
+ LVS_EX_FULLROWSELECT or LVS_EX_CHECKBOXES);
+
+ TranslateDialogDefault(Dialog);
+
+ addcolumn(listhwnd,95 ,'Setting');
+ addcolumn(listhwnd,105,'Module/InfoType');
+ addcolumn(listhwnd,85 ,'Title');
+ addcolumn(listhwnd,20 ,'#');
+ addsettypes (GetDlgItem(Dialog,IDC_C_VARTYPE));
+ addsetcnftypes(GetDlgItem(Dialog,IDC_C_CNFTYPE));
+ addparamtypes (GetDlgItem(Dialog,IDC_C_WPAR));
+ addparamtypes (GetDlgItem(Dialog,IDC_C_LPAR));
+ addresulttypes(GetDlgItem(Dialog,IDC_C_RESULT));
+
+ CheckDlgButton(Dialog,IDC_CH_SORTSTATUS ,ORD(qsopt.sortbystatus));
+ CheckDlgButton(Dialog,IDC_CH_SHOWINMENU ,ORD(qsopt.showinmenu));
+ CheckDlgButton(Dialog,IDC_CH_SHOWONLYUSERS ,ORD(qsopt.showonlyinlist));
+ CheckDlgButton(Dialog,IDC_CH_AUTOCLOSE ,ORD(qsopt.closeafteraction));
+ CheckDlgButton(Dialog,IDC_CH_ADDTOTOPTOOLBAR,ORD(qsopt.showintoptoolbar));
+ CheckDlgButton(Dialog,IDC_CH_USETOOLSTYLE ,ORD(qsopt.usetoolstyle));
+ CheckDlgButton(Dialog,IDC_CH_DRAWGRID ,ORD(qsopt.drawgrid));
+ CheckDlgButton(Dialog,IDC_CH_SINGLECSV ,ORD(qsopt.singlecsv));
+ CheckDlgButton(Dialog,IDC_CH_EXPORTHEADERS ,ORD(qsopt.exportheaders));
+ CheckDlgButton(Dialog,IDC_CH_SKIPMINIMIZED ,ORD(qsopt.skipminimized));
+ CheckDlgButton(Dialog,IDC_CH_SAVEPATTERN ,ORD(qsopt.savepattern));
+ if ServiceExists(MS_FP_GETCLIENTICON)<>0 then
+ CheckDlgButton(Dialog,IDC_CH_SHOWCLIENTICONS,ORD(qsopt.showclienticons))
+ else
+ EnableWindow(GetDlgItem(Dialog,IDC_CH_SHOWCLIENTICONS),false);
+
+ if ServiceExists(MS_TTB_ADDBUTTON)=0 then
+ EnableWindow(GetDlgItem(Dialog,IDC_CH_ADDTOTOPTOOLBAR),FALSE);
+{
+ hwndTooltip:=CreateWindowW(TOOLTIPS_CLASS,nil,TTS_ALWAYSTIP,
+ integer(CW_USEDEFAULT),integer(CW_USEDEFAULT),
+ integer(CW_USEDEFAULT),integer(CW_USEDEFAULT),
+ Dialog,0,hInstance,nil);
+}
+ hNew :=GetDlgItem(Dialog,IDC_NEW);
+ SendMessage(hNew,BUTTONADDTOOLTIP,TWPARAM(TranslateW('New')),BATF_UNICODE);
+ hItem :=GetDlgItem(Dialog,IDC_SETITEM);
+ SendMessage(hItem,BUTTONADDTOOLTIP,TWPARAM(TranslateW('Save Item')),BATF_UNICODE);
+ hUp :=GetDlgItem(Dialog,IDC_UP);
+ SendMessage(hUp,BUTTONADDTOOLTIP,TWPARAM(TranslateW('Up')),BATF_UNICODE);
+ hDown :=GetDlgItem(Dialog,IDC_DN);
+ SendMessage(hDown,BUTTONADDTOOLTIP,TWPARAM(TranslateW('Down')),BATF_UNICODE);
+ hDelete :=GetDlgItem(Dialog,IDC_DELETE);
+ SendMessage(hDelete,BUTTONADDTOOLTIP,TWPARAM(TranslateW('Delete')),BATF_UNICODE);
+ hDefault:=GetDlgItem(Dialog,IDC_DEFAULT);
+ SendMessage(hDefault,BUTTONADDTOOLTIP,TWPARAM(TranslateW('Default')),BATF_UNICODE);
+ hReload :=GetDlgItem(Dialog,IDC_RELOAD);
+ SendMessage(hReload,BUTTONADDTOOLTIP,TWPARAM(TranslateW('Reload')),BATF_UNICODE);
+{
+ FillChar(ti,SizeOf(ti),0);
+ ti.cbSize :=sizeof(TOOLINFO);
+ ti.uFlags :=TTF_IDISHWND or TTF_SUBCLASS;
+ ti.hwnd :=Dialog;
+ ti.hinst :=hInstance;
+ ti.uId :=hNew;
+ ti.lpszText:=TranslateW('New');
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,tlparam(@ti));
+ ti.uId :=hItem;
+ ti.lpszText:=TranslateW('Save Item');
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,tlparam(@ti));
+ ti.uId :=hUp;
+ ti.lpszText:=TranslateW('Up');
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,tlparam(@ti));
+ ti.uId :=hDown;
+ ti.lpszText:=TranslateW('Down');
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,tlparam(@ti));
+ ti.uId :=hDelete;
+ ti.lpszText:=TranslateW('Delete');
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,tlparam(@ti));
+ ti.uId :=hDefault;
+ ti.lpszText:=TranslateW('Default');
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,tlparam(@ti));
+ ti.uId :=hReload;
+ ti.lpszText:=TranslateW('Reload');
+ SendMessageW(hwndTooltip,TTM_ADDTOOLW,0,tlparam(@ti));
+}
+ SetButtonIcon(hNew ,QS_NEW);
+ SetButtonIcon(hItem, QS_ITEM);
+ SetButtonIcon(hUp ,QS_UP);
+ SetButtonIcon(hDown ,QS_DOWN);
+ SetButtonIcon(hDelete ,QS_DELETE);
+ SetButtonIcon(hDefault,QS_DEFAULT);
+ SetButtonIcon(hReload ,QS_RELOAD);
+
+ update_list(listhwnd);
+
+ maindlg:=Dialog;
+ hook:=HookEvent(ME_SKIN2_ICONSCHANGED,@IconChanged);
+
+ result:=1;
+
+ OldListProc:=pointer(SetWindowLongPtrW(listhwnd,GWL_WNDPROC,LONG_PTR(@NewListProc)));
+
+ InitDlg:=false;
+ end;
+
+ WM_NOTIFY: begin
+ case integer(PNMHdr(lParam)^.code) of
+
+ PSN_APPLY: begin
+ // checkboxes
+ listhwnd:=GetDlgItem(Dialog,IDC_LIST);
+
+ for i:=0 to SendMessage(listhwnd,LVM_GETITEMCOUNT,0,0)-1 do
+ begin
+ with qsopt.columns[i] do
+ begin
+ if ListView_GetCheckSTate(listhwnd,i)=0 then
+ flags:=flags and not COL_ON
+ else
+ flags:=flags or COL_ON;
+ end;
+ end;
+
+ disable_elem(Dialog,IDC_SETITEM);
+ savecuritem(Dialog);
+
+ qsopt.sortbystatus :=IsDlgButtonChecked(Dialog,IDC_CH_SORTSTATUS )<>BST_UNCHECKED;
+ qsopt.showonlyinlist :=IsDlgButtonChecked(Dialog,IDC_CH_SHOWONLYUSERS )<>BST_UNCHECKED;
+ qsopt.closeafteraction:=IsDlgButtonChecked(Dialog,IDC_CH_AUTOCLOSE )<>BST_UNCHECKED;
+ qsopt.usetoolstyle :=IsDlgButtonChecked(Dialog,IDC_CH_USETOOLSTYLE )<>BST_UNCHECKED;
+ qsopt.drawgrid :=IsDlgButtonChecked(Dialog,IDC_CH_DRAWGRID )<>BST_UNCHECKED;
+ qsopt.showclienticons :=IsDlgButtonChecked(Dialog,IDC_CH_SHOWCLIENTICONS)<>BST_UNCHECKED;
+ qsopt.singlecsv :=IsDlgButtonChecked(Dialog,IDC_CH_SINGLECSV )<>BST_UNCHECKED;
+ qsopt.exportheaders :=IsDlgButtonChecked(Dialog,IDC_CH_EXPORTHEADERS )<>BST_UNCHECKED;
+ qsopt.skipminimized :=IsDlgButtonChecked(Dialog,IDC_CH_SKIPMINIMIZED )<>BST_UNCHECKED;
+ qsopt.savepattern :=IsDlgButtonChecked(Dialog,IDC_CH_SAVEPATTERN )<>BST_UNCHECKED;
+
+ tmpbool:=IsDlgButtonChecked(Dialog,IDC_CH_SHOWINMENU)<>BST_UNCHECKED;
+ if qsopt.showinmenu<>tmpbool then
+ begin
+ qsopt.showinmenu:=tmpbool;
+ AddRemoveMenuItemToMainMenu;
+ end;
+ tmpbool:=IsDlgButtonChecked(Dialog,IDC_CH_ADDTOTOPTOOLBAR )<>BST_UNCHECKED;
+ if qsopt.showintoptoolbar<>tmpbool then
+ begin
+ qsopt.showintoptoolbar:=tmpbool;
+ addtotoolbar;
+ end;
+
+ saveopt_db;
+ result:=1;
+ end;
+
+ LVN_ITEMCHANGED: begin
+ if wParam=IDC_LIST then
+ begin
+ i:=(PNMLISTVIEW(lParam)^.uOldState and LVNI_FOCUSED)-
+ (PNMLISTVIEW(lParam)^.uNewState and LVNI_FOCUSED);
+ if i<0 then // new focus
+ begin
+ InitDlg:=true;
+ displcurinfo(Dialog,PNMLISTVIEW(lParam)^.iItem);
+{!!
+ displcurinfo(Dialog,
+ LV_GetLParam(PNMLISTVIEW(lParam)^.hdr.hwndFrom,
+ PNMLISTVIEW(lParam)^.iItem));
+}
+ InitDlg:=false;
+ result:=1;
+ end else if (i=0) and not InitDlg then
+ begin
+ if (PNMLISTVIEW(lParam)^.uOldState or PNMLISTVIEW(lParam)^.uNewState)=$3000 then
+ begin
+ i:=PNMLISTVIEW(lParam)^.uOldState-PNMLISTVIEW(lParam)^.uNewState;
+ if abs(i)=$1000 then
+ begin
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ if i<0 then
+ i:=wcShow
+ else
+ i:=wcHide;
+ WndChangeColumns(i,PNMLISTVIEW(lParam)^.iItem);
+ result:=1;
+ end;
+ end;
+ end;
+ end;
+ end;
+
+ end;
+ end;
+
+ WM_MYSHOWHIDEITEM: begin
+ InitDlg:=true;
+ ListView_SetCheckState(GetDlgItem(Dialog,IDC_LIST),wParam,lParam<>0);
+ InitDlg:=false;
+ end;
+
+ WM_MYMOVEITEM: begin
+ listhwnd:=GetDlgItem(Dialog,IDC_LIST);
+ LV_MoveItem(listhwnd,lParam,wParam);
+ itemsel:=wParam+lParam;
+ i:=SizeOf(tcolumnitem)*abs(integer(lParam));
+ move(qsopt.columns[wParam],tmpcol,SizeOf(tcolumnitem));
+
+ if integer(lParam)>0 then
+ move(qsopt.columns[wParam+1],qsopt.columns[wParam],i)
+ else
+ move(qsopt.columns[itemsel],qsopt.columns[itemsel+1],i);
+
+ move(tmpcol,qsopt.columns[itemsel],SizeOf(tcolumnitem));
+
+ CheckDirection(Dialog,getselecteditem(listhwnd));
+ end;
+
+ WM_COMMAND: begin
+ if ((wParam shr 16)=CBN_SELCHANGE) then
+ begin
+ case loword(wParam) of
+ IDC_C_VARTYPE: begin
+ i:=SendMessage(lParam,CB_GETITEMDATA,
+ SendMessage(lParam,CB_GETCURSEL,0,0),0);
+
+ SetupControls(Dialog,i);
+
+ EnableWindow(GetDlgItem(Dialog,IDC_E_VAR),
+ SendDlgItemMessage(Dialog,IDC_C_WPAR,CB_GETCURSEL,0,0)<>ptCurrent);
+ EnableWindow(GetDlgItem(Dialog,IDC_E_LPAR),
+ SendDlgItemMessage(Dialog,IDC_C_LPAR,CB_GETCURSEL,0,0)<>ptCurrent);
+ end;
+ IDC_C_WPAR: begin
+ EnableWindow(GetDlgItem(Dialog,IDC_E_VAR),
+ SendMessage(lParam,CB_GETCURSEL,0,0)<>ptCurrent);
+ end;
+ IDC_C_LPAR: begin
+ EnableWindow(GetDlgItem(Dialog,IDC_E_LPAR),
+ SendMessage(lParam,CB_GETCURSEL,0,0)<>ptCurrent);
+ end;
+ end;
+ end;
+
+ if not InitDlg then
+ case wParam shr 16 of
+ CBN_SELCHANGE,
+ BN_CLICKED,
+ EN_CHANGE: begin
+ SendMessage(GetParent(Dialog),PSM_CHANGED,0,0);
+ enable_elem(Dialog,IDC_SETITEM);
+ end;
+ end;
+
+ listhwnd:=GetDlgItem(Dialog,IDC_LIST);
+ result:=1;
+ case loword(wParam) of
+ IDC_SCRIPT: begin
+ tmpwnd:=DialogBoxParamW(hInstance,MAKEINTRESOURCEW(IDD_SCRIPT),
+ Dialog,@ScriptEdit,tlparam(curscript));
+ if tmpwnd<>0 then
+ begin
+ curscript:=pointer(tmpwnd);
+ end;
+ end;
+
+ IDC_NEW: begin
+ InitDlg:=true;
+ WndChangeColumns(wcInsert,
+ add_column(listhwnd,new_column(getselecteditem(listhwnd))));
+
+ SendMessage(listhwnd,LVM_ENSUREVISIBLE,qsopt.numcolumns-1,0);
+ ListView_SetItemState(listhwnd,qsopt.numcolumns-1,
+ LVIS_FOCUSED+LVIS_SELECTED,LVIS_FOCUSED+LVIS_SELECTED);
+ InitDlg:=false;
+ end;
+
+ IDC_DELETE: begin
+ i:=getselecteditem(listhwnd);
+ SendMessage(listhwnd,LVM_DELETEITEM,i,0);
+ delete_column(i);
+ WndChangeColumns(wcDelete,i);
+// update_list(listhwnd);
+
+ if i=qsopt.numcolumns then dec(i);
+ ListView_SetItemState(listhwnd,i,
+ LVIS_FOCUSED+LVIS_SELECTED,LVIS_FOCUSED+LVIS_SELECTED);
+ end;
+
+ IDC_UP: begin
+ itemsel:=getselecteditem(listhwnd);
+ if itemsel>0 then
+ begin
+ LV_MoveItem(listhwnd,-1,itemsel);
+ move(qsopt.columns[itemsel] ,tmpcol ,SizeOf(tcolumnitem));
+ move(qsopt.columns[itemsel-1],qsopt.columns[itemsel] ,SizeOf(tcolumnitem));
+ move(tmpcol ,qsopt.columns[itemsel-1],SizeOf(tcolumnitem));
+ WndChangeColumns(wcUp,itemsel);
+ CheckDirection(Dialog,itemsel-1);
+ end;
+ end;
+
+ IDC_DN: begin
+ itemsel:=getselecteditem(listhwnd);
+ if (itemsel>=0) and (itemsel<(qsopt.numcolumns-1)) then
+ begin
+ LV_MoveItem(listhwnd,1,itemsel);
+ move(qsopt.columns[itemsel] ,tmpcol ,SizeOf(tcolumnitem));
+ move(qsopt.columns[itemsel+1],qsopt.columns[itemsel] ,SizeOf(tcolumnitem));
+ move(tmpcol ,qsopt.columns[itemsel+1],SizeOf(tcolumnitem));
+ WndChangeColumns(wcDown,itemsel);
+ CheckDirection(Dialog,itemsel+1);
+ end;
+ end;
+
+ IDC_SETITEM: begin
+ WndChangeColumns(wcChange,savecuritem(Dialog));
+ end;
+
+ IDC_DEFAULT: begin
+ InitDlg:=true;
+ loaddefaultcolumns;
+ update_list(listhwnd);
+ WndChangeColumns(wcRefresh);
+ InitDlg:=false;
+ end;
+
+ IDC_RELOAD: begin
+ InitDlg:=true;
+ loadopt_db(false);
+ update_list(listhwnd);
+ WndChangeColumns(wcRefresh);
+ InitDlg:=false;
+ end;
+ else
+ result:=0;
+ end;
+ end;
+// else
+// result:=DefWindowProc(Dialog,hMessage,wParam,lParam);
+ end;
+ DefWindowProc(Dialog,hMessage,wParam,lParam);
+end;
+
+procedure OptChangeColumns(code:integer;column,data:integer);
+begin
+ case code of
+ wcUp: begin
+ SendMessage(maindlg,WM_MYSHOWHIDEITEM,column,data);
+ end;
+
+ wcShow: begin
+ SendMessage(maindlg,WM_MYSHOWHIDEITEM,column,data);
+ end;
+ end;
+end;
+
+end.
diff --git a/plugins/QuickSearch/sr_window.pas b/plugins/QuickSearch/sr_window.pas new file mode 100644 index 0000000000..5df340f575 --- /dev/null +++ b/plugins/QuickSearch/sr_window.pas @@ -0,0 +1,2943 @@ +unit sr_window;
+
+interface
+
+uses windows,m_api;
+
+function OpenSrWindow(apattern:PWideChar;flags:LPARAM):boolean;
+function BringToFront:integer;
+function CloseSrWindow:boolean;
+procedure WndChangeColumns(code:integer;column:integer=-1);
+
+function OnContactAdded (wParam:WPARAM;lParam:LPARAM):int;cdecl;
+function OnStatusChanged (wParam:WPARAM;lParam:LPARAM):int;cdecl;
+function OnContactDeleted(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+function OnAccountChanged(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+procedure RegisterColors;
+
+const
+ grid:HWND = 0;
+
+implementation
+
+uses messages,commctrl,sr_global,common,dbsettings,mirutils,
+ wrapper,sr_optdialog,protocols;
+
+const
+ flt_show_offline = $100;
+const
+ strCListDel:PAnsiChar='CList/DeleteContactCommand';
+const
+ LVS_EX_LABELTIP = $4000;
+const
+ hIconF :HICON = 0;
+ hIconM :HICON = 0;
+ mainwnd :HWND = 0;
+ StatusBar:HWND = 0;
+ sortcoldn:THANDLE = 0;
+ sortcolup:THANDLE = 0;
+ gridbrush:HBRUSH = 0;
+const
+ OldLVProc :pointer = nil;
+ OldProc :pointer = nil;
+ OldEditProc:pointer = nil;
+const
+ pattern:pWideChar = nil;
+const
+ QSF_INLIST = $0001; // in constant list
+ QSF_ACTIVE = $0002; // contact in listview
+ QSF_DELETED = $0004; // contact deleted
+ QSF_PATTERN = $0008; // pattern check passed
+ QSF_ACCDEL = $0010; // account deleted
+ QSF_ACCOFF = $0020; // account disabled
+ QSF_META = $0040; // contact is metacontact
+ QSF_SUBMETA = $0080; // contact is part of metacontact
+
+type
+ pQSRec = ^tQSRec;
+ tQSRec = record // cell
+ text:PWideChar;
+ data:uint_ptr;
+ end;
+ pQSFRec = ^tQSFRec;
+ tQSFRec = record // row
+ contact:THANDLE;
+ proto :uint_ptr;
+ flags :dword;
+ status :dword;
+ wparam :WPARAM;
+ lparam :LPARAM;
+ end;
+var
+ colorhook:THANDLE;
+ MainBuf:array of array of tQSRec;
+ FlagBuf:array of tQSFRec;
+ LastMeta:integer;
+ tstrMale,
+ tstrFemale,
+ tstrUnknown:PWideChar;
+ colorder:array of integer;
+ tablecolumns:integer;
+
+const
+ maxpattern = 8;
+var
+ patterns:array [0..maxpattern-1] of record
+ str:PWideChar;
+ res:bool;
+ end;
+const
+ patstr:PWideChar=nil;
+ numpattern:integer=0;
+
+const
+ TIMERID_HOVER = 10;
+const
+ TTShowed:bool=false;
+ TTInstalled:bool = false;
+
+const
+ bkg_norm:pAnsiChar = 'Normal background';
+ fgr_norm:pAnsiChar = 'Normal foreground';
+ bkg_odd :pAnsiChar = 'Odd background';
+ fgr_odd :pAnsiChar = 'Odd foreground';
+ bkg_dis :pAnsiChar = 'Disabled account background';
+ fgr_dis :pAnsiChar = 'Disabled account foreground';
+ bkg_del :pAnsiChar = 'Deleted account background';
+ fgr_del :pAnsiChar = 'Deleted account foreground';
+ bkg_hid :pAnsiChar = 'Hidden contact background';
+ fgr_hid :pAnsiChar = 'Hidden contact foreground';
+ bkg_meta:pAnsiChar = 'Metacontact background';
+ fgr_meta:pAnsiChar = 'Metacontact foreground';
+ bkg_sub :pAnsiChar = 'SubMetacontact background';
+ fgr_sub :pAnsiChar = 'SubMetacontact foreground';
+
+var
+ cbkg_norm,
+ cfgr_norm,
+ cbkg_odd,
+ cfgr_odd,
+ cbkg_dis,
+ cfgr_dis,
+ cbkg_del,
+ cfgr_del,
+ cbkg_hid,
+ cfgr_hid,
+ cbkg_meta,
+ cfgr_meta,
+ cbkg_sub,
+ cfgr_sub:TCOLORREF;
+ AdvFilter:cardinal;
+
+function GetQSColumn(item:integer):LPARAM;
+var
+ i:integer;
+begin
+ for i:=0 to qsopt.numcolumns-1 do
+ begin
+ if colorder[i]=item then
+ begin
+ result:=i;
+ exit;
+ end;
+ end;
+ result:=-1;
+end;
+{
+procedure SwitchOrder(var src,dst:array of dword);
+var
+ i:integer;
+begin
+ for i:=0 to HIGH(src) do
+ begin
+ dst[src[i]]:=i;
+ end;
+end;
+}
+procedure ShiftColumns(item,shift:integer); // item - table item, order - new screen order
+var
+ i,col:integer;
+ buf:tQSRec;
+ lsize,lshift:integer;
+begin
+ col:=-1;
+ lshift:=0;
+ for i:=0 to qsopt.numcolumns-1 do
+ begin
+ if (qsopt.columns[i].flags and COL_ON)<>0 then
+ begin
+ if shift=0 then
+ col:=i; // new position
+ dec(shift);
+ end;
+ if colorder[i]=item then
+ begin
+ lshift:=i; // column in buffer
+ end;
+ end;
+ item:=lshift;
+ shift:=col-item;
+
+ col:=colorder[item];
+ lsize:=sizeof(tQSRec)*abs(shift);
+ lshift:=item+shift;
+ if shift>0 then
+ begin
+ for i:=0 to HIGH(MainBuf) do
+ begin
+ buf:=MainBuf[i,item];
+ move(MainBuf[i,item+1],MainBuf[i,item],lsize);
+ MainBuf[i,lshift]:=buf;
+ end;
+
+ move(colorder[item+1],colorder[item],SizeOf(integer)*shift);
+ end
+ else // shift<0
+ begin
+ for i:=0 to HIGH(MainBuf) do
+ begin
+ buf:=MainBuf[i,item];
+ move(MainBuf[i,lshift],MainBuf[i,lshift+1],lsize);
+ MainBuf[i,lshift]:=buf;
+ end;
+
+ move(colorder[lshift],colorder[lshift+1],sizeof(integer)*(-shift));
+ end;
+ colorder[lshift]:=col;
+ OptChangeColumns(wcUp,item,shift);
+end;
+
+function GetColor(name:pAnsiChar):TCOLORREF;
+var
+ cid:TColourID;
+begin
+ cid.cbSize:=SizeOf(cid);
+ StrCopy(cid.group,'QuickSearch');
+ StrCopy(cid.name ,name);
+ result:=CallService(MS_COLOUR_GETA,lparam(@cid),0);
+end;
+
+procedure RegisterColors;
+var
+ cid:TColourID;
+begin
+ cid.cbSize:=SizeOf(cid);
+ cid.flags :=0;
+ StrCopy(cid.group,'QuickSearch');
+ StrCopy(cid.dbSettingsGroup,qs_module);
+
+ StrCopy(cid.name ,bkg_norm);
+ StrCopy(cid.setting,'back_norm');
+ cid.defcolour:=$00FFFFFF;
+ cid.order :=0;
+ ColourRegister(@cid);
+
+ StrCopy(cid.name ,fgr_norm);
+ StrCopy(cid.setting,'fore_norm');
+ cid.defcolour:=$00000000;
+ cid.order :=1;
+ ColourRegister(@cid);
+
+ StrCopy(cid.name ,bkg_odd);
+ StrCopy(cid.setting,'back_odd');
+ cid.defcolour:=$00EBE6DE;
+ cid.order :=2;
+ ColourRegister(@cid);
+
+ StrCopy(cid.name ,fgr_odd);
+ StrCopy(cid.setting,'fore_odd');
+ cid.defcolour:=$00000000;
+ cid.order :=3;
+ ColourRegister(@cid);
+
+ StrCopy(cid.name ,bkg_dis);
+ StrCopy(cid.setting,'back_dis');
+ cid.defcolour:=$008080FF;
+ cid.order :=4;
+ ColourRegister(@cid);
+
+ StrCopy(cid.name ,fgr_dis);
+ StrCopy(cid.setting,'fore_dis');
+ cid.defcolour:=$00000000;
+ cid.order :=5;
+ ColourRegister(@cid);
+
+ StrCopy(cid.name ,bkg_del);
+ StrCopy(cid.setting,'back_del');
+ cid.defcolour:=$008000FF;
+ cid.order :=6;
+ ColourRegister(@cid);
+
+ StrCopy(cid.name ,fgr_del);
+ StrCopy(cid.setting,'fore_del');
+ cid.defcolour:=$00000000;
+ cid.order :=7;
+ ColourRegister(@cid);
+
+ StrCopy(cid.name ,bkg_hid);
+ StrCopy(cid.setting,'back_hid');
+ cid.defcolour:=$0080FFFF;
+ cid.order :=8;
+ ColourRegister(@cid);
+
+ StrCopy(cid.name ,fgr_hid);
+ StrCopy(cid.setting,'fore_hid');
+ cid.defcolour:=$00000000;
+ cid.order :=9;
+ ColourRegister(@cid);
+
+ StrCopy(cid.name ,bkg_meta);
+ StrCopy(cid.setting,'back_meta');
+ cid.defcolour:=$00BAE699;
+ cid.order :=10;
+ ColourRegister(@cid);
+
+ StrCopy(cid.name ,fgr_meta);
+ StrCopy(cid.setting,'fore_meta');
+ cid.defcolour:=$00000000;
+ cid.order :=11;
+ ColourRegister(@cid);
+
+ StrCopy(cid.name ,bkg_sub);
+ StrCopy(cid.setting,'back_sub');
+ cid.defcolour:=$00B3CCC1;
+ cid.order :=12;
+ ColourRegister(@cid);
+
+ StrCopy(cid.name ,fgr_sub);
+ StrCopy(cid.setting,'fore_sub');
+ cid.defcolour:=$00000000;
+ cid.order :=13;
+ ColourRegister(@cid);
+end;
+
+function int2strw(i:integer):PWideChar;
+var
+ buf:array [0..31] of WideChar;
+begin
+ IntToStr(buf,i);
+ StrDupW(result,buf);
+end;
+
+function int2hexw(i:integer):PWideChar;
+var
+ buf:array [0..31] of WideChar;
+begin
+ IntToHex(buf,i);
+ StrDupW(result,buf);
+end;
+
+function BuildLastSeenTime(cont:THANDLE;modulename:PAnsiChar):PWideChar;
+
+var
+ buf:array [0..19] of WideChar;
+ pc:pWideChar;
+ year:integer;
+begin
+ pc:=@buf;
+ year:=DBReadWord(cont,modulename,'Year',0);
+ if year<>0 then
+ begin
+ IntToStr(pc,DBReadWord(cont,modulename,'Day',0),2);
+ inc(pc,2);
+ pc^:='.'; inc(pc);
+ IntToStr(pc,DBReadWord(cont,modulename,'Month',0),2);
+ inc(pc,2);
+ pc^:='.'; inc(pc);
+ IntToStr(pc,year,4);
+ inc(pc,4);
+ pc^:=' '; inc(pc);
+ pc^:='-'; inc(pc);
+ pc^:=' '; inc(pc);
+ IntToStr(pc,DBReadWord(cont,modulename,'Hours',0),2);
+ inc(pc,2);
+ pc^:=':'; inc(pc);
+ IntToStr(pc,DBReadWord(cont,modulename,'Minutes',0),2);
+
+ StrDupW(result,@buf);
+ end
+ else
+ result:=nil;
+{
+var
+ vars:array [0..4] of uint_ptr;
+begin
+ vars[2]:=DBReadWord(cont,modulename,'Year',0);
+ if vars[2]<>0 then
+ begin
+ mGetMem(result,20*SizeOf(WideChar));
+ vars[1]:=DBReadWord(cont,modulename,'Month' ,0);
+ vars[0]:=DBReadWord(cont,modulename,'Day' ,0);
+ vars[3]:=DBReadWord(cont,modulename,'Hours' ,0);
+ vars[4]:=DBReadWord(cont,modulename,'Minutes',0);
+ wvsprintfw(result,'%.2lu.%.2lu.%.4lu - %.2lu:%.2lu',@vars);
+ end
+ else
+ result:=nil;
+}
+end;
+
+function BuildLastSeenTimeInt(cont:thandle;modulename:PAnsiChar):cardinal;
+var
+ Day,Month,Year,Hours,Minutes:word;
+begin
+ Year:=DBReadWord(cont,modulename,'Year',0);
+ if Year<>0 then
+ begin
+ Month :=DBReadWord(cont,modulename,'Month' ,0);
+ Day :=DBReadWord(cont,modulename,'Day' ,0);
+ Hours :=DBReadWord(cont,modulename,'Hours' ,0);
+ Minutes:=DBReadWord(cont,modulename,'Minutes',0);
+ result:=Minutes+Hours*60+Day*60*24+Month*60*24*31+(Year-1980)*60*24*31*356; // was 366
+ end
+ else
+ result:=0;
+end;
+
+function IPtoStr(ip:dword):PWideChar;
+var
+ buf:array [0..16] of WideChar;
+ p:PWideChar;
+begin
+ p:=@buf;
+ IntToStr(buf,ip shr 24);
+ while p^<>#0 do inc(p); p^:='.'; inc(p);
+ IntToStr(p,(ip shr 16) and $FF);
+ while p^<>#0 do inc(p); p^:='.'; inc(p);
+ IntToStr(p,HIByte(ip));
+ while p^<>#0 do inc(p); p^:='.'; inc(p);
+ IntToStr(p,LOByte(ip));
+ StrDupW(result,buf);
+end;
+
+function TimeToStrW(data:dword):PWideChar;
+var
+ strdatetime:array [0..63] of WideChar;
+ dbtts:TDBTIMETOSTRING;
+begin
+ dbtts.cbDest :=sizeof(strdatetime);
+ dbtts.szDest.w :=@strdatetime;
+ dbtts.szFormat.w:='d - t';
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT,data,lparam(@dbtts));
+ StrDupW(result,strdatetime);
+end;
+
+function FindMeta(hMeta:THANDLE;var MetaNum:WPARAM):LPARAM;
+var
+ i:integer;
+begin
+ result:=0;
+ for i:=0 to HIGH(FlagBuf) do
+ begin
+ with FlagBuf[i] do
+ begin
+ if contact=hMeta then
+ begin
+ if wparam=0 then // new meta
+ begin
+ inc(LastMeta);
+ wparam :=LastMeta;
+ lparam :=0;
+ end;
+ MetaNum:=wparam;
+ inc(lparam);
+ result:=lparam;
+ break;
+ end;
+ end;
+ end;
+end;
+
+function DoMeta(hContact:THANDLE):pointer;
+var
+ pw:pWideChar;
+ i:integer;
+begin
+ result:=nil;
+ for i:=0 to HIGH(FlagBuf) do
+ begin
+ with FlagBuf[i] do
+ begin
+ if contact=hContact then
+ begin
+ if (flags and QSF_META)<>0 then // adding new meta count
+ begin
+ if wparam=0 then
+ begin
+ inc(LastMeta);
+ wparam:=LastMeta;
+// lparam:=0;
+ end;
+ end
+ else if (flags and QSF_SUBMETA)<>0 then
+ begin
+ lparam:=FindMeta(CallService(MS_MC_GETMETACONTACT,hContact,0),wparam);
+ end;
+
+ if wparam>0 then
+ begin
+ mGetMem(result,32);
+ pw:=result;
+ pw[0]:='[';
+ IntToStr(pw+1,wparam,3);
+ pw[4]:=']';
+ if lparam>0 then
+ begin
+ pw[5]:=' ';
+ IntToStr(pw+6,lparam);
+ end
+ else
+ pw[5]:=#0;
+ end;
+ break;
+ end;
+ end;
+ end;
+end;
+
+procedure LoadOneItem(hContact:THANDLE;num:integer;proto:integer; var res:tQSRec);
+var
+ cni:TCONTACTINFO;
+ dbei:TDBEVENTINFO;
+ hDbEvent:cardinal;
+ tmp:int_ptr;
+ protov:PAnsiChar;
+begin
+ FillChar(res,SizeOf(tQSRec),0);
+ res.data:=dword(-1);
+ res.text:=nil;
+ with qsopt.columns[num] do
+ begin
+
+ if module_name<>nil then
+ protov:=module_name
+ else
+ protov:=GetProtoName(proto);
+
+ case setting_type of
+ ST_METACONTACT: begin
+ res.text:=DoMeta(hContact);
+ end;
+
+ ST_SCRIPT: begin
+ res.text:=ParseVarString(wparam.w,hContact);
+ end;
+
+ ST_SERVICE: begin
+ if wparam._type=ptCurrent then wparam.n:=hContact;
+ if lparam._type=ptCurrent then lparam.n:=hContact;
+ tmp:=CallService(protov,wparam.n,lparam.n);
+ if int_ptr(tmp)=int_ptr(CALLSERVICE_NOTFOUND) then exit;
+ case setting_cnftype of
+ ptString: begin
+ AnsiToWide(PAnsiChar(tmp),res.text);
+ end;
+ ptUnicode: begin
+ StrDupW(res.text,PWideChar(tmp));
+ end;
+ ptNumber,ptInteger:begin
+ res.data:=tmp;
+ res.text:=int2strw(tmp);
+ end;
+ end;
+ end;
+
+ ST_CONTACTINFO: begin
+ FillChar(cni,SizeOf(cni),0);
+ cni.cbSize :=sizeof(cni);
+ cni.dwFlag:=setting_cnftype or CNF_UNICODE;
+ cni.hContact:=hContact;
+ cni.szProto :=GetProtoName(proto);
+ if CallService(MS_CONTACT_GETCONTACTINFO,0,tlparam(@cni))=0 then
+ begin
+ case cni._type of
+ CNFT_ASCIIZ: begin
+ if cni.retval.szVal.w<>nil then
+ begin
+ StrDupW(res.text,cni.retval.szVal.w);
+ mir_free(cni.retval.szVal.w);
+ end;
+ exit;
+ end;
+ CNFT_BYTE :begin
+ res.data:=cni.retval.bVal;
+ if setting_cnftype=CNF_GENDER then
+ begin
+ if not (res.data in [70,77]) then
+ res.data:=DBReadByte(hContact,'UserInfo','Gender',0);
+ exit;
+ end
+ end;
+ CNFT_WORD :res.data:=cni.retval.wVal;
+ CNFT_DWORD:res.data:=cni.retval.dVal;
+ end;
+ res.text:=int2strw(res.data);
+ end;
+ end;
+
+ ST_STRING: begin
+ res.text:=DBReadUnicode(hContact,protov,wparam.a,nil)
+ end;
+
+ ST_BYTE: begin
+ res.data:=DBReadByte(hContact,protov,wparam.a,0);
+ res.text:=int2strw(res.data);
+ end;
+
+ ST_WORD: begin
+ res.data:=DBReadWord(hContact,protov,wparam.a,0);
+ res.text:=int2strw(res.data);
+ end;
+
+ ST_INT: begin
+ if (module_name=nil) and (wparam.a=nil) then
+ begin
+ res.data:=hContact;
+ res.text:=int2hexw(res.data);
+ end
+ else
+ begin
+ res.data:=DBReadDWord(hContact,protov,wparam.a,0);
+ res.text:=int2strw(res.data);
+ end;
+ end;
+
+ ST_LASTSEEN: begin
+ res.data:=BuildLastSeenTimeInt(hContact,protov);
+ res.text:=BuildLastSeenTime (hContact,protov);
+ end;
+
+ ST_IP: begin
+ res.data:=DBReadDWord(hContact,protov,wparam.a,0);
+ res.text:=IPtoStr(res.data);
+ end;
+
+ ST_TIMESTAMP: begin
+ res.data:=DBReadDWord(hContact,protov,wparam.a,0);
+ if res.data<>0 then
+ res.text:=TimeToStrW(res.data);
+ end;
+
+ ST_LASTEVENT: begin
+ hDbEvent:=CallService(MS_DB_EVENT_FINDLAST,hContact,0);
+ if hDbEvent<>0 then
+ begin
+ ZeroMemory(@dbei,sizeof(dbei));
+ dbei.cbSize:=SizeOf(dbei);
+ CallService(MS_DB_EVENT_GET,hDbEvent,tlparam(@dbei));
+ res.data:=dbei.timestamp;
+ res.text:=TimeToStrW(res.data);
+ end
+ else
+ res.data:=0;
+ end;
+ end;
+ end;
+end;
+
+function CompareItem(lParam1,lParam2:LPARAM;SortType:LPARAM):int; stdcall;
+var
+ typ1,typ2:boolean;
+ res1,res2:pQSRec;
+ i1,i2:uint_ptr;
+begin
+ result:=0;
+ if SortType=StatusSort then //sort by status
+ begin
+ i1:=FlagBuf[lParam1].status;
+ i2:=FlagBuf[lParam2].status;
+ // offline - to the end
+ if i1=ID_STATUS_OFFLINE then i1:=ID_STATUS_OFFLINE+64;
+ if i2=ID_STATUS_OFFLINE then i2:=ID_STATUS_OFFLINE+64;
+ // not string parameters
+ typ1:=false;
+ typ2:=false;
+ end
+ else
+ begin
+ res1:=@MainBuf[lParam1,SortType];
+ res2:=@MainBuf[lParam2,SortType];
+ i1 := res1^.data;
+ i2 := res2^.data;
+ typ1:=i1=uint_ptr(-1);
+ typ2:=i2=uint_ptr(-1);
+
+ if (typ1 and typ2) then // string & string
+ begin
+ if (res2.text=nil) and (res1.text=nil) then // nil
+ result:=0
+ else if res2.text=nil then
+ result:=1
+ else if res1.text=nil then
+ result:=-1
+ else
+ result:=lstrcmpiw(res1.text,res2.text);
+ end
+ else if typ1 or typ2 then // string & num
+ begin
+ if typ1 then
+ result:=1
+ else
+ result:=-1;
+ end;
+ end;
+ if not (typ1 or typ2) then // not strings
+ begin
+ if i1>i2 then
+ result:=1
+ else if i1<i2 then
+ result:=-1
+ else
+ result:=0;
+ end;
+ if not qsopt.ascendsort then
+ result:=-result;
+end;
+
+function FindBufNumber(hContact:THANDLE):integer;
+var
+ i:integer;
+begin
+ for i:=0 to HIGH(FlagBuf) do
+ begin
+ if FlagBuf[i].contact=hContact then
+ begin
+ result:=i;
+ exit;
+ end;
+ end;
+ result:=-1;
+end;
+
+function FindItem(num:integer):integer;
+var
+ fi:LV_FINDINFO;
+begin
+ if num>=0 then
+ begin
+ FillChar(fi,SizeOf(fi),0);
+ fi.flags :=LVFI_PARAM;
+ fi.lParam:=num;
+ result:=SendMessage(grid,LVM_FINDITEM,wparam(-1),lparam(@fi));
+ end
+ else
+ result:=num;
+end;
+
+procedure AddContactToList(hContact:THANDLE;num:integer);
+var
+ i:integer;
+ li:LV_ITEMW;
+begin
+ FillChar(li,SizeOf(li),0);
+ li.iItem :=100000; //!! need append
+ li.mask :=LVIF_IMAGE or LVIF_PARAM;
+ li.iImage:=CallService(MS_CLIST_GETCONTACTICON,hContact,0);
+ li.lParam:=num;
+ li.iItem :=SendMessageW(grid,LVM_INSERTITEMW,0,lparam(@li));
+
+ li.iImage:=0;
+ for i:=0 to qsopt.numcolumns-1 do
+ begin
+ if (qsopt.columns[i].flags and COL_ON)<>0 then
+ begin
+ // Client icons preprocess
+ li.pszText :=MainBuf[num,i].text;
+ if (((qsopt.columns[i].flags and COL_CLIENT)<>0) and
+ (li.pszText<>NIL) and qsopt.showclienticons) OR
+ ((qsopt.columns[i].flags and (COL_XSTATUS or COL_GENDER))<>0) then
+ li.mask:=LVIF_IMAGE or LVIF_TEXT
+ else
+ li.mask:=LVIF_TEXT;
+ li.iSubItem:=colorder[i];
+ SendMessageW(grid,LVM_SETITEMW,0,lparam(@li));
+ end;
+ end;
+end;
+
+type
+ pSBDataRecord = ^tSBDataRecord;
+ tSBDataRecord = record
+ flags :cardinal;
+ total :cardinal; // in clist
+ found :cardinal; // by pattern
+ online:cardinal; // clist online
+ liston:cardinal; // pattern online
+ end;
+ tSBData = array [0..63] of tSBDataRecord;
+
+procedure DrawSBW(const SBData:tSBData);
+var
+ aPartPos:array [0..63 ] of integer;
+ buf :array [0..255] of WideChar;
+ fmtstr :array [0..255] of WideChar;
+ all:integer;
+ i,j:integer;
+ p,pc,po,pd,poff,pa:PWideChar;
+ rc:TRECT;
+ dc:HDC;
+ icon:HICON;
+ protocnt:integer;
+begin
+ p:=@buf;
+ p:=StrEndW(IntToStr(p,SBData[0].found));
+ p:=StrCopyEW(p,TranslateW(' users found ('));
+ p:=StrEndW(IntToStr(p,Length(FlagBuf)));
+ p:=StrCopyEW(p,TranslateW(') Online: '));
+ IntToStr(p,SBData[0].online);
+
+ dc:=GetDC(StatusBar);
+ DrawTextW(dc,pWidechar(@buf),-1,rc,DT_CALCRECT);
+ ReleaseDC(StatusBar,dc);
+ all:=rc.right-rc.left;
+ aPartPos[0]:=all;
+ protocnt:=GetNumProto;
+ i:=1;
+ while i<=protocnt do
+ begin
+ inc(all,55);
+ aPartPos[i]:=all;
+ inc(i);
+ end;
+ aPartPos[i]:=-1;
+ SendMessageW(StatusBar,SB_SETPARTS,protocnt+2,lparam(@aPartPos));
+ SendMessageW(StatusBar,SB_SETTEXTW,0,lparam(@buf));
+
+ po :=TranslateW('Online');
+ pd :=TranslateW('deleted');
+ poff:=TranslateW('off');
+ pa :=TranslateW('active');
+
+ for i:=1 to protocnt do
+ begin
+ if ((SBData[i].flags and (QSF_ACCDEL or QSF_ACCOFF))<>0) then
+ begin
+ icon:=CallService(MS_SKIN_LOADPROTOICON,0,ID_STATUS_OFFLINE);
+ end
+ else
+ begin
+ icon:=CallService(
+ MS_SKIN_LOADPROTOICON,wparam(GetProtoName(i)),ID_STATUS_ONLINE);
+ end;
+
+ FastAnsiToWideBuf(GetProtoName(i),fmtstr);
+
+ SendMessageW(StatusBar,SB_SETICON,i,icon);
+
+ j:=High(buf);//(SizeOf(buf) div SizeOf(WideChar))-1;
+ buf[j]:=#0;
+
+ // fill by spaces
+ p:=@buf[0];
+ while j>0 do
+ begin
+ dec(j);
+ p^:=' ';
+ inc(p);
+ end;
+
+ if (SBData[i].flags and QSF_ACCDEL)<>0 then
+ begin
+ buf [0]:='!';
+ pc:=pd;
+ end
+ else if (SBData[i].flags and QSF_ACCOFF)<>0 then
+ begin
+ buf [0]:='?';
+ pc:=poff
+ end
+ else
+ pc:=pa;
+
+ IntToStr(pWideChar(@buf[2]),SBData[i].found);
+ StrEndW(buf)^:=' ';
+ SendMessageW(StatusBar,SB_SETTEXTW,i,lparam(@buf));
+
+// create tooltip
+ p:=@buf;
+ p:=StrCopyEW(p,fmtstr); // Protocol
+ p^:=' '; inc(p);
+ p^:='('; inc(p);
+ p:=StrCopyEW(p,pc); // Protocol status
+ p^:=')'; inc(p);
+ p^:=':'; inc(p);
+ p^:=' '; inc(p);
+
+ with SBData[i] do
+ begin
+ p:=StrEndW(IntToStr(p,found));
+ p^:=' '; inc(p);
+ p^:='('; inc(p);
+ p:=StrEndW(IntToStr(p,total));
+ p^:=')'; inc(p);
+ p^:=';'; inc(p);
+ p^:=' '; inc(p);
+ p:=StrCopyEW(p,po);
+ p^:=' '; inc(p);
+ p:=StrEndW(IntToStr(p,liston));
+ p^:=' '; inc(p);
+ p^:='('; inc(p);
+ p:=StrEndW(IntToStr(p,online));
+ p^:=')'; inc(p);
+ end;
+ p^:=#0;
+ SendMessageW(StatusBar,SB_SETTIPTEXTW,i,lparam(@buf));
+ end;
+
+end;
+
+procedure UpdateSB;
+var
+ SBData: tSBData;
+ j:integer;
+ p:pSBDataRecord;
+begin
+ FillChar(SBData,SizeOf(SBData),0);
+
+ // for all contacts
+ for j:=0 to HIGH(FlagBuf) do
+ begin
+ p:=@SBData[FlagBuf[j].proto];
+ p^.flags:=FlagBuf[j].flags;
+
+ inc(p^.total);
+
+ if (p^.flags and QSF_ACTIVE)<>0 then
+ begin
+ inc(p^.found);
+ inc(SBData[0].found);
+ end;
+
+ if FlagBuf[j].status<>ID_STATUS_OFFLINE then
+ begin
+ inc(p^.online);
+ inc(SBData[0].online);
+ if (p^.flags and QSF_ACTIVE)<>0 then
+ begin
+ inc(p^.liston);
+ inc(SBData[0].liston);
+ end;
+ end;
+
+ end;
+
+ DrawSBW(SBData);
+end;
+
+procedure Sort;
+begin
+ if qsopt.columnsort>=tablecolumns then
+ qsopt.columnsort:=StatusSort;
+
+ SendMessage(grid,LVM_SORTITEMS,GetQSColumn(qsopt.columnsort),LPARAM(@CompareItem));
+// ListView_SortItems(grid,@CompareItem,GetQSColumn(qsopt.columnsort));
+
+ if (qsopt.columnsort<>StatusSort) and qsopt.sortbystatus then
+ SendMessage(grid,LVM_SORTITEMS,StatusSort,LPARAM(@CompareItem));
+// ListView_SortItems(grid,@CompareItem,StatusSort);
+end;
+
+procedure MakePatternW;
+var
+ wasquote:bool;
+ lpatptr:PWideChar;
+begin
+ numpattern:=0;
+ mFreeMem(patstr);
+ if (pattern<>nil) and (pattern^<>#0) then
+ begin
+ wasquote:=false;
+ StrDupW(patstr,pattern);
+ lpatptr:=patstr;
+ repeat
+ while lpatptr^=' ' do inc(lpatptr);
+ if lpatptr^<>#0 then
+ begin
+ if lpatptr^='"' then
+ begin
+ inc(lpatptr);
+ wasquote:=true;
+ end
+ else
+ begin
+ patterns[numpattern].str:=lpatptr;
+ inc(numpattern);
+ while lpatptr^<>#0 do
+ begin
+ if wasquote then
+ begin
+ if lpatptr^='"' then
+ begin
+ wasquote:=false;
+ break;
+ end;
+ end
+ else if lpatptr^=' ' then
+ break;
+ inc(lpatptr);
+ end;
+ if lpatptr^<>#0 then
+ begin
+ lpatptr^:=#0;
+ inc(lpatptr);
+ end;
+ end;
+ if numpattern=maxpattern then break;
+ end;
+ until lpatptr^=#0;
+ end;
+end;
+
+function CheckPatternW(cnt:integer):boolean;
+var
+ lstr:array [0..1023] of WideChar;
+ i,j:integer;
+begin
+ if numpattern>0 then
+ begin
+ for i:=0 to numpattern-1 do
+ patterns[i].res:=false;
+
+ for i:=0 to qsopt.numcolumns-1 do
+ begin
+ if ((qsopt.columns[i].flags and COL_ON)<>0) and
+ (MainBuf[cnt,i].text<>nil) then
+ begin
+ StrCopyW(lstr,MainBuf[cnt,i].text,HIGH(lstr));
+ CharLowerW(lstr);
+ for j:=0 to numpattern-1 do
+ if not patterns[j].res then
+ begin
+ if StrPosW(lstr,patterns[j].str)<>nil then //!!
+ patterns[j].res:=true;
+ end;
+ end;
+ end;
+
+ result:=true;
+ for i:=0 to numpattern-1 do
+ result:=result and patterns[i].res;
+ end
+ else
+ result:=true;
+end;
+
+procedure ProcessLine(num:integer;test:boolean=true);
+var
+ p:pQSFRec;
+ l:boolean;
+begin
+ p:=@FlagBuf[num];
+ if (p^.flags and QSF_DELETED)<>0 then
+ exit;
+
+ if qsopt.showonlyinlist then
+ begin
+ if (p^.flags and QSF_INLIST)=0 then
+ exit;
+ end;
+
+ if test then
+ begin
+ l:=CheckPatternW(num);
+ if l then
+ p^.flags:=p^.flags or QSF_PATTERN
+ else
+ p^.flags:=p^.flags and not QSF_PATTERN;
+ end
+ else
+ l:=(p^.flags and QSF_PATTERN)<>0;//true;
+
+ if l then
+ begin
+ if (p^.flags and QSF_ACTIVE)=0 then
+ begin
+ if (qsopt.showoffline) or (p^.status<>ID_STATUS_OFFLINE) then
+ begin
+ p^.flags:=p^.flags or QSF_ACTIVE;
+ AddContactToList(p^.contact,num);
+ end;
+ end
+ end
+ else
+ begin
+ if (p^.flags and QSF_ACTIVE)<>0 then
+ begin
+ p^.flags:=p^.flags and not QSF_ACTIVE;
+ ListView_DeleteItem(grid,FindItem(num));
+ end;
+ end;
+end;
+
+function AdvancedFilter:integer;
+var
+ p:pQSFRec;
+ i:integer;
+ show:boolean;
+begin
+ result:=0;
+
+ SendMessage(grid,WM_SETREDRAW,0,0);
+
+ for i:=0 to HIGH(FlagBuf) do
+ begin
+ p:=@FlagBuf[i];
+ // firstly = proto
+ show:=(LoByte(AdvFilter)=0) or (p^.proto=LoByte(AdvFilter));
+ // secondary = show/hide offline
+ show:=show and ((p^.status<>ID_STATUS_OFFLINE) or ((AdvFilter and flt_show_offline)<>0));
+
+ if (p^.flags and QSF_PATTERN)<>0 then
+ begin
+ if show then
+ begin
+ if (p^.flags and QSF_ACTIVE)=0 then
+ ProcessLine(i,false);
+ end
+ else
+ begin
+ p^.flags:=p^.flags and not QSF_ACTIVE;
+ ListView_DeleteItem(grid,FindItem(i));
+ end;
+ end;
+ end;
+
+ SendMessage(grid,WM_SETREDRAW,1,0);
+ InvalidateRect(grid,nil,false);
+
+ Sort;
+ UpdateSB;
+end;
+
+procedure FillGrid;
+var
+ cnt:integer;
+begin
+
+ SendMessage(grid,WM_SETREDRAW,0,0);
+
+ MakePatternW;
+
+ for cnt:=0 to HIGH(FlagBuf) do
+ ProcessLine(cnt);
+
+ SendMessage(grid,WM_SETREDRAW,1,0);
+ InvalidateRect(grid,nil,false);
+
+ Sort;
+ UpdateSB;
+
+ AdvancedFilter; //!!
+
+ ListView_SetItemState(grid,0,LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+end;
+
+procedure AddContact(num:integer;hContact:THANDLE);
+var
+ i:integer;
+ tmpstr:array [0..63] of AnsiChar;
+begin
+ FillChar(FlagBuf[num],SizeOf(tQSFRec),0);
+ with FlagBuf[num] do
+ begin
+ contact:=hContact;
+ flags :=0;
+ i:=IsContactActive(hContact,tmpstr);
+ proto:=FindProto(tmpstr);
+
+ case i of
+ -2: flags:=flags or QSF_ACCDEL; // deleted account
+ -1: flags:=flags or QSF_ACCOFF; // disabled account
+// 0 : ; // hidden contact
+ 1 : flags:=flags or QSF_META; // metacontact
+ 2 : flags:=flags or QSF_SUBMETA; // subMetacontact
+ end;
+ if i>0 then
+ flags:=flags or QSF_INLIST; // normal contact
+
+ if (proto=0) or (i<0) then
+ status:=ID_STATUS_OFFLINE
+ else
+ status:=DBReadWord(contact,GetProtoName(proto),'Status',ID_STATUS_OFFLINE);
+
+ for i:=0 to qsopt.numcolumns-1 do
+ if (qsopt.columns[i].flags and COL_ON)<>0 then
+ LoadOneItem(contact,i,proto,MainBuf[num,i]);
+ end;
+
+end;
+
+function PrepareToFill:boolean;
+var
+ cnt,cnt1:integer;
+ hContact:THANDLE;
+ i:integer;
+begin
+ result:=false;
+ if qsopt.numcolumns=0 then
+ exit;
+ // calculating contacts
+ cnt:=CallService(MS_DB_CONTACT_GETCOUNT,0,0);
+ if cnt=0 then
+ exit;
+
+ result:=true;
+ // Allocate mem
+ SetLength(MainBuf,cnt,qsopt.numcolumns);
+ SetLength(FlagBuf,cnt);
+
+ // filling buffer
+ LastMeta:=0;
+ cnt1:=0;
+ hContact:=CallService(MS_DB_CONTACT_FINDFIRST,0,0);
+ while hContact<>0 do
+ begin
+ //!! check account
+ AddContact(cnt1,hContact);
+ inc(cnt1);
+ if cnt1=cnt then break; // additional checking
+ hContact:=CallService(MS_DB_CONTACT_FINDNEXT,hContact,0);
+ end;
+ if cnt1<>cnt then
+ begin
+ SetLength(MainBuf,cnt1);
+ SetLength(FlagBuf,cnt1);
+ end;
+
+ SetLength(colorder,qsopt.numcolumns);
+ cnt:=0;
+ for i:=0 to qsopt.numcolumns-1 do
+ begin
+ if (qsopt.columns[i].flags and COL_ON)<>0 then
+ begin
+ colorder[i]:=cnt;
+ inc(cnt);
+ qsopt.columns[i].flags := qsopt.columns[i].flags or COL_INIT;
+ end
+ else
+ colorder[i]:=-1;
+ end;
+
+end;
+
+function GetFocusedhContact:THANDLE;
+var
+ i:integer;
+begin
+ i:=LV_GetLParam(grid);
+ if i=-1 then
+ result:=0
+ else
+ result:=FlagBuf[i].contact;
+end;
+
+procedure ShowContactMsgDlg(hContact:THANDLE);
+begin
+ if hContact<>0 then
+ begin
+ ShowContactDialog(hContact);
+ if qsopt.closeafteraction then DestroyWindow(mainwnd);
+ end;
+end;
+
+procedure DeleteOneContact(hContact:THANDLE);
+begin
+ if ServiceExists(strCListDel)>0 then
+ CallService(strCListDel,hContact,0)
+ else
+ CallService(MS_DB_CONTACT_DELETE,hContact,0);
+end;
+
+procedure DeleteByList;
+var
+ i,j:integer;
+begin
+ j:=ListView_GetItemCount(grid)-1;
+
+ i:=MessageBoxW(0,TranslateW('Do you really want to delete selected contacts?'),
+ TranslateW('Warning'),MB_OKCANCEL+MB_ICONWARNING);
+
+ if i=IDOK then
+ begin
+ SendMessage(grid,WM_SETREDRAW,0,0);
+ for i:=j downto 0 do
+ begin
+ if ListView_GetItemState(grid,i,LVIS_SELECTED)<>0 then
+ CallService(MS_DB_CONTACT_DELETE,FlagBuf[LV_GetLParam(grid,i)].contact,0);
+ end;
+ SendMessage(grid,WM_SETREDRAW,1,0);
+ end;
+end;
+
+procedure ConvertToMeta;
+var
+ i,j:integer;
+ hMeta:THANDLE;
+ tmp:THANDLE;
+begin
+ j:=ListView_GetItemCount(grid)-1;
+
+ hMeta:=0;
+ for i:=j downto 0 do // check
+ begin
+ if ListView_GetItemState(grid,i,LVIS_SELECTED)<>0 then
+ begin
+ tmp:=CallService(MS_MC_GETMETACONTACT,FlagBuf[LV_GetLParam(grid,i)].contact,0);
+ if tmp<>0 then
+ if hMeta=0 then
+ hMeta:=tmp
+ else if tmp<>hMeta then
+ begin
+ MessageBoxW(0,
+ TranslateW('Some of selected contacts in different metacontacts already'),
+ 'Quick Search',MB_ICONERROR);
+ exit;
+ end;
+ end;
+ end;
+
+ if hMeta<>0 then
+ begin
+ i:=MessageBoxW(0,
+ TranslateW('One or more contacts in same Meta already. Try to convert anyway?'),
+ 'Quick Search',MB_YESNO+MB_ICONWARNING);
+ if i<>IDYES then
+ exit;
+ end;
+
+ // convert if needed
+ for i:=j downto 0 do
+ begin
+ if ListView_GetItemState(grid,i,LVIS_SELECTED)<>0 then
+ begin
+ if hMeta=0 then
+ hMeta:=CallService(MS_MC_CONVERTTOMETA,FlagBuf[LV_GetLParam(grid,i)].contact,0)
+ else
+ CallService(MS_MC_ADDTOMETA,FlagBuf[LV_GetLParam(grid,i)].contact,hMeta);
+ end;
+ end;
+end;
+
+procedure MoveToGroup(group:PWideChar);
+var
+ i,j,grcol:integer;
+ contact:THANDLE;
+begin
+ j:=ListView_GetItemCount(grid)-1;
+ grcol:=-1;
+ for i:=0 to qsopt.numcolumns-1 do
+ begin
+ with qsopt.columns[i] do
+ if (setting_type=ST_STRING) and
+ (StrCmp(module_name,'CList')=0) and
+ (StrCmp(wparam.a ,'Group')=0) then
+ begin
+ if (flags and COL_ON)=0 then
+ flags:=flags and not COL_INIT
+ else
+ grcol:=i;
+ break;
+ end
+ end;
+ for i:=0 to j do
+ begin
+ if ListView_GetItemState(grid,i,LVIS_SELECTED)<>0 then
+ begin
+ contact:=FlagBuf[LV_GetLParam(grid,i)].contact;
+ DBWriteUnicode(contact,strCList,'Group',group);
+ if (not qsopt.closeafteraction) and (grcol>=0) then
+ begin
+ LoadOneItem(contact,grcol,0,MainBuf[i,grcol]);
+ end;
+ end;
+ end;
+ if (not qsopt.closeafteraction) and (grcol>=0) then
+ FillGrid;
+end;
+
+function IsColumnMinimized(num:integer):bool;
+begin
+ result:=ListView_GetColumnWidth(grid,num)<=10;
+end;
+
+procedure CopyMultiLinesW(num:integer);
+var
+ i,j,k:integer;
+ p,buf:PWideChar;
+ tmpcnt,cnt:integer;
+begin
+ cnt:=0;
+ if qsopt.exportheaders then
+ begin
+ k:=0;
+ while k<qsopt.numcolumns do
+ begin
+ if not (qsopt.skipminimized and IsColumnMinimized(k)) then
+ inc(cnt,StrLenW(TranslateW(qsopt.columns[k].title))+1);
+ Inc(k);
+ end;
+ if cnt>0 then
+ inc(cnt,2);
+ end;
+ j:=ListView_GetItemCount(grid)-1;
+ tmpcnt:=cnt;
+ for i:=0 to j do
+ begin
+ if ListView_GetItemState(grid,i,LVIS_SELECTED)<>0 then
+ begin
+ k:=0;
+ num:=LV_GetLParam(grid,i);
+ while k<qsopt.numcolumns do
+ begin
+ if not (qsopt.skipminimized and IsColumnMinimized(k)) then
+ inc(cnt,StrLenW(MainBuf[num,k].text)+1);
+ Inc(k);
+ end;
+ end;
+ if tmpcnt<>cnt then
+ inc(cnt,2);
+ end;
+ if cnt=0 then
+ exit;
+
+ inc(cnt);
+ mGetMem(buf,cnt*SizeOf(WideChar));
+ p:=buf;
+
+ if qsopt.exportheaders then
+ begin
+ k:=0;
+ while k<qsopt.numcolumns do
+ begin
+ if not (qsopt.skipminimized and IsColumnMinimized(k)) then
+ begin
+ StrCopyW(p,TranslateW(qsopt.columns[k].title));
+ p:=StrEndW(p);
+ p^:=#9;
+ inc(p);
+ end;
+ inc(k);
+ end;
+ (p-1)^:=#13;
+ p^ :=#10;
+ inc(p);
+ end;
+ for i:=0 to j do
+ begin
+ if ListView_GetItemState(grid,i,LVIS_SELECTED)<>0 then
+ begin
+ k:=0;
+ num:=LV_GetLParam(grid,i);
+ while k<qsopt.numcolumns do
+ begin
+ if not (qsopt.skipminimized and IsColumnMinimized(k)) then
+ begin
+ StrCopyW(p,MainBuf[num,k].text);
+ p:=StrEndW(p);
+ p^:=#9;
+ inc(p);
+ end;
+ inc(k);
+ end;
+ (p-1)^:=#13;
+ p^ :=#10;
+ inc(p);
+ end;
+ end;
+ p^:=#0;
+ CopyToClipboard(buf,false);
+ mFreeMem(buf);
+end;
+
+var
+ HintWnd:HWND;
+
+function NewLVProc(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+const
+ OldHItem :integer=0;
+ OldHSubItem:integer=0;
+var
+ buf :array [0..255] of WideChar; //!! for spec columns and patterns now only
+ buf1:array [0..127] of AnsiChar;
+ p,pp:PWideChar;
+ i,num,cnt:integer;
+ pinfo:LV_HITTESTINFO;
+ TI:TToolInfoW;
+ ics:TICQ_CUSTOM_STATUS;
+
+ info:TCLCINFOTIP;
+// qsr:tQSRec;
+ tmpCursor:TPOINT;
+begin
+ result:=0;
+ case hMessage of
+
+ WM_DESTROY: begin
+ if TTInstalled then
+ KillTimer(Dialog,TIMERID_HOVER);
+ end;
+
+ WM_LBUTTONDBLCLK: begin
+ ShowContactMsgDlg(GetFocusedhContact);
+ exit;
+ end;
+
+ WM_CHAR: begin
+ if wParam=27 then // ESC
+ begin
+ PostMessage(GetParent(Dialog),WM_COMMAND,(BN_CLICKED shl 16)+IDCANCEL,0);
+ exit;
+ end;
+ case wParam of
+ 1: begin
+ ListView_SetItemState(grid,-1,LVIS_SELECTED,LVIS_SELECTED);
+ end;
+ // Ctrl-C
+ 3: begin
+ i:=ListView_GetSelectedCount(grid);
+ if (i>1) or qsopt.singlecsv then
+ begin
+ CopyMultiLinesW(i);
+ exit;
+ end;
+
+ cnt:=0;
+ num:=LV_GetLParam(grid,ListView_GetNextItem(grid,-1,LVNI_FOCUSED));
+ i:=0;
+ while i<qsopt.numcolumns do
+ begin
+ if not (qsopt.skipminimized and IsColumnMinimized(i)) then
+ begin
+ p:=TranslateW(qsopt.columns[i].title);
+ inc(cnt,StrLenW(p)+1);
+ if (StrEndW(p)-1)^<>':' then
+ inc(cnt);
+
+ inc(cnt,StrLenW(MainBuf[num,i].text)+2);
+ end;
+ end;
+ if cnt=0 then
+ exit;
+ mGetMem(pp,(cnt+1)*SizeOf(WideChar));
+ p:=pp;
+
+ i:=0;
+ while i<qsopt.numcolumns do
+ begin
+ if not (qsopt.skipminimized and IsColumnMinimized(i)) then
+ begin
+ StrCopyW(p,TranslateW(qsopt.columns[i].title));
+ p:=StrEndW(p);
+ if (p-1)^<>':' then
+ begin
+ p^:=':';
+ inc(p);
+ end;
+ p^:=' '; inc(p);
+ StrCopyW(p,MainBuf[num,i].text);
+ p:=StrEndW(p);
+ p^:=#13; (p+1)^:=#10; inc(p,2);
+ end;
+ end;
+ p^:=#0;
+
+ CopyToClipboard(pp,false);
+ mFreeMem(pp);
+ exit;
+ end;
+ // backspace
+ 8: begin
+ if pattern<>nil then
+ begin
+ StrCopyW(buf,pattern);
+ p:=StrEndW(buf);
+ (p-1)^:=#0;
+ SetDlgItemTextW(mainwnd,IDC_E_SEARCHTEXT,buf);
+ end;
+ end;
+ // letters
+ 32..127: begin
+ if pattern<>nil then
+ StrCopyW(buf,pattern)
+ else
+ buf[0]:=#0;
+ p:=StrEndW(buf);
+ p^:=WideChar(wParam);
+ (p+1)^:=#0;
+ SetDlgItemTextW(mainwnd,IDC_E_SEARCHTEXT,buf);
+ end;
+ end
+ end;
+
+ WM_TIMER: begin
+ if wParam=TIMERID_HOVER then
+ begin
+ KillTimer(Dialog,TIMERID_HOVER);
+ if GetForegroundWindow<>mainwnd then exit;
+ i:=LV_GetLParam(grid,OldHItem);
+ FillChar(info,SizeOf(info),0);
+ with info do
+ begin
+ cbSize :=SizeOf(info);
+ hItem :=FlagBuf[i].contact;
+ GetCursorPos(ptCursor);
+ tmpCursor :=ptCursor;
+{
+ ptCursor.x:=loword(lParam);
+ ptCursor.y:=hiword(lParam);
+}
+ SendMessage(grid,LVM_GETITEMRECT,OldHItem,tlparam(@rcItem));
+ ScreenToClient(grid,tmpCursor);
+ if not PtInRect(rcItem,tmpCursor) then exit;
+ end;
+// mGetMem(txt,16384*SizeOf(WideChar));
+{
+ p:=txt;
+ for cnt:=0 to HIGH(MainBuf[0]) do
+ begin
+ if (qsopt.columns[cnt].flags and COL_ON)=0 then
+ begin
+ LoadOneItem(info.hItem,cnt,FlagBuf[i].proto,qsr);
+ if qsr.text<>nil then
+ begin
+ if qsr.text^<>#0 then
+ begin
+//!! need: buffer free space check here
+num:=StrLenW(qsopt.columns[cnt].title)+StrLenW(qsr.text)+4;
+if (16384-num)>(p-txt) then
+begin
+
+ p:=StrCopyEW(p,qsopt.columns[cnt].title);
+ p^:=':'; inc(p); p^:=' '; inc(p);
+ p:=StrCopyEW(p,qsr.text);
+ p^:=#13; inc(p); p^:=#10; inc(p);
+end
+else
+begin
+ mFreeMem(qsr.text);
+ break;
+end;
+ end;
+ mFreeMem(qsr.text);
+ end;
+ end;
+ end;
+ p^:=#0;
+}
+ CallService(MS_TIPPER_SHOWTIPW,0{dword(txt)},tlparam(@info));
+// mFreeMem(txt);
+ TTShowed:=true;
+ end;
+ end;
+
+ WM_MOUSEMOVE: begin
+ pinfo.pt.x:=loword(lParam);
+ pinfo.pt.y:=hiword(lParam);
+ pinfo.flags:=0;
+ if integer(SendMessage(grid,LVM_SUBITEMHITTEST,0,tlparam(@pinfo)))<>-1 then
+ begin
+ if (pinfo.iItem<>OldHItem) or (pinfo.iSubItem<>OldHSubItem) then
+ begin
+ OldHSubItem:=pinfo.iSubItem;
+ OldHItem :=pinfo.iItem;
+
+ if TTInstalled then
+ begin
+ if TTShowed then
+ begin
+ TTShowed:=false;
+ CallService(MS_TIPPER_HIDETIP,0,0);
+ end;
+ KillTimer(Dialog, TIMERID_HOVER);
+ if OldHSubItem=0 then
+ begin
+ SetTimer(Dialog, TIMERID_HOVER, 450, nil);
+ exit;
+ end;
+ end;
+//!!
+ with TI do
+ begin
+ cbSize:=SizeOf(TI);
+ uFlags:=TTF_SUBCLASS+TTF_IDISHWND;
+ hWnd :=mainwnd;
+ uId :=Dialog;
+ hInst :=0;
+ end;
+
+ OldHSubItem:=GetQSColumn(OldHSubItem);
+ if (qsopt.columns[OldHSubItem].flags and
+ (COL_XSTATUS or COL_GENDER))<>0 then
+ begin
+ i:=LV_GetLParam(grid,OldHItem);
+// TTShowed:=true;
+ if (qsopt.columns[OldHSubItem].flags and COL_GENDER)<>0 then
+ begin
+ case MainBuf[i,OldHSubItem].data of
+ 77: TI.lpszText:=tstrMale;
+ 70: TI.lpszText:=tstrFemale;
+ else
+ TI.lpszText:=tstrUnknown;
+ end;
+ end
+ else // if (qsopt.columns[OldHSubItem].flags and COL_XSTATUS)<>0 then
+ begin
+ StrCopyW(buf,MainBuf[i,OldHSubItem].text);
+ ics.flags:=CSSF_DEFAULT_NAME or CSSF_MASK_NAME or CSSF_UNICODE;
+
+ StrCopy(StrCopyE(buf1,GetProtoName(FlagBuf[i].proto)),PS_ICQ_GETCUSTOMSTATUSEX);
+
+ i:=StrToInt(buf);
+ ics.wParam:=@i;
+ ics.cbSize:=SizeOf(ics);
+ ics.szName.w:=@buf;
+
+ CallService(buf1,0,tlparam(@ics));
+ TI.lpszText:=TranslateW(@buf);
+ end;
+ end
+ else
+ begin
+ TI.lpszText:=nil;
+// TTShowed:=false;
+ end;
+ SendMessageW(HintWnd,TTM_SETTOOLINFOW,0,tlparam(@TI));
+ end
+ end;
+ end;
+
+ WM_KEYUP: begin
+ case wParam of
+ VK_RETURN: begin
+ if ListView_GetSelectedCount(grid)=1 then
+ ShowContactMsgDlg(GetFocusedhContact);
+ exit;
+ end;
+ VK_INSERT: begin
+ CallService(MS_FINDADDFINDADD,0,0);
+ exit;
+ end;
+ VK_DELETE: begin
+ lParam:=ListView_GetSelectedCount(grid);
+ if lParam>1 then
+ DeleteByList
+ else if lParam=1 then
+ DeleteOneContact(GetFocusedhContact);
+ exit;
+ end;
+ VK_F5: begin
+ PostMessage(GetParent(Dialog),WM_COMMAND,(BN_CLICKED shl 16)+IDC_REFRESH,0);
+ exit;
+ end;
+ end;
+ end;
+
+ WM_NOTIFY: begin
+ if integer(PNMHdr(lParam)^.code)=HDN_ENDDRAG then
+ begin
+ ShiftColumns(PHDNotify(lParam)^.Item,PHDNotify(lParam)^.pitem^.iOrder);
+ end;
+ end;
+
+ end;
+ result:=CallWindowProc(OldLVProc,Dialog,hMessage,wParam,lParam);
+end;
+
+procedure ColumnClick(wnd:HWND;num:integer);
+var
+ hdi:THDITEM;
+ header:HWND;
+begin
+ zeromemory(@hdi,sizeof(hdi));
+ hdi.mask:=HDI_BITMAP or HDI_FORMAT;
+ hdi.fmt :=HDF_LEFT or HDF_STRING;
+ header:=ListView_GetHeader(wnd);
+ SendMessage(header,HDM_SETITEM,qsopt.columnsort,lparam(@hdi));
+
+ if qsopt.columnsort<>num then
+ begin
+ qsopt.ascendsort:=true;
+ qsopt.columnsort:=num;
+ end
+ else
+ qsopt.ascendsort:=not qsopt.ascendsort;
+
+ if qsopt.ascendsort then
+ hdi.hbm:=sortcoldn
+ else
+ hdi.hbm:=sortcolup;
+ hdi.fmt:=HDF_LEFT or HDF_BITMAP or HDF_BITMAP_ON_RIGHT or HDF_STRING;
+ Header_SetItem(header,num,hdi);
+
+ Sort;
+end;
+
+procedure MakeColumnMenu;
+var
+ menu:HMENU;
+ flag,id:integer;
+ pt:TPOINT;
+begin
+ menu:=CreatePopupMenu;
+ if menu<>0 then
+ begin
+ for id:=0 to qsopt.numcolumns-1 do
+ begin
+ if (qsopt.columns[id].flags and COL_ON)<>0 then
+ flag:=MF_CHECKED or MF_STRING
+ else
+ flag:=MF_UNCHECKED or MF_STRING;
+ AppendMenuW(menu,flag,100+id,TranslateW(qsopt.columns[id].title));
+ end;
+ GetCursorPos(pt);
+ id:=integer(TrackPopupMenu(menu,TPM_RETURNCMD+TPM_NONOTIFY,pt.x,pt.y,0,mainwnd,nil));
+ if id>100 then
+ begin
+ dec(id,100);
+ with qsopt.columns[id] do
+ begin
+ flags:=flags xor COL_ON;
+ if (flags and COL_ON)<>0 then
+ flag:=wcShow
+ else
+ flag:=wcHide;
+ end;
+ WndChangeColumns(flag,id);
+ OptChangeColumns(wcShow,id,ord(flag=wcShow));
+ end;
+ DestroyMenu(menu);
+ end;
+end;
+
+function NewLVHProc(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+begin
+ case hMessage of
+
+ WM_RBUTTONUP: begin
+ result:=0;
+ exit;
+ end;
+
+ WM_RBUTTONDOWN: begin
+ MakeColumnMenu;
+ end;
+ end;
+ result:=CallWindowProc(OldProc,Dialog,hMessage,wParam,lParam);
+end;
+
+procedure SetCellColor(lplvcd:PNMLVCUSTOMDRAW;idx:integer);
+begin
+ if qsopt.colorize then
+ begin
+ with FlagBuf[idx] do
+ begin
+ if (flags and QSF_ACCDEL)<>0 then
+ begin
+ lplvcd^.clrTextBk:=cbkg_del;
+ lplvcd^.clrText :=cfgr_del;
+ end
+ else if (flags and QSF_ACCOFF)<>0 then
+ begin
+ lplvcd^.clrTextBk:=cbkg_dis;
+ lplvcd^.clrText :=cfgr_dis;
+ end
+ else if (flags and QSF_META)<>0 then
+ begin
+ lplvcd^.clrTextBk:=cbkg_meta;
+ lplvcd^.clrText :=cfgr_meta;
+ end
+ else if (flags and QSF_SUBMETA)<>0 then
+ begin
+ lplvcd^.clrTextBk:=cbkg_sub;
+ lplvcd^.clrText :=cfgr_sub;
+ end
+ else if (flags and QSF_INLIST)=0 then
+ begin
+ lplvcd^.clrTextBk:=cbkg_hid;
+ lplvcd^.clrText :=cfgr_hid;
+ end
+ else
+ idx:=-1;
+ end;
+ end
+ else
+ idx:=-1;
+ if idx<0 then
+ begin
+ if (not qsopt.drawgrid) and odd(lplvcd^.nmcd.dwItemSpec) then
+ begin
+ lplvcd^.clrTextBk:=cbkg_odd;
+ lplvcd^.clrText :=cfgr_odd;
+ end
+ else
+ begin
+ lplvcd^.clrTextBk:=cbkg_norm;
+ lplvcd^.clrText :=cfgr_norm;
+ end;
+ end;
+end;
+
+function ProcessCustomDraw(lParam:LPARAM):integer;
+var
+ lplvcd:PNMLVCUSTOMDRAW;
+ rc:TRECT;
+ h:HICON;
+ buf:array [0..255] of AnsiChar;
+ i,j,sub:integer;
+begin
+ lplvcd:=pointer(lParam);
+ result:=CDRF_DODEFAULT;
+ case lplvcd^.nmcd.dwDrawStage of
+ CDDS_PREPAINT: begin
+ result:=CDRF_NOTIFYITEMDRAW;
+ exit;
+ end;
+ CDDS_ITEMPREPAINT: begin
+ result:=CDRF_NOTIFYSUBITEMDRAW;
+
+ SetCellColor(lplvcd,LV_GetLParam(grid,lplvcd^.nmcd.dwItemSpec));
+
+ exit;
+ end;
+ CDDS_SUBITEM or CDDS_ITEMPREPAINT: begin
+
+ i:=LV_GetLParam(grid,lplvcd^.nmcd.dwItemSpec);
+ SetCellColor(lplvcd,i);
+ sub:=GetQSColumn(lplvcd^.iSubItem);
+ if (qsopt.columns[sub].flags and COL_GENDER)<>0 then
+ begin
+ ListView_GetSubItemRect(grid,lplvcd^.nmcd.dwItemSpec,lplvcd^.iSubItem,LVIR_ICON,@rc);
+
+ case MainBuf[i,sub].data of
+ 70: h:=hIconF;
+ 77: h:=hIconM;
+ else
+ h:=0;
+ end;
+ if h<>0 then
+ begin
+ DrawIconEx(lplvcd^.nmcd.hdc,rc.left+1,rc.top,h,16,16,0,0,DI_NORMAL);
+ end;
+ result:=CDRF_SKIPDEFAULT;
+ end
+ else if (qsopt.columns[sub].flags and COL_XSTATUS)<>0 then
+ begin
+ j:=StrToInt(MainBuf[i,sub].text);
+ if j>0 then
+ begin
+ StrCopy(StrCopyE(buf,GetProtoName(FlagBuf[i].proto)),PS_ICQ_GETCUSTOMSTATUSICON);
+ if ServiceExists(buf)<>0 then
+ begin
+ h:=CallService(buf,j,LR_SHARED);
+
+ ListView_GetSubItemRect(grid,lplvcd^.nmcd.dwItemSpec,lplvcd^.iSubItem,LVIR_ICON,@rc);
+ DrawIconEx(lplvcd^.nmcd.hdc,rc.left+1,rc.top,h,16,16,0,0,DI_NORMAL);
+ end;
+ end;
+ result:=CDRF_SKIPDEFAULT;
+ end
+ else if qsopt.showclienticons and
+ ((qsopt.columns[sub].flags and COL_CLIENT)<>0) then
+ result:=CDRF_NOTIFYPOSTPAINT;
+ end;
+ CDDS_SUBITEM or CDDS_ITEMPOSTPAINT: begin
+ sub:=GetQSColumn(lplvcd^.iSubItem);
+ if (qsopt.columns[sub].flags and COL_CLIENT)<>0 then
+ begin
+ i:=LV_GetLParam(grid,lplvcd^.nmcd.dwItemSpec);
+ FastWideToAnsiBuf(MainBuf[i,sub].text,buf);
+
+// ListView_GetItemTextA(grid,lplvcd^.nmcd.dwItemSpec,lplvcd^.iSubItem,buf,SizeOf(buf));
+ if buf[0]<>#0 then
+ begin
+ h:=CallService(MS_FP_GETCLIENTICON,tlparam(@buf),0);
+ ListView_GetSubItemRect(grid,lplvcd^.nmcd.dwItemSpec,lplvcd^.iSubItem,LVIR_ICON,@rc);
+ DrawIconEx(lplvcd^.nmcd.hdc,rc.left+1,rc.top,h,16,16,0,0,DI_NORMAL);
+ DestroyIcon(h);
+ end;
+ result:=CDRF_SKIPDEFAULT;
+ end;
+ end;
+ end;
+end;
+
+function NewEditProc(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+var
+ count,current,next,perpage:integer;
+ li:LV_ITEM;
+begin
+ result:=0;
+ case hMessage of
+ WM_CHAR: if wParam=27 then
+ begin
+ PostMessage(GetParent(Dialog),WM_COMMAND,(BN_CLICKED shl 16)+IDCANCEL,0);
+ exit;
+ end;
+ WM_KEYUP: if wParam=VK_RETURN then
+ begin
+ if ListView_GetSelectedCount(grid)=1 then
+ ShowContactMsgDlg(GetFocusedhContact);
+ exit;
+ end;
+ WM_KEYDOWN: begin
+ count :=ListView_GetItemCount(grid);
+ current:=ListView_GetNextItem(grid,-1,LVNI_FOCUSED);
+ next:=-1;
+ if count>0 then
+ case wParam of
+ VK_NEXT,VK_PRIOR: begin
+ perpage:=ListView_GetCountPerPage(grid);
+ if wParam=VK_NEXT then
+ next:=Min(current+perpage,count)
+ else
+ next:=Max(current-perpage,0);
+ end;
+ VK_UP: begin
+ if current>0 then
+ next:=current-1
+ end;
+ VK_DOWN: begin
+ if current<count-1 then
+ next:=current+1
+ end;
+ VK_F5: begin
+ PostMessage(GetParent(Dialog),WM_COMMAND,(BN_CLICKED shl 16)+IDC_REFRESH,0);
+ exit;
+ end;
+ end;
+ if next>=0 then
+ begin
+ li.statemask:=LVIS_SELECTED;
+ li.state:=0;
+ SendMessage(grid,LVM_SETITEMSTATE,twparam(-1),tlparam(@li));
+ ListView_SetItemState(grid,next,LVIS_FOCUSED or LVIS_SELECTED,
+ LVIS_FOCUSED or LVIS_SELECTED);
+ // ListView_EnsureVisible(grid,next,false);
+ SendMessage(grid,LVM_ENSUREVISIBLE,next,0);
+ result:=0;
+ exit;
+ end;
+ end;
+ end;
+ result:=CallWindowProc(OldEditProc,Dialog,hMessage,wParam,lParam);
+end;
+
+function ShowContactMenu(wnd:HWND;hContact:THANDLE):HMENU;
+var
+ pt:tpoint;
+begin
+ if hContact<>0 then
+ begin
+ GetCursorPos(pt);
+ result:=CallService(MS_CLIST_MENUBUILDCONTACT,hContact,0);
+ if result<>0 then
+ begin
+ TrackPopupMenu(result,0,pt.x,pt.y,0,wnd,nil);
+ DestroyMenu(result);
+ end;
+ end
+ else
+ result:=0;
+end;
+
+procedure ShowMultiPopup(cnt:integer);
+var
+ mmenu,grpmenu:HMENU;
+ i:integer;
+ buf:array [0..255] of WideChar;
+ p:PWideChar;
+ pt:TPOINT;
+begin
+ mmenu:=CreatePopupMenu;
+ if mmenu=0 then
+ exit;
+
+ StrCopyW(buf,TranslateW('Selected'));
+ p:=@buf;
+ while p^<>#0 do inc(p);
+ p^:=' '; inc(p);
+
+ IntToStr(p,cnt);
+
+ while p^<>#0 do inc(p);
+ p^:=' '; inc(p);
+ StrCopyW(p,TranslateW('contacts'));
+ AppendMenuW(mmenu,MF_DISABLED+MF_STRING,0,buf);
+ AppendMenuW(mmenu,MF_SEPARATOR,0,nil);
+ AppendMenuW(mmenu,MF_STRING,101,TranslateW('&Delete'));
+ AppendMenuW(mmenu,MF_STRING,102,TranslateW('&Copy'));
+ if ServiceExists(MS_MC_CONVERTTOMETA)<>0 then
+ AppendMenuW(mmenu,MF_STRING,103,TranslateW('C&onvert to Meta'));
+
+ grpmenu:=MakeGroupMenu(400);
+
+// grpmenu:=CallService(MS_CLIST_GROUPBUILDMENU,0,0);
+ AppendMenuW(mmenu,MF_POPUP,grpmenu,TranslateW('&Move to Group'));
+
+ GetCursorPos(pt);
+ i:=integer(TrackPopupMenu(mmenu,TPM_RETURNCMD+TPM_NONOTIFY,pt.x,pt.y,0,mainwnd,nil));
+ case i of
+ 101: DeleteByList;
+ 102: begin
+ CopyMultiLinesW(ListView_GetSelectedCount(grid))
+ end;
+ 103: ConvertToMeta;
+ else
+ if i>0 then
+ begin // move to group
+ if i=400 then // root group
+ buf[0]:=#0
+ else
+ begin
+ GetMenuStringW(grpmenu,i,buf,SizeOf(buf),MF_BYCOMMAND);
+ end;
+ MoveToGroup(buf);
+ end;
+ end;
+ DestroyMenu(mmenu);
+ if qsopt.closeafteraction then
+ CloseSrWindow;
+end;
+
+procedure addcolumn(handle:hwnd;num,width:integer;title:PWideChar);
+var
+ lvcol:LV_COLUMNW;
+begin
+ zeromemory(@lvcol,sizeof(lvcol));
+ lvcol.mask :=LVCF_TEXT or LVCF_WIDTH;
+ lvcol.pszText :=title;
+ lvcol.cx :=width;
+ SendMessageW(handle,LVM_INSERTCOLUMNW,num,lparam(@lvcol));
+end;
+{
+// from zero!!
+function GetNthByMask(const arr:tcolumnarray; num:cardinal; mask:dword):tcolumnitem;
+var
+ i:cardinal;
+begin
+ for i:=0 to HIGH(arr) do
+ begin
+ if (arr[i].flags and mask)<>0 then
+ begin
+ if num=0 then
+ begin
+ result:=arr[i];
+ exit;
+ end;
+ dec(num);
+ end;
+ end;
+ result:=arr[0];
+end;
+}
+function ColorReload(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+begin
+ result:=0;
+ cbkg_norm:=GetColor(bkg_norm);
+ cfgr_norm:=GetColor(fgr_norm);
+ cbkg_odd :=GetColor(bkg_odd);
+ cfgr_odd :=GetColor(fgr_odd);
+ cbkg_dis :=GetColor(bkg_dis);
+ cfgr_dis :=GetColor(fgr_dis);
+ cbkg_del :=GetColor(bkg_del);
+ cfgr_del :=GetColor(fgr_del);
+ cbkg_hid :=GetColor(bkg_hid);
+ cfgr_hid :=GetColor(fgr_hid);
+ cbkg_meta:=GetColor(bkg_meta);
+ cfgr_meta:=GetColor(fgr_meta);
+ cbkg_sub :=GetColor(bkg_sub);
+ cfgr_sub :=GetColor(fgr_sub);
+end;
+
+procedure ClearBuffers;
+var
+ w,h:integer;
+begin
+ for w:=0 to HIGH(MainBuf) do
+ for h:=0 to HIGH(MainBuf[0]) do
+ mFreeMem(MainBuf[w,h].text);
+end;
+
+procedure SetSpecialColumns(num:integer);
+begin
+ with qsopt.columns[num] do
+ begin
+ if (setting_type=ST_BYTE) and
+ (lstrcmpia(wparam.a,'XStatusId')=0) then
+ begin
+ flags:=flags or COL_XSTATUS;
+ end
+
+ else if (setting_type=ST_CONTACTINFO) and
+ (setting_cnftype=CNF_GENDER) then
+ begin
+ if hIconF=0 then hIconF:=CallService(MS_SKIN2_GETICON,0,tlparam(QS_FEMALE));
+ if hIconM=0 then hIconM:=CallService(MS_SKIN2_GETICON,0,tlparam(QS_MALE));
+ flags:=flags or COL_GENDER;
+ tstrMale :=TranslateW('Male');
+ tstrFemale :=TranslateW('Female');
+ tstrUnknown:=TranslateW('Unknown');
+ end
+
+ else if (wparam.a<>NIL) and // FingerPrint preprocess
+ (setting_type=ST_STRING) and
+ (lstrcmpia(wparam.a,'MirVer')=0) and
+ (ServiceExists(MS_FP_GETCLIENTICON)<>0) then
+ flags:=flags or COL_CLIENT;
+ end;
+end;
+
+function FindAddDlgResizer(Dialog:HWND;lParam:LPARAM;urc:PUTILRESIZECONTROL):int; cdecl;
+begin
+ case urc^.wId of
+ IDCANCEL: result:=RD_ANCHORX_RIGHT or RD_ANCHORY_TOP;
+ IDC_REFRESH: result:=RD_ANCHORX_RIGHT or RD_ANCHORY_TOP;
+ IDC_CH_SHOWOFFLINE: result:=RD_ANCHORX_LEFT or RD_ANCHORY_TOP;
+ IDC_CH_COLORIZE: result:=RD_ANCHORX_LEFT or RD_ANCHORY_TOP;
+ IDC_CB_PROTOCOLS: result:=RD_ANCHORX_LEFT or RD_ANCHORY_TOP;
+ IDC_E_SEARCHTEXT: result:=RD_ANCHORX_WIDTH or RD_ANCHORY_TOP;
+ IDC_LIST: result:=RD_ANCHORX_WIDTH or RD_ANCHORY_HEIGHT;
+ IDC_STATUSBAR: result:=RD_ANCHORX_WIDTH or RD_ANCHORY_BOTTOM;
+ else
+ result:=0;
+ end;
+end;
+
+procedure PrepareTable(reset:boolean=false);
+var
+ i:integer;
+ old:integer;
+begin
+ old:=tablecolumns;
+ tablecolumns:=0;
+ for i:=0 to qsopt.numcolumns-1 do
+ begin
+ with qsopt.columns[i] do
+ begin
+ if (flags and COL_ON)<>0 then
+ begin
+ addcolumn(grid,tablecolumns,width,TranslateW(title));
+ inc(tablecolumns);
+ end;
+
+ SetSpecialColumns(i);
+ end;
+ end;
+ if reset then
+ begin
+ for i:=old+tablecolumns-1 downto tablecolumns do
+ begin
+ SendMessage(grid,LVM_DELETECOLUMN,i,0);
+ end;
+ end;
+
+ ListView_DeleteAllItems(grid);
+ ListView_SetItemCount(grid,HIGH(FlagBuf)+1);
+end;
+
+procedure FillProtoCombo(cb:HWND);
+var
+ i:integer;
+ buf:array [0..63] of WideChar;
+begin
+ SendMessage(cb,CB_RESETCONTENT,0,0);
+ CB_AddStrDataW(cb,TranslateW('All'));
+ for i:=1 to GetNumProto do
+ begin
+ CB_AddStrDataW(cb,FastAnsiToWideBuf(GetProtoName(i),@buf),i);
+ end;
+ SendMessage(cb,CB_SETCURSEL,0,0);
+end;
+
+function QSMainWndProc(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall;
+var
+ tmp:LONG_PTR;
+ tmph:THANDLE;
+ w,h:uint_ptr;
+ i:integer;
+ buf:array [0..255] of WideChar;
+ rc:TRECT;
+ pt:TPOINT;
+ smenu:HMENU;
+ TI:tToolInfoW;
+ urd:TUTILRESIZEDIALOG;
+begin
+ result:=0;
+ case hMessage of
+ WM_DESTROY: begin
+ UnhookEvent(colorhook);
+
+ StatusBar:=0;
+ DeleteObject(gridbrush);
+ GetWindowRect(Dialog,rc);
+
+ CopyRect(qsopt.grrect,rc);
+
+ // set column width - only for enabled columns
+ for tmp:=0 to qsopt.numcolumns-1 do
+ begin
+ if {(qsopt.columns[tmp].flags and COL_ON)<>0} colorder[tmp]>=0 then
+ begin
+ w:=ListView_GetColumnWidth(grid,colorder[tmp]);
+ if w<>0 then
+ qsopt.columns[tmp].width:=w;
+ end;
+ end;
+ saveopt_wnd;
+
+ ListView_SetImageList(grid,0,LVSIL_SMALL);
+ opened:=false;
+
+ tmp:=GetDC(grid);
+ h:=GetCurrentObject(tmp,OBJ_FONT);
+ SendMessage(grid,WM_SETFONT,0,1);
+ DeleteObject(h);
+ ReleaseDC(grid,tmp);
+
+ grid:=0;
+
+ if qsopt.savepattern then
+ DBWriteUnicode(0,qs_module,'pattern',pattern);
+
+ mFreeMem(patstr);
+ mFreeMem(pattern);
+
+ ClearBuffers;
+ end;
+
+ WM_INITDIALOG: begin
+
+ tmph:=GetModuleHandle(nil);
+ if sortcoldn=0 then
+ sortcoldn:=LoadImageA(tmph,PAnsiChar(240),IMAGE_BITMAP,0,0,LR_LOADMAP3DCOLORS);
+ if sortcolup=0 then
+ sortcolup:=LoadImageA(tmph,PAnsiChar(239),IMAGE_BITMAP,0,0,LR_LOADMAP3DCOLORS);
+
+ SetWindowTextW(Dialog,'Quick Search');
+
+ StatusBar:=GetDlgItem(Dialog,IDC_STATUSBAR);
+
+ smenu:=GetSystemMenu(Dialog,false);
+ InsertMenu (smenu,5,MF_BYPOSITION or MF_SEPARATOR,0,nil);
+ InsertMenuW(smenu,6,MF_BYPOSITION or MF_STRING,
+ IDM_STAYONTOP,TranslateW('Stay on Top'));
+
+ if qsopt.stayontop then
+ begin
+ CheckMenuItem(smenu,IDM_STAYONTOP,MF_BYCOMMAND or MF_CHECKED);
+ SetWindowPos(Dialog,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE or SWP_NOSIZE);
+ end;
+ AdvFilter:=0;
+ if qsopt.showoffline then
+ begin
+ CheckDlgButton(Dialog,IDC_CH_SHOWOFFLINE,ORD(qsopt.showoffline));
+ AdvFilter:=AdvFilter or flt_show_offline;
+ end;
+
+ if qsopt.colorize then
+ CheckDlgButton(Dialog,IDC_CH_COLORIZE,ORD(qsopt.colorize));
+
+ gridbrush:=CreateSolidBrush(RGB(222,230,235));
+
+ mainwnd:=Dialog;
+ tmp:=GetWindowLongPtrW(Dialog,GWL_EXSTYLE);
+ if qsopt.usetoolstyle then
+ tmp:=tmp or WS_EX_TOOLWINDOW
+ else
+ tmp:=tmp and not WS_EX_TOOLWINDOW;
+ SetWindowLongPtrW(Dialog,GWL_EXSTYLE,tmp);
+
+ SendMessage(Dialog,WM_SETICON,ICON_SMALL,//LoadIcon(hInstance,PAnsiChar(IDI_QS))
+ CallService(MS_SKIN2_GETICON,0,tlparam(QS_QS)));
+ grid:=GetDlgItem(Dialog,IDC_LIST);
+
+ ListView_SetImageList(grid,
+ CallService(MS_CLIST_GETICONSIMAGELIST,0,0),LVSIL_SMALL);
+
+ tmp:=LVS_EX_FULLROWSELECT or LVS_EX_SUBITEMIMAGES or LVS_EX_HEADERDRAGDROP or LVS_EX_LABELTIP;
+ if qsopt.drawgrid then
+ tmp:=tmp or LVS_EX_GRIDLINES;
+ SendMessage(grid,LVM_SETEXTENDEDLISTVIEWSTYLE,0,tmp);
+
+ OldLVProc :=pointer(SetWindowLongPtrW(grid,GWL_WNDPROC,LONG_PTR(@NewLVProc)));
+ OldEditProc:=pointer(SetWindowLongPtrW(GetDlgItem(Dialog,IDC_E_SEARCHTEXT),
+ GWL_WNDPROC,LONG_PTR(@NewEditProc)));
+
+ OldProc:=pointer(SetWindowLongPtrW(
+ SendMessage(grid,LVM_GETHEADER,0,0),
+ GWL_WNDPROC,LONG_PTR(@NewLVHProc)));
+
+ FillProtoCombo(GetDlgItem(Dialog,IDC_CB_PROTOCOLS));
+
+ PrepareTable;
+
+ if pattern<>nil then
+ begin
+ SetDlgItemTextW(Dialog,IDC_E_SEARCHTEXT,pattern)
+ end
+ else
+ begin
+ buf[0]:=#0;
+ SetDlgItemTextW(Dialog,IDC_E_SEARCHTEXT,@buf);
+ FillGrid;
+ end;
+
+ TranslateDialogDefault(Dialog);
+
+ SnapToScreen(qsopt.grrect);
+ with qsopt.grrect do
+ MoveWindow(Dialog,left,top,right-left,bottom-top,false);
+
+ with TI do
+ begin
+ cbSize :=SizeOf(TI);
+ uFlags :=TTF_SUBCLASS+TTF_IDISHWND;
+ hWnd :=Dialog;
+ uId :=grid;
+ hInst :=0;
+ lpszText :=nil;
+ end;
+ HintWnd:=CreateWindowExW(0,TOOLTIPS_CLASS,nil,0,
+ integer(CW_USEDEFAULT),integer(CW_USEDEFAULT),
+ integer(CW_USEDEFAULT),integer(CW_USEDEFAULT),
+ Dialog,0,HInstance,NIL);
+
+ SendMessageW(HintWnd,TTM_ADDTOOLW,0,tlparam(@TI));
+// SetWindowsHookEx(WH_KEYBOARD,@QSKbdHook,0,GetCurrentThreadId);
+ colorhook:=HookEvent(ME_COLOUR_RELOAD,@ColorReload);
+
+ opened:=true;
+ end;
+
+ WM_GETMINMAXINFO: begin
+ with PMINMAXINFO(lParam)^ do
+ begin
+ ptMinTrackSize.x:=300;
+ ptMinTrackSize.y:=160;
+ end;
+ end;
+
+ WM_SIZE: begin
+ SendMessage(StatusBar,WM_SIZE,0,0);
+ FillChar(urd,SizeOf(TUTILRESIZEDIALOG),0);
+ urd.cbSize :=SizeOf(urd);
+ urd.hwndDlg :=Dialog;
+ urd.hInstance :=hInstance;
+ urd.lpTemplate:=MAKEINTRESOURCEA(IDD_MAIN);
+ urd.lParam :=0;
+ urd.pfnResizer:=@FindAddDlgResizer;
+ CallService(MS_UTILS_RESIZEDIALOG,0,tlparam(@urd));
+ end;
+
+ WM_SYSCOMMAND: begin
+ if wParam=IDM_STAYONTOP then
+ begin
+ if qsopt.stayontop then
+ begin
+ h:=MF_BYCOMMAND or MF_UNCHECKED;
+ w:=HWND_NOTOPMOST;
+ end
+ else
+ begin
+ h:=MF_BYCOMMAND or MF_CHECKED;
+ w:=HWND_TOPMOST;
+ end;
+ CheckMenuItem(GetSystemMenu(Dialog,false),IDM_STAYONTOP,h);
+ SetWindowPos(Dialog,w,0,0,0,0,SWP_NOMOVE or SWP_NOSIZE);
+ qsopt.stayontop:=not qsopt.stayontop;
+ exit;
+ end;
+ end;
+
+ WM_CONTEXTMENU: begin
+ if wParam=tWPARAM(GetDlgItem(Dialog,IDC_LIST)) then
+ begin
+ w:=ListView_GetSelectedCount(grid);
+ if w>1 then
+ ShowMultiPopup(w)
+ else
+ ShowContactMenu(Dialog,GetFocusedhContact);
+ end;
+ end;
+
+ WM_MYADDCONTACT: begin
+ // refresh table to add contact
+ i:=Length(MainBuf);
+ SetLength(MainBuf,i+1);
+ SetLength(MainBuf[i],qsopt.numcolumns);
+ SetLength(FlagBuf,i+1);
+
+ AddContact(i,wParam);
+ ProcessLine(i);
+ Sort;
+ UpdateSB;
+ end;
+
+ WM_MYDELETECONTACT: begin
+ i:=FindBufNumber(wParam);
+ if i>=0 then
+ begin
+ FlagBuf[i].flags:=(FlagBuf[i].flags or QSF_DELETED) and not QSF_ACTIVE;
+ for w:=0 to HIGH(MainBuf[0]) do
+ mFreeMem(MainBuf[i,w].text);
+ i:=FindItem(i);
+ if i>=0 then
+ ListView_DeleteItem(grid,i);
+ UpdateSB;
+ end;
+ end;
+
+ WM_MEASUREITEM:
+ CallService(MS_CLIST_MENUMEASUREITEM,wParam,lParam);
+ WM_DRAWITEM:
+ CallService(MS_CLIST_MENUDRAWITEM,wParam,lParam);
+
+ WM_MOUSEMOVE: begin
+ if TTInstalled then
+ begin
+ GetWindowRect(grid,rc);
+ pt.x:=loword(lParam);
+ pt.y:=hiword(lParam);
+ ClientToScreen(Dialog,pt);
+ if not PtInRect(rc,pt) then
+ begin
+ if TTShowed then
+ begin
+ TTShowed:=false;
+ CallService(MS_TIPPER_HIDETIP,0,0);
+ end;
+ KillTimer(grid,TIMERID_HOVER);
+ end;
+ end;
+ end;
+
+ WM_KEYDOWN: begin
+ case wParam of
+ VK_F5: begin
+ PostMessage(Dialog,WM_COMMAND,(BN_CLICKED shl 16)+IDC_REFRESH,0);
+ exit;
+ end;
+ end;
+ end;
+
+ WM_COMMAND: begin
+ if opened and (CallService(MS_CLIST_MENUPROCESSCOMMAND,
+ MAKEWPARAM(LOWORD(wParam),MPCF_CONTACTMENU),
+ GetFocusedhContact)<>0) then
+ begin
+ if qsopt.closeafteraction then
+ CloseSrWindow;
+ exit;
+ end;
+
+ case wParam shr 16 of
+ CBN_SELCHANGE: begin
+ AdvFilter:=(AdvFilter and not $FF) or cardinal(CB_GetData(lParam));
+ AdvancedFilter;
+ end;
+
+ EN_CHANGE: begin
+ GetDlgItemTextW(Dialog,IDC_E_SEARCHTEXT,buf,sizeOf(buf));
+ mFreeMem(pattern);
+ StrDupW(pattern,buf);
+ if pattern<>nil then
+ CharLowerW(pattern);
+ FillGrid; //!!
+ end;
+
+ BN_CLICKED: begin
+ case loword(wParam) of
+ IDC_CH_SHOWOFFLINE: begin
+ qsopt.showoffline:=IsDlgButtonChecked(Dialog,IDC_CH_SHOWOFFLINE)<>BST_UNCHECKED;
+ if qsopt.showoffline then
+ AdvFilter:=AdvFilter or flt_show_offline
+ else
+ AdvFilter:=AdvFilter and not flt_show_offline;
+ AdvancedFilter;
+ end;
+
+ IDC_CH_COLORIZE: begin
+ qsopt.colorize:=IsDlgButtonChecked(Dialog,IDC_CH_COLORIZE)<>BST_UNCHECKED;
+ RedrawWindow(grid,nil,0,RDW_INVALIDATE);
+ end;
+
+ IDC_REFRESH: begin
+ ClearBuffers;
+ PrepareToFill;
+ PrepareTable(true);
+ FillGrid;
+ end;
+
+ IDCANCEL: CloseSrWindow();
+ end;
+ end;
+ end;
+ end;
+
+ WM_NOTIFY: begin
+ case integer(PNMHdr(lParam)^.code) of
+ LVN_COLUMNCLICK: begin
+ ColumnClick(PNMListView(lParam)^.hdr.hwndFrom,PNMListView(lParam)^.iSubItem);
+ end;
+ NM_CUSTOMDRAW: begin
+ if PNMHdr(lParam)^.hwndFrom=grid then
+ begin
+ SetWindowLongPtrW(Dialog,DWL_MSGRESULT,ProcessCustomDraw(lParam));
+ result:=1;
+ end;
+ end;
+ end;
+ end;
+
+// else
+// result:=DefWindowProc(Dialog,hMessage,wParam,lParam);
+ end;
+end;
+
+function CloseSrWindow:boolean;
+begin
+ result:=true;
+ if opened and (mainwnd<>0) then
+ begin
+ DestroyWindow(mainwnd);
+
+ opened:=false;
+ mainwnd:=0;
+ end;
+ FreeProtoList;
+end;
+
+function OpenSRWindow(apattern:PWideChar;flags:LPARAM):boolean;
+begin
+ result:=true;
+ if opened then
+ exit;
+
+ TTInstalled := ServiceExists(MS_TIPPER_SHOWTIP)<>0;
+ // too lazy to move pattern and flags to thread
+ if apattern<>nil then
+ begin
+ if flags=0 then
+ StrDupW(pattern,apattern)
+ else
+ AnsiToWide(PAnsiChar(apattern),pattern);
+ CharLowerW(pattern);
+ end
+ else if qsopt.savepattern then
+ pattern:=DBReadUnicode(0,qs_module,'pattern',nil)
+ else
+ pattern:=nil;
+
+ CreateProtoList;
+ if PrepareToFill then
+ begin
+//!! SetLength(colorder,qsopt.numcolumns);
+ ColorReload(0,0);
+ CreateDialogW(hInstance,PWideChar(IDD_MAIN),0,@QSMainWndProc);
+ end;
+end;
+
+function BringToFront:integer;
+var
+ wp:TWINDOWPLACEMENT;
+begin
+ result:=1;
+ wp.length:=SizeOf(TWINDOWPLACEMENT);
+ GetWindowPlacement(mainwnd,@wp);
+ if wp.showCmd=SW_SHOWMINIMIZED then
+ ShowWindow(mainwnd,SW_RESTORE);
+ SetForegroundWindow(mainwnd);
+end;
+
+procedure ChangeStatusPicture(row:integer; hContact:THANDLE;Pic:integer);
+var
+ li:LV_ITEM;
+begin
+ row:=FindItem(row);
+ if row>=0 then
+ begin
+ li.iItem :=row;
+ li.iSubItem:=0;
+ li.mask :=LVIF_IMAGE;
+ li.iImage :=Pic;//CallService(MS_CLIST_GETCONTACTICON,hContact,0);
+ SendMessage(grid,LVM_SETITEM,0,lparam(@li));
+ end;
+end;
+
+function OnStatusChanged(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+var
+ j:integer;
+ oldstat,newstat:integer;
+begin
+ result:=0;
+ if not opened then exit;
+
+ j:=FindBufNumber(wParam);
+ if j>=0 then
+ begin
+ oldstat:=FlagBuf[j].status;
+ newstat:=DBReadWord(wParam,GetProtoName(FlagBuf[j].proto),'Status',ID_STATUS_OFFLINE);
+ FlagBuf[j].status:=newstat;
+
+ if (oldstat<>ID_STATUS_OFFLINE) and (newstat<>ID_STATUS_OFFLINE) then
+ ChangeStatusPicture(j,wParam,lParam)
+ else if (oldstat=ID_STATUS_OFFLINE) {and (newstat<>ID_STATUS_OFFLINE)} then
+ begin
+ if qsopt.showoffline then
+ ChangeStatusPicture(j,wParam,lParam)
+ else
+ ProcessLine(j,false) // why false? need to filter!
+ end
+ else if {(oldstat<>ID_STATUS_OFFLINE) and} (newstat=ID_STATUS_OFFLINE) then
+ begin
+ if qsopt.showoffline then
+ ChangeStatusPicture(j,wParam,lParam)
+ else
+ begin
+ FlagBuf[j].flags:=FlagBuf[j].flags and not QSF_ACTIVE;
+ ListView_DeleteItem(grid,FindItem(j));
+ end;
+ end;
+
+ // refresh table to new filtering
+ if qsopt.sortbystatus then
+ Sort;
+ UpdateSB;
+ end;
+end;
+
+function OnContactAdded(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+begin
+ result:=0;
+ if opened then
+ PostMessage(mainwnd,WM_MYADDCONTACT,wParam,lParam);
+end;
+
+function OnContactDeleted(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+begin
+ result:=0;
+ if opened then
+ PostMessage(mainwnd,WM_MYDELETECONTACT,wParam,lParam);
+end;
+
+function OnAccountChanged(wParam:WPARAM;lParam:LPARAM):int;cdecl;
+begin
+ result:=0;
+ if not opened then exit;
+ case wParam of
+ PRAC_ADDED: begin
+ end;
+ PRAC_REMOVED: begin
+ end;
+ PRAC_CHECKED: begin
+ with PPROTOACCOUNT(lParam)^ do
+ begin
+ if bIsEnabled<>0 then
+ begin
+ end
+ else
+ begin
+ end;
+ end;
+ end;
+ end;
+end;
+
+function ShiftIndex(idx:integer;var order:array of integer):pointer;
+var
+ i,n:integer;
+begin
+ n:=colorder[idx];
+ for i:=0 to qsopt.numcolumns-1 do
+ if order[i]>n then dec(order[i]);
+ result:=@order;
+end;
+
+procedure FillLVColumn(column,lvcolumn:integer);
+var
+ li:LV_ITEMW;
+ i:integer;
+begin
+ FillChar(li,SizeOf(li),0);
+ for i:=0 to ListView_GetItemCount(grid)-1 do
+ begin
+ li.iItem :=i;
+ li.mask :=LVIF_PARAM;
+ li.iSubItem:=0;
+ SendMessage(grid,LVM_GETITEM,0,lparam(@li));
+
+ li.pszText :=MainBuf[li.lParam,column].text;
+ // Client icons preprocess
+ if (((qsopt.columns[column].flags and COL_CLIENT)<>0) and
+ (li.pszText<>NIL) and qsopt.showclienticons) OR
+ ((qsopt.columns[column].flags and (COL_XSTATUS or COL_GENDER))<>0) then
+ li.mask:=LVIF_IMAGE or LVIF_TEXT
+ else
+ li.mask:=LVIF_TEXT;
+ li.iSubItem:=lvcolumn;
+ SendMessageW(grid,LVM_SETITEMW,0,lparam(@li));
+ end;
+end;
+
+procedure SetColumnOrder;
+var
+ i,col:integer;
+ lcol:array [0..99] of integer;
+begin
+ col:=0;
+ for i:=0 to qsopt.numcolumns-1 do
+ if colorder[i]>=0 then
+ begin
+ lcol[col]:=colorder[i];
+ inc(col);
+ end;
+
+ SendMessageW(grid,LVM_SETCOLUMNORDERARRAY,col,lparam(@lcol[0]));
+
+ InvalidateRect(grid,nil,false);
+end;
+
+procedure WndChangeColumns(code:integer;column:integer=-1);
+var
+ i,col:integer;
+ coldata:tQSRec;
+// lcol:array of integer;
+ incr:integer;
+begin
+ if (grid<>0) and
+ ((code=wcRefresh) or ((column>=0) and (column<qsopt.numcolumns))) then
+ begin
+ SendMessage(grid,WM_SETREDRAW,0,0);
+ case code of
+ wcUp,wcDown: begin
+ // changing buffer data
+ if code=wcUp then
+ incr:=-1
+ else
+ incr:=1;
+
+ // memory
+ for i:=0 to HIGH(MainBuf) do
+ begin
+ coldata :=MainBuf[i,column];
+ MainBuf[i,column ]:=MainBuf[i,column+incr];
+ MainBuf[i,column+incr]:=coldata;
+ end;
+
+ // index
+ col :=colorder[column];
+ colorder[column ]:=colorder[column+incr];
+ colorder[column+incr]:=col;
+
+ // check needs for screen resort (columns are AFTER resort)
+ if ((qsopt.columns[column ].flags and COL_ON)=COL_ON) and
+ ((qsopt.columns[column+incr].flags and COL_ON)=COL_ON) then // both visible
+ begin // need resort on screen
+ SetColumnOrder;
+ end;
+ SendMessage(grid,WM_SETREDRAW,1,0);
+ exit;
+ end;
+
+ wcHide: begin // hide column
+ // screen
+ SendMessage(grid,LVM_DELETECOLUMN,colorder[column],0);
+ dec(tablecolumns);
+ // index
+ ShiftIndex(column,colorder);
+ colorder[column]:=-1;
+ end;
+
+ wcDelete: begin // delete column
+ // screen
+ SendMessage(grid,LVM_DELETECOLUMN,colorder[column],0);
+ dec(tablecolumns);
+ // memory
+ for i:=0 to HIGH(MainBuf) do
+ begin
+ mFreeMem(MainBuf[i,column].text);
+ if column<qsopt.numcolumns then
+ move(MainBuf[i,column+1],MainBuf[i,column],SizeOf(tQSRec));
+ end;
+ SetLength(MainBuf,Length(MainBuf),qsopt.numcolumns); //!!!!
+ // index
+ if column<qsopt.numcolumns then
+ move(colorder[column+1],colorder[column],SizeOf(integer));
+ SetLength(colorder,qsopt.numcolumns);
+ end;
+
+ wcShow: begin // show column
+ // memory
+ if (qsopt.columns[column].flags and COL_INIT)=0 then
+ begin
+ for i:=0 to HIGH(MainBuf) do // contacts
+ begin
+ LoadOneItem(FlagBuf[i].contact,column,FlagBuf[i].proto,MainBuf[i,column]);
+ end;
+ qsopt.columns[column].flags:=qsopt.columns[column].flags or COL_INIT;
+ end;
+ // screen
+ with qsopt.columns[column] do // atm - to the end only
+ addcolumn(grid,tablecolumns,width,TranslateW(title));
+
+ // fill new column
+ FillLVColumn(column,tablecolumns);
+ // index
+ colorder[column]:=tablecolumns;
+ inc(tablecolumns);
+
+ SetColumnOrder;
+{
+ SetLength(lcol,tablecolumns);
+ col:=0;
+ for i:=0 to qsopt.numcolumns-1 do
+ if colorder[i]>=0 then
+ begin
+ lcol[col]:=colorder[i];
+ inc(col);
+ end;
+
+ SendMessageW(grid,LVM_SETCOLUMNORDERARRAY,tablecolumns,dword(@lcol[0]));
+
+ InvalidateRect(grid,nil,false);
+}
+ end;
+
+ wcInsert: begin // add column
+ // memory
+ SetLength(MainBuf,Length(MainBuf),qsopt.numcolumns+1); //!!!!
+ SetSpecialColumns(column);
+ // index
+ SetLength(colorder,qsopt.numcolumns+1);
+ // screen
+ if (qsopt.columns[column].flags and COL_ON)<>0 then
+ WndChangeColumns(wcShow,column)
+ else
+ colorder[column]:=-1;
+ end;
+
+ wcChange: begin // change column
+ for i:=0 to HIGH(MainBuf) do
+ begin
+ mFreeMem(MainBuf[i,column].text);
+ end;
+ SetSpecialColumns(column);
+ qsopt.columns[column].flags:=qsopt.columns[column].flags and not COL_INIT;
+ if (qsopt.columns[column].flags and COL_ON)<>0 then
+ FillLVColumn(column,colorder[column]);
+ end;
+
+ wcRefresh: begin // refresh all info
+ ClearBuffers;
+ PrepareToFill;
+ PrepareTable(true);
+ end;
+ end;
+ FillGrid;
+ SendMessage(grid,WM_SETREDRAW,1,0);
+ end;
+end;
+
+begin
+end.
|