From 0cfbb97047e562b9d19d201c61a94da79d3d2bd8 Mon Sep 17 00:00:00 2001 From: Alexey Kulakov Date: Wed, 15 Jan 2014 21:21:49 +0000 Subject: updated to 1.4.2.0 git-svn-id: http://svn.miranda-ng.org/main/trunk@7672 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/QuickSearch/i_ok.inc | 860 ++++++++ plugins/QuickSearch/ico/item.ico | Bin 1150 -> 0 bytes plugins/QuickSearch/qs.rc | 142 +- plugins/QuickSearch/qs.res | Bin 15388 -> 13144 bytes plugins/QuickSearch/quicksearch.dpr | 53 +- plugins/QuickSearch/quicksearch_history.txt | 6 +- plugins/QuickSearch/resource.inc | 80 +- plugins/QuickSearch/sr_global.pas | 899 ++++---- plugins/QuickSearch/sr_optdialog.pas | 1439 +++++++------ plugins/QuickSearch/sr_window.pas | 2988 +++++++++++---------------- 10 files changed, 3361 insertions(+), 3106 deletions(-) create mode 100644 plugins/QuickSearch/i_ok.inc delete mode 100644 plugins/QuickSearch/ico/item.ico (limited to 'plugins/QuickSearch') diff --git a/plugins/QuickSearch/i_ok.inc b/plugins/QuickSearch/i_ok.inc new file mode 100644 index 0000000000..bbeb383fb0 --- /dev/null +++ b/plugins/QuickSearch/i_ok.inc @@ -0,0 +1,860 @@ +{} +//----- Color functions ----- + +var + colorhook:THANDLE; + +type + tqscolor = ( + bkg_norm,fgr_norm, + bkg_odd ,fgr_odd, + bkg_dis ,fgr_dis, + bkg_del ,fgr_del, + bkg_hid ,fgr_hid, + bkg_meta,fgr_meta, + bkg_sub ,fgr_sub + ); +type + tQSColorRec = record + color : TCOLORREF; + setting : PAnsiChar; + descr : PAnsiChar; + end; +const + QSColors: array [tqscolor] of tQSColorRec =( + (color: $00FFFFFF; setting: 'back_norm'; descr: 'Normal background' ), + (color: $00000000; setting: 'fore_norm'; descr: 'Normal foreground' ), + (color: $00EBE6DE; setting: 'back_odd' ; descr: 'Odd background' ), + (color: $00000000; setting: 'fore_odd' ; descr: 'Odd foreground' ), + (color: $008080FF; setting: 'back_dis' ; descr: 'Disabled account background'), + (color: $00000000; setting: 'fore_dis' ; descr: 'Disabled account foreground'), + (color: $008000FF; setting: 'back_del' ; descr: 'Deleted account background' ), + (color: $00000000; setting: 'fore_del' ; descr: 'Deleted account foreground' ), + (color: $0080FFFF; setting: 'back_hid' ; descr: 'Hidden contact background' ), + (color: $00000000; setting: 'fore_hid' ; descr: 'Hidden contact foreground' ), + (color: $00BAE699; setting: 'back_meta'; descr: 'Metacontact background' ), + (color: $00000000; setting: 'fore_meta'; descr: 'Metacontact foreground' ), + (color: $00B3CCC1; setting: 'back_sub' ; descr: 'SubMetacontact background' ), + (color: $00000000; setting: 'fore_sub' ; descr: 'SubMetacontact foreground' ) + ); + + +procedure RegisterColors; +var + cid:TColourID; + i:tqscolor; +begin + cid.cbSize:=SizeOf(cid); + cid.flags :=0; + StrCopy(cid.group,qs_module); + StrCopy(cid.dbSettingsGroup,qs_module); + + for i:=Low(tqscolor) to High(tqscolor) do + begin + StrCopy(cid.name ,QSColors[i].descr); + StrCopy(cid.setting,QSColors[i].setting); + cid.defcolour:=QSColors[i].color; + cid.order :=ORD(i); + ColourRegister(@cid); + end; +end; + +function ColorReload(wParam:WPARAM;lParam:LPARAM):int;cdecl; +var + cid:TColourID; + i:tqscolor; +begin + result:=0; + cid.cbSize:=SizeOf(cid); + StrCopy(cid.group,qs_module); + for i:=Low(tqscolor) to High(tqscolor) do + begin + StrCopy(cid.name ,QSColors[i].descr); + QSColors[i].color:=CallService(MS_COLOUR_GETA,tlparam(@cid),0); + end; +end; + +//----- Item fill ----- + +function int2strw(i:uint_ptr;signed:bool=false):PWideChar; +var + buf:array [0..31] of WideChar; +begin + if signed then + StrDupW(result,IntToStr(buf,int_ptr(i))) + else + StrDupW(result,IntToStr(buf,i)); +end; + +function int2hexw(i:uint_ptr):PWideChar; +var + buf:array [0..31] of WideChar; +begin + StrDupW(result,IntToHex(buf,i)); +end; + +function BuildLastSeenTime(date:integer):PWideChar; +var + pc:pWideChar; + buf:array [0..19] of WideChar; + year,month,day,hours,min:integer; +begin + year:=(date div (60*24*31*356))+1980; + + if year<>0 then + begin + date:= date mod (60*24*31*356); + pc:=@buf; + + month:=date div (60*24*31); + date :=date mod (60*24*31); + day :=date div (60*24); + date :=date mod (60*24); + hours:=date div 60; + min :=date mod 60; + + IntToStr(pc,day,2); + + inc(pc,2); + pc^:='.'; inc(pc); + IntToStr(pc,month,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,hours,2); + inc(pc,2); + pc^:=':'; inc(pc); + IntToStr(pc,min,2); + + StrDupW(result,@buf); + 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 + p:PWideChar; + buf:array [0..16] of WideChar; +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;column:pcolumnitem;proto:integer; var res:tQSRec); +var + tmp:uint_ptr; + lmodule,srv:PAnsiChar; + DbEvent:HDBEVENT; + cni:TCONTACTINFO; + dbei:TDBEVENTINFO; + b:bool; +begin + FillChar(res,SizeOf(tQSRec),0); + res.data:=uint_ptr(-1); + res.text:=nil; + with column^ do + begin + + case setting_type of + QST_SCRIPT: begin + res.text:=ParseVarString(script,hContact); + end; + + QST_SERVICE: begin + if wparam._type=ACF_CURRENT then wparam.value:=hContact; + if lparam._type=ACF_CURRENT then lparam.value:=hContact; + + if (restype and ACF_SCRIPT_SERVICE)<>0 then + srv:=ParseVarString(service,hContact,nil) + else + srv:=service; + tmp:=uint_ptr(CallService(srv,TWPARAM(wparam.value),TLPARAM(lparam.value))); + if (restype and ACF_SCRIPT_SERVICE)<>0 then + mFreeMem(srv); + + if tmp=CALLSERVICE_NOTFOUND then exit; + if (restype and ACF_RSTRING)<>0 then + AnsiToWide(PAnsiChar(tmp),res.text) + else if (restype and ACF_RUNICODE)<>0 then + StrDupW(res.text,PWideChar(tmp)) + else// if (restype and ACF_RNUMBER)<>0 then + begin + res.data:=tmp; + if (restype and ACF_RHEXNUM)<>0 then + res.text:=int2hexw(tmp) + else + begin + b:=(restype and ACF_RSIGNED)<>0; + res.text:=int2strw(tmp,b); + end; + end; + end; + + QST_CONTACTINFO: begin + FillChar(cni,SizeOf(cni),0); + cni.cbSize :=sizeof(cni); + cni.dwFlag :=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 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; + + QST_SETTING: begin + if module<>nil then + lmodule:=module + else + lmodule:=GetProtoName(proto); + + case datatype of + QSTS_STRING: begin + res.text:=DBReadUnicode(hContact,lmodule,setting,nil) + end; + + QSTS_BYTE: begin + res.data:=DBReadByte(hContact,lmodule,setting,0); + res.text:=int2strw(res.data); + end; + + QSTS_WORD: begin + res.data:=DBReadWord(hContact,lmodule,setting,0); + res.text:=int2strw(res.data); + end; + + QSTS_DWORD: begin + if (module=nil) and (setting=nil) then + begin + res.data:=hContact; + res.text:=int2hexw(res.data); + end + else + begin + res.data:=DBReadDWord(hContact,lmodule,setting,0); + res.text:=int2strw(res.data); + end; + end; + + QSTS_SIGNED: begin + res.data:=DBReadDWord(hContact,lmodule,setting,0); + res.text:=int2strw(res.data,true); + end; + + QSTS_HEXNUM: begin + res.data:=DBReadDWord(hContact,lmodule,setting,0); + res.text:=int2hexw(res.data); + end; + + QSTS_IP: begin + res.data:=DBReadDWord(hContact,lmodule,setting,0); + if res.data<>0 then + res.text:=IPtoStr(res.data); + end; + + QSTS_TIMESTAMP: begin + res.data:=DBReadDWord(hContact,lmodule,setting,0); + if res.data<>0 then + res.text:=TimeToStrW(res.data); + end; + end; + end; + + QST_OTHER: case other of + QSTO_LASTSEEN: begin + res.data:=BuildLastSeenTimeInt(hContact,'SeenModule'); + res.text:=BuildLastSeenTime (res.data); + end; + + QSTO_LASTEVENT: begin + DbEvent:=db_event_last(hContact); + if DbEvent<>0 then + begin + ZeroMemory(@dbei,sizeof(dbei)); + dbei.cbSize:=SizeOf(dbei); + db_event_get(DbEvent, @dbei); + res.data:=dbei.timestamp; + res.text:=TimeToStrW(res.data); + end + else + res.data:=0; + end; + + QSTO_METACONTACT: begin + res.text:=DoMeta(hContact); + end; + + QSTO_EVENTCOUNT: begin + res.text:=int2strw(db_event_count(hContact)); + end; + end; + + end; + end; +end; + +//----- Initial table filling ----- + +procedure AddContact(num:integer;hContact:THANDLE); +var + col:pcolumnitem; + tmpstr:array [0..63] of AnsiChar; + i:integer; +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 + begin + col:=@qsopt.columns[i]; + // col.flags must me same as colorder[i].flags + if (col.flags and COL_ON)<>0 then + LoadOneItem(contact,col,proto,MainBuf[num,i]); + end; + 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); + + for i:=0 to qsopt.numcolumns-1 do + begin + with qsopt.columns[i] do + begin + if (flags and COL_ON)<>0 then + flags := flags or COL_INIT; + end; + end; + + // filling buffer + LastMeta:=0; + cnt1:=0; + hContact:=db_find_first(); + while hContact<>0 do + begin + //!! check account + AddContact(cnt1,hContact); + inc(cnt1); + if cnt1=cnt then break; // additional checking + hContact:=db_find_next(hContact); + end; + if cnt1<>cnt then + begin + SetLength(MainBuf,cnt1); + SetLength(FlagBuf,cnt1); + end; +end; + +//----- Status bar ----- +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:=FormatSimpleW('%i users found (%i) Online: %i',[SBData[0].found,Length(FlagBuf),SBData[0].online]); + 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){p}); + // mFreeMem(p); + + 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 +// FormatSimpleW('%s (%s): %i (%i); %s %i (%i)', +// [fmtstr,pc,found,total,po,liston,online]); + 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; + +//----- Patterns ----- + +const + pattern:pWideChar = nil; // edit field text +const + maxpattern = 8; +var + patterns:array [0..maxpattern-1] of record + str:PWideChar; + res:bool; + end; +const + patstr:PWideChar=nil; // work pattern buffer + numpattern:integer=0; + +procedure MakePatternW; +var + lpatptr:PWideChar; + wasquote:bool; +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 or COL_FILTER))=(COL_ON or COL_FILTER)) 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; + +//----- support (column index converters) ----- + +{ + ListView - ListView (visible) column + QS - Buffer column + Column - qsopt.columns +} + +function ListViewToColumn(col:integer):LPARAM; +var + i:integer; +begin + for i:=0 to qsopt.numcolumns-1 do + begin + if (qsopt.columns[i].flags and COL_ON)<>0 then + begin + dec(col); + if col<0 then + begin + result:=i; + exit; + end; + end; + end; + result:=-1; +end; + +function ColumnToListView(col:integer):LPARAM; +var + i:integer; +begin + result:=-1; + for i:=0 to qsopt.numcolumns-1 do + begin + if (qsopt.columns[i].flags and COL_ON)<>0 then + inc(result); + + dec(col); + if col<0 then + break; + end; +end; + +// return buffer index for contact +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 IsColumnMinimized(num:integer):bool; +begin + result:=ListView_GetColumnWidth(grid,num)<=10; +end; diff --git a/plugins/QuickSearch/ico/item.ico b/plugins/QuickSearch/ico/item.ico deleted file mode 100644 index 27def2fb4b..0000000000 Binary files a/plugins/QuickSearch/ico/item.ico and /dev/null differ diff --git a/plugins/QuickSearch/qs.rc b/plugins/QuickSearch/qs.rc index fe94e16e24..83c5fa21a6 100644 --- a/plugins/QuickSearch/qs.rc +++ b/plugins/QuickSearch/qs.rc @@ -1,7 +1,19 @@ #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" @@ -14,94 +26,82 @@ FONT 8, "MS Shell Dlg", 0, 0 PUSHBUTTON "&Help" , IDHELP , 156, 64, 46, 14 PUSHBUTTON "C&ancel", IDCANCEL , 206, 64, 46, 14 } - -IDD_DIALOG1 DIALOGEX 40, 40, 314, 240 +*/ +IDD_DIALOG1 DIALOGEX 0, 0, 314, 250 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 "Reload" ,IDC_RELOAD ,"MButtonClass",WS_TABSTOP, 2,148,16,16,$18000000 + CONTROL "New" ,IDC_NEW ,"MButtonClass",WS_TABSTOP, 32,148,16,16,$18000000 + CONTROL "Up" ,IDC_UP ,"MButtonClass",WS_TABSTOP, 62,148,16,16,$18000000 + CONTROL "Down" ,IDC_DN ,"MButtonClass",WS_TABSTOP, 80,148,16,16,$18000000 + CONTROL "Delete" ,IDC_DELETE ,"MButtonClass",WS_TABSTOP,112,148,16,16,$18000000 + CONTROL "Default",IDC_DEFAULT,"MButtonClass",WS_TABSTOP,142,148,16,16,$18000000 CONTROL "List2",IDC_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | - WS_BORDER | WS_TABSTOP,0,2,213,150 + WS_BORDER | WS_TABSTOP,0,2,158,144 - CTEXT "Settings",-1 ,234, 2,77,12, SS_CENTERIMAGE - CONTROL "", -1, "STATIC", SS_ETCHEDHORZ, 234, 14, 77, 2 + CONTROL ">>",IDC_B_RESIZE,"Button", BS_FLAT | WS_TABSTOP,160,2,10,246 - LTEXT "Title:",-1 ,236, 16,75,12, SS_CENTERIMAGE - EDITTEXT IDC_E_TITLE ,234, 28,77,14, ES_AUTOHSCROLL | WS_TABSTOP + // Common header + CTEXT "Settings",IDC_S_COLSETTING,172,2,139,12, SS_CENTERIMAGE + CONTROL "", IDC_S_LINE, "STATIC", SS_ETCHEDHORZ, 172,14,139,2 - 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 "Title:",IDC_S_TITLE,174,16,137,12, SS_CENTERIMAGE + EDITTEXT IDC_E_TITLE,172,28,139,14, ES_AUTOHSCROLL | 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 + // TYPE + LTEXT "Type:",IDC_S_VARTYPE,174,44,137,12, SS_CENTERIMAGE + COMBOBOX IDC_C_VARTYPE,172,56,139,80, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | + WS_VSCROLL | WS_TABSTOP - 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 + // SETTING + LTEXT "Data type:" ,IDC_S_DATATYPE, 174,72,137,12, SS_CENTERIMAGE + COMBOBOX IDC_C_DATATYPE, 172,84,139,80, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | + WS_VSCROLL | 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 "Module:", IDC_S_MODULE, 174,104,137,12, SS_CENTERIMAGE + EDITTEXT IDC_E_MODULE, 172,116,139,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 "Setting:", IDC_S_SETTING, 174,132,137,12, SS_CENTERIMAGE + EDITTEXT IDC_E_SETTING, 172,144,139,14, ES_AUTOHSCROLL | WS_TABSTOP - LTEXT "lParam:",-1,236,184,75,12, SS_CENTERIMAGE - EDITTEXT IDC_E_LPAR ,234,196,77,14, ES_AUTOHSCROLL | WS_TABSTOP + // CONTACTINFO + LTEXT "InfoType:",IDC_S_CNFTYPE, 174,72,137,12, SS_CENTERIMAGE + COMBOBOX IDC_C_CNFTYPE, 172,84,139,80, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | + WS_VSCROLL | 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 + // SERVICE + + // SCRIPT + EDITTEXT IDC_E_SCRIPT, 172,72,139,14, ES_AUTOHSCROLL | WS_TABSTOP + + // -- NO PARAM -- + COMBOBOX IDC_C_OTHER, 172,72,139,150, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + + + PUSHBUTTON "Save", IDC_SETITEM, 259,234,52,14, 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 + CONTROL "Tool Window Style",IDC_CH_USETOOLSTYLE,"Button", + BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,3,176,152,12 + CONTROL "Draw Grid",IDC_CH_DRAWGRID,"Button", + BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,3,188,152,12 + CONTROL "Save search pattern",IDC_CH_SAVEPATTERN,"Button", + BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,3,200,152,12 + CONTROL "Auto Close mode",IDC_CH_AUTOCLOSE,"Button", + BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,3,212,152,12 + CONTROL "Sort by Status",IDC_CH_SORTSTATUS,"Button", + BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,3,224,152,12 + CONTROL "Show Client Icons",IDC_CH_CLIENTICONS,"Button", + BS_AUTOCHECKBOX | BS_FLAT | WS_TABSTOP,3,236,152,12 + GROUPBOX "Additional Options",IDC_CH_GROUP,0,168,158,82 } 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" @@ -138,8 +138,8 @@ FONT 8, "Ms Shell Dlg",0,0 } /* VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,4,1,20 - PRODUCTVERSION 1,4,1,20 + FILEVERSION 1,4,1,18 + PRODUCTVERSION 0,8,0,0 FILEFLAGSMASK $3F FILEOS 4 FILETYPE 2 @@ -152,11 +152,11 @@ 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, 20 "0 + VALUE "FileVersion", "1, 4, 1, 19 "0 VALUE "InternalName", "QuickSearch"0 VALUE "OriginalFilename", "quicksearch.dll"0 VALUE "ProductName", "QuickSearch Dynamic Link Library (DLL)"0 - VALUE "ProductVersion", "1, 4, 1, 20 "0 + VALUE "ProductVersion", "0, 8, 0, 0 "0 VALUE "SpecialBuild", "12.09.2012 "0 END END diff --git a/plugins/QuickSearch/qs.res b/plugins/QuickSearch/qs.res index 3d56f7aa9a..222402e284 100644 Binary files a/plugins/QuickSearch/qs.res and b/plugins/QuickSearch/qs.res differ diff --git a/plugins/QuickSearch/quicksearch.dpr b/plugins/QuickSearch/quicksearch.dpr index d804236eb3..4629676407 100644 --- a/plugins/QuickSearch/quicksearch.dpr +++ b/plugins/QuickSearch/quicksearch.dpr @@ -19,24 +19,12 @@ uses 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'; - PluginInfo.version :=$01040114; + PluginInfo.version :=$01040200; PluginInfo.description:= 'This plugin allows you to quick search for nickname, '+ 'firstname, lastname, email, uin in your contact list. '+ @@ -102,12 +90,6 @@ begin 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'; @@ -150,7 +132,7 @@ begin Skin_AddIcon(@sid); DestroyIcon(sid.hDefaultIcon); - icohook:=HookEvent(ME_SKIN2_ICONSCHANGED,@IconChanged); + HookEvent(ME_SKIN2_ICONSCHANGED,@IconChanged); end; function OnOptInitialise(wParam:WPARAM;lParam:LPARAM):int;cdecl; @@ -174,29 +156,21 @@ end; function OpenSearchWindow(wParam:WPARAM;lParam:LPARAM):int_ptr;cdecl; begin result:=0; - if not opened then - OpenSrWindow(pointer(wParam),lParam) - else - BringToFront; + OpenSrWindow(pointer(wParam),lParam) end; function OnModulesLoaded(wParam:WPARAM;lParam:LPARAM):int;cdecl; begin - UnhookEvent(onloadhook); - RegisterIcons; RegisterColors; - servshow:=CreateServiceFunction(QS_SHOWSERVICE,@OpenSearchWindow); + 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); + Result:=0; end; @@ -204,9 +178,9 @@ function Load():Integer;cdecl; begin Result:=0; Langpack_register; - opthook :=HookEvent(ME_OPT_INITIALISE ,@OnOptInitialise); - onloadhook:=HookEvent(ME_SYSTEM_MODULESLOADED,@OnModulesLoaded); - loadopt_db(true); + HookEvent(ME_OPT_INITIALISE ,@OnOptInitialise); + HookEvent(ME_SYSTEM_MODULESLOADED,@OnModulesLoaded); + qsopt.numcolumns:=loadopt_db(qsopt.columns); end; function Unload:Integer;cdecl; @@ -214,20 +188,11 @@ begin result:=0; removetoolbar; //?? - DestroyServiceFunction(servshow); - UnhookEvent(opthook); - UnhookEvent(onadd); - UnhookEvent(ondelete); - UnhookEvent(onstatus); -// UnhookEvent(onaccount); - if icohook<>0 then - UnhookEvent(icohook); - // unreghotkeys; CloseSrWindow; - clear_columns; + clear_columns(qsopt.columns); end; exports diff --git a/plugins/QuickSearch/quicksearch_history.txt b/plugins/QuickSearch/quicksearch_history.txt index ff2ffb3f28..f7b8af5f18 100644 --- a/plugins/QuickSearch/quicksearch_history.txt +++ b/plugins/QuickSearch/quicksearch_history.txt @@ -7,7 +7,11 @@ Service: History: -1.4.1.20 - unneded frame removed +1.4.2.0 (27 dec 2013) + Options dialog redesign + Lot of internal changes + "life" sync between option dialog and main window removed + Contact list frame removed 1.4.1.19 () FastMM4 memory manager used (not native Delphi or miranda) Fixed some Memory leaks diff --git a/plugins/QuickSearch/resource.inc b/plugins/QuickSearch/resource.inc index 57100e9106..ed5b399e6b 100644 --- a/plugins/QuickSearch/resource.inc +++ b/plugins/QuickSearch/resource.inc @@ -2,16 +2,16 @@ 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_UP = 111; + IDI_DOWN = 112; + IDI_DELETE = 113; + IDI_DEFAULT = 114; + IDI_RELOAD = 115; IDI_MALE = 120; IDI_FEMALE = 121; @@ -24,41 +24,39 @@ const 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_LIST = 1010; + IDC_B_RESIZE = 1011; + 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_CH_AUTOCLOSE = 1031; + IDC_CH_USETOOLSTYLE = 1032; + IDC_CH_DRAWGRID = 1033; + IDC_CH_CLIENTICONS = 1034; + IDC_CH_SAVEPATTERN = 1035; + IDC_CH_GROUP = 1040; + + IDC_S_COLSETTING = 1020; + IDC_S_LINE = 1021; + + IDC_E_TITLE = 1022; + IDC_S_TITLE = 1023; + IDC_C_VARTYPE = 1024; + IDC_S_VARTYPE = 1025; + + IDC_E_SCRIPT = 2001; + + IDC_S_DATATYPE = 2010; + IDC_C_DATATYPE = 2011; + IDC_S_MODULE = 2012; + IDC_E_MODULE = 2013; + IDC_S_SETTING = 2014; + IDC_E_SETTING = 2015; + + IDC_S_CNFTYPE = 2020; + IDC_C_CNFTYPE = 2021; + + IDC_C_OTHER = 2030; + IDC_E_SEARCHTEXT = 1001; IDC_CH_SHOWOFFLINE = 1031; @@ -66,5 +64,3 @@ const IDC_REFRESH = 1033; IDC_STATUSBAR = 1034; IDC_CB_PROTOCOLS = 1035; - - IDC_EDIT_SCRIPT = 1025; diff --git a/plugins/QuickSearch/sr_global.pas b/plugins/QuickSearch/sr_global.pas index 5110ef8de8..a6d1caab98 100644 --- a/plugins/QuickSearch/sr_global.pas +++ b/plugins/QuickSearch/sr_global.pas @@ -3,26 +3,6 @@ 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'; @@ -42,91 +22,123 @@ const 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; + QSTS_BYTE = 0; + QSTS_WORD = 1; + QSTS_DWORD = 2; + QSTS_STRING = 3; + QSTS_IP = 4; + QSTS_TIMESTAMP = 5; + QSTS_SIGNED = 6; + QSTS_HEXNUM = 7; + + // must be non-zero for empty-column checking + QST_SETTING = 100; + QST_SCRIPT = 1; + QST_SERVICE = 2; + QST_CONTACTINFO = 3; + QST_OTHER = 200; + + QSTO_LASTSEEN = 0; + QSTO_LASTEVENT = 1; + QSTO_METACONTACT = 2; + QSTO_EVENTCOUNT = 3; const COL_ON = $0001; // Show column COL_INIT = $0002; // No need to update + COL_FILTER = $0004; // Filter column by pattern + // QS window runtime flags COL_XSTATUS = $0100; COL_GENDER = $0200; COL_CLIENT = $0400; + COL_GROUP = $0800; + COL_CNTNR = $1000; + COL_REFRESH = $FF00; // mask + +const + QSO_SORTBYSTATUS = $00000001; // Sort by status + QSO_DRAWGRID = $00000002; // Draw listview grid + QSO_TOOLSTYLE = $00000004; // QS window tool style + QSO_SAVEPATTERN = $00000008; // Save filter pattern + QSO_AUTOCLOSE = $00000010; // Close QS window after action + QSO_CLIENTICONS = $00000020; // Show client icons (fingerprint) + + QSO_MAINOPTIONS = $0000FFFF; // mask for common options + + // QS window options + QSO_STAYONTOP = $00010000; // Stay QS window on top + QSO_SHOWOFFLINE = $00020000; // Show offline contacts + QSO_COLORIZE = $00040000; // Colorize lines + QSO_SORTASC = $00080000; // Sort column ascending {$include resource.inc} type tserviceparam = record - case _type:word of - 0: (n:dword); - 1: (i:integer); - 2: (a:PAnsiChar); - 3: (w:PWideChar); + value:uint_ptr; + _type:dword; end; + type - tcolumnitem=record + pcolumnitem = ^tcolumnitem; + 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 + setting_type :dword; // QST_* constants + flags :word; // COL_* constants + width :word; + case integer of + // db setting + 0: ( + datatype:integer; // QSTS_* constants + module :pAnsiChar; + setting :pAnsiChar; + ); + // script + 1: (script:pWideChar); + // service + 2: ( + service:pAnsiChar; + wparam :tserviceparam; + lparam :tserviceparam; + restype:dword; + ); + // contact info + 3: (cnftype:dword); // CNF_* constants + // other + 4: (other:integer); // QSTO_* 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; + +const + MaxColumnAmount = 64; +type + tqsopt = record + grrect :TRECT; // QS window rect + columns :array [0..MaxColumnAmount-1] of tcolumnitem; + numcolumns:integer; // columns array size (really, needs just for db reading) + columnsort:integer; // sorted column number + flags :dword; // QSO_* options end; + procedure reghotkeys; procedure unreghotkeys; procedure saveopt_wnd; +procedure loadopt_wnd; +function savecolumn(num:integer; const column:tcolumnitem):boolean; 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; +function loadopt_db(var columns:array of tcolumnitem):integer; +function loaddefaultcolumns(var columns:array of tcolumnitem):integer; + +function CloneColumns(var dst: array of tcolumnitem; const src:array of tcolumnitem):integer; +function CloneColumn (var dst:tcolumnitem; const src:tcolumnitem):boolean; + +procedure clear_columns(var columns:array of tcolumnitem); +procedure clear_column (var column:tcolumnitem); + +function new_column(var columns:array of tcolumnitem):integer; procedure AddRemoveMenuItemToMainMenu; procedure addtotoolbar; @@ -137,11 +149,11 @@ var const MainMenuItem:integer=0; - hTTBButton :thandle=0; + hTTBButton :THANDLE=0; implementation -uses common; +uses common, sparam; const HKN_GLOBAL:PAnsiChar = 'QS_Global'; @@ -150,36 +162,34 @@ const 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_flags :PAnsiChar = 'flags'; + 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__width :PAnsiChar = '_width'; + so__flags :PAnsiChar = '_flags'; so__setting_type :PAnsiChar = '_setting_type'; - so__setting_cnftype:PAnsiChar = '_setting_cnftype'; - so__module_name :PAnsiChar = '_module_name'; + + so__cnftype :PAnsiChar = '_cnftype'; + + so__datatype :PAnsiChar = '_datatype'; + so__module :PAnsiChar = '_module'; + so__setting :PAnsiChar = '_setting'; + + so__script :PAnsiChar = '_script'; + + so__service :PAnsiChar = '_service'; + so__restype :PAnsiChar = '_restype'; 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'; + + so__other :PAnsiChar = '_other'; procedure reghotkeys; var @@ -221,21 +231,18 @@ var begin removetoolbar; - if qsopt.showintoptoolbar then + if ServiceExists(MS_TTB_ADDBUTTON)>0 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; + 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; @@ -243,256 +250,336 @@ 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; + 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 + cmi.pszService :=QS_SHOWSERVICE; + cmi.hIcon :=CallService(MS_SKIN2_GETICON,0,lparam(QS_QS)); + MainMenuItem :=Menu_AddMainMenuItem(@cmi); + 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); +function CloneColumn(var dst:tcolumnitem; const src:tcolumnitem):boolean; begin - with qsopt.columns[num] do + if src.setting_type=0 then 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; + result:=false; + exit; + end; + + move(src,dst,SizeOf(tcolumnitem)); + StrDupW(dst.title,dst.title); + case dst.setting_type of + QST_SETTING: begin + StrDup(dst.module,dst.module); + StrDup(dst.setting,dst.setting); + end; + QST_SCRIPT: begin + StrDupW(dst.script,dst.script); + end; + QST_SERVICE: begin + StrDup(dst.service,dst.service); + if (dst.wparam._type=ACF_STRING) or (dst.wparam._type=ACF_UNICODE) then + StrDupW(pWideChar(dst.wparam.value),pWideChar(dst.wparam.value)); + if (dst.wparam._type=ACF_STRING) or (dst.wparam._type=ACF_UNICODE) then + StrDupW(pWideChar(dst.lparam.value),pWideChar(dst.lparam.value)); end; end; + result:=true; end; -procedure clear_columns; +function CloneColumns(var dst: array of tcolumnitem; const src:array of tcolumnitem):integer; var - i:integer; + i,cnt: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 + cnt:=0; + for i:=0 to MaxColumnAmount-1 do 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); + if CloneColumn(dst[cnt],src[i]) then + inc(cnt); end; + result:=cnt; end; -function new_column(after:integer=-1):integer; +procedure clear_column(var column:tcolumnitem); 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; + if column.setting_type=0 then // empty already + exit; + + mFreeMem(column.title); + case column.setting_type of + QST_SETTING: begin + mFreeMem(column.module); + mFreeMem(column.setting); + end; + QST_SCRIPT: begin + mFreeMem(column.script); + end; + QST_SERVICE: begin + mFreeMem(column.service); + if (column.wparam._type=ACF_STRING) or (column.wparam._type=ACF_UNICODE) then + mFreeMem(pointer(column.wparam.value)); + if (column.wparam._type=ACF_STRING) or (column.wparam._type=ACF_UNICODE) then + mFreeMem(pointer(column.lparam.value)); + end; + QST_CONTACTINFO: begin + end; + QST_OTHER: begin + end; end; - result:=qsopt.numcolumns; - inc(qsopt.numcolumns); + column.setting_type:=0; // mark as unused end; -procedure MakeTitle(var title; name:pAnsiChar); +procedure clear_columns(var columns:array of tcolumnitem); +var + i:integer; begin - FastAnsiToWide(name,pWideChar(title)); + for i:=0 to MaxColumnAmount-1 do + clear_column(columns[i]); end; -procedure loaddefaultcolumns; +function new_column(var columns:array of tcolumnitem):integer; +var + i:integer; 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 + result:=MaxColumnAmount-1; + for i:=0 to MaxColumnAmount-1 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; + if columns[i].setting_type=0 then // "empty" condition + begin + with columns[i] do + begin + StrDupW(title,'New column'); + width:=64; + flags:=COL_ON; + setting_type:=QST_SETTING; + end; + + result:=i; + break; + end; end; +end; + +function loaddefaultcolumns(var columns:array of tcolumnitem):integer; +var + i:integer; +begin + clear_columns(columns); + // lazy to renumber if changes + i:=0; - with qsopt.columns[1] do + // account + with columns[i] do begin - MakeTitle(title,'Real Protocol'); - StrDup(module_name,'Protocol'); - StrDup(wparam.a ,'p'); + StrDupW(title,'Account'); width :=82; - setting_type :=ST_STRING; - flags :=0; + flags :=COL_ON; + setting_type :=QST_SERVICE; + StrDup (service,MS_PROTO_GETCONTACTBASEACCOUNT); + restype :=ACF_RSTRING; + wparam._type :=ACF_CURRENT; + lparam._type :=ACF_NUMBER; + lparam.value :=0; end; + inc(i); - //gender - with qsopt.columns[2] do + // gender + with columns[i] do begin - MakeTitle(title,'Gender'); + StrDupW(title,'Gender'); width :=20; - setting_type :=ST_CONTACTINFO; - setting_cnftype:=CNF_GENDER; flags :=COL_ON; + setting_type :=QST_CONTACTINFO; + cnftype :=CNF_GENDER; end; + inc(i); - //uin - with qsopt.columns[3] do + // uin + with columns[i] do begin - MakeTitle(title,'UserID'); + StrDupW(title,'UserID'); width :=80; - setting_type :=ST_CONTACTINFO; - setting_cnftype:=CNF_UNIQUEID; flags :=COL_ON; + setting_type :=QST_CONTACTINFO; + cnftype :=CNF_UNIQUEID; end; + inc(i); - //username(displayname) - with qsopt.columns[4] do + // username(displayname) + with columns[i] do begin - MakeTitle(title,'Nickname'); - StrDup(module_name,MS_CLIST_GETCONTACTDISPLAYNAME); + StrDupW(title,'Nickname'); width :=76; - setting_type :=ST_SERVICE; - setting_cnftype:=ptUnicode; - wparam._type :=ptCurrent; - lparam._type :=ptNumber; - lparam.n :=2; // 0 for ANSI flags :=COL_ON; + setting_type :=QST_SERVICE; + StrDup(service,MS_CLIST_GETCONTACTDISPLAYNAME); + restype :=ACF_RUNICODE; + wparam._type :=ACF_CURRENT; + lparam._type :=ACF_NUMBER; + lparam.value :=2; // 0 for ANSI end; + inc(i); - //firstname - with qsopt.columns[5] do + // firstname + with columns[i] do begin - MakeTitle(title,'First name'); + StrDupW(title,'First name'); width :=68; - setting_type :=ST_CONTACTINFO; - setting_cnftype:=CNF_FIRSTNAME; flags :=COL_ON; + setting_type :=QST_CONTACTINFO; + cnftype :=CNF_FIRSTNAME; end; + inc(i); - //lastname - with qsopt.columns[6] do + // lastname + with columns[i] do begin - MakeTitle(title,'Last name'); + StrDupW(title,'Last name'); width :=66; - setting_type :=ST_CONTACTINFO; - setting_cnftype:=CNF_LASTNAME; flags :=COL_ON; + setting_type :=QST_CONTACTINFO; + cnftype :=CNF_LASTNAME; + end; + inc(i); + + // group + with columns[i] do + begin + StrDupW(title,'Group'); + width :=80; + flags :=COL_ON; + setting_type :=QST_SETTING; + datatype :=QSTS_STRING; + StrDup(module ,'CList'); + StrDup(setting,'Group'); end; + inc(i); - //group - with qsopt.columns[7] do + // TabSRMM container + with columns[i] do begin - MakeTitle(title,'Group'); + StrDupW(title,'Container'); width :=80; - StrDup(module_name,'CList'); - StrDup(wparam.a ,'Group'); - setting_type :=ST_STRING; flags :=COL_ON; + setting_type :=QST_SETTING; + datatype :=QSTS_STRING; + StrDup(module ,'Tab_SRMsg'); + StrDup(setting,'containerW'); end; + inc(i); - //email - with qsopt.columns[8] do + // email + with columns[i] do begin - MakeTitle(title,'E-mail'); + StrDupW(title,'E-mail'); width :=116; - setting_type :=ST_CONTACTINFO; - setting_cnftype:=CNF_EMAIL; flags :=COL_ON; + setting_type :=QST_CONTACTINFO; + cnftype :=CNF_EMAIL; end; + inc(i); - //miranda version - with qsopt.columns[9] do + // miranda version + with columns[i] do begin - MakeTitle(title,'Client ID'); - StrDup(wparam.a,'MirVer'); + StrDupW(title,'Client ID'); width :=60; - setting_type:=ST_STRING; flags :=COL_ON; + setting_type:=QST_SETTING; + datatype :=QSTS_STRING; + StrDup(setting,'MirVer'); end; + inc(i); - //IP version - with qsopt.columns[10] do + // IP version + with columns[i] do begin - MakeTitle(title,'Ext IP'); - StrDup(module_name,'ICQ'); - StrDup(wparam.a ,'IP'); + StrDupW(title,'Ext IP'); width :=100; - setting_type:=ST_IP; flags :=0; + setting_type:=QST_SETTING; + datatype :=QSTS_IP; + StrDup(module ,'ICQ'); + StrDup(setting,'IP'); end; + inc(i); - //LastSeen - with qsopt.columns[11] do + // LastSeen + with columns[i] do begin - MakeTitle(title,'LastSeen'); - StrDup(module_name,'SeenModule'); + StrDupW(title,'LastSeen'); width :=116; - setting_type:=ST_LASTSEEN; flags :=0; + setting_type:=QST_OTHER; + other :=QSTO_LASTSEEN; end; + inc(i); - //last event - with qsopt.columns[12] do + // last event + with columns[i] do begin - MakeTitle(title,'Last Event'); + StrDupW(title,'Last Event'); width :=100; - setting_type:=ST_LASTEVENT; flags :=0; + setting_type:=QST_OTHER; + other :=QSTO_LASTEVENT; end; + inc(i); - //online since - with qsopt.columns[13] do + // online since + with columns[i] do begin - MakeTitle(title,'Online since'); - StrDup(module_name,'ICQ'); - StrDup(wparam.a ,'LogonTS'); + StrDupW(title,'Online since'); width :=100; - setting_type:=ST_TIMESTAMP; flags :=0; + setting_type:=QST_SETTING; + datatype :=QSTS_TIMESTAMP; + StrDup(module ,'ICQ'); + StrDup(setting,'LogonTS'); end; + inc(i); - //metacontacts - with qsopt.columns[14] do + // metacontacts + with columns[i] do begin - MakeTitle(title,'Metacontact'); + StrDupW(title,'Metacontact'); width :=50; - setting_type:=ST_METACONTACT; flags :=0; + setting_type:=QST_OTHER; + other :=QSTO_METACONTACT; end; + inc(i); + + // events + with columns[i] do + begin + StrDupW(title,'Event count'); + width :=50; + flags :=0; + setting_type:=QST_OTHER; + other :=QSTO_EVENTCOUNT; + end; + inc(i); + + result:=i; end; // -------- save/load settings --------- @@ -513,114 +600,93 @@ procedure WriteUnicode(setting:PAnsiChar;value:PWideChar); begin DBWriteUnicode(0,qs_module,setting,value) end; -procedure WriteBool(setting:PAnsiChar;value:bool); + +procedure saveopt_wnd; begin - DBWriteByte(0,qs_module,setting,ord(value)) + WriteInt(so_mbottom ,qsopt.grrect.bottom); + WriteInt(so_mright ,qsopt.grrect.right); + WriteInt(so_mtop ,qsopt.grrect.top); + WriteInt(so_mleft ,qsopt.grrect.left); + + WriteInt(so_flags ,qsopt.flags); + WriteInt(so_columnsort ,qsopt.columnsort); end; -procedure saveopt_wnd; +function savecolumn(num:integer; const column:tcolumnitem):boolean; 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); + if column.setting_type=0 then + begin + result:=false; + exit; + end; + result:=true; pp:=StrCopyE(buf,so_item); - for i:=0 to qsopt.numcolumns-1 do + p:=StrEnd(IntToStr(pp,num)); + with column 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); + StrCopy(p,so__setting_type); WriteWord(buf,setting_type); + StrCopy(p,so__title); WriteUnicode(buf,title); + StrCopy(p,so__flags); WriteWord(buf,flags); + StrCopy(p,so__width); WriteWord(buf,width); + case setting_type of + QST_SETTING: begin + StrCopy(p,so__datatype); WriteInt(buf,datatype); + StrCopy(p,so__module ); WriteStr(buf,module); + StrCopy(p,so__setting ); WriteStr(buf,setting); + end; + + QST_SCRIPT: begin + StrCopy(p,so__script); WriteUnicode(buf,script); + end; + + QST_CONTACTINFO: begin + StrCopy(p,so__cnftype); WriteWord(buf,cnftype); + end; + + QST_SERVICE: begin + StrCopy(p,so__service ); WriteStr(buf,service); + StrCopy(p,so__restype ); WriteInt(buf,restype); + StrCopy(p,so__wparam_type); WriteInt(buf,wparam._type); + StrCopy(p,so__lparam_type); WriteInt(buf,lparam._type); + StrCopy(p,so__wparam); + case wparam._type of + ACF_NUMBER : WriteInt (buf,wparam.value); + ACF_STRING : WriteStr (buf,pointer(wparam.value)); + ACF_UNICODE: WriteUnicode(buf,pointer(wparam.value)); + end; + StrCopy(p,so__lparam); + case lparam._type of + ACF_NUMBER : WriteInt (buf,lparam.value); + ACF_STRING : WriteStr (buf,pointer(lparam.value)); + ACF_UNICODE: WriteUnicode(buf,pointer(lparam.value)); + end; + end; + + QST_OTHER: begin + StrCopy(p,so__other); WriteInt(buf,other); + end; 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; + i,cnt:integer; 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); + DBDeleteGroup(0,qs_module,'item*'); + WriteInt(so_flags,qsopt.flags); - pp:=StrCopyE(buf,so_item); - for i:=0 to qsopt.numcolumns-1 do + cnt:=0; + for i:=0 to MaxColumnAmount-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; + if savecolumn(cnt,qsopt.columns[i]) then + inc(cnt); end; + WriteWord(so_numcolumns,cnt); end; function GetInt(setting:PAnsiChar;default:integer):integer; @@ -631,10 +697,6 @@ 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); @@ -648,100 +710,101 @@ end; if "fast"writing enabled fill columns accordingly comumn order array } -procedure loadopt_db(full:boolean); + +procedure loadopt_wnd; +begin + 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.flags :=GetInt(so_flags,QSO_SORTBYSTATUS+QSO_DRAWGRID+QSO_CLIENTICONS+ + QSO_COLORIZE+QSO_SORTASC); +end; + +function loadopt_db(var columns:array of tcolumnitem):integer; var - i:integer; buf:array [0..127] of AnsiChar; p,pp:PAnsiChar; + i:integer; begin - if full then + if DBGetSettingType(0,qs_module,so_flags)=DBVT_DELETED 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_GETCLIENTICONW)<>0 then - qsopt.showclienticons:=GetBool(so_showclienticons,true) - else - qsopt.showclienticons:=false; + DBDeleteModule(qs_module); + qsopt.flags:= + QSO_SORTBYSTATUS or QSO_DRAWGRID or + QSO_CLIENTICONS or QSO_COLORIZE or + QSO_SORTASC; + result:=0; end else - clear_columns; + begin + qsopt.flags:=GetInt(so_flags, + QSO_SORTBYSTATUS or QSO_DRAWGRID or + QSO_CLIENTICONS or QSO_COLORIZE or + QSO_SORTASC); + result:=GetWord(so_numcolumns,0); + end; - qsopt.numcolumns:=GetWord(so_numcolumns,0); - if qsopt.numcolumns=0 then + if result=0 then begin - loaddefaultcolumns; + result:=loaddefaultcolumns(columns); saveopt_db; end else begin + clear_columns(columns); + 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 +//?? FillChar(qsopt.columns[0],SizeOf(qsopt.columns),0); + for i:=0 to result-1 do begin p:=StrEnd(IntToStr(pp,i)); - with qsopt.columns[i] do + with columns[i] do begin - StrCopy(p,so__title); - title:=GetUnicode(buf); StrCopy(p,so__setting_type); setting_type:=GetWord(buf,0); + StrCopy(p,so__title); title:=GetUnicode(buf); + StrCopy(p,so__width); width:=GetWord(buf,20); + StrCopy(p,so__flags); flags:=GetWord(buf,COL_ON); case setting_type of - ST_SCRIPT: begin - StrCopy(p,so__wparam); - wparam.w:=GetUnicode(buf); + QST_SETTING: begin + StrCopy(p,so__datatype); datatype:=GetInt(buf,0); + StrCopy(p,so__module ); module :=GetStr(buf); + StrCopy(p,so__setting ); setting :=GetStr(buf); + end; + + QST_SCRIPT: begin + StrCopy(p,so__script); script:=GetUnicode(buf); end; - ST_CONTACTINFO: begin - StrCopy(p,so__setting_cnftype); setting_cnftype:=GetWord(buf,0); + + QST_CONTACTINFO: begin + StrCopy(p,so__cnftype); 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); + + QST_SERVICE: begin + StrCopy(p,so__service); service:=GetStr(buf); + StrCopy(p,so__restype); restype:=GetInt(buf,0); + StrCopy(p,so__wparam_type); wparam._type:=GetInt(buf,0); + StrCopy(p,so__lparam_type); lparam._type:=GetInt(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); + ACF_NUMBER : wparam.value:=GetInt(buf,0); + ACF_STRING : wparam.value:=uint_ptr(GetStr(buf)); + ACF_UNICODE: wparam.value:=uint_ptr(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); + ACF_NUMBER : lparam.value:=GetInt(buf,0); + ACF_STRING : lparam.value:=uint_ptr(GetStr(buf)); + ACF_UNICODE: lparam.value:=uint_ptr(GetUnicode(buf)); end; end; - else - StrCopy(p,so__module_name); module_name:=GetStr(buf); - StrCopy(p,so__wparam ); wparam.a :=GetStr(buf); + + QST_OTHER: begin + StrCopy(p,so__other); other:=GetInt(buf,0); + end; end; - StrCopy(p,so__width); width:=GetWord(buf,20); - StrCopy(p,so__flags); flags:=GetInt (buf,COL_ON); end; end; end; diff --git a/plugins/QuickSearch/sr_optdialog.pas b/plugins/QuickSearch/sr_optdialog.pas index 0bdb9e444c..a161fd28dc 100644 --- a/plugins/QuickSearch/sr_optdialog.pas +++ b/plugins/QuickSearch/sr_optdialog.pas @@ -3,36 +3,42 @@ 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; +uses + messages,commctrl, + m_api,common,mirutils,wrapper,dbsettings, + sr_global,sr_window, + sparam,editwrapper,srvblock; var OldListProc:pointer; -const - curscript:pointer=nil; +var + ServiceBlock:HWND; // single copy, can make it global +var + editcolumns:array [0..MaxColumnAmount-1] of tcolumnitem; 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'; + stByte :PWideChar = 'Byte'; + stWord :PWideChar = 'Word'; + stDWord :PWideChar = 'DWord'; + stSigned :PWideChar = 'Signed'; + stHexnum :PWideChar = 'As hex'; + stString :PWideChar = 'String'; + stLastSeen :PWideChar = 'LastSeen'; + stIP :PWideChar = 'IP'; + stContactInfo:PWideChar = 'ContactInfo'; + stLastEvent :PWideChar = 'LastEvent'; + stTimeStamp :PWideChar = 'TimeStamp'; + stService :PWideChar = 'Service'; + stScript :PWideChar = 'Script'; + stMetacontact:PWideChar = 'Metacontact'; + stEventCount :PWideChar = 'EventCount'; + + stSetting :PWideChar = 'DB setting'; + stOther :PWideChar = 'Other'; const cnFirstName = 'FIRSTNAME' ; @@ -57,80 +63,23 @@ const cnBirthday = 'BIRTHDAY' ; cnBirthMonth = 'BIRTHMONTH'; cnBirthYear = 'BIRTHYEAR' ; - cnZIP = 'ZIP' ; cnStreet = 'STREET' ; + cnZIP = 'ZIP' ; 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; + cnCoDept = 'CODEPT' ; + cnCoPosition = 'COPOSITION'; + cnCoStreet = 'COSTREET' ; + cnCoCity = 'COCITY' ; + cnCoState = 'COSTATE' ; + cnCoZIP = 'COZIP' ; + cnCoCountry = 'COCOUNTRY' ; + cnCoHomepage = 'COHOMEPAGE'; + cnDisplayUID = 'DISPLAYUID'; + +//----- Contact info ----- function setcnftype2str(settype:integer):PWideChar; var @@ -166,451 +115,395 @@ begin CNF_LANGUAGE2: res:=cnLanguage2 ; CNF_LANGUAGE3: res:=cnLanguage3 ; CNF_CONAME: res:=cnCoName ; + CNF_CODEPT: res:=cnCoDept ; + CNF_COPOSITION: res:=cnCoPosition; + CNF_COSTREET: res:=cnCoStreet ; + CNF_COCITY: res:=cnCoCity ; + CNF_COSTATE: res:=cnCoState ; + CNF_COZIP: res:=cnCoZIP ; + CNF_COCOUNTRY: res:=cnCoCountry ; + CNF_COHOMEPAGE: res:=cnCoHomepage; + CNF_DISPLAYUID: res:=cnDisplayUID; 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; +procedure AddCnf(list:HWND;param:integer); begin - lvcol.mask:=LVCF_TEXT or LVCF_WIDTH; - lvcol.cx :=width; - lvcol.pszText:=TranslateW(FastAnsiToWideBuf(title,buf)); - SendMessageW(handle,LVM_INSERTCOLUMNW,0,lparam(@lvcol)); +// CB_AddStrDataW(list,setcnftype2str(param),param); + SendMessage(list,CB_SETITEMDATA, + SendMessageW(list,CB_ADDSTRING,0,lparam(setcnftype2str(param))), + param); end; -function getselecteditem(list:hwnd):integer; +procedure addsetcnftypes(list:hwnd); begin - result:=SendMessage(list,LVM_GETNEXTITEM,-1,LVNI_FOCUSED); -end; + 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); -function savecuritem(Dialog:hwnd):integer; -var - listhwnd:hwnd; - selitem:integer; + 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); + AddCnf(list,CNF_CODEPT); + AddCnf(list,CNF_COPOSITION); + AddCnf(list,CNF_COSTREET); + AddCnf(list,CNF_COCITY); + AddCnf(list,CNF_COSTATE); + AddCnf(list,CNF_COZIP); + AddCnf(list,CNF_COCOUNTRY); + AddCnf(list,CNF_COHOMEPAGE); + AddCnf(list,CNF_DISPLAYUID); - 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; + SendMessage(list,CB_SETCURSEL,0,0); +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; +function GetSelectedItem(list:hwnd):integer; +begin + result:=SendMessage(list,LVM_GETNEXTITEM,-1,LVNI_FOCUSED); +end; -var - tpc :array [0..127] of WideChar; - tmpwnd:HWND; - oldtype,i:integer; - column:integer; +//----- Common interface ----- + +function IconChanged(wParam:WPARAM;lParam:LPARAM;lParam1:LPARAM):int;cdecl; begin - listhwnd:=GetDlgItem(Dialog,IDC_LIST); - selitem:=getselecteditem(listhwnd); -//!! column:=LV_GetLParam(listhwnd,selitem); - column:=selitem; - result:=selitem; - if (selitem>=0) and (selitem0); - oldtype:=setting_type; + EnableWindow(GetDlgItem(Dialog,IDC_DN), + item<(SendMessage(GetDlgItem(Dialog,IDC_LIST),LVM_GETITEMCOUNT,0,0)-1)); +end; - tmpwnd:=GetDlgItem(Dialog,IDC_C_VARTYPE); +//----- Basic screen functions ----- - setting_type:=SendMessage(tmpwnd,CB_GETITEMDATA, - SendMessage(tmpwnd,CB_GETCURSEL,0,0),0); +procedure InitScreen(Dialog:HWND); +begin + // setting + SendMessage(GetDlgItem(Dialog,IDC_C_DATATYPE),CB_SETCURSEL,0,0); + SetDlgItemTextW(Dialog,IDC_E_MODULE ,nil); + SetDlgItemTextW(Dialog,IDC_E_SETTING,nil); + // script + SetDlgItemTextW(Dialog,IDC_E_SCRIPT,nil); + // service + ClearServiceBlock(ServiceBlock); + // contact info + SendMessage(GetDlgItem(Dialog,IDC_C_CNFTYPE),CB_SETCURSEL,0,0); + // others + SendMessage(GetDlgItem(Dialog,IDC_C_OTHER),CB_SETCURSEL,0,0); +end; - GetText(IDC_E_TITLE,1,title); +procedure ClearScreen(Dialog:HWND); +begin + // setting + ShowWindow(GetDlgItem(Dialog,IDC_S_DATATYPE),SW_HIDE); + ShowWindow(GetDlgItem(Dialog,IDC_C_DATATYPE),SW_HIDE); + ShowWindow(GetDlgItem(Dialog,IDC_S_MODULE ),SW_HIDE); + ShowWindow(GetDlgItem(Dialog,IDC_E_MODULE ),SW_HIDE); + ShowWindow(GetDlgItem(Dialog,IDC_S_SETTING ),SW_HIDE); + ShowWindow(GetDlgItem(Dialog,IDC_E_SETTING ),SW_HIDE); + + // script + ShowEditField(Dialog,IDC_E_SCRIPT,SW_HIDE); + + // service + ShowWindow(ServiceBlock,SW_HIDE); + + // contact info + ShowWindow(GetDlgItem(Dialog,IDC_S_CNFTYPE),SW_HIDE); + ShowWindow(GetDlgItem(Dialog,IDC_C_CNFTYPE),SW_HIDE); + + // others + ShowWindow(GetDlgItem(Dialog,IDC_C_OTHER),SW_HIDE); +end; - 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; +procedure SetupScreen(Dialog:HWND;code:integer); +begin + if not IsWindowVisible(GetDlgItem(Dialog,IDC_E_TITLE)) then + exit; - case setting_type of - ST_METACONTACT: begin - LV_SetItemW(listhwnd,TranslateW('Metacontact'),selitem,2); - end; + case code of + // setting + QST_SETTING: begin + ShowWindow(GetDlgItem(Dialog,IDC_S_DATATYPE),SW_SHOW); + ShowWindow(GetDlgItem(Dialog,IDC_C_DATATYPE),SW_SHOW); + ShowWindow(GetDlgItem(Dialog,IDC_S_MODULE ),SW_SHOW); + ShowWindow(GetDlgItem(Dialog,IDC_E_MODULE ),SW_SHOW); + ShowWindow(GetDlgItem(Dialog,IDC_S_SETTING ),SW_SHOW); + ShowWindow(GetDlgItem(Dialog,IDC_E_SETTING ),SW_SHOW); + end; - ST_SCRIPT: begin - StrDupW(wparam.w,curscript); - LV_SetItemW(listhwnd,TranslateW('Script'),selitem,2); - end; + // script + QST_SCRIPT: begin + ShowEditField(Dialog,IDC_E_SCRIPT,SW_SHOW); + end; - ST_CONTACTINFO: begin - FillChar(tpc,SizeOf(tpc),0); - tmpwnd:=GetDlgItem(Dialog,IDC_C_CNFTYPE); + // service + QST_SERVICE: begin + ShowWindow(ServiceBlock,SW_SHOW); + end; - i:=SendMessage(tmpwnd,CB_GETCURSEL,0,0); - setting_cnftype:=SendMessage(tmpwnd,CB_GETITEMDATA,i,0); + // contact info + QST_CONTACTINFO: begin + ShowWindow(GetDlgItem(Dialog,IDC_S_CNFTYPE),SW_SHOW); + ShowWindow(GetDlgItem(Dialog,IDC_C_CNFTYPE),SW_SHOW); + end; - SendMessageW(tmpwnd,CB_GETLBTEXT,i,tlparam(@tpc)); - LV_SetItemW(listhwnd,tpc,selitem,2); - end; + // others + QST_OTHER: begin + ShowWindow(GetDlgItem(Dialog,IDC_C_OTHER),SW_SHOW); + end; + end; +end; - ST_SERVICE: begin - GetText(IDC_E_MODULE,3,module_name); - LV_SetItemW(listhwnd,TranslateW('Service'),selitem,2); -//!! setitem(listhwnd,selitem,3,module_name); +//----- single column processing ----- - 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); +procedure FillTableLine(list:HWND;item:integer;const column:tcolumnitem); +begin + LV_SetItemW(list,column.title,item,1); + case column.setting_type of + QST_SETTING: begin + LV_SetItem(list,column.module ,item,2); + LV_SetItem(list,column.setting,item,3); + end; + QST_SCRIPT: begin + LV_SetItemW(list,TranslateW('Script'),item,2); +// LV_SetItemW(list,column.script,item,3); + end; + QST_SERVICE: begin + LV_SetItemW(list,TranslateW('Service'),item,2); + LV_SetItem (list,column.service ,item,3); + end; + QST_CONTACTINFO: begin + LV_SetItemW(list,TranslateW('Contact info') ,item,2); + LV_SetItemW(list,setcnftype2str(column.cnftype),item,3); + end; + QST_OTHER: begin + case column.other of + QSTO_METACONTACT: begin + LV_SetItemW(list,TranslateW('Metacontact'),item,2); 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); +function savecuritem(Dialog:hwnd):integer; +var + list:HWND; + srvalue:tServiceValue; + i:integer; + idx,lwidth:integer; begin - EnableWindow(GetDlgItem(Dialog,id),FALSE); -end; + list:=GetDlgItem(Dialog,IDC_LIST); + i:=GetSelectedItem(list); + idx:=LV_GetLParam(list,i); + result:=idx; + + lwidth:=editcolumns[idx].width; + clear_column(editcolumns[idx]); + with editcolumns[idx] do + begin + flags:=0; -procedure enable_elem(Dialog:hwnd;id:cardinal); -begin - EnableWindow(GetDlgItem(Dialog,id),TRUE); -end; + if ListView_GetCheckState(list,i)=BST_CHECKED then + flags:=flags or COL_ON; -procedure CheckDirection(Dialog:HWND;item:integer); -begin - if item=0 then - disable_elem(Dialog,IDC_UP) - else - enable_elem(Dialog,IDC_UP); + setting_type:=CB_GetData(GetDlgItem(Dialog,IDC_C_VARTYPE)); + + title:=GetDlgText(Dialog,IDC_E_TITLE); + width:=lwidth; - if item=(qsopt.numcolumns-1) then - disable_elem(Dialog,IDC_DN) - else - enable_elem(Dialog,IDC_DN); -end; + case setting_type of + QST_SETTING: begin + datatype:=CB_GetData(GetDlgItem(Dialog,IDC_C_DATATYPE)); + module :=GetDlgText(Dialog,IDC_E_MODULE ,true); + setting :=GetDlgText(Dialog,IDC_E_SETTING,true); + end; + + QST_SCRIPT: begin + script:=GetDlgText(Dialog,IDC_E_SCRIPT); + end; -procedure displcurinfo(Dialog:hwnd;column:integer); + QST_CONTACTINFO: begin + cnftype:=CB_GetData(GetDlgItem(Dialog,IDC_C_CNFTYPE)); + end; - 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,''); + QST_SERVICE: begin + GetSrvBlockValue(ServiceBlock,srvalue); + service :=srvalue.service; + wparam.value:=uint_ptr(srvalue.wparam); + wparam._type:=srvalue.w_flag; + lparam.value:=uint_ptr(srvalue.lparam); + lparam._type:=srvalue.l_flag; + restype :=srvalue.flags; + end; + + QST_OTHER: begin + other:=CB_GetData(GetDlgItem(Dialog,IDC_C_OTHER)); + end; end; - EnableWindow(GetDlgItem(Dialog,id),param._type<>ptCurrent); end; + FillTableLine(list,i,editcolumns[idx]); +end; +procedure displcurinfo(Dialog:HWND;const column:tcolumnitem); var - v:PWideChar; - i:int_ptr; - selpos:integer; + srvalue:tServiceValue; begin - CheckDirection(Dialog,column); + ClearScreen(Dialog); + SetupScreen(Dialog,column.setting_type); - selpos:=column; - if (selpos>=0) and (selpos0); - 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; + i,cnt:integer; begin ListView_DeleteAllItems(list); - ListView_SetItemCount(list,qsopt.numcolumns); - for i:=0 to qsopt.numcolumns-1 do + cnt:=0; + for i:=0 to MaxColumnAmount-1 do begin - add_column(list,i); + if editcolumns[i].setting_type<>0 then + begin + add_column(list,cnt,i); + FillTableLine(list,cnt,editcolumns[i]); + ListView_SetCheckState(list,cnt,(editcolumns[i].flags and COL_ON)<>0); + inc(cnt); + end; 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); + ListView_SetItemState(list,0, + LVIS_FOCUSED or LVIS_SELECTED, + LVIS_FOCUSED or LVIS_SELECTED); end; -procedure addparamtypes(list:integer); -begin - addresulttypes(list); - SendMessageW(list,CB_INSERTSTRING,ptCurrent,lparam(TranslateW('current contact'))); -end; +// fill comboboxes lists -procedure AddVal(list:HWND;param:integer); -var - i:integer; - v:pointer; +procedure adddbsettypes(list:hwnd); begin - v:=settype2str(param); - i:=SendMessageW(list,CB_ADDSTRING,0,lparam(v)); - mFreeMem(v); - SendMessage(list,CB_SETITEMDATA,i,param); -end; + CB_AddStrDataW(list,stByte ,QSTS_BYTE); + CB_AddStrDataW(list,stWord ,QSTS_WORD); + CB_AddStrDataW(list,stDword ,QSTS_DWORD); + CB_AddStrDataW(list,stSigned ,QSTS_SIGNED); + CB_AddStrDataW(list,stHexnum ,QSTS_HEXNUM); + CB_AddStrDataW(list,stString ,QSTS_STRING); + CB_AddStrDataW(list,stIP ,QSTS_IP); + CB_AddStrDataW(list,stTimeStamp,QSTS_TIMESTAMP); -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); +procedure addothertypes(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); + CB_AddStrDataW(list,stLastSeen ,QSTO_LASTSEEN); + CB_AddStrDataW(list,stLastEvent ,QSTO_LASTEVENT); + CB_AddStrDataW(list,stMetacontact,QSTO_METACONTACT); + CB_AddStrDataW(list,stEventCount ,QSTO_EVENTCOUNT); SendMessage(list,CB_SETCURSEL,0,0); end; -procedure _GetIcon(idc:integer;ico:PAnsiChar); +procedure addsettypes(list:hwnd); begin - SetButtonIcon(GetDlgItem(maindlg,idc),ico); -end; + CB_AddStrDataW(list,stSetting,QST_SETTING); -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); + CB_AddStrDataW(list,stScript ,QST_SCRIPT); + CB_AddStrDataW(list,stService ,QST_SERVICE); + CB_AddStrDataW(list,stContactInfo,QST_CONTACTINFO); + + CB_AddStrDataW(list,stOther,QST_OTHER); + + SendMessage(list,CB_SETCURSEL,0,0); end; -function ScriptEdit(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall; +procedure addcolumn(handle:hwnd;width:word;title:PWideChar); var - tmp:pointer; - vhi:TVARHELPINFO; + lvcol:LV_COLUMNW; 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; + lvcol.mask :=LVCF_TEXT or LVCF_WIDTH; + lvcol.cx :=width; + lvcol.pszText:=TranslateW(title); + SendMessageW(handle,LVM_INSERTCOLUMNW,0,lparam(@lvcol)); end; function NewListProc(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):integer; stdcall; @@ -646,40 +539,199 @@ begin 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; +procedure ResizeControl(Dialog:HWND;id:integer;width:integer); +var + wnd:HWND; + rc:TRECT; +begin + wnd:=GetDlgItem(Dialog,id); + GetWindowRect(wnd,rc); + SetWindowPos(wnd,0,0,0,width,rc.bottom-rc.top,SWP_NOMOVE or SWP_NOZORDER or SWP_SHOWWINDOW); +end; + +procedure DoResize(Dialog:HWND); +var + wSeparator:HWND; + pcw:pWideChar; + rc,rc1:TRECT; + pt:TPOINT; + dx,rside:integer; +begin + GetClientRect(Dialog,rc); + wSeparator:=GetDlgItem(Dialog,IDC_B_RESIZE); + GetWindowRect(wSeparator,rc1); + pt.x:=rc1.left; + pt.y:=0; + ScreenToClient(Dialog,pt); + if pt.x<(rc.right-50) then //!! + begin + rside:=SW_HIDE; + dx:=rc.right-(rc1.right-rc1.left)-4; + pcw:='<'; + end + else + begin + rside:=SW_SHOW; + + GetWindowRect(GetDlgItem(Dialog,IDC_S_COLSETTING),rc); + pt.x:=rc.left; + pt.y:=0; + ScreenToClient(Dialog,pt); + dx:=pt.x-(rc1.right-rc1.left)-4; + pcw:='>'; + end; + SendMessageW(wSeparator,WM_SETTEXT,0,lparam(pcw)); + + // move separator button + SetWindowPos(wSeparator,0,dx+2,2,0,0,SWP_NOSIZE or SWP_NOZORDER or SWP_SHOWWINDOW); + + // resize left side controls + ResizeControl(Dialog,IDC_LIST ,dx); + ResizeControl(Dialog,IDC_CH_GROUP,dx); + + ResizeControl(Dialog,IDC_CH_USETOOLSTYLE,dx-8); + ResizeControl(Dialog,IDC_CH_DRAWGRID ,dx-8); + ResizeControl(Dialog,IDC_CH_SAVEPATTERN ,dx-8); + ResizeControl(Dialog,IDC_CH_AUTOCLOSE ,dx-8); + ResizeControl(Dialog,IDC_CH_SORTSTATUS ,dx-8); + ResizeControl(Dialog,IDC_CH_CLIENTICONS ,dx-8); + + // show/hide setting block (ugly, i know!) + ShowWindow(GetDlgItem(Dialog,IDC_S_COLSETTING),rside); + ShowWindow(GetDlgItem(Dialog,IDC_S_LINE ),rside); + ShowWindow(GetDlgItem(Dialog,IDC_S_TITLE ),rside); + ShowWindow(GetDlgItem(Dialog,IDC_E_TITLE ),rside); + ShowWindow(GetDlgItem(Dialog,IDC_S_VARTYPE ),rside); + ShowWindow(GetDlgItem(Dialog,IDC_C_VARTYPE ),rside); + ShowWindow(GetDlgItem(Dialog,IDC_SETITEM ),rside); + + ClearScreen(Dialog); + + if rside=SW_SHOW then + begin + SetupScreen(Dialog,CB_GetData(GetDlgItem(Dialog,IDC_C_VARTYPE))); + end; +end; + +procedure SetButtons(Dialog:HWND); 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; +begin +{ + 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); + 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(hUp ,QS_UP); + SetButtonIcon(hDown ,QS_DOWN); + SetButtonIcon(hDelete ,QS_DELETE); + SetButtonIcon(hDefault,QS_DEFAULT); + SetButtonIcon(hReload ,QS_RELOAD); + +end; + +procedure AddControls(Dialog:HWND); +var + rc:TRECT; + pt,pt1:TPOINT; + width,height:integer; +begin + // Settings + // Script + MakeEditField(Dialog, IDC_E_SCRIPT); + SetEditFlags (Dialog, IDC_E_SCRIPT,EF_FORCE,EF_FORCES); + + // Service + GetWindowRect(GetDlgItem(Dialog,IDC_C_VARTYPE),rc); + width:=rc.right-rc.left; + pt.x:=rc.left; + pt.y:=rc.bottom; + ScreenToClient(Dialog,pt); + + GetWindowRect(GetDlgItem(Dialog,IDC_SETITEM),rc); + pt1.x:=rc.left; + pt1.y:=rc.top; + ScreenToClient(Dialog,pt1); + + height:=pt1.y-pt.y-2; + ServiceBlock:=CreateServiceBlock(Dialog,pt.x,pt.y,width,height,ACF_NOSTRUCT); + + // Contact info + // Other +end; + +function DlgProcOptions(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall; +const + InitDlg:bool = true; + hook:THANDLE = 0; +var + pc:pWideChar; + i,idx:integer; + itemsel:integer; 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); + clear_columns(editcolumns); - mFreeMem(curscript); if hook<>0 then UnhookEvent(hook); - maindlg:=0; + + listhwnd:=GetDlgItem(Dialog,IDC_LIST); + DBWriteWord(0,qs_module,'col1',ListView_GetColumnWidth(listhwnd,1)); + DBWriteWord(0,qs_module,'col2',ListView_GetColumnWidth(listhwnd,2)); + DBWriteWord(0,qs_module,'col3',ListView_GetColumnWidth(listhwnd,3)); end; WM_INITDIALOG: begin @@ -692,99 +744,39 @@ begin TranslateDialogDefault(Dialog); - addcolumn(listhwnd,95 ,'Setting'); - addcolumn(listhwnd,105,'Module/InfoType'); - addcolumn(listhwnd,85 ,'Title'); + addcolumn(listhwnd,DBReadWord(0,qs_module,'col3',95) ,'Setting'); + addcolumn(listhwnd,DBReadWord(0,qs_module,'col2',105),'Module/InfoType'); + addcolumn(listhwnd,DBReadWord(0,qs_module,'col1',85) ,'Title'); addcolumn(listhwnd,20 ,'#'); + addsettypes (GetDlgItem(Dialog,IDC_C_VARTYPE)); + adddbsettypes (GetDlgItem(Dialog,IDC_C_DATATYPE)); + addothertypes (GetDlgItem(Dialog,IDC_C_OTHER)); 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_GETCLIENTICONW)<>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); + + CheckDlgButton(Dialog,IDC_CH_SORTSTATUS ,ORD((qsopt.flags and QSO_SORTBYSTATUS)<>0)); + CheckDlgButton(Dialog,IDC_CH_AUTOCLOSE ,ORD((qsopt.flags and QSO_AUTOCLOSE)<>0)); + CheckDlgButton(Dialog,IDC_CH_USETOOLSTYLE,ORD((qsopt.flags and QSO_TOOLSTYLE)<>0)); + CheckDlgButton(Dialog,IDC_CH_DRAWGRID ,ORD((qsopt.flags and QSO_DRAWGRID)<>0)); + CheckDlgButton(Dialog,IDC_CH_SAVEPATTERN ,ORD((qsopt.flags and QSO_SAVEPATTERN)<>0)); + CheckDlgButton(Dialog,IDC_CH_CLIENTICONS ,ORD((qsopt.flags and QSO_CLIENTICONS)<>0)); + + SetButtons(Dialog); + + AddControls(Dialog); + + CloneColumns(editcolumns,qsopt.columns); update_list(listhwnd); - maindlg:=Dialog; - hook:=HookEvent(ME_SKIN2_ICONSCHANGED,@IconChanged); + hook:=HookEventParam(ME_SKIN2_ICONSCHANGED,@IconChanged,Dialog); result:=1; OldListProc:=pointer(SetWindowLongPtrW(listhwnd,GWL_WNDPROC,LONG_PTR(@NewListProc))); + DoResize(Dialog); + InitDlg:=false; end; @@ -795,45 +787,75 @@ begin // checkboxes listhwnd:=GetDlgItem(Dialog,IDC_LIST); - for i:=0 to SendMessage(listhwnd,LVM_GETITEMCOUNT,0,0)-1 do + clear_columns(qsopt.columns); + qsopt.numcolumns:=SendMessage(listhwnd,LVM_GETITEMCOUNT,0,0); + for i:=0 to qsopt.numcolumns-1 do begin - with qsopt.columns[i] do + idx:=LV_GetLParam(listhwnd,i); + with editcolumns[idx] do begin if ListView_GetCheckSTate(listhwnd,i)=0 then flags:=flags and not COL_ON else flags:=flags or COL_ON; end; + CloneColumn(qsopt.columns[i],editcolumns[idx]); 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; + qsopt.flags:=qsopt.flags and not QSO_MAINOPTIONS; + + if IsDlgButtonChecked(Dialog,IDC_CH_SORTSTATUS)<>BST_UNCHECKED then + qsopt.flags:=qsopt.flags or QSO_SORTBYSTATUS; + + if IsDlgButtonChecked(Dialog,IDC_CH_AUTOCLOSE)<>BST_UNCHECKED then + qsopt.flags:=qsopt.flags or QSO_AUTOCLOSE; + + if IsDlgButtonChecked(Dialog,IDC_CH_USETOOLSTYLE)<>BST_UNCHECKED then + qsopt.flags:=qsopt.flags or QSO_TOOLSTYLE; + + if IsDlgButtonChecked(Dialog,IDC_CH_DRAWGRID)<>BST_UNCHECKED then + qsopt.flags:=qsopt.flags or QSO_DRAWGRID; + + if IsDlgButtonChecked(Dialog,IDC_CH_CLIENTICONS)<>BST_UNCHECKED then + qsopt.flags:=qsopt.flags or QSO_CLIENTICONS; + if IsDlgButtonChecked(Dialog,IDC_CH_SAVEPATTERN)<>BST_UNCHECKED then + qsopt.flags:=qsopt.flags or QSO_SAVEPATTERN; +{ + if IsDlgButtonChecked(Dialog,IDC_CH_SORTSTATUS)<>BST_UNCHECKED then + qsopt.flags:=qsopt.flags or QSO_SORTBYSTATUS + else + qsopt.flags:=qsopt.flags and not QSO_SORTBYSTATUS; + + if IsDlgButtonChecked(Dialog,IDC_CH_AUTOCLOSE)<>BST_UNCHECKED then + qsopt.flags:=qsopt.flags or QSO_AUTOCLOSE + else + qsopt.flags:=qsopt.flags and not QSO_AUTOCLOSE; + + if IsDlgButtonChecked(Dialog,IDC_CH_USETOOLSTYLE)<>BST_UNCHECKED then + qsopt.flags:=qsopt.flags or QSO_TOOLSTYLE + else + qsopt.flags:=qsopt.flags and not QSO_TOOLSTYLE; + + if IsDlgButtonChecked(Dialog,IDC_CH_DRAWGRID)<>BST_UNCHECKED then + qsopt.flags:=qsopt.flags or QSO_DRAWGRID + else + qsopt.flags:=qsopt.flags and not QSO_DRAWGRID; + + if IsDlgButtonChecked(Dialog,IDC_CH_CLIENTICONS)<>BST_UNCHECKED then + qsopt.flags:=qsopt.flags or QSO_CLIENTICONS + else + qsopt.flags:=qsopt.flags and not QSO_CLIENTICONS; + + if IsDlgButtonChecked(Dialog,IDC_CH_SAVEPATTERN)<>BST_UNCHECKED then + qsopt.flags:=qsopt.flags or QSO_SAVEPATTERN + else + qsopt.flags:=qsopt.flags and not QSO_SAVEPATTERN; +} saveopt_db; + //?? refresh QS window if it was opened + if CloseSrWindow then + OpenSrWindow(nil,qsopt.flags); result:=1; end; @@ -844,14 +866,10 @@ begin (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; + CheckDirection(Dialog,PNMLISTVIEW(lParam)^.iItem); + InitScreen(Dialog); + displcurinfo(Dialog,editcolumns[PNMLISTVIEW(lParam)^.lParam]); + result:=1; end else if (i=0) and not InitDlg then begin @@ -861,11 +879,6 @@ begin 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; @@ -876,166 +889,150 @@ begin 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); + case wParam shr 16 of + CBN_SELCHANGE: begin + if loword(wParam)=IDC_C_VARTYPE then + begin + ClearScreen(Dialog); + SetupScreen(Dialog,CB_GetData(lParam)); end; end; - end; - if not InitDlg then - case wParam shr 16 of - CBN_SELCHANGE, - BN_CLICKED, - EN_CHANGE: begin + BN_CLICKED: begin + if loword(wParam)<>IDC_B_RESIZE then 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; + listhwnd:=GetDlgItem(Dialog,IDC_LIST); + result:=1; + case loword(wParam) of + IDC_NEW: begin + i:=GetSelectedItem(listhwnd)+1; + add_column(listhwnd,i,new_column(editcolumns)); + + SendMessage(listhwnd,LVM_ENSUREVISIBLE,i,0); + ListView_SetItemState(listhwnd,i, + LVIS_FOCUSED+LVIS_SELECTED,LVIS_FOCUSED+LVIS_SELECTED); + InitScreen(Dialog); + CheckDirection(Dialog,i); + EnableWindow(GetDlgItem(Dialog,IDC_DELETE),true); + end; - IDC_NEW: begin - InitDlg:=true; - WndChangeColumns(wcInsert, - add_column(listhwnd,new_column(getselecteditem(listhwnd)))); + IDC_DELETE: begin + i:=GetSelectedItem(listhwnd); + clear_column(editcolumns[LV_GetLParam(listhwnd,i)]); + SendMessage(listhwnd,LVM_DELETEITEM,i,0); - 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; + idx:=SendMessage(listhwnd,LVM_GETITEMCOUNT,0,0); + if idx=0 then + begin + EnableWindow(lParam,false); + InitScreen(Dialog); + end + else + begin + if i=idx then dec(i); + ListView_SetItemState(listhwnd,i, + LVIS_FOCUSED+LVIS_SELECTED,LVIS_FOCUSED+LVIS_SELECTED); + end; + CheckDirection(Dialog,i); + end; - IDC_DELETE: begin - i:=getselecteditem(listhwnd); - SendMessage(listhwnd,LVM_DELETEITEM,i,0); - delete_column(i); - WndChangeColumns(wcDelete,i); -// update_list(listhwnd); + IDC_UP: begin + itemsel:=GetSelectedItem(listhwnd); + if itemsel>0 then + begin + LV_MoveItem(listhwnd,-1,itemsel); + CheckDirection(Dialog,itemsel-1); + end; + end; - if i=qsopt.numcolumns then dec(i); - ListView_SetItemState(listhwnd,i, - LVIS_FOCUSED+LVIS_SELECTED,LVIS_FOCUSED+LVIS_SELECTED); - end; + IDC_DN: begin + itemsel:=GetSelectedItem(listhwnd); + if itemsel>=0 then + begin + LV_MoveItem(listhwnd,1,itemsel); + CheckDirection(Dialog,itemsel+1); + end; + 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_SETITEM: begin + if SendMessage(listhwnd,LVM_GETITEMCOUNT,0,0)=0 then + begin + add_column(listhwnd,0,0); + ListView_SetItemState(listhwnd,0, + LVIS_FOCUSED+LVIS_SELECTED,LVIS_FOCUSED+LVIS_SELECTED); + EnableWindow(GetDlgItem(Dialog,IDC_DELETE),true); + end; + savecuritem(Dialog); + 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); + IDC_DEFAULT: begin + loaddefaultcolumns(editcolumns); + update_list(listhwnd); + end; + + IDC_RELOAD: begin + loadopt_db(editcolumns); + update_list(listhwnd); + end; + + IDC_B_RESIZE: begin + DoResize(Dialog); + end; + else + result:=0; end; end; + end; + end; - IDC_SETITEM: begin - WndChangeColumns(wcChange,savecuritem(Dialog)); + WM_HELP: begin + case CB_GetData(GetDlgItem(Dialog,IDC_C_VARTYPE)) of + QST_SETTING: begin + MessageBoxW(0, + TranslateW('Column content is simple database setting.'), + TranslateW('DB setting'),0); end; - - IDC_DEFAULT: begin - InitDlg:=true; - loaddefaultcolumns; - update_list(listhwnd); - WndChangeColumns(wcRefresh); - InitDlg:=false; + QST_SCRIPT: begin + MessageBoxW(0, + TranslateW('Column content is script result.'#13#10+ + 'More help from "Help" button in script dialog.'), + TranslateW('Script'),0); end; - - IDC_RELOAD: begin - InitDlg:=true; - loadopt_db(false); - update_list(listhwnd); - WndChangeColumns(wcRefresh); - InitDlg:=false; + QST_SERVICE: begin + SendMessage(ServiceBlock,WM_HELP,0,0); + end; + QST_CONTACTINFO: begin + MessageBoxW(0, + TranslateW('Column content is contact property (see list). Can be empty.'), + TranslateW('ContactInfo'),0); + end; + QST_OTHER: begin + case CB_GetData(GetDlgItem(Dialog,IDC_C_OTHER)) of + QSTO_LASTSEEN: begin + pc:='Content is last online time.'; + end; + QSTO_LASTEVENT: begin + pc:='Content is time of last contact event.'; + end; + QSTO_METACONTACT: begin + pc:='Content is metacontact info.'; + end; + QSTO_EVENTCOUNT: begin + pc:='Content is count of ALL contact events (not messages only)'; + end; + end; + MessageBoxW(0,TranslateW(pc),TranslateW('Other info'),0); end; - else - result:=0; end; + result:=1; 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; + DefWindowProc(Dialog,hMessage,wParam,lParam); end; end. diff --git a/plugins/QuickSearch/sr_window.pas b/plugins/QuickSearch/sr_window.pas index 361ec3ca4e..dea7113310 100644 --- a/plugins/QuickSearch/sr_window.pas +++ b/plugins/QuickSearch/sr_window.pas @@ -5,14 +5,8 @@ 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 @@ -21,28 +15,24 @@ const implementation uses messages,commctrl,sr_global,common,dbsettings,mirutils, - wrapper,sr_optdialog,protocols; + wrapper,protocols,sparam,srvblock,editwrapper; + +const + IDM_STAYONTOP = WM_USER+1; 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; + OldLVHProc :pointer = nil; OldEditProc:pointer = nil; -const - pattern:pWideChar = nil; const QSF_INLIST = $0001; // in constant list QSF_ACTIVE = $0002; // contact in listview @@ -60,35 +50,24 @@ type data:uint_ptr; end; pQSFRec = ^tQSFRec; - tQSFRec = record // row + tQSFRec = record // row (contact) contact:THANDLE; proto :uint_ptr; flags :dword; status :dword; - wparam :WPARAM; +//--- Metacontacts only --- + wparam :WPARAM; lparam :LPARAM; end; var - colorhook:THANDLE; MainBuf:array of array of tQSRec; FlagBuf:array of tQSFRec; LastMeta:integer; + tablecolumns:integer; +var 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; @@ -96,550 +75,134 @@ 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; +{$i i_ok.inc} -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; +function FindItem(num:integer):integer; var - Day,Month,Year,Hours,Minutes:word; + fi:LV_FINDINFO; begin - Year:=DBReadWord(cont,modulename,'Year',0); - if Year<>0 then + if num>=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 + FillChar(fi,SizeOf(fi),0); + fi.flags :=LVFI_PARAM; + fi.lParam:=num; + result:=SendMessage(grid,LVM_FINDITEM,wparam(-1),lparam(@fi)); 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); + result:=num; end; -function FindMeta(hMeta:THANDLE;var MetaNum:WPARAM):LPARAM; +function GetLVSubItem(x,y:integer):integer; var - i:integer; + pinfo:LV_HITTESTINFO; begin - result:=0; - for i:=0 to HIGH(FlagBuf) do + pinfo.flags:=0; + pinfo.pt.x:=x; + pinfo.pt.y:=y; + ScreenToClient(grid,pinfo.pt); + result:=-1; + if integer(SendMessage(grid,LVM_SUBITEMHITTEST,0,tlparam(@pinfo)))<>-1 then begin - with FlagBuf[i] do + if (pinfo.flags and LVHT_ONITEM)<>0 then 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; + result:=pinfo.iSubItem; end; end; end; -function DoMeta(hContact:THANDLE):pointer; +procedure AddContactToList(hContact:THANDLE;num:integer); var - pw:pWideChar; + li:LV_ITEMW; i:integer; begin - result:=nil; - for i:=0 to HIGH(FlagBuf) do + 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; + li.iSubItem:=0; + for i:=0 to qsopt.numcolumns-1 do begin - with FlagBuf[i] do + with qsopt.columns[i] do begin - if contact=hContact then + if (flags and COL_ON)<>0 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; + // Client icons preprocess + li.pszText :=MainBuf[num,i].text; + if (((flags and COL_CLIENT)<>0) and + ((qsopt.flags and QSO_CLIENTICONS)<>0) and + (li.pszText<>NIL)) OR + ((flags and (COL_XSTATUS or COL_GENDER))<>0) then + li.mask:=LVIF_IMAGE or LVIF_TEXT + else + li.mask:=LVIF_TEXT; + SendMessageW(grid,LVM_SETITEMW,0,tlparam(@li)); + inc(li.iSubItem); end; end; end; end; -procedure LoadOneItem(hContact:THANDLE;num:integer;proto:integer; var res:tQSRec); + +procedure ProcessLine(num:integer;test:boolean=true); var - cni:TCONTACTINFO; - dbei:TDBEVENTINFO; - hDbEvent:cardinal; - tmp:int_ptr; - protov:PAnsiChar; + p:pQSFRec; + l:boolean; begin - FillChar(res,SizeOf(tQSRec),0); - res.data:=uint_ptr(-1); - res.text:=nil; - with qsopt.columns[num] do - begin + p:=@FlagBuf[num]; + if (p^.flags and QSF_DELETED)<>0 then + exit; - if module_name<>nil then - protov:=module_name + if test then + begin + l:=CheckPatternW(num); + if l then + p^.flags:=p^.flags or QSF_PATTERN 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:=int_ptr(CallService(protov,wparam.n,lparam.n)); - if tmp=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; + p^.flags:=p^.flags and not QSF_PATTERN; + end + else + l:=(p^.flags and QSF_PATTERN)<>0;//true; - ST_INT: begin - if (module_name=nil) and (wparam.a=nil) then - begin - res.data:=hContact; - res.text:=int2hexw(res.data); - end - else + if l then + begin + if (p^.flags and QSF_ACTIVE)=0 then + begin + if ((qsopt.flags and QSO_SHOWOFFLINE)<>0) or (p^.status<>ID_STATUS_OFFLINE) then + begin + // check for proto in combo + if (LoByte(AdvFilter)=0) or (p^.proto=LoByte(AdvFilter)) then begin - res.data:=DBReadDWord(hContact,protov,wparam.a,0); - res.text:=int2strw(res.data); + p^.flags:=p^.flags or QSF_ACTIVE; + AddContactToList(p^.contact,num); 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:=db_event_last(hContact); - if hDbEvent<>0 then - begin - ZeroMemory(@dbei,sizeof(dbei)); - dbei.cbSize:=SizeOf(dbei); - db_event_get(hDbEvent, @dbei); - res.data:=dbei.timestamp; - res.text:=TimeToStrW(res.data); - end - else - res.data:=0; - 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 CompareItem(lParam1,lParam2:LPARAM;SortType:LPARAM):int; stdcall; var - typ1,typ2:boolean; res1,res2:pQSRec; i1,i2:uint_ptr; + typ1,typ2:boolean; begin result:=0; if SortType=StatusSort then //sort by status @@ -690,388 +253,26 @@ begin else result:=0; end; - if not qsopt.ascendsort then + if (qsopt.flags and QSO_SORTASC)=0 then result:=-result; end; -function FindBufNumber(hContact:THANDLE):integer; -var - i:integer; +procedure Sort; begin - for i:=0 to HIGH(FlagBuf) do - begin - if FlagBuf[i].contact=hContact then - begin - result:=i; - exit; - end; - end; - result:=-1; -end; + if qsopt.columnsort>=tablecolumns then + qsopt.columnsort:=StatusSort; -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; + SendMessage(grid,LVM_SORTITEMS,ListViewToColumn(qsopt.columnsort),LPARAM(@CompareItem)); +// ListView_SortItems(grid,@CompareItem,GetQSColumn(qsopt.columnsort)); + + if (qsopt.columnsort<>StatusSort) and ((qsopt.flags and QSO_SORTBYSTATUS)<>0) then + SendMessage(grid,LVM_SORTITEMS,StatusSort,LPARAM(@CompareItem)); +// ListView_SortItems(grid,@CompareItem,StatusSort); end; -procedure AddContactToList(hContact:THANDLE;num:integer); +function AdvancedFilter: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; + p:pQSFRec; i:integer; show:boolean; begin @@ -1133,93 +334,8 @@ begin 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:=db_find_first(); - while hContact<>0 do - begin - //!! check account - AddContact(cnt1,hContact); - inc(cnt1); - if cnt1=cnt then break; // additional checking - hContact:=db_find_next(hContact); - 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; +//----- contacts actions ----- function GetFocusedhContact:THANDLE; var @@ -1237,7 +353,7 @@ begin if hContact<>0 then begin ShowContactDialog(hContact); - if qsopt.closeafteraction then DestroyWindow(mainwnd); + if (qsopt.flags and QSO_AUTOCLOSE)<>0 then DestroyWindow(mainwnd); end; end; @@ -1272,9 +388,9 @@ end; procedure ConvertToMeta; var - i,j:integer; hMeta:THANDLE; tmp:THANDLE; + i,j:integer; begin j:=ListView_GetItemCount(grid)-1; @@ -1319,19 +435,51 @@ begin end; end; +procedure UpdateLVCell(item,column:integer;text:pWideChar=pWideChar(-1)); +var + li:LV_ITEMW; + contact:THANDLE; + row:integer; +begin + contact:=FlagBuf[LV_GetLParam(grid,item)].contact; + // get buffer row from LV item + row:=FindBufNumber(contact); + // get cell text + if text=pWideChar(-1) then + begin + if (qsopt.columns[column].flags or COL_INIT)<>0 then //?? + mFreeMem(MainBuf[row,column].text); + LoadOneItem(contact,@qsopt.columns[column],0,MainBuf[row,column]); + text:=MainBuf[row,column].text; + end; + + // rewrite LV cell + zeromemory(@li,sizeof(li)); + li.mask :=LVIF_TEXT; + li.iItem :=item; + li.iSubItem:=ColumnToListview(column); // buffer column to LV subitem + li.pszText :=text; + SendMessageW(grid,LVM_SETITEMW,0,tlparam(@li)); + + // if need to filter and sort, do it + if (qsopt.columns[column].flags and COL_FILTER)<>0 then + ProcessLine(row); + if qsopt.columnsort=li.iSubItem then + Sort; +end; + procedure MoveToGroup(group:PWideChar); var - i,j,grcol:integer; contact:THANDLE; + i,j,grcol,row:integer; begin j:=ListView_GetItemCount(grid)-1; + // search group column in QS window (if presents) 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 + if (flags and COL_GROUP)<>0 then begin if (flags and COL_ON)=0 then flags:=flags and not COL_INIT @@ -1340,58 +488,120 @@ begin break; end end; + // move to new group and changing in LV if needs for i:=0 to j do begin if ListView_GetItemState(grid,i,LVIS_SELECTED)<>0 then begin contact:=FlagBuf[LV_GetLParam(grid,i)].contact; + // change settings DBWriteUnicode(contact,strCList,'Group',group); - if (not qsopt.closeafteraction) and (grcol>=0) then + // update buffer and LV + if ((qsopt.flags and QSO_AUTOCLOSE)=0) and (grcol>=0) then begin - LoadOneItem(contact,grcol,0,MainBuf[i,grcol]); + row:=FindBufNumber(contact); + + mFreeMem(MainBuf[row,grcol].text); + StrDupW(MainBuf[row,grcol].text,group); + +// LoadOneItem(contact,qsopt.columns[grcol],0,MainBuf[row,grcol]); + UpdateLVCell(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); +procedure MoveToContainer(container:PWideChar); var - i,j,k:integer; - p,buf:PWideChar; - tmpcnt,cnt:integer; + contact:THANDLE; + i,j,grcol,row:integer; begin - cnt:=0; - if qsopt.exportheaders then + j:=ListView_GetItemCount(grid)-1; + // search container column in QS window (if presents) + grcol:=-1; + + for i:=0 to qsopt.numcolumns-1 do begin - k:=0; - while k0 then - inc(cnt,2); + with qsopt.columns[i] do + if (flags and COL_CNTNR)<>0 then + begin + if (flags and COL_ON)=0 then + flags:=flags and not COL_INIT + else + grcol:=i; + break; + end end; - j:=ListView_GetItemCount(grid)-1; - tmpcnt:=cnt; + + // attach to new container and changing in LV if needs 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=0) then + begin + row:=FindBufNumber(contact); + + mFreeMem(MainBuf[row,grcol].text); + StrDupW(MainBuf[row,grcol].text,container); + +// LoadOneItem(contact,qsopt.columns[grcol],0,MainBuf[row,grcol]); + UpdateLVCell(i,grcol); + end; + end; + end; +end; + +// right now - memory column order, not screen +procedure CopyMultiLinesW; +var + p,buf:PWideChar; + idx:integer; + i,j,k:integer; + tmpcnt,cnt:integer; +begin +{ + lv:LV_COLUMNW; + buf:array [0..127] of WideChar; + + lv.mask :=LVCF_TEXT; + lv.cchTextMax:=128; + lv.pszText :=@buf; + + SendMessageW(LVM_GETCOLUMNW,i,LPARAM(@lv)); + + use lv.pszText, not qsopt.columns[i].title +} + // calculate buffer size, column order not important + cnt:=0; + + k:=0; + while k0 then + inc(cnt,2); + + 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; + idx:=LV_GetLParam(grid,i); + while k0 then begin k:=0; - num:=LV_GetLParam(grid,i); + idx:=LV_GetLParam(grid,i); while k':' 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':' then + begin + p^:=':'; + inc(p); + end; + p^:=' '; inc(p); + p:=StrCopyEW(p,MainBuf[num,i].text); + p^:=#13; (p+1)^:=#10; inc(p,2); + end; + end; + p^:=#0; + + CopyToClipboard(pp,false); + mFreeMem(pp); +end; +} +const + srvhandle:THANDLE=0; + mnuhandle:THANDLE=0; + cmcolumn :integer=-1; + +function ColChangeFunc(wParam:WPARAM;lParam:LPARAM):int_ptr; cdecl; +var + pc,pc1:pWideChar; + p:pAnsiChar; + tbuf:array [0..255] of WideChar; + lmodule:pAnsiChar; + contact:integer; + col:pcolumnitem; + qsr:pQSRec; +begin + col:=@qsopt.columns[cmcolumn]; + StrCopyW(StrCopyEW(@tbuf,TranslateW('Editing of column ')),col.title); + contact:=FindBufNumber(wParam); + qsr:=@MainBuf[contact,cmcolumn]; + pc:=qsr.text; + result:=ShowEditBox(grid,pc,@tbuf); + if result=-1 then + exit + else if result=1 then + begin + pc1:=pc; + pc:=ParseVarString(pc1,wParam); + mFreeMem(pc1); + end; + // change buffer value + mFreeMem(qsr.text); + qsr.text:=pc; + if col.datatype<>QSTS_STRING then + begin + qsr.data:=NumToInt(qsr.text); + end; + // change database setting value + if col.module<>nil then + lmodule:=col.module + else + begin + lmodule:=GetProtoName(FlagBuf[contact].proto); + end; + + case col.datatype of + QSTS_BYTE: begin + DBWriteByte(wParam,lmodule, + col.setting,qsr.data); + end; + QSTS_WORD: begin + DBWriteWord(wParam,lmodule, + col.setting,qsr.data); + end; + QSTS_DWORD,QSTS_SIGNED,QSTS_HEXNUM: begin + DBWriteDWord(wParam,lmodule, + col.setting,dword(qsr.data)); + end; + QSTS_STRING: begin + case DBGetSettingType(wParam,lmodule,col.setting) of + DBVT_ASCIIZ: begin + WideToAnsi(qsr.text,p,MirandaCP); + DBWriteString(wParam,lmodule,col.setting,p); + mFreeMem(p); + end; + DBVT_UTF8: begin + WidetoUTF8(qsr.text,p); + DBWriteUTF8(wParam,lmodule,col.setting,p); + mFreeMem(p); + end; + DBVT_WCHAR: begin + DBWriteUnicode(wParam,lmodule, + col.setting,qsr.text); + end; + end; + end; + end; + + UpdateLVCell(SendMessage(grid,LVM_GETNEXTITEM,-1,LVNI_FOCUSED),cmcolumn,qsr.text); +end; + +function ShowContactMenu(wnd:HWND;hContact:THANDLE;col:integer=-1):HMENU; +var + mi:TCListMenuItem; + pt:tpoint; + doit:bool; +begin + if hContact<>0 then + begin + doit:=false; + if col>=0 then + begin + col:=ListViewToColumn(col); + if (qsopt.columns[col].setting_type=QST_SETTING) and + // right now, not time or IP + (qsopt.columns[col].datatype<>QSTS_IP) and + (qsopt.columns[col].datatype<>QSTS_TIMESTAMP) then + begin + doit:=true; + + if srvhandle=0 then + srvhandle:=CreateServiceFunction('QS/dummy',@ColChangeFunc); + + cmcolumn:=col; + + FillChar(mi,SizeOf(mi),0); + mi.cbSize:=SizeOf(mi); + if mnuhandle=0 then + begin + mi.flags :=CMIF_UNICODE; + mi.szName.w :='Change setting through QS'; + mi.pszService:='QS/dummy'; + mnuhandle:=Menu_AddContactMenuItem(@mi); + end + else + begin + mi.flags :=CMIM_FLAGS; + CallService(MS_CLIST_MODIFYMENUITEM,mnuhandle,LPARAM(@mi)); + end; + end; + end; + + 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; + // Due to stupid miranda logic, we need to clear tails at service processing, not earlier + if doit then + begin + mi.cbSize:=SizeOf(mi); + mi.flags :=CMIM_FLAGS or CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM,mnuhandle,LPARAM(@mi)); + end; + + end + else + result:=0; +end; + +function MyStrSort(para1:pointer; para2:pointer):int; cdecl; +begin + result:=StrCmpW(pWideChar(para1),pWideChar(para2)); +end; + +function MakeContainerMenu(idxfrom:integer=100):HMENU; +var + sl:TSortedList; + i:integer; + b:array [0..15] of AnsiChar; + p:pWideChar; +begin + result:=CreatePopupMenu; + AppendMenuW(result,MF_STRING,idxfrom,TranslateW('default')); + AppendMenuW(result,MF_SEPARATOR,0,nil); + FillChar(sl,SizeOf(sl),0); + sl.increment:=16; + sl.sortFunc:=@MyStrSort; + i:=1; + repeat + p:=DBReadUnicode(0,'TAB_ContainersW',IntToStr(b,i),nil); + if p=nil then break; + List_InsertPtr(@sl,p); + inc(i); + until false; + inc(idxfrom); + for i:=0 to sl.realCount-1 do + begin + p:=pWideChar(sl.Items[i]); + AppendMenuW(result,MF_STRING,idxfrom+i,p); + mFreeMem(p); + end; + List_Destroy(@sl); +end; + +procedure ShowMultiPopup(cnt:integer); +var + mmenu,grpmenu,cntmenu:HMENU; + p:PWideChar; + pt:TPOINT; + buf:array [0..255] of WideChar; + i:integer; +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')); + + cntmenu:=MakeContainerMenu(300); + AppendMenuW(mmenu,MF_POPUP,cntmenu,TranslateW('Attach to &Tab container')); + + grpmenu:=MakeGroupMenu(400); + AppendMenuW(mmenu,MF_POPUP,grpmenu,TranslateW('&Move to Group')); +// grpmenu:=CallService(MS_CLIST_GROUPBUILDMENU,0,0); + + 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; + 300..399: begin + if i=300 then // default container, just delete setting + buf[0]:=#0 + else + begin + GetMenuStringW(cntmenu,i,buf,SizeOf(buf),MF_BYCOMMAND); + end; + MoveToContainer(buf); + end; + 400..499: begin + 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.flags and QSO_AUTOCLOSE)<>0 then + CloseSrWindow; +end; + +//----- ListView Columns ----- + +procedure ColumnClick(wnd:HWND;num:integer); +var + hdi:THDITEM; + header:HWND; +begin + header:=ListView_GetHeader(wnd); + + zeromemory(@hdi,sizeof(hdi)); + // clear sort mark + hdi.mask:=HDI_FORMAT; + SendMessage(header,HDM_GETITEM,qsopt.columnsort,lparam(@hdi)); + hdi.fmt:=hdi.fmt and not (HDF_SORTDOWN or HDF_SORTUP); + SendMessage(header,HDM_SETITEM,qsopt.columnsort,lparam(@hdi)); + + if qsopt.columnsort<>num then + begin + qsopt.flags:=qsopt.flags or QSO_SORTASC; + qsopt.columnsort:=num; + end + else + qsopt.flags:=qsopt.flags xor QSO_SORTASC; + + // set new sort mark + SendMessage(header,HDM_GETITEM,qsopt.columnsort,lparam(@hdi)); + if (qsopt.flags and QSO_SORTASC)<>0 then + hdi.fmt:=hdi.fmt or HDF_SORTDOWN + else + hdi.fmt:=hdi.fmt or HDF_SORTUP; + SendMessage(header,HDM_SETITEM,qsopt.columnsort,lparam(@hdi)); + + Sort; +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 + ((qsopt.flags and QSO_CLIENTICONS)<>0) and + (li.pszText<>NIL)) 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 MakeColumnMenu; +var + column:pcolumnitem; + menu:HMENU; + lvcol:LV_COLUMNW; + pt:TPOINT; + flag,id,i,j:integer; +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); + column:=@qsopt.columns[id]; + column.flags:=column.flags xor COL_ON; + if (column.flags and COL_ON)<>0 then + begin + // memory + if (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,id]); + end; + column.flags:=column.flags or COL_INIT; + end; + // screen + i:=ColumnToListView(id); + zeromemory(@lvcol,sizeof(lvcol)); + lvcol.mask :=LVCF_TEXT or LVCF_WIDTH; + lvcol.pszText :=TranslateW(column.title); + lvcol.cx :=column.width; + //!! + SendMessageW(grid,LVM_INSERTCOLUMNW,i,tlparam(@lvcol)); + + // fill new column + FillLVColumn(id,i); + end + else + begin + j:=0; + for i:=0 to qsopt.numcolumns-1 do + begin + if (qsopt.columns[i].flags and COL_ON)<>0 then + inc(j); + end; + // keep at least one visible column + if j>1 then + SendMessage(grid,LVM_DELETECOLUMN,ColumnToListView(id),0) + else + column.flags:=column.flags or COL_ON; + end; + 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(OldLVHProc,Dialog,hMessage,wParam,lParam); end; var @@ -1458,17 +1102,17 @@ const OldHItem :integer=0; OldHSubItem:integer=0; var + p:PWideChar; 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; + tmpCursor:TPOINT; pinfo:LV_HITTESTINFO; TI:TToolInfoW; ics:TCUSTOM_STATUS; info:TCLCINFOTIP; // qsr:tQSRec; - tmpCursor:TPOINT; + i,num:integer; begin result:=0; case hMessage of @@ -1495,55 +1139,8 @@ begin 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':' 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':' 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); +// i:=ListView_GetSelectedCount(grid); + CopyMultiLinesW(); exit; end; // backspace @@ -1637,7 +1234,8 @@ end; pinfo.flags:=0; if integer(SendMessage(grid,LVM_SUBITEMHITTEST,0,tlparam(@pinfo)))<>-1 then begin - if (pinfo.iItem<>OldHItem) or (pinfo.iSubItem<>OldHSubItem) then + if ((pinfo.flags and LVHT_ONITEM)<>0) and + ((pinfo.iItem<>OldHItem) or (pinfo.iSubItem<>OldHSubItem)) then begin OldHSubItem:=pinfo.iSubItem; OldHItem :=pinfo.iItem; @@ -1666,24 +1264,24 @@ end; hInst :=0; end; - OldHSubItem:=GetQSColumn(OldHSubItem); - if (qsopt.columns[OldHSubItem].flags and + num:=ListViewToColumn(OldHSubItem); + if (qsopt.columns[num].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 + if (qsopt.columns[num].flags and COL_GENDER)<>0 then begin - case MainBuf[i,OldHSubItem].data of + case MainBuf[i,num].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 + else // if (qsopt.columns[num].flags and COL_XSTATUS)<>0 then begin - StrCopyW(buf,MainBuf[i,OldHSubItem].text); + StrCopyW(buf,MainBuf[i,num].text); ics.flags:=CSSF_DEFAULT_NAME or CSSF_MASK_NAME or CSSF_UNICODE; StrCopy(StrCopyE(buf1,GetProtoName(FlagBuf[i].proto)),PS_GETCUSTOMSTATUSEX); @@ -1715,7 +1313,7 @@ end; exit; end; VK_INSERT: begin - CallService(MS_FINDADDFINDADD,0,0); + CallService(MS_FINDADD_FINDADD,0,0); exit; end; VK_DELETE: begin @@ -1734,128 +1332,71 @@ 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; + case integer(PNMHdr(lParam)^.code) of + HDN_ITEMSTATEICONCLICK: begin + if ((PHDNotify(lParam)^.pitem^.mask and HDI_FORMAT )<>0) and + ((PHDNotify(lParam)^.pitem^.fmt and HDF_CHECKBOX)<>0) then + begin + i:=ListViewToColumn(PHDNotify(lParam)^.Item); -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; + if (PHDNotify(lParam)^.pitem^.fmt and HDF_CHECKED)=0 then // OLD state + begin + qsopt.columns[i].flags:=qsopt.columns[i].flags or COL_FILTER; + PHDNotify(lParam)^.pitem^.fmt:=PHDNotify(lParam)^.pitem^.fmt or HDF_CHECKED + end + else + begin + qsopt.columns[i].flags:=qsopt.columns[i].flags and not COL_FILTER; + PHDNotify(lParam)^.pitem^.fmt:=PHDNotify(lParam)^.pitem^.fmt and not HDF_CHECKED + end; + SendMessage( + PHDNotify(lParam)^.hdr.hWndFrom,HDM_SETITEM, + PHDNotify(lParam)^.Item,tlparam(PHDNotify(lParam)^.pitem)); +// result:=1; + FillGrid; + exit; + end; + end; + HDN_ENDDRAG: begin + end; end; - WndChangeColumns(flag,id); - OptChangeColumns(wcShow,id,ord(flag=wcShow)); end; - DestroyMenu(menu); end; + result:=CallWindowProc(OldLVProc,Dialog,hMessage,wParam,lParam); 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; +//----- Single cell painting ----- procedure SetCellColor(lplvcd:PNMLVCUSTOMDRAW;idx:integer); begin - if qsopt.colorize then + if (qsopt.flags and QSO_COLORIZE)<>0 then begin - with FlagBuf[idx] do + with FlagBuf[idx] do begin if (flags and QSF_ACCDEL)<>0 then begin - lplvcd^.clrTextBk:=cbkg_del; - lplvcd^.clrText :=cfgr_del; + lplvcd^.clrTextBk:=QSColors[bkg_del].color; + lplvcd^.clrText :=QSColors[fgr_del].color; end else if (flags and QSF_ACCOFF)<>0 then begin - lplvcd^.clrTextBk:=cbkg_dis; - lplvcd^.clrText :=cfgr_dis; + lplvcd^.clrTextBk:=QSColors[bkg_dis].color; + lplvcd^.clrText :=QSColors[fgr_dis].color; end else if (flags and QSF_META)<>0 then begin - lplvcd^.clrTextBk:=cbkg_meta; - lplvcd^.clrText :=cfgr_meta; + lplvcd^.clrTextBk:=QSColors[bkg_meta].color; + lplvcd^.clrText :=QSColors[fgr_meta].color; end else if (flags and QSF_SUBMETA)<>0 then begin - lplvcd^.clrTextBk:=cbkg_sub; - lplvcd^.clrText :=cfgr_sub; + lplvcd^.clrTextBk:=QSColors[bkg_sub].color; + lplvcd^.clrText :=QSColors[fgr_sub].color; end else if (flags and QSF_INLIST)=0 then begin - lplvcd^.clrTextBk:=cbkg_hid; - lplvcd^.clrText :=cfgr_hid; + lplvcd^.clrTextBk:=QSColors[bkg_hid].color; + lplvcd^.clrText :=QSColors[fgr_hid].color; end else idx:=-1; @@ -1865,15 +1406,15 @@ begin idx:=-1; if idx<0 then begin - if (not qsopt.drawgrid) and odd(lplvcd^.nmcd.dwItemSpec) then + if ((qsopt.flags and QSO_DRAWGRID)=0) and odd(lplvcd^.nmcd.dwItemSpec) then begin - lplvcd^.clrTextBk:=cbkg_odd; - lplvcd^.clrText :=cfgr_odd; + lplvcd^.clrTextBk:=QSColors[bkg_odd].color; + lplvcd^.clrText :=QSColors[fgr_odd].color; end else begin - lplvcd^.clrTextBk:=cbkg_norm; - lplvcd^.clrText :=cfgr_norm; + lplvcd^.clrTextBk:=QSColors[bkg_norm].color; + lplvcd^.clrText :=QSColors[fgr_norm].color; end; end; end; @@ -1881,10 +1422,10 @@ end; function ProcessCustomDraw(lParam:LPARAM):integer; var lplvcd:PNMLVCUSTOMDRAW; - rc:TRECT; h:HICON; + MirVerW:pWideChar; buf:array [0..255] of AnsiChar; - MirVerW:PWideChar; + rc:TRECT; i,j,sub:integer; begin lplvcd:=pointer(lParam); @@ -1897,15 +1438,17 @@ begin CDDS_ITEMPREPAINT: begin result:=CDRF_NOTIFYSUBITEMDRAW; - SetCellColor(lplvcd,LV_GetLParam(grid,lplvcd^.nmcd.dwItemSpec)); + SetCellColor(lplvcd,lplvcd^.nmcd.lItemlParam); exit; end; CDDS_SUBITEM or CDDS_ITEMPREPAINT: begin - i:=LV_GetLParam(grid,lplvcd^.nmcd.dwItemSpec); + i:=lplvcd^.nmcd.lItemlParam; SetCellColor(lplvcd,i); - sub:=GetQSColumn(lplvcd^.iSubItem); + + sub:=ListViewToColumn(lplvcd^.iSubItem); + if (qsopt.columns[sub].flags and COL_GENDER)<>0 then begin ListView_GetSubItemRect(grid,lplvcd^.nmcd.dwItemSpec,lplvcd^.iSubItem,LVIR_ICON,@rc); @@ -1922,6 +1465,7 @@ begin end; result:=CDRF_SKIPDEFAULT; end + else if (qsopt.columns[sub].flags and COL_XSTATUS)<>0 then begin j:=StrToInt(MainBuf[i,sub].text); @@ -1938,215 +1482,91 @@ begin end; result:=CDRF_SKIPDEFAULT; end - else if qsopt.showclienticons and + + else if ((qsopt.flags and QSO_CLIENTICONS)<>0) and ((qsopt.columns[sub].flags and COL_CLIENT)<>0) then result:=CDRF_NOTIFYPOSTPAINT; end; + CDDS_SUBITEM or CDDS_ITEMPOSTPAINT: begin - sub:=GetQSColumn(lplvcd^.iSubItem); + sub:=ListViewToColumn(lplvcd^.iSubItem); if (qsopt.columns[sub].flags and COL_CLIENT)<>0 then begin - i:=LV_GetLParam(grid,lplvcd^.nmcd.dwItemSpec); - MirVerW:=MainBuf[i,sub].text; - if (lstrlenW(MirVerW)<>0) and (ServiceExists(MS_FP_GETCLIENTICONW)<>0) then + MirVerW:=MainBuf[lplvcd^.nmcd.lItemlParam,sub].text; + +//!! + if (MirVerW<>nil) and (MirVerW[0]<>#0) and (ServiceExists(MS_FP_GETCLIENTICONW)<>0) then begin h:=CallService(MS_FP_GETCLIENTICONW,tlparam(MirVerW),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=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; + result:=CDRF_SKIPDEFAULT; 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; + +function NewEditProc(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall; var - i:cardinal; + li:LV_ITEM; + count,current,next,perpage:integer; begin - for i:=0 to HIGH(arr) do - begin - if (arr[i].flags and mask)<>0 then + 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 num=0 then + 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=0 then begin - result:=arr[i]; + 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); + SendMessage(grid,LVM_ENSUREVISIBLE,next,0); + result:=0; 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); + result:=CallWindowProc(OldEditProc,Dialog,hMessage,wParam,lParam); end; procedure ClearBuffers; @@ -2156,20 +1576,44 @@ begin for w:=0 to HIGH(MainBuf) do for h:=0 to HIGH(MainBuf[0]) do mFreeMem(MainBuf[w,h].text); + + SetLength(MainBuf,0); + SetLength(FlagBuf,0); end; procedure SetSpecialColumns(num:integer); begin with qsopt.columns[num] do begin - if (setting_type=ST_BYTE) and - (lstrcmpia(wparam.a,'XStatusId')=0) then + if setting_type=QST_SETTING then begin - flags:=flags or COL_XSTATUS; - end + if (datatype=QSTS_STRING) and + (StrCmp(module ,'CList')=0) and + (StrCmp(setting,'Group')=0) then + begin + flags:=flags or COL_GROUP + end + + else if (datatype=QSTS_STRING) and + (StrCmp(module ,'Tab_SRMsg' )=0) and + (StrCmp(setting,'containerW')=0) then + begin + flags:=flags or COL_CNTNR + end + + else if (datatype=QSTS_BYTE) and + (lstrcmpia(setting,'XStatusId')=0) then + begin + flags:=flags or COL_XSTATUS; + end + + else if (datatype=QSTS_STRING) and + (StrCmp(setting,'MirVer')=0) and + (ServiceExists(MS_FP_GETCLIENTICONW)<>0) then + flags:=flags or COL_CLIENT; - else if (setting_type=ST_CONTACTINFO) and - (setting_cnftype=CNF_GENDER) then + end + else if (setting_type=QST_CONTACTINFO) and (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)); @@ -2177,52 +1621,67 @@ begin tstrMale :=TranslateW('Male'); tstrFemale :=TranslateW('Female'); tstrUnknown:=TranslateW('Unknown'); - end + end; - else if (wparam.a<>NIL) and // FingerPrint preprocess - (setting_type=ST_STRING) and - (lstrcmpia(wparam.a,'MirVer')=0) and - (ServiceExists(MS_FP_GETCLIENTICONW)<>0) then - flags:=flags or COL_CLIENT; + qsopt.columns[num].flags:=flags; end; end; - -function FindAddDlgResizer(Dialog:HWND;lParam:LPARAM;urc:PUTILRESIZECONTROL):int; cdecl; +{ +procedure addcolumn(handle:hwnd;num,width:integer;title:PWideChar); +var + lvcol:LV_COLUMNW; 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; + 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; - +} +// Set columns and clear listview procedure PrepareTable(reset:boolean=false); var + lvcol:LV_COLUMNW; + hdi:THDITEM; + header:HWND; i:integer; old:integer; begin + SendMessage(grid,LVM_DELETEALLITEMS,0,0); + header:=ListView_GetHeader(grid); + + zeromemory(@hdi,sizeof(hdi)); + hdi.mask:=HDI_FORMAT; + old:=tablecolumns; tablecolumns:=0; + zeromemory(@lvcol,sizeof(lvcol)); + lvcol.mask:=LVCF_TEXT or LVCF_WIDTH; 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)); + lvcol.pszText:=TranslateW(title); + lvcol.cx :=width; + SendMessageW(grid,LVM_INSERTCOLUMNW,tablecolumns,tlparam(@lvcol)); +// addcolumn(grid,tablecolumns,width,TranslateW(title)); + + // set checkbox in column header + if (flags and COL_FILTER)<>0 then + hdi.fmt:=HDF_LEFT or HDF_STRING or HDF_CHECKBOX or HDF_CHECKED + else + hdi.fmt:=HDF_LEFT or HDF_STRING or HDF_CHECKBOX; + SendMessage(header,HDM_SETITEM,tablecolumns,tlparam(@hdi)); + inc(tablecolumns); end; SetSpecialColumns(i); end; end; + if reset then begin for i:=old+tablecolumns-1 downto tablecolumns do @@ -2231,10 +1690,143 @@ begin end; end; - ListView_DeleteAllItems(grid); ListView_SetItemCount(grid,HIGH(FlagBuf)+1); end; +//----- Miranda Events ----- + +procedure ChangeStatusPicture(row:integer; hContact:THANDLE; Pic:integer); +var + li:LV_ITEMW; +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); + SendMessageW(grid,LVM_SETITEMW,0,lparam(@li)); + end; +end; + +function OnStatusChanged(wParam:WPARAM;lParam:LPARAM):int;cdecl; +var + j:integer; + oldstat,newstat:integer; +begin + result:=0; + + 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.flags and QSO_SHOWOFFLINE)<>0 then + ChangeStatusPicture(j,wParam,lParam) + else + ProcessLine(j,true) // why false? need to filter! + end + else if {(oldstat<>ID_STATUS_OFFLINE) and} (newstat=ID_STATUS_OFFLINE) then + begin + if (qsopt.flags and QSO_SHOWOFFLINE)<>0 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.flags and QSO_SORTBYSTATUS)<>0 then + Sort; + UpdateSB; + end; +end; + +function OnContactAdded(wParam:WPARAM;lParam:LPARAM):int;cdecl; +var + i:integer; +begin + result:=0; + // 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; + +function OnContactDeleted(wParam:WPARAM;lParam:LPARAM):int;cdecl; +var + i,j:integer; +begin + result:=0; + i:=FindBufNumber(wParam); + if i>=0 then + begin + FlagBuf[i].flags:=(FlagBuf[i].flags or QSF_DELETED) and not QSF_ACTIVE; + for j:=0 to HIGH(MainBuf[0]) do + mFreeMem(MainBuf[i,j].text); + i:=FindItem(i); + if i>=0 then + ListView_DeleteItem(grid,i); + UpdateSB; + end; +end; +{ +function OnAccountChanged(wParam:WPARAM;lParam:LPARAM):int;cdecl; +begin + result:=0; + + 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; +} +//----- Main window procedure with support ----- + +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 FillProtoCombo(cb:HWND); var i:integer; @@ -2248,44 +1840,93 @@ begin SendMessage(cb,CB_SETCURSEL,0,0); end; +var + hAdd, + hDelete, +// hAccount, + hChange:THANDLE; + +procedure SaveColumnOrder; +var + tmpcolumns:array [0..MaxColumnAmount-1] of integer; + lvc:LV_COLUMNW; + i,idx,num,cnt:integer; +begin + DBDeleteGroup(0,qs_module,'item*'); + idx:=0; + lvc.mask:=LVCF_ORDER or LVCF_WIDTH; + for i:=0 to qsopt.numcolumns-1 do + begin + if qsopt.columns[i].setting_type<>0 then + begin + if (qsopt.columns[i].flags and COL_ON)<>0 then + begin + SendMessageW(grid,LVM_GETCOLUMN,idx,tlparam(@lvc)); + qsopt.columns[i].width:=lvc.cx; + tmpcolumns[lvc.iOrder]:=i; + inc(idx); + end; + end; + end; + idx:=0; + cnt:=0; + for i:=0 to qsopt.numcolumns-1 do + begin + if qsopt.columns[i].setting_type<>0 then + begin + if (qsopt.columns[i].flags and COL_ON)<>0 then + begin + num:=tmpcolumns[idx]; + inc(idx); + end + else + num:=i; + savecolumn(cnt,qsopt.columns[num]); + inc(cnt); + end + end; +end; + function QSMainWndProc(Dialog:HWnd;hMessage:UINT;wParam:WPARAM;lParam:LPARAM):lresult; stdcall; var - tmp:LONG_PTR; - tmph:THANDLE; + smenu:HMENU; + header:HWND; + hdi:THDITEM; w,h:uint_ptr; - i:integer; + tmp:LONG_PTR; buf:array [0..255] of WideChar; + colarr:array [0..127] of integer absolute buf; rc:TRECT; pt:TPOINT; - smenu:HMENU; TI:tToolInfoW; urd:TUTILRESIZEDIALOG; begin result:=0; case hMessage of WM_DESTROY: begin + if srvhandle<>0 then DestroyServiceFunction(srvhandle); + if mnuhandle<>0 then CallService(MO_REMOVEMENUITEM,mnuhandle,0); + + UnhookEvent(hAdd); + UnhookEvent(hDelete); + UnhookEvent(hChange); +// UnhookEvent(hAccount); + UnhookEvent(colorhook); + mainwnd:=0; + 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; + // save column width/order + SaveColumnOrder; + saveopt_wnd; ListView_SetImageList(grid,0,LVSIL_SMALL); - opened:=false; tmp:=GetDC(grid); h:=GetCurrentObject(tmp,OBJ_FONT); @@ -2295,22 +1936,21 @@ begin grid:=0; - if qsopt.savepattern then + if (qsopt.flags and QSO_SAVEPATTERN)<>0 then + begin DBWriteUnicode(0,qs_module,'pattern',pattern); + end; 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); + srvhandle:=0; + mnuhandle:=0; SetWindowTextW(Dialog,'Quick Search'); @@ -2321,26 +1961,24 @@ begin InsertMenuW(smenu,6,MF_BYPOSITION or MF_STRING, IDM_STAYONTOP,TranslateW('Stay on Top')); - if qsopt.stayontop then + if (qsopt.flags and QSO_STAYONTOP)<>0 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 + CheckDlgButton(Dialog,IDC_CH_SHOWOFFLINE,ORD((qsopt.flags and QSO_SHOWOFFLINE)<>0)); + if (qsopt.flags and QSO_SHOWOFFLINE)<>0 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)); + CheckDlgButton(Dialog,IDC_CH_COLORIZE,ORD((qsopt.flags and QSO_COLORIZE)<>0)); + // Window mainwnd:=Dialog; tmp:=GetWindowLongPtrW(Dialog,GWL_EXSTYLE); - if qsopt.usetoolstyle then + if (qsopt.flags and QSO_TOOLSTYLE)<>0 then tmp:=tmp or WS_EX_TOOLWINDOW else tmp:=tmp and not WS_EX_TOOLWINDOW; @@ -2350,19 +1988,26 @@ begin CallService(MS_SKIN2_GETICON,0,tlparam(QS_QS))); grid:=GetDlgItem(Dialog,IDC_LIST); + // ListView 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:=LVS_EX_FULLROWSELECT or LVS_EX_SUBITEMIMAGES or LVS_EX_HEADERDRAGDROP or + LVS_EX_LABELTIP or LVS_EX_DOUBLEBUFFER; + if (qsopt.flags and QSO_DRAWGRID)<>0 then tmp:=tmp or LVS_EX_GRIDLINES; SendMessage(grid,LVM_SETEXTENDEDLISTVIEWSTYLE,0,tmp); + // ListView header + header:=ListView_GetHeader(grid); + SetWindowLongPtrW(header,GWL_STYLE, + GetWindowLongPtrW(header,GWL_STYLE) or HDS_CHECKBOXES); + 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( + OldLVHProc:=pointer(SetWindowLongPtrW( SendMessage(grid,LVM_GETHEADER,0,0), GWL_WNDPROC,LONG_PTR(@NewLVHProc))); @@ -2381,6 +2026,17 @@ begin FillGrid; end; + // Show sorting column + zeromemory(@hdi,sizeof(hdi)); + hdi.mask:=HDI_FORMAT; + SendMessageW(header,HDM_GETITEM,qsopt.columnsort,tlparam(@hdi)); + if (qsopt.flags and QSO_SORTASC)<>0 then + hdi.fmt:=hdi.fmt or HDF_SORTDOWN + else + hdi.fmt:=hdi.fmt or HDF_SORTUP; + SendMessageW(header,HDM_SETITEM,qsopt.columnsort,tlparam(@hdi)); + + TranslateDialogDefault(Dialog); SnapToScreen(qsopt.grrect); @@ -2402,10 +2058,12 @@ begin 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; + hAdd :=HookEvent(ME_DB_CONTACT_ADDED ,@OnContactAdded); + hDelete:=HookEvent(ME_DB_CONTACT_DELETED ,@OnContactDeleted); + hChange:=HookEvent(ME_CLIST_CONTACTICONCHANGED,@OnStatusChanged); +// hAccount:=HookEvent(ME_PROTO_ACCLISTCHANGED ,@OnAccountChanged); end; WM_GETMINMAXINFO: begin @@ -2431,7 +2089,7 @@ begin WM_SYSCOMMAND: begin if wParam=IDM_STAYONTOP then begin - if qsopt.stayontop then + if (qsopt.flags and QSO_STAYONTOP)<>0 then begin h:=MF_BYCOMMAND or MF_UNCHECKED; w:=HWND_NOTOPMOST; @@ -2443,7 +2101,7 @@ begin 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; + qsopt.flags:=qsopt.flags xor QSO_STAYONTOP; exit; end; end; @@ -2455,34 +2113,10 @@ begin 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; + begin + ShowContactMenu(Dialog,GetFocusedhContact, + GetLVSubItem(loword(lParam),hiword(lParam))); + end; end; end; @@ -2520,11 +2154,11 @@ begin end; WM_COMMAND: begin - if opened and (CallService(MS_CLIST_MENUPROCESSCOMMAND, - MAKEWPARAM(LOWORD(wParam),MPCF_CONTACTMENU), - GetFocusedhContact)<>0) then + if CallService(MS_CLIST_MENUPROCESSCOMMAND, + MAKEWPARAM(LOWORD(wParam),MPCF_CONTACTMENU), + GetFocusedhContact)<>0 then begin - if qsopt.closeafteraction then + if (qsopt.flags and QSO_AUTOCLOSE)<>0 then CloseSrWindow; exit; end; @@ -2547,16 +2181,24 @@ begin BN_CLICKED: begin case loword(wParam) of IDC_CH_SHOWOFFLINE: begin - qsopt.showoffline:=IsDlgButtonChecked(Dialog,IDC_CH_SHOWOFFLINE)<>BST_UNCHECKED; - if qsopt.showoffline then + if IsDlgButtonChecked(Dialog,IDC_CH_SHOWOFFLINE)<>BST_UNCHECKED then + begin + qsopt.flags:=qsopt.flags or QSO_SHOWOFFLINE; AdvFilter:=AdvFilter or flt_show_offline + end else + begin + qsopt.flags:=qsopt.flags and not QSO_SHOWOFFLINE; AdvFilter:=AdvFilter and not flt_show_offline; + end; AdvancedFilter; end; IDC_CH_COLORIZE: begin - qsopt.colorize:=IsDlgButtonChecked(Dialog,IDC_CH_COLORIZE)<>BST_UNCHECKED; + if IsDlgButtonChecked(Dialog,IDC_CH_COLORIZE)=BST_UNCHECKED then + qsopt.flags:=qsopt.flags and not QSO_COLORIZE + else + qsopt.flags:=qsopt.flags or QSO_COLORIZE; RedrawWindow(grid,nil,0,RDW_INVALIDATE); end; @@ -2593,47 +2235,20 @@ begin end; end; +//----- base QS window functions ----- + function CloseSrWindow:boolean; begin - result:=true; - if opened and (mainwnd<>0) then + if mainwnd<>0 then begin + result:=true; 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); + FreeProtoList; 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; + result:=false; end; function BringToFront:integer; @@ -2648,294 +2263,49 @@ begin SetForegroundWindow(mainwnd); end; -procedure ChangeStatusPicture(row:integer; hContact:THANDLE;Pic:integer); +function OpenSRWindow(apattern:PWideChar;flags:LPARAM):boolean; var - li:LV_ITEM; + i,j:integer; begin - row:=FindItem(row); - if row>=0 then + result:=true; + if mainwnd<>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)); + BringToFront; + exit; 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 + j:=0; + for i:=0 to qsopt.numcolumns-1 do 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; + if (qsopt.columns[i].flags and COL_ON)<>0 then + inc(j); 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; + // no even one visible column + if j=0 then + exit; -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 + TTInstalled := ServiceExists(MS_TIPPER_SHOWTIP)<>0; + // too lazy to move pattern and flags to thread + if apattern<>nil then 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 + if flags=0 then + StrDupW(pattern,apattern) 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; + AnsiToWide(PAnsiChar(apattern),pattern); + CharLowerW(pattern); + end + else if (qsopt.flags and QSO_SAVEPATTERN)<>0 then + pattern:=DBReadUnicode(0,qs_module,'pattern',nil) + else + pattern:=nil; -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=0 then - begin - lcol[col]:=colorder[i]; - inc(col); - end; - - SendMessageW(grid,LVM_SETCOLUMNORDERARRAY,tablecolumns,tlparam(@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); + ColorReload(0,0); + loadopt_wnd; + CreateDialogW(hInstance,PWideChar(IDD_MAIN),0,@QSMainWndProc); end; end; -begin end. -- cgit v1.2.3