You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
RnQ/RnQ/mainDlg.pas

613 lines
18 KiB
Plaintext

{
This file is part of R&Q.
Under same license
}
unit mainDlg;
{$I RnQConfig.inc}
interface
uses
Winapi.Windows, System.SysUtils, Vcl.Graphics, Vcl.Forms, Vcl.ExtCtrls;
{$I NoRTTI.inc}
type
// procedure AddContactsAction(Sender: TObject);
// procedure SendContactsAction(Sender: TObject);
// function AddMainMenuItem(wPar: WPARAM; lPar: LPARAM): Integer; cdecl;
//function AddContactMenuItem(pMI: PCLISTMENUITEM): Integer; // cdecl;
{ function AddContactMenuItem(pPluginProc : Pointer; menuIcon: hIcon; menuCaption:String;
menuHint:string; //procIdx : Integer;
position : Integer;
PopupName : String; popupPosition : Integer;
hotKey : DWORD; PicName : String = ''):integer; }
// function UpdateContactMenuItem(menuHandle: hmenu; pMI : PCLISTMENUITEM): Integer;// cdecl;
// procedure UpdateContactMenuItem(menuHandle: hmenu; pMI: PCLISTMENUITEM); // cdecl;
// procedure DelContactMenuItem(menuHandle: hmenu);
// procedure OnPluginMenuClick(Sender: TObject);
TTimerClass = class
public
procedure OnTimer(Sender: TObject);
end;
var
TimerClass: TTimerClass;
MainTimer: TTimer;
LastMonCnt: Integer;
implementation
uses
Math, GlobalLib, OutboxLib, SciterLib, IniLib, RoasterLib, UtilLib,
RDUtils, RQUtil, RnQSysUtils, RnQGraphics32, RnQ_Avatars, RnQTrayLib, RnQNet, RQlog, Events, Nodes, Hook,
ICQCommon, ICQSession, ICQConsts, ICQContacts, viewinfoDlg, outboxDlg, RnQdbDlg, HiddenForm;
//procedure TRnQmain.SendContactsAction(Sender: TObject);
//var
// // i:integer;
// // s : String;
// s: RawByteString;
// cnt: TICQContact;
// wnd: TselectCntsFrm;
// cl: TRnQCList;
//begin
// wnd := (Sender as Tcontrol).parent as TselectCntsFrm;
// cl := wnd.selectedList;
// if not cl.empty then
// begin
// s := (wnd.extra as Tincapsulate).str;
// if s > '' then
// begin
// // cnt := contactsDB.get(TICQContact, s);
// cnt := wnd.proto.getContact(s);
// begin
// Account.outbox.add(OE_CONTACTS, cnt, 0, cl);
// if Assigned(outboxFrm) then
// outboxFrm.updateList;
// end;
// end;
// end;
// cl.free;
// wnd.extra.free;
// wnd.close;
//end;
procedure TTimerClass.OnTimer(Sender: TObject);
procedure ProcessOutbox;
var
oe: Toevent;
begin
if outboxCount > 0 then
dec(outboxCount);
if outboxCount = 0 then
if Assigned(Account.AccProto) and Account.AccProto.IsOnline and outboxprocessChk then
begin
oe := Account.outbox.Pop;
if oe = nil then
Exit;
outboxCount := timeBetweenMsgs;
UI.UpdateOutbox;
processOevent(oe);
oe.Free;
end;
end;
var
i: Integer;
cnt: TICQContact;
cntarr: TArray;
aNewDawn: Boolean; // TRUE once after each midnight
IsSSRuning: BOOL;
begin
aNewDawn := False;
if not running then
Exit;
// things to do once per second
{ flapSecs:=succ(flapSecs) mod 10;
if flapSecs = 0 then
begin
if SendedFlaps >= ICQMaxFlaps then
icq.sock.Resume;
SendedFlaps := 0;
end; }
if not Assigned(Account.AccProto) then
Exit;
// hide taskbar button
hideTaskButtonIfUhave2;
// trackingMouse;
longdelayCount := succ(longdelayCount) mod 50;
reconnectdelayCount := succ(reconnectdelayCount) mod boundInt(toReconnectTime, 50, 600);
if longdelayCount = 1 then
begin
aNewDawn := trunc(now) - trunc(lastOnTimer) = 1;
lastOnTimer := now;
// trayicon could disappear on crash, lets replace it
if Assigned(StatusIcon) and Assigned(StatusIcon.TrayIcon) then
StatusIcon.TrayIcon.Update;
// update recently offline
if EnableRecentlyOffline then
begin
cntarr := UI.CL.GetContacts(d_recent);
if Length(cntarr) > 0 then
for cnt in cntarr do
if Assigned(cnt) then
if not TICQContact(cnt).IsRecent then
roasterLib.Update(TICQContact(cnt));
SetLength(cntarr, 0);
end;
// Check for updates every 24 hours
if CheckUpdate.Enabled and (Now - CheckUpdate.Last > CheckUpdate.Every) and not CheckUpdate.Checking and not StartingLock then
Check4Update;
end;
/// ////////////////// USER RELATED EVENTS //////////////////////
if usertime < 0 then
Exit;
inc(usertime); // keep track of user time
if aNewDawn then // if new day begin
begin
if Assigned(Account.AccProto) then
Account.AccProto.ApplyBalloon;
CheckBDays;
end;
// have messages been seen
if AutoConsumeEvents and Assigned(UI.Chat) and UI.Chat.IsVisible then
UI.Chat.SawAllHere;
ProcessOutbox;
// query contacts infos
if usertime mod 20 = 0 then
begin
if Assigned(retrieveQ) and (Account.AccProto.IsOnline) and not retrieveQ.empty then
begin
Account.AccProto.GetProfile(retrieveQ.getAt(0).UID);
retrieveQ.delete(0);
SaveListsDelayed := True;
end;
if Assigned(reqAvatarsQ) and Account.AccProto.AvatarsSupport and not reqAvatarsQ.empty then
begin
DownloadAvatar(TICQCOntact(reqAvatarsQ.getAt(0)));
reqAvatarsQ.delete(0);
end;
end;
Inc(InactiveTime);
{ autohide triggers if
{ - it is enabled
{ - time set has passed
{ - the windows is visible
{ - the mouse is not over the window }
if inactiveHide and (InactiveTime >= inactivehideTime) and UI.CL.Visible and not into(MousePos, UI.CL.GetBounds) then
UI.CL.ToggleVisible;
if InactiveTrim and (InactiveTime mod 36000 = 0) then
TrimWorkingSet;
if ShowBalloonTime > 0 then
begin
Dec(ShowBalloonTime, MainTimer.Interval);
if ShowBalloonTime <= 0 then
StatusIcon.HideBalloon;
end;
// decay events
i := 0;
with eventQ do
while i < Count do
try
with Thevent(Items[i]) do
if expires = 0 then
begin
free;
removeAt(i);
end
else
begin
if expires > 0 then
dec(expires);
inc(i);
end;
except
end;
// do blink!
blinkCount := succ(blinkCount) mod blinkSpeed;
if blinkCount = 0 then
begin
blinking := not blinking;
if Assigned(StatusIcon) then
begin
if StatusIcon.TrayIcon.Hidden and not BossMode.isBossKeyOn then
StatusIcon.TrayIcon.Show
else if not StatusIcon.TrayIcon.Hidden and BossMode.isBossKeyOn then
StatusIcon.TrayIcon.Hide;
StatusIcon.Update;
end;
end;
if saveDBtimer2 > 0 then
begin
dec(saveDBtimer2);
if saveDBtimer2 = 0 then
begin
saveListsDelayed := False;
// saveCfgDelayed := false;
saveInboxDelayed := False;
saveOutboxDelayed := False;
saveGroupsDelayed := False;
saveAllListsAsync(Account.ProtoPath, Account.AccProto, AllProxies);
end;
if saveDBtimer2 > 3000 then
saveDBtimer2 := 3000;
end;
if showRosterTimer > 0 then
begin
dec(showRosterTimer);
if showRosterTimer = 0 then
if not UI.CL.Visible then
UI.CL.ToggleVisible;
end;
if (reconnectdelayCount = 0) and running then
begin
// auto-reconnection
if StayConnected and Account.AccProto.IsOffline and ConnectionAvailable then
begin
Account.AccProto.SetStatus(LastStatus, True);
Inc(toReconnectTime, 50);
BoundInt(toReconnectTime, 50, 600);
end;
if ConnectOnConnection and Account.AccProto.IsOffline and not enteringProtoPWD and (LastStatusUserSet <> Byte(SC_OFFLINE)) and ConnectionAvailable then
Account.AccProto.SetStatus(LastStatusUserSet, True);
end;
if longdelayCount = 0 then
begin
// screen size could change, so update window position
if docking.active then
utilLib.dockSet;
saveDBtimer2 := min(saveDBtimer2, 600);
if not fantomWork then
begin
if saveCfgDelayed then
begin
UpdateProperties;
saveListsDelayed := False;
saveCfgDelayed := False;
saveInboxDelayed := False;
saveOutboxDelayed := False;
saveGroupsDelayed := False;
saveDBtimer2 := 0;
saveAllListsAsync(Account.ProtoPath, Account.AccProto, AllProxies);
end;
if saveInboxDelayed or saveOutboxDelayed or saveListsDelayed or saveGroupsDelayed or saveCfgDelayed then
begin
saveListsDelayed := False;
saveCfgDelayed := False;
saveInboxDelayed := False;
saveOutboxDelayed := False;
saveGroupsDelayed := False;
saveDBtimer2 := 0;
saveAllListsAsync(Account.ProtoPath, Account.AccProto, AllProxies);
end;
end;
end;
// things to do twice per second
delayCount := succ(delayCount) mod 5;
if delayCount = 0 then
begin
FlushLogPktFile;
FlushLogEvFile;
with updateViewInfoQ do
begin
resetEnumeration;
while hasMore do
UpdateViewInfo(getNext);
clear;
end;
// auto-away (isHooked is needed for keyboard handling)
if IsHooked and Account.AccProto.IsOnline then
begin
// SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, @isSSActive, 0);
SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, @isSSRuning, 0);
Inc(autoaway.time, 5); // we are in delay-block then 0.5s
if IsMoved and not (autoaway.ss and (IsSSRuning or IsLocked)) and not (autoaway.boss and BossMode.isBossKeyOn) then
begin
autoaway.time := 0;
if (autoaway.autoexit) and (autoaway.triggered <> TR_NONE) then
ExitFromAutoaway;
end else if (autoaway.triggered = TR_NONE) and not (Account.AccProto.GetStatus in [Byte(SC_AWAY), Byte(SC_NA)]) or
(autoaway.triggered <> TR_NONE) then
begin
if autoaway.away and (autoaway.time >= autoaway.awayTime) and (autoaway.triggered = TR_NONE) then
begin
if autoaway.setxstatus then
begin
autoaway.bakxstatus := Account.AccProto.GetXStatus;
Account.AccProto.CurXStatus := autoaway.xstatus;
end;
autoaway.bakstatus := Account.AccProto.SetStatus(Byte(SC_AWAY), True);
autoaway.triggered := TR_AWAY; // has to be set AFTER setstatus
end;
if (autoaway.na and (autoaway.time >= autoaway.naTime) and (autoaway.triggered <> TR_NA)) or
(autoaway.ss and (isSSRuning or isLocked)) or (autoaway.boss and BossMode.isBossKeyOn) then
begin
if autoaway.triggered = TR_NONE then
begin
if autoaway.setxstatus then
begin
autoaway.bakxstatus := Account.AccProto.GetXStatus;
Account.AccProto.CurXStatus := autoaway.xstatus;
end;
autoaway.bakstatus := Account.AccProto.SetStatus(Byte(SC_NA), True);
end else
Account.AccProto.SetStatus(Byte(SC_NA));
autoaway.triggered := TR_NA; // has to be set AFTER setstatus
end;
end;
end;
if appBarResizeDelayed then
begin
appBarResizeDelayed := False;
if docking.appBar then
utilLib.setAppBarSize;
end;
if dbUpdateDelayed then
begin
dbUpdateDelayed := False;
incDBTimer;
UI.UpdateDB;
end;
end;
// update noincomingcounter
if NoIncomingCounter > 0 then
Dec(NoIncomingCounter);
UI.Chat.Chats.CheckTypingTimeAll;
// apply alwaysOnTop
if UI.CL.Visible and (alwaysOnTop <> IsTopMostWindow(UI.CL.Window)) then
begin
SetTopMost(Hidden, alwaysOnTop);
SetTopMostWindow(UI.CL.Window, alwaysOnTop);
end;
if MustQuit then
Quit;
end;
//// Mute
//// Exec
// if Assigned(Account.AccProto) and Assigned(clickedContact) then
// Account.AccProto.SetMuted(clickedContact, not clickedContact.IsMuted);
//
//// Update
// TAction(Sender).Visible := False; Exit; // Unused
//
// if not Assigned(clickedContact) then
// Exit;
//
// TAction(Sender).Visible := not (clickedContact.UID2Cmp = spamsFilename);
// TAction(Sender).Enabled := Account.AccProto.IsOnline;
//
// if clickedContact.IsMuted then
// begin
// TAction(Sender).HelpKeyword := 'unmuted';
// TAction(Sender).Caption := GetTranslation('Unmute');
// end
// else
// begin
// TAction(Sender).HelpKeyword := 'muted';
// TAction(Sender).Caption := GetTranslation('Mute');
// end;
// if OnlFeature(Account.AccProto) then
// Account.AccProto.RemoveMeFromHisCL(clickedContact.uid)
// TODO: Plugin menu items
// function TRnQmain.AddMainMenuItem(wPar: WPARAM; lPar: LPARAM): Integer; cdecl;
//function TRnQmain.AddContactMenuItem(pMI: PCLISTMENUITEM): Integer; // cdecl;
//{ function TRnQmain.AddContactMenuItem(pPluginProc : Pointer; menuIcon: hIcon; menuCaption:String;
// menuHint:string; //procIdx : Integer;
// position : Integer;
// PopupName : String; popupPosition : Integer;
// hotKey : DWORD; PicName : String = ''):integer; }
//var
// // clMI : TCLISTMENUITEM;
// str, Str1: String;
// i: Integer;
// MI: TRQMenuItem;
// PM: TRQMenuItem;
// MM: TMenuItem;
// // Ic : TIcon;
// // bmp : TBitmap;
//begin
// // Str :=String(wPar);
// // clMI := PCLISTMENUITEM(lPar)^;
// if pMI.cbSize <> sizeof(TCLISTMENUITEM) then
// begin
// Result := 0;
// Exit;
// end;
// // Str := pMI.pszName;
// MI := TRQMenuItem.Create(Self);
// MI.caption := UnUTF(pMI.pszName);
// MI.Hint := UnUTF(pMI.pszHint);
// if (pMI.hIcon <> 0) then
// begin
// ico2bmp2(pMI.hIcon, MI.Bitmap);
// end;
// // MI.ServiceName := clMI.pszService;
// MI.PluginProc := pMI.Proc;
// // MI.Plugin := pPlugin;
// // MI.ProcIdx := procIdx;
// if pMI.Proc = NIL then
// MI.OnClick := NIL
// else
// MI.OnClick := OnPluginMenuClick;
// MI.ImageName := pMI.pszPic;
// MI.Enabled := (pMI.flags and RQFM_DISABLED) = 0;
// MI.visible := (pMI.flags and RQFM_HIDDEN) = 0;
// MM := contactMenu.Items;
// str := UnUTF(pMI.pszPopupName);
// if str <> '' then
// begin
// Str1 := str;
// while str > '' do
// begin
// i := pos('\', str);
// if i = 0 then
// i := length(str) + 1;
// Str1 := copy(str, 1, i - 1);
// delete(str, 1, i + length('\') - 1);
// if Assigned(MM.Find(Str1)) then
// MM := TMenuItem(MM.Find(Str1))
// else
// begin
// PM := TRQMenuItem.Create(contactMenu);
// PM.caption := Str1;
// MM.add(PM);
// MM := PM;
// // PM.Add(MI);
// end;
// end;
// end;
// // else
// // contactMenu.Items.Insert(12, MI);
// MM.add(MI);
// Result := MI.Handle;
//end;
//
//// function TRnQmain.UpdateContactMenuItem(menuHandle: hmenu; pMI : PCLISTMENUITEM ): Integer;// cdecl;
//Procedure TRnQmain.UpdateContactMenuItem(menuHandle: hmenu; pMI: PCLISTMENUITEM); // cdecl;
// function findItem(item: TMenuItem): TMenuItem;
// var
// i: Integer;
// begin
// Result := NIL;
// if item.Handle = menuHandle then
// Result := item
// else if item.Count > 0 then
// for i := 0 to item.Count - 1 do
// begin
// // if item.Items[i].Count > 0 then
// Result := findItem(item.Items[i]);
// if Result <> NIL then
// break;
// end;
// end;
//
//var
// MI: TMenuItem;
//begin
// MI := findItem(contactMenu.Items);
// if MI <> NIL then
// begin
// if (pMI.flags and RQFM_UPD_CAPTION) > 0 then
// MI.caption := UnUTF(pMI.pszName);
// if (pMI.flags and RQFM_UPD_HINT) > 0 then
// MI.Hint := UnUTF(pMI.pszHint);
// if (pMI.flags and RQFM_UPD_ENABLE) > 0 then
// MI.Enabled := (pMI.flags and RQFM_DISABLED) = 0;
// if (pMI.flags and RQFM_UPD_VISIBLE) > 0 then
// MI.visible := (pMI.flags and RQFM_HIDDEN) = 0;
// if (pMI.flags and RQFM_UPD_ICON) > 0 then
// if (pMI.hIcon <> 0) then
// ico2bmp2(pMI.hIcon, MI.Bitmap)
// else
// begin
// MI.Bitmap := NIL; // .Empty := True;
// end;
// end;
// // Result := mi
//end;
//
//procedure TRnQmain.DelContactMenuItem(menuHandle: hmenu);
// function findItem(item: TMenuItem): TMenuItem;
// var
// i: Integer;
// begin
// Result := NIL;
// if item.Handle = menuHandle then
// Result := item
// else if item.Count > 0 then
// for i := 0 to item.Count - 1 do
// begin
// // if item.Items[i].Count > 0 then
// Result := findItem(item.Items[i]);
// if Result <> NIL then
// break;
// end;
// end;
//
//var
// item, parItem: TMenuItem;
//begin
// item := findItem(contactMenu.Items);
// if item <> NIL then
// begin
// parItem := item.parent;
// parItem.remove(item);
// item.free;
// while (parItem <> contactMenu.Items) and (parItem.Count = 0) do
// begin
// item := parItem;
// parItem := item.parent;
// parItem.remove(item);
// item.free;
// end;
// end;
//end;
//
//procedure TRnQmain.OnPluginMenuClick(Sender: TObject);
//var
// // pr : procedure(uid:String);
// pr: procedure(uid: RawByteString);
//begin
// if Sender is TRQMenuItem then
// begin
// if TRQMenuItem(Sender).PluginProc <> NIL then
// // if (TRQMenuItem(Sender).Plugin^) is Tplugin then
// begin
// pr := TRQMenuItem(Sender).PluginProc;
// pr(clickedContact.UID2cmp);
// // Tplugin(TRQMenuItem(Sender).Plugin).cast(
// // char(PM_EVENT)+char(PE_CONTACTMENUCLICK)+_int(TRQMenuItem(Sender).ProcIdx)+_int(StrToIntDef(clickedContact.UID, 0))
// // )
// end;
// end;
//end;
initialization
TimerClass := TTimerClass.Create;
MainTimer := TTimer.Create(nil);
finalization
FreeAndNil(MainTimer);
FreeAndNil(TimerClass);
end.