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.
1880 lines
59 KiB
Plaintext
1880 lines
59 KiB
Plaintext
{
|
|
This file is part of R&Q.
|
|
Under same license
|
|
}
|
|
unit SciterLib;
|
|
{$I RnQConfig.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes, System.UITypes, System.StrUtils, System.Variants, System.TypInfo,
|
|
System.NetEncoding, Generics.Collections, Vcl.Graphics, Vcl.Forms, Vcl.Imaging.PNGImage, Vcl.Menus,
|
|
SciterJS, SciterJSAPI, RDGlobal, ICQCommon, ICQContacts, Nodes, CLBox, ChatBox, RQLog, RnQTips, PrefSheet, MainDlg, UtilLib;
|
|
|
|
{$I PubRTTI.inc}
|
|
|
|
type
|
|
TSCOptions = set of (sco_multi, sco_groups, sco_predefined);
|
|
|
|
TSprite = record
|
|
name: String;
|
|
x, y, width, height: Integer;
|
|
end;
|
|
|
|
TMessageStatus = record
|
|
when, msgid: String;
|
|
eventimg: Variant;
|
|
end;
|
|
|
|
TMessageHeader = record
|
|
when, caption, text, img: String;
|
|
end;
|
|
|
|
TContactStatus = record
|
|
code: Byte;
|
|
name, desc: String;
|
|
official, bot, deleted: Boolean;
|
|
statusimg, eventimg: Variant;
|
|
end;
|
|
|
|
TContactXStatus = record
|
|
status, text: String;
|
|
end;
|
|
|
|
TCommonSettings = record
|
|
supportAvatars, avatarShowInHint, avatarUsePalette, newSettings, animateWindows, animatedScroll, quitConfirmation, alertTopMost: Boolean;
|
|
end;
|
|
|
|
TNodeData = record
|
|
kind, group, divisor, order: Integer;
|
|
uid, uid2show: TUID;
|
|
hash, displayed, nick, first, last, birth, birthLocal, lastActivity,
|
|
clientClosed, clientDesc, onlineSince, lastTimeSeenOnline: String;
|
|
status, xstatus, clientimg, bdimg: Variant;
|
|
expanded, local, needAuth, hasAvatar, noClient: Boolean;
|
|
end;
|
|
|
|
{$I NoRTTI.inc}
|
|
|
|
TCommonMethods = class(TNativeMethods)
|
|
class procedure RegisterMethods(var ReturnValue: TSciterValue); override;
|
|
class procedure GetWindowCaptionHeight(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetTranslation(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetTranslations(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetSpriteData(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetImageBytes(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure CheckOnline(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure SetLargeWindowIcon(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetMaxPasswordLength(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetPwd(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetCurrentUserName(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetCurrentUserAcc(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetAccountPassword(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure SaveAccountPassword(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure IsAIM(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure HTMLDecode(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure ShowTaskbarButton(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure HideTaskbarButton(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure HideTaskbarButton2(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure SavePreviousWindow(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure ClearPreviousWindow(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure SwitchToPreviousWindow(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetContactIdle(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetContactImportant(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetContactIgnored(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetGroupName(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetContactData(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure SaveNewAccountPassword(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure CheckLockPassword(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure OpenLink(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure OpenPortal(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure IsOnline(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure IsElevated(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure IsWindows10(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure IsWindows8(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure ProcessMacro(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetUploadServerName(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetUpdateInfo(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetDoubleClickDelay(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetWeekDayByNumber(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetMonthNameByNumber(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure PrettyPrint(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
class procedure GetSystemAccentColors(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
end;
|
|
|
|
TSciterHelper = class helper for TSciter
|
|
function LoadTemplate(const Doc, Filename: String; Debug: Boolean = True): Boolean;
|
|
procedure InitRequest(ASender: TObject; const URL: WideString; ResType: SciterResourceType; RequestId: Pointer; out Discard: Boolean; out Delay: Boolean; out Myself: Boolean);
|
|
end;
|
|
|
|
TRequestHandler = class
|
|
private
|
|
FDataStream: TMemoryStream;
|
|
protected
|
|
procedure ProcessRequest(ASender: TObject; URL: WideString; ResType: SciterResourceType; RequestId: Pointer; out Discard: Boolean; out Delay: Boolean; out Myself: Boolean);
|
|
procedure CheckAnimatedGifSize(var ms: TMemoryStream);
|
|
public
|
|
constructor Create(Sender: TSciter);
|
|
destructor Destroy; override;
|
|
end;
|
|
|
|
TUI = class(TSciter)
|
|
private
|
|
ContactStatus: TContactStatus;
|
|
ContactXStatus: TContactXStatus;
|
|
StatusSprite, EventSprite, ClientSprite, BDSprite: TSprite;
|
|
public
|
|
CL: TContactList;
|
|
Chat: TChatBox;
|
|
Log: TLog;
|
|
Tips: TTips;
|
|
Prefs: TPrefs;
|
|
|
|
constructor Create;
|
|
procedure AppActivate(Sender: TObject);
|
|
procedure AppDeactivate(Sender: TObject);
|
|
procedure SystemSettingChange(Sender: TObject; Flag: Integer; const Section: string; var Result: Longint);
|
|
|
|
function GetNodeData(var Node: TNode; Lite: Boolean = False): TNodeData;
|
|
function IsVisible(Element: HELEMENT): Boolean;
|
|
function GetID(Element: HELEMENT): String;
|
|
function GetAttr(Element: HELEMENT; const AttrName: AnsiString): String;
|
|
function GetTag(Element: HELEMENT): String;
|
|
function CallOnElement(Element: HELEMENT; const FuncName: AnsiString; Params: TArray |
|
procedure FireOnElement(Element: HELEMENT; const name: String; data: Variant; async: Boolean = True);
|
|
procedure CallInWindow(const WindowID, FuncName: AnsiString; Params: TArray |
|
|
|
procedure CreateCL;
|
|
procedure CreateChat;
|
|
procedure CreateLog;
|
|
procedure CreateTips;
|
|
|
|
procedure ApplySystemSettings;
|
|
function GetFocused(Window: HWINDOW): HELEMENT;
|
|
// function GetCurrentRoot: HELEMENT;
|
|
function GetImageColors(var str: TMemoryStream): TParams;
|
|
function EnterPassword(const Title: String; MaxLength: Integer = 0): String;
|
|
procedure EnterLockPassword(const Title, Hint: String; MaxLength: Integer = 0);
|
|
function CreateDialog(const Msg: String; DlgType: TMsgDlgType; Buttons: TMsgDlgButtons; Seconds: Integer): Integer;
|
|
procedure MessageDialog(const Msg: String; Kind: TMsgDlgType);
|
|
function InputQuery(const Caption, Text, Icon: String): String;
|
|
function SwitchUser(ShowConflictMsg: Boolean = False): TUID;
|
|
function SelectContacts(const Caption, Btn: String; Options: TSCOptions; CheckUID: TUID = ''): TParams;
|
|
procedure InitSettings;
|
|
procedure ReloadUsers;
|
|
procedure ViewInfo(UID: TUID; const Caption: String; UpdateOnly: Boolean = False);
|
|
procedure OpenPrefs(const Page: String = ''; Full: Boolean = True);
|
|
procedure OpenHistorySearch;
|
|
procedure OpenUpdater;
|
|
function OpenLangs(Langs: Variant): Integer;
|
|
procedure UpdateViewInfoAnP(UID: TUID);
|
|
procedure UpdateOutbox;
|
|
procedure UpdateDB;
|
|
procedure UpdateSessions(Current: Boolean = False);
|
|
procedure UpdateTranslations;
|
|
procedure CloseAllChildWindows;
|
|
procedure LoadData(ASender: TObject; const URL: WideString; ResType: SciterResourceType; RequestId: Pointer; out Discard, Delay, Myself: Boolean);
|
|
procedure ScriptingCall(ASender: TObject; const Args: TElementOnScriptingCallArgs);
|
|
end;
|
|
|
|
function GetWindowHandle(argc: UINT; argv: PSciterValue; Root: Boolean = True): HWND;
|
|
|
|
function MakeSprite(const Pic: TPicName): TSprite;
|
|
|
|
var
|
|
UI: TUI;
|
|
|
|
implementation
|
|
|
|
uses
|
|
System.JSON,
|
|
GlobalLib, GroupsLib, RoasterLib, IniLib, ThemesLib, RQUtil, RDUtils, Murmur2, litegif1,
|
|
RnQNet, RnQLangs, RnQGlobal, RnQGraphics32, RQThemes, RnQPics, RnQDialogs, RnQ_Avatars, RnQMacros, RnQSysUtils, Stickers,
|
|
ICQConsts, Protocol_ICQ, events, usersDlg, viewInfoDlg, aboutDlg, outboxDlg, RnQdbDlg, selectcontactsDlg,
|
|
HistAllSearch, StatusForm;
|
|
|
|
function LooksLikeALink(const link: String): Boolean;
|
|
begin
|
|
Result := StartsText('http://', link) or StartsText('https://', link) or StartsText('www.', link);
|
|
end;
|
|
|
|
{ TRequestHandler }
|
|
|
|
constructor TRequestHandler.Create(Sender: TSciter);
|
|
begin
|
|
FDataStream := nil;
|
|
end;
|
|
|
|
destructor TRequestHandler.Destroy;
|
|
begin
|
|
FreeAndNil(FDataStream);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TRequestHandler.CheckAnimatedGifSize(var ms: TMemoryStream);
|
|
var
|
|
aGif: TGif;
|
|
sz: Single;
|
|
FStreamFormat: TPAFormat;
|
|
PNG: TPNGImage;
|
|
begin
|
|
FStreamFormat := DetectFileFormatStream(ms);
|
|
if (FStreamFormat = PA_FORMAT_GIF) then
|
|
begin
|
|
ms.Seek(0, soFromBeginning);
|
|
aGif := TGif.Create;
|
|
try
|
|
aGif.LoadFromStream(ms);
|
|
with aGif do
|
|
if ImageCount > 1 then
|
|
begin
|
|
sz := 4.85 * ImageCount * Width * Height / 1048576;
|
|
if sz > 50 then
|
|
try
|
|
ms.Clear;
|
|
PNG := TPNGImage.Create;
|
|
PNG.Assign(aGif.Bitmap[0]);
|
|
PNG.SaveToStream(ms);
|
|
PNG.Free;
|
|
ms.Seek(0, soFromBeginning);
|
|
except end;
|
|
end;
|
|
finally
|
|
aGif.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TRequestHandler.ProcessRequest(ASender: TObject; URL: WideString; ResType: SciterResourceType; RequestId: Pointer; out Discard, Delay, Myself: Boolean);
|
|
var
|
|
Hash: LongWord;
|
|
Img: TBytes;
|
|
PNG: TPNGImage;
|
|
Ico: TIcon;
|
|
RealURL, FileURL, FileName, MurmurStr: String;
|
|
Mini: Boolean;
|
|
Pic: TPicName;
|
|
ResStream: TResourceStream;
|
|
StrStream: TStringStream;
|
|
Cached, IsImg, Check, Ignore, Async, HasAoP: Boolean;
|
|
FBox: TSciter;
|
|
Contact: TICQContact;
|
|
FileInfo: TICQFileInfo;
|
|
Pos: Integer;
|
|
begin
|
|
Ignore := False;
|
|
Async := False;
|
|
Myself := False;
|
|
FBox := ASender as TSciter;
|
|
|
|
if StartsText('file://', url) or StartsText('sciter:', url) then
|
|
if ContainsStr(url, 'url(') then // Some weird Sciter bug
|
|
begin
|
|
Pos := String(url).LastIndexOf('url(');
|
|
url := String(url).Substring(Pos + 4, Length(url) - Pos - 5);
|
|
end else
|
|
Exit;
|
|
|
|
FDataStream := nil;
|
|
|
|
// CSS reload fix
|
|
if StartsText('template:url(', url) then
|
|
url := Copy(url, 14, Length(url) - 14);
|
|
|
|
if StartsText('template:', url) then
|
|
begin
|
|
FDataStream := TMemoryStream.Create;
|
|
RealURL := Copy(url, 10, Length(url));
|
|
FBox.GetPackedItem('template', PWideChar(RealURL), FDataStream);
|
|
end else if StartsText('themeicon:', url) then
|
|
begin
|
|
RealURL := Copy(url, 11, Length(url));
|
|
Ico := TIcon.Create;
|
|
if theme.pic2ico(RQteDefault, RealURL, Ico) then
|
|
begin
|
|
FDataStream := TMemoryStream.Create;
|
|
Ico.SaveToStream(FDataStream)
|
|
end else
|
|
Ignore := True;
|
|
Ico.Free;
|
|
end else if StartsText('themepic:', url) then
|
|
begin
|
|
Pic := Copy(url, 10, Length(url));
|
|
if not theme.GetOrigPic(Pic, FDataStream) then
|
|
Ignore := True;
|
|
end else if StartsText('themepicsingle:', url) then
|
|
begin
|
|
RealURL := Copy(url, 16, Length(url));
|
|
if theme.Pic2PNG(RealURL, PNG) then
|
|
begin
|
|
FDataStream := TMemoryStream.Create;
|
|
PNG.SaveToStream(FDataStream)
|
|
end else
|
|
Ignore := True;
|
|
FreeAndNil(PNG);
|
|
end else if StartsText('pluginpic:', url) then
|
|
begin
|
|
Pic := Copy(url, 11, Length(url));
|
|
if theme.Pic2PNG(Pic, PNG) then
|
|
begin
|
|
FDataStream := TMemoryStream.Create;
|
|
PNG.SaveToStream(FDataStream);
|
|
end else
|
|
Ignore := True;
|
|
FreeAndNil(PNG);
|
|
end else if StartsText('contactpic:', url) and UseContactThemes and Assigned(ContactsTheme) then
|
|
begin
|
|
Pic := Copy(url, 12, Length(url));
|
|
if not ContactsTheme.GetOrigPic(Pic, FDataStream) then
|
|
Ignore := True;
|
|
end else if StartsText('smile:', url) then
|
|
begin
|
|
Pic := Copy(url, 7 + 1, Length(url));
|
|
if not theme.GetOrigSmile(Pic, FDataStream) then
|
|
Ignore := True;
|
|
end else if StartsText('sticker:', url) then
|
|
begin
|
|
RealURL := Copy(url, 9 + 1, Length(url));
|
|
TThread.CreateAnonymousThread(procedure
|
|
var
|
|
fs: TMemoryStream;
|
|
begin
|
|
fs := TMemoryStream.Create;
|
|
if String(url).startsWith('sticker:a') then
|
|
GetAnimatedSticker(RealURL, fs)
|
|
else
|
|
GetSticker(RealURL, fs);
|
|
|
|
if Assigned(FBox) and Running then
|
|
FBox.DataReadyAsync(url, fs.Memory, fs.Size, RequestId);
|
|
|
|
FreeAndNil(fs);
|
|
end).Start;
|
|
|
|
Delay := True;
|
|
Exit;
|
|
end else if StartsText('picker:', url) then
|
|
begin
|
|
RealURL := Copy(url, 8 + 1, Length(url));
|
|
TThread.CreateAnonymousThread(procedure
|
|
var
|
|
fs: TMemoryStream;
|
|
begin
|
|
fs := TMemoryStream.Create;
|
|
if String(url).startsWith('picker:a') then
|
|
GetAnimatedSticker(RealURL, fs, True)
|
|
else
|
|
GetSticker(RealURL, fs, 'stickerpicker_small');
|
|
|
|
if Assigned(FBox) and Running then
|
|
FBox.DataReadyAsync(url, fs.Memory, fs.Size, RequestId);
|
|
|
|
FreeAndNil(fs);
|
|
end).Start;
|
|
|
|
Delay := True;
|
|
Exit;
|
|
end else if StartsText('listicon:', url) then
|
|
begin
|
|
RealURL := Copy(url, 10 + 1, Length(url));
|
|
TThread.CreateAnonymousThread(procedure
|
|
var
|
|
fs: TMemoryStream;
|
|
begin
|
|
var
|
|
fn: String;
|
|
|
|
fs := TMemoryStream.Create;
|
|
fn := StickerPath + RealURL + '_listicon_small.webp';
|
|
|
|
if FileExists(fn) then
|
|
fs.LoadFromFile(fn);
|
|
|
|
if Assigned(FBox) and Running then
|
|
FBox.DataReadyAsync(url, fs.Memory, fs.Size, RequestId);
|
|
|
|
FreeAndNil(fs);
|
|
end).Start;
|
|
|
|
Delay := True;
|
|
Exit;
|
|
end else if StartsText('avatar:', url) or StartsText('miniavatar:', url) then
|
|
begin
|
|
Mini := StartsText('miniavatar:', url);
|
|
RealURL := Copy(url, IfThen(Mini, 12, 8), Length(url));
|
|
Contact := Account.AccProto.GetContact(RealURL);
|
|
if Contact.icon.ToShow = IS_AVATAR then
|
|
begin
|
|
FDataStream := TMemoryStream.Create;
|
|
LoadAoPStreamByUIN(Contact.UID, FDataStream, HasAoP, FileName, 0);
|
|
|
|
if Assigned(FDataStream) and (FDataStream.Size = 0) then
|
|
begin
|
|
FreeAndNil(FDataStream);
|
|
Ignore := True;
|
|
end;
|
|
|
|
if Mini and not Ignore then
|
|
ResampleProportional(FDataStream, 32, 32);
|
|
end else if Contact.icon.ToShow = IS_PHOTO then
|
|
begin
|
|
FDataStream := TMemoryStream.Create;
|
|
LoadAoPStreamByUIN(Contact.UID, FDataStream, HasAoP, FileName, 1);
|
|
|
|
if Assigned(FDataStream) and (FDataStream.Size = 0) then
|
|
begin
|
|
FreeAndNil(FDataStream);
|
|
Ignore := True;
|
|
end;
|
|
end else Ignore := True;
|
|
end else if StartsText('justavatar:', url) then
|
|
begin
|
|
RealURL := Copy(url, 12, Length(url));
|
|
Contact := Account.AccProto.GetContact(RealURL);
|
|
FDataStream := TMemoryStream.Create;
|
|
LoadAoPStreamByUIN(Contact.UID, FDataStream, HasAoP, FileName, 0);
|
|
|
|
if Assigned(FDataStream) and (FDataStream.Size = 0) then
|
|
begin
|
|
FreeAndNil(FDataStream);
|
|
Ignore := True;
|
|
end;
|
|
end else if StartsText('justphoto:', url) then
|
|
begin
|
|
RealURL := Copy(url, 11, Length(url));
|
|
Contact := Account.AccProto.GetContact(RealURL);
|
|
FDataStream := TMemoryStream.Create;
|
|
LoadAoPStreamByUIN(Contact.UID, FDataStream, HasAoP, FileName, 1);
|
|
|
|
if Assigned(FDataStream) and (FDataStream.Size = 0) then
|
|
begin
|
|
FreeAndNil(FDataStream);
|
|
Ignore := True;
|
|
end;
|
|
end else if StartsText('resource:', url) then
|
|
begin
|
|
RealURL := Copy(url, 10, Length(url));
|
|
ResStream := TResourceStream.Create(HInstance, UpperCase(RealURL), RT_RCDATA);
|
|
try
|
|
FDataStream := TMemoryStream.Create;
|
|
ResStream.SaveToStream(FDataStream);
|
|
finally
|
|
ResStream.Free;
|
|
end;
|
|
end else if StartsText('iconresource:', url) then
|
|
begin
|
|
RealURL := Copy(url, 14, Length(url));
|
|
ResStream := TResourceStream.Create(HInstance, UpperCase(RealURL), RT_ICON);
|
|
try
|
|
FDataStream := TMemoryStream.Create;
|
|
ResStream.SaveToStream(FDataStream);
|
|
finally
|
|
ResStream.Free;
|
|
end;
|
|
end else if StartsText('link:', url) then
|
|
begin
|
|
RealURL := ValidateURL(Copy(url, 6, Length(url)));
|
|
if ContainsText(RealURL, 'files.icq.net/') then
|
|
begin
|
|
if Account.AccProto.AimSid = '' then
|
|
FileInfo := GetICQFileLinkInfoPublic(RealURL)
|
|
else
|
|
FileInfo := GetICQFileLinkInfoPrivate(RealURL);
|
|
if FileInfo.dlink = '' then
|
|
FileURL := FileInfo.jsonlink
|
|
else
|
|
FileURL := FileInfo.dlink;
|
|
if not (FileURL = '') then
|
|
RealURL := FileURL;
|
|
end;
|
|
OpenURL(RealURL);
|
|
Ignore := True;
|
|
end else if StartsText('mailto:', url) then
|
|
begin
|
|
OpenURL(url);
|
|
Ignore := True;
|
|
end else if StartsText('embedded:', url) then
|
|
begin
|
|
if TryStrToLongWord(Copy(url, 10, Length(url)), Hash) and Assigned(EmbeddedImgs) and EmbeddedImgs.TryGetValue(Hash, Img) then
|
|
begin
|
|
FDataStream := TMemoryStream.Create;
|
|
FDataStream.Write(Img, Length(Img));
|
|
CheckAnimatedGifSize(FDataStream);
|
|
end;
|
|
end else if StartsText('tabicon:', url) then
|
|
begin
|
|
PNG := nil;
|
|
if TryStrToLongWord(Copy(url, 9, Length(url)), Hash) and Assigned(TabsIconCache) and TabsIconCache.TryGetValue(Hash, PNG) then
|
|
if Assigned(PNG) then
|
|
begin
|
|
FDataStream := TMemoryStream.Create;
|
|
PNG.SaveToStream(FDataStream)
|
|
end else
|
|
Ignore := True;
|
|
end else if StartsText('check:', url) or StartsText('download:', url) then
|
|
begin
|
|
if StartsText('check:', url) then
|
|
begin
|
|
Check := True;
|
|
RealURL := Copy(url, 7, Length(url));
|
|
end
|
|
else
|
|
begin
|
|
Check := False;
|
|
RealURL := Copy(url, 10, Length(url));
|
|
end;
|
|
|
|
if LooksLikeALink(RealURL) then
|
|
begin
|
|
MurmurStr := ImgCacheInfo.ReadString(RealURL, 'hash', '0');
|
|
FileName := myPath + 'Cache\Images\' + MurmurStr + '.' + ImgCacheInfo.ReadString(RealURL, 'ext', 'jpg');
|
|
if MurmurStr = '0' then
|
|
Cached := False
|
|
else
|
|
Cached := FileExists(FileName);
|
|
|
|
if not Check then
|
|
Async := True
|
|
else if Cached then
|
|
begin
|
|
IsImg := True;
|
|
Async := False;
|
|
end else if ImgCacheInfo.ValueExists(RealURL, 'mime') and not MatchText(ImgCacheInfo.ReadString(RealURL, 'mime', ''), ImageContentTypes) then
|
|
begin
|
|
IsImg := False;
|
|
Async := False;
|
|
end else
|
|
Async := True;
|
|
|
|
if not Async then
|
|
begin
|
|
StrStream := TStringStream.Create('{ "isImg": ' + IfThen(IsImg, '1', '0') + ', "isLottie": ' + IfThen(IsLottieMime(RealURL), '1', '0') + ', "link": "' + RealURL + '" }', TEncoding.UTF8);
|
|
FDataStream := TMemoryStream.Create;
|
|
FDataStream.CopyFrom(StrStream, 0);
|
|
StrStream.Free;
|
|
end;
|
|
end else
|
|
Ignore := True;
|
|
end else
|
|
begin
|
|
Discard := False;
|
|
Delay := False;
|
|
Exit;
|
|
end;
|
|
|
|
if not Ignore then
|
|
begin
|
|
if not Async then
|
|
begin
|
|
Delay := False;
|
|
FDataStream.Seek(0, soFromBeginning);
|
|
FBox.DataReady(url, FDataStream.Memory, FDataStream.Size);
|
|
end
|
|
else
|
|
begin
|
|
Myself := True;
|
|
RAPI.RequestUse(RequestId);
|
|
TThread.CreateAnonymousThread(procedure
|
|
var
|
|
ms: TMemoryStream;
|
|
fs: TFileStream;
|
|
ss: TStringStream;
|
|
begin
|
|
if Check then
|
|
begin
|
|
ss := TStringStream.Create('{ "isImg": ' + IfThen(CheckType(RealURL), '1', '0') + ', "isLottie": ' + IfThen(IsLottieMime(RealURL), '1', '0') + ', "link": "' + RealURL + '" }', TEncoding.UTF8);
|
|
TThread.Synchronize(nil, procedure begin
|
|
if Running then
|
|
begin
|
|
RAPI.RequestSetSucceeded(RequestId, 200, ss.Memory, ss.Size);
|
|
RAPI.RequestUnUse(RequestId);
|
|
end;
|
|
end);
|
|
FreeAndNil(ss);
|
|
Exit;
|
|
end;
|
|
|
|
fs := nil;
|
|
ms := nil;
|
|
|
|
if not Cached then
|
|
Cached := DownloadAndCache(RealURL);
|
|
|
|
if Cached then
|
|
try
|
|
FileName := myPath + 'Cache\Images\' + ImgCacheInfo.ReadString(RealURL, 'hash', '0') + '.' + ImgCacheInfo.ReadString(RealURL, 'ext', 'jpg');
|
|
fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
|
|
ms := TMemoryStream.Create;
|
|
ms.LoadFromStream(fs);
|
|
CheckAnimatedGifSize(ms);
|
|
TThread.Synchronize(nil, procedure begin
|
|
if not Running then
|
|
Exit;
|
|
RAPI.RequestSetSucceeded(RequestId, 200, ms.Memory, ms.Size);
|
|
RAPI.RequestUnUse(RequestId);
|
|
if Assigned(UI.Chat) then
|
|
UI.Chat.FinishImage(url);
|
|
if Assigned(PreviewChat) then
|
|
PreviewChat.FinishImage(url);
|
|
end);
|
|
except end else
|
|
TThread.Synchronize(nil, procedure()
|
|
begin
|
|
if not Running then
|
|
Exit;
|
|
RAPI.RequestSetFailed(RequestId, 404, nil, 0);
|
|
RAPI.RequestUnUse(RequestId);
|
|
end);
|
|
|
|
FreeAndNil(fs);
|
|
FreeAndNil(ms);
|
|
end).Start;
|
|
end;
|
|
Discard := False;
|
|
end else
|
|
Discard := True;
|
|
|
|
FreeAndNil(FDataStream);
|
|
end;
|
|
|
|
function MakeSprite(const Pic: TPicName): TSprite;
|
|
var
|
|
Rect: TGPRect;
|
|
begin
|
|
if (theme.token = 101) then
|
|
begin
|
|
Result.name := '';
|
|
Result.x := 0;
|
|
Result.y := 0;
|
|
Result.width := 0;
|
|
Result.height := 0;
|
|
Exit;
|
|
end;
|
|
|
|
Rect := theme.GetPicRect(RQteDefault, Pic);
|
|
Result.name := theme.GetPicSprite(RQteDefault, Pic);
|
|
Result.x := -rect.X;
|
|
Result.y := -rect.Y;
|
|
Result.width := rect.Width;
|
|
Result.height := rect.Height;
|
|
end;
|
|
|
|
{ TSciterEx }
|
|
|
|
function TUI.GetNodeData(var Node: TNode; Lite: Boolean = False): TNodeData;
|
|
var
|
|
LastActivity: TDateTime;
|
|
Group: TGroup;
|
|
Pic: String;
|
|
Event: Thevent;
|
|
begin
|
|
Result := Default(TNodeData);
|
|
|
|
if not Assigned(Node) then
|
|
Exit;
|
|
|
|
Result.divisor := Integer(Node.divisor);
|
|
Result.group := Node.groupId;
|
|
Result.kind := Node.kind;
|
|
Result.order := Node.order;
|
|
|
|
if Node.kind = NODE_DIV then
|
|
begin
|
|
case Node.divisor of
|
|
d_online: Result.order := 1;
|
|
d_nil: Result.order := 2;
|
|
d_recent: Result.order := 3;
|
|
d_offline: Result.order := 4;
|
|
d_contacts: Result.order := 5;
|
|
end;
|
|
end else if Node.kind = NODE_GROUP then
|
|
begin
|
|
Group := groups.Get(Node.groupId);
|
|
Result.displayed := Group.Name;
|
|
Result.expanded := Group.Expanded[Node.divisor];
|
|
Result.local := Group.IsLocal;
|
|
end else if Node.kind = NODE_CONTACT then
|
|
if Assigned(Node.contact) then
|
|
begin
|
|
Result.displayed := Node.contact.Displayed;
|
|
Result.uid := Node.contact.UID;
|
|
Result.uid2show := Node.contact.UIN2Show;
|
|
Result.nick := Node.contact.Nick;
|
|
Result.first := Node.contact.First;
|
|
Result.last := Node.contact.Last;
|
|
Result.birth := IfThen(Node.contact.Birth = 0, '', FormatDateTime('DD.MM.YYYY', Node.contact.Birth));
|
|
Result.birthLocal := IfThen(Node.contact.BirthL = 0, '', FormatDateTime('DD.MM.YYYY', Node.contact.BirthL));
|
|
Result.needAuth := not Node.contact.Authorized and not Node.contact.CntIsLocal;
|
|
Result.local := Node.contact.CntIsLocal;
|
|
Result.noClient := Node.contact.NoClient;
|
|
Result.clientClosed := TimeToString(Node.contact.ClientClosed);
|
|
Result.clientDesc := Node.contact.ClientDesc;
|
|
Result.onlineSince := TimeToString(Node.contact.OnlineSince);
|
|
Result.lastTimeSeenOnline := TimeToString(Node.contact.LastTimeSeenOnline);
|
|
|
|
if Lite then
|
|
Exit;
|
|
|
|
LastActivity := TCE(Node.contact.data^).lastMsgTime;
|
|
if LastActivity < StartTime then
|
|
// if not Node.contact.IsOnline then
|
|
begin
|
|
LastActivity := TCE(Node.contact.data^).lastEventTime;
|
|
if LastActivity < StartTime then
|
|
LastActivity := 0;
|
|
end;
|
|
|
|
Result.lastActivity := FloatToStr(LastActivity);
|
|
Result.hasAvatar := CheckAvatar(Node.contact);
|
|
|
|
// Status
|
|
|
|
Pic := RosterImgNameFor(Node.contact);
|
|
if Pic = '' then
|
|
Exit;
|
|
|
|
ContactStatus.official := Node.contact.Official;
|
|
ContactStatus.bot := Node.contact.Bot;
|
|
ContactStatus.deleted := Node.contact.Deleted;
|
|
ContactStatus.code := Node.contact.GetStatus;
|
|
ContactStatus.desc := Node.contact.StatusStr;
|
|
ContactStatus.name := Node.contact.GetStatusName;
|
|
|
|
StatusSprite := MakeSprite(Pic);
|
|
ContactStatus.statusimg := RecordToVar(StatusSprite);
|
|
|
|
Event := eventQ.firstEventFor(Node.contact);
|
|
if Assigned(Event) and not (Event.pic = '') then
|
|
begin
|
|
EventSprite := MakeSprite(Event.pic);
|
|
ContactStatus.eventimg := RecordToVar(EventSprite);
|
|
end else
|
|
ContactStatus.eventimg := False;
|
|
|
|
Result.status := RecordToVar(ContactStatus);
|
|
|
|
ContactXStatus.status := Node.contact.XStatus;
|
|
ContactXStatus.text := XStatus2Text(ContactXStatus.status);
|
|
|
|
Result.xstatus := RecordToVar(ContactXStatus);
|
|
|
|
// Client
|
|
|
|
if not (Node.contact.ClientPic = '') then
|
|
begin
|
|
ClientSprite := MakeSprite(Node.contact.ClientPic);
|
|
Result.clientimg := RecordToVar(ClientSprite);
|
|
end else
|
|
Result.clientimg := False;
|
|
|
|
// Birthday
|
|
|
|
case Node.contact.Days2Bd of
|
|
0: Pic := PIC_BIRTH;
|
|
1: Pic := PIC_BIRTH1;
|
|
2: Pic := PIC_BIRTH2;
|
|
else
|
|
Pic := '';
|
|
end;
|
|
|
|
if not (Pic = '') then
|
|
begin
|
|
BDSprite := MakeSprite(Pic);
|
|
Result.bdimg := RecordToVar(BDSprite);
|
|
end else
|
|
Result.bdimg := False;
|
|
end;
|
|
|
|
Result.hash := IntToStr(CalcMurmur2(TEncoding.UTF8.GetBytes(IntToStr(Result.kind) + '_' + IntToStr(Result.divisor) + '_' + IntToStr(Result.group) + '_' + String(Result.uid))));
|
|
// if Result.kind = NODE_GROUP then
|
|
// ODS('Group node: ' + inttostr(Result.group) + ' ' + Result.displayed + ' | ' + Result.hash);
|
|
end;
|
|
|
|
function TUI.IsVisible(Element: HELEMENT): Boolean;
|
|
var
|
|
pResult: LongBool;
|
|
begin
|
|
API.SciterIsElementVisible(Element, pResult);
|
|
Result := pResult;
|
|
end;
|
|
|
|
function TUI.GetID(Element: HELEMENT): String;
|
|
begin
|
|
Result := GetAttr(Element, 'id');
|
|
end;
|
|
|
|
procedure GetTextCallback(str: PWideChar; str_length: UINT; param: Pointer); stdcall;
|
|
begin
|
|
if not (str = nil) and not (str_length = 0) then
|
|
String(param^) := String(str);
|
|
end;
|
|
|
|
function TUI.GetAttr(Element: HELEMENT; const AttrName: AnsiString): String;
|
|
begin
|
|
Result := '';
|
|
if AttrName = '' then
|
|
Exit;
|
|
|
|
API.SciterGetAttributeByNameCB(Element, PAnsiChar(AttrName), PLPCWSTR_RECEIVER(@GetTextCallback), @Result);
|
|
end;
|
|
|
|
function TUI.GetTag(Element: HELEMENT): String;
|
|
begin
|
|
API.SciterGetElementTypeCB(Element, PLPCSTR_RECEIVER(@GetTextCallback), @Result);
|
|
end;
|
|
|
|
{ TSciterHelper }
|
|
|
|
function TSciterHelper.LoadTemplate(const Doc, Filename: String; Debug: Boolean = True): Boolean;
|
|
begin
|
|
SetOption(SCITER_SET_SCRIPT_RUNTIME_FEATURES, UINT_PTR(ALLOW_FILE_IO) or UINT_PTR(ALLOW_SOCKET_IO) or UINT_PTR(ALLOW_EVAL) or UINT_PTR(ALLOW_SYSINFO));
|
|
SetOption(SCITER_SET_PX_AS_DIP, UINT_PTR(False));
|
|
SetOption(SCITER_SET_DEBUG_MODE, UINT_PTR(DevMode and Debug));
|
|
if DevMode then
|
|
Result := LoadURL(FilePathToURL(myPath + Doc + '\' + Filename))
|
|
else if FileExists(myPath + Doc + '.zip') then
|
|
Result := LoadURL(FilePathToURL(myPath + Doc + '.zip#' + Filename))
|
|
else
|
|
begin
|
|
LoadPackedResource(Doc, RT_RCDATA);
|
|
Result := LoadURL(Doc + ':' + Filename);
|
|
end;
|
|
end;
|
|
|
|
procedure TSciterHelper.InitRequest(ASender: TObject; const URL: WideString; ResType: SciterResourceType; RequestId: Pointer; out Discard, Delay, Myself: Boolean);
|
|
var
|
|
handler: TRequestHandler;
|
|
begin
|
|
handler := TRequestHandler.Create(Self);
|
|
handler.ProcessRequest(ASender, URL, ResType, RequestId, Discard, Delay, Myself);
|
|
handler.Free;
|
|
end;
|
|
|
|
// Native methods
|
|
|
|
class procedure TCommonMethods.GetSpriteData(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
str: String;
|
|
Sprite: TSprite;
|
|
begin
|
|
if argc = 0 then
|
|
Exit;
|
|
|
|
str := SciterVarToString(argv);
|
|
|
|
if str = '' then
|
|
Exit;
|
|
|
|
with UI do
|
|
begin
|
|
Sprite := MakeSprite(str);
|
|
V2S(RecordToVar(Sprite), retval);
|
|
end;
|
|
end;
|
|
|
|
class procedure TCommonMethods.GetImageBytes(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
URL, RealURL: String;
|
|
PNG: TPNGImage;
|
|
Bytes: TBytesStream;
|
|
begin
|
|
URL := SciterVarToString(argv);
|
|
RealURL := '';
|
|
if StartsText('themepicsingle:', URL) then
|
|
RealURL := Copy(URL, 16, Length(URL));
|
|
if RealURL = '' then
|
|
Exit;
|
|
|
|
if theme.Pic2PNG(RealURL, PNG) then
|
|
begin
|
|
Bytes := TBytesStream.Create;
|
|
PNG.SaveToStream(Bytes);
|
|
V2S(Bytes.Bytes, retval);
|
|
Bytes.Free;
|
|
end;
|
|
FreeAndNil(PNG);
|
|
end;
|
|
|
|
class procedure TCommonMethods.GetTranslation(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
strData: String;
|
|
begin
|
|
if argc = 0 then
|
|
Exit;
|
|
|
|
strData := SciterVarToString(argv);
|
|
strData := RnQLangs.GetTranslation(strData);
|
|
API.ValueStringDataSet(retval, PWideChar(strData), Length(strData), 0);
|
|
end;
|
|
|
|
function EnumParams(param: Pointer; const pkey: PSciterValue; const pval: PSciterValue): BOOL; stdcall;
|
|
var
|
|
key, val: String;
|
|
newval: TSciterValue;
|
|
begin
|
|
Result := True;
|
|
key := SciterVarToString(pval);
|
|
if key = '' then
|
|
Exit;
|
|
val := SciterVarToString(pval);
|
|
val := GetTranslation(val);
|
|
API.ValueInit(@newval);
|
|
API.ValueStringDataSet(@newval, PWideChar(val), Length(val), 0);
|
|
API.ValueSetValueToKey(param, pkey, @newval);
|
|
API.ValueClear(@newval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.GetTranslations(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
arrSize, i: UINT;
|
|
strData: PWideChar;
|
|
strLen: UINT;
|
|
val: TSciterValue;
|
|
begin
|
|
if argc = 0 then
|
|
Exit;
|
|
|
|
if argv.t = UINT(T_OBJECT) then
|
|
if argv.u = UINT(UT_OBJECT_OBJECT) then
|
|
API.ValueEnumElements(argv, @EnumParams, retval)
|
|
else if argv.u = UINT(UT_OBJECT_ARRAY) then
|
|
begin
|
|
arrSize := 0;
|
|
API.ValueIsolate(argv);
|
|
API.ValueElementsCount(argv, arrSize);
|
|
for i := 0 to arrSize - 1 do
|
|
begin
|
|
API.ValueInit(@val);
|
|
if API.ValueNthElementValue(argv, i, val) = HV_OK then
|
|
begin
|
|
API.ValueStringData(@val, strData, strLen);
|
|
strData := PWideChar(RnQLangs.GetTranslation(strData));
|
|
API.ValueStringDataSet(@val, strData, Length(strData), 0);
|
|
API.ValueNthElementValueSet(retval, i, @val)
|
|
end;
|
|
API.ValueClear(@val);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
class procedure TCommonMethods.CheckOnline(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
res: Boolean;
|
|
begin
|
|
res := OnlFeature(Account.AccProto);
|
|
API.ValueIntDataSet(retval, RDUtils.IfThen(res, 1), T_BOOL, 0);
|
|
end;
|
|
|
|
class procedure TCommonMethods.SetLargeWindowIcon(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
Hndl: HWND;
|
|
HIco: HIcon;
|
|
Pic: String;
|
|
begin
|
|
Hndl := GetWindowHandle(argc, argv);
|
|
if Hndl <= 0 then
|
|
Exit;
|
|
|
|
Inc(argv);
|
|
Pic := SciterVarToString(argv);
|
|
try
|
|
if (Pic = '') or (Pic = '-') then
|
|
HIco := Application.Icon.Handle
|
|
else
|
|
HIco := LoadIcon(HInstance, PWideChar(Pic));
|
|
|
|
SendMessage(Hndl, WM_SETICON, ICON_BIG, HIco);
|
|
if Pic = '-' then
|
|
begin
|
|
SendMessage(Hndl, WM_SETICON, ICON_SMALL, 0);
|
|
// SetWindowLong(Hndl, GWL_EXSTYLE, GetWindowLong(Hndl, GWL_EXSTYLE) or WS_EX_DLGMODALFRAME);
|
|
// SetWindowPos(Hndl, 0, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOZORDER or SWP_FRAMECHANGED or SWP_NOACTIVATE);
|
|
end;
|
|
except end;
|
|
end;
|
|
|
|
class procedure TCommonMethods.GetMaxPasswordLength(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
V2S(Account.AccProto._MaxPwdLen, retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.GetPwd(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
V2S(Account.AccProto.Pwd, retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.GetContactIdle(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
UIN: TUID;
|
|
IdleTime: Integer;
|
|
Contact: TICQContact;
|
|
begin
|
|
Contact := nil;
|
|
IdleTime := 0;
|
|
UIN := SciterVarToString(argv);
|
|
if not (UIN = '') then
|
|
Contact := Account.AccProto.GetContact(UIN);
|
|
if Assigned(Contact) then
|
|
IdleTime := Contact.IdleTime;
|
|
V2S(IdleTime, retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.GetContactImportant(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
UIN: TUID;
|
|
Important: String;
|
|
Tmp: Integer;
|
|
GetLocal: Boolean;
|
|
Contact: TICQContact;
|
|
begin
|
|
Contact := nil;
|
|
Important := '';
|
|
UIN := SciterVarToString(argv);
|
|
if not (UIN = '') then
|
|
Contact := Account.AccProto.GetContact(UIN);
|
|
Inc(argv);
|
|
Tmp := 0;
|
|
API.ValueIntData(argv, Tmp);
|
|
GetLocal := Tmp = 1;
|
|
|
|
if Assigned(Contact) then
|
|
Important := IfThen(GetLocal, Contact.lclImportant, Contact.ssImportant);
|
|
|
|
V2S(Important, retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.GetContactIgnored(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
UIN: TUID;
|
|
Contact: TICQContact;
|
|
Ignored: Boolean;
|
|
begin
|
|
Contact := nil;
|
|
Ignored := False;
|
|
UIN := SciterVarToString(argv);
|
|
if not (UIN = '') then
|
|
Contact := Account.AccProto.GetContact(UIN);
|
|
if Assigned(Contact) then
|
|
Ignored := Contact.IsInList(LT_SPAM) or IgnoreList.exists(Contact);
|
|
V2S(Ignored, retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.GetCurrentUserName(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
V2S(RnQUser, retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.GetGroupName(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
Group: Integer;
|
|
begin
|
|
Group := 0;
|
|
API.ValueIntData(argv, Group);
|
|
if Group = 0 then
|
|
V2S('', retval)
|
|
else
|
|
V2S(groups.ID2Name(Group), retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.GetContactData(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
UIN: TUID;
|
|
Contact: TICQContact;
|
|
NodeData: TNodeData;
|
|
begin
|
|
Contact := nil;
|
|
UIN := SciterVarToString(argv);
|
|
|
|
if not (UIN = '') then
|
|
Contact := Account.AccProto.GetContact(UIN);
|
|
|
|
if not Assigned(Contact) then
|
|
begin
|
|
V2S(varNull, retval);
|
|
Exit;
|
|
end;
|
|
|
|
with UI do
|
|
begin
|
|
if TCE(Contact.Data^).Node = nil then
|
|
TCE(Contact.Data^).Node := TNode.Create(d_nil, Contact);
|
|
NodeData := GetNodeData(TCE(Contact.Data^).Node);
|
|
V2S(RecordToVar(NodeData), retval);
|
|
end;
|
|
end;
|
|
|
|
class procedure TCommonMethods.GetCurrentUserAcc(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
V2S(Account.AccProto.MyAccNum, retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.GetAccountPassword(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
V2S(AccPass, retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.SaveAccountPassword(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
if argc = 0 then
|
|
Exit;
|
|
|
|
if UpdateAccountEncryption(SciterVarToString(argv)) then
|
|
ActionManager.Execute(AK_SAVECONFIG, SaveDelay);
|
|
end;
|
|
|
|
class procedure TCommonMethods.SaveNewAccountPassword(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
if argc > 0 then
|
|
NewAccPass := SciterVarToString(argv);
|
|
end;
|
|
|
|
class procedure TCommonMethods.CheckLockPassword(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
Pwd: String;
|
|
begin
|
|
if argc = 0 then
|
|
Exit;
|
|
|
|
Pwd := SciterVarToString(argv);
|
|
if not (AccPass = '') then
|
|
V2S(CompareText(AccPass, Pwd) = 0, retval)
|
|
else
|
|
V2S(Account.AccProto.PwdEqual(Pwd), retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.OpenLink(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
URL: String;
|
|
begin
|
|
URL := SciterVarToString(argv);
|
|
if not (URL = '') then
|
|
OpenURL(URL);
|
|
end;
|
|
|
|
class procedure TCommonMethods.OpenPortal(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
OpenURL(rnqSite)
|
|
end;
|
|
|
|
class procedure TCommonMethods.IsOnline(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
V2S(Assigned(Account.AccProto) and Account.AccProto.IsOnline, retval)
|
|
end;
|
|
|
|
class procedure TCommonMethods.IsAIM(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
MyInf: TICQContact;
|
|
IsAIM: Boolean;
|
|
begin
|
|
IsAIM := False;
|
|
if not Assigned(Account.AccProto) then
|
|
Exit;
|
|
MyInf := Account.AccProto.GetMyInfo;
|
|
if Assigned(MyInf) then
|
|
IsAIM := MyInf.isAIM;
|
|
V2S(IsAIM, retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.IsElevated(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
V2S(utilLib.IsElevated, retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.IsWindows10(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
V2S(IsTen, retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.IsWindows8(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
V2S(IsEight, retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.ProcessMacro(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
I, Key: Integer;
|
|
Shift: TShiftState;
|
|
|
|
function Match(Shortcut: TShortcut): Boolean;
|
|
var
|
|
HK: Word;
|
|
State: TShiftState;
|
|
begin
|
|
ShortCutToKey(Shortcut, HK, State);
|
|
if ShortCut and scCommand <> 0 then Include(State, ssCommand); // WIN key
|
|
Result := ((HK and not scCommand) = Key) and (State = Shift);
|
|
end;
|
|
|
|
begin
|
|
Key := 0;
|
|
API.ValueIntData(argv, Key);
|
|
|
|
Shift := [];
|
|
|
|
Inc(argv);
|
|
I := 0;
|
|
API.ValueIntData(argv, I);
|
|
if I = 1 then
|
|
Shift := Shift + [ssShift];
|
|
|
|
Inc(argv);
|
|
I := 0;
|
|
API.ValueIntData(argv, I);
|
|
if I = 1 then
|
|
Shift := Shift + [ssCtrl];
|
|
|
|
Inc(argv);
|
|
I := 0;
|
|
API.ValueIntData(argv, I);
|
|
if I = 1 then
|
|
Shift := Shift + [ssAlt];
|
|
|
|
Inc(argv);
|
|
I := 0;
|
|
API.ValueIntData(argv, I);
|
|
if I = 1 then
|
|
Shift := Shift + [ssCommand];
|
|
|
|
if HotkeysEnabled and (Key > 0) then
|
|
for I := Low(Macros) to High(Macros) do
|
|
if not Macros[I].sw and Match(Macros[i].hk) then
|
|
ExecuteMacro(Macros[i].opcode);
|
|
end;
|
|
|
|
class procedure TCommonMethods.GetUploadServerName(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
if ServerToUpload = 0 then
|
|
V2S('files.icq.net', retval)
|
|
else if ServerToUpload = 1 then
|
|
V2S('code.highspec.ru', retval)
|
|
else
|
|
V2S('rnq.ru', retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.GetUpdateInfo(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
UpdateInfo: TUpdateInfo;
|
|
begin
|
|
CheckUpdates(UpdateInfo);
|
|
V2S(UI.RecordToVar(UpdateInfo), retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.GetDoubleClickDelay(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
V2S(GetDoubleClickTime, retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.GetWindowCaptionHeight(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
Height: Integer;
|
|
begin
|
|
Height := GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXPADDEDBORDER) * 2 + GetSystemMetrics(SM_CYFRAME) * 2;
|
|
V2S(Height, retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.GetWeekDayByNumber(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
Num: Integer;
|
|
WeekDay: String;
|
|
begin
|
|
Num := 0;
|
|
API.ValueIntData(argv, Num);
|
|
WeekDay := GetWeekDay(Num);
|
|
V2S(WeekDay, retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.GetMonthNameByNumber(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
Num: Integer;
|
|
MonthName: String;
|
|
begin
|
|
Num := 0;
|
|
API.ValueIntData(argv, Num);
|
|
MonthName := GetGenitiveMonthName(Num);
|
|
V2S(MonthName, retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.PrettyPrint(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
Text: String;
|
|
begin
|
|
Text := PrettyPrintJSON(TJSONValue.ParseJSONValue(SciterVarToString(argv)));
|
|
V2S(Text, retval);
|
|
end;
|
|
|
|
class procedure TCommonMethods.GetSystemAccentColors(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
AccentColors: TArray |
|
begin
|
|
AccentColors := [GetRValue(AccentColor), GetGValue(AccentColor), GetBValue(AccentColor), Byte(AccentColor shr 24)];
|
|
V2S(AccentColors, retval);
|
|
end;
|
|
|
|
function GetWindowHandle(argc: UINT; argv: PSciterValue; Root: Boolean = True): HWND;
|
|
var
|
|
B: PByte;
|
|
Pb: Cardinal;
|
|
PResult: HELEMENT;
|
|
Hndl: HWND;
|
|
begin
|
|
B := nil;
|
|
Hndl := 0;
|
|
if (argc > 0) then
|
|
if argv.t = UINT(T_RESOURCE) then
|
|
begin
|
|
API.SciterElementUnwrap(argv, PResult);
|
|
if Assigned(PResult) then
|
|
API.SciterGetElementHwnd(PResult, Hndl, Root);
|
|
end else if (argv.t = UINT(T_OBJECT)) and (argv.u = UINT(UT_OBJECT_NATIVE)) then
|
|
begin
|
|
API.ValueBinaryData(argv, B, Pb);
|
|
if Assigned(B) then
|
|
API.SciterGetElementHwnd(B, Hndl, Root);
|
|
end;
|
|
Result := Hndl;
|
|
end;
|
|
|
|
//procedure TCommonMethods.ActivateWindow(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
//var
|
|
// Hndl: HWND;
|
|
//begin
|
|
// Hndl := GetWindowHandle(argc, argv);
|
|
// if Hndl > 0 then
|
|
// SetForegroundWindow(Hndl);
|
|
//end;
|
|
|
|
//procedure TCommonMethods.IsWindowActive(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
//var
|
|
// Hndl, Forg: HWND;
|
|
//begin
|
|
// Hndl := GetWindowHandle(argc, argv);
|
|
// Forg := GetForegroundWindow;
|
|
// if Hndl > 0 then
|
|
// V2S((Forg = Hndl) or (Forg = GetParent(Hndl)), retval)
|
|
// else
|
|
// V2S(False, retval)
|
|
//end;
|
|
|
|
procedure SetupWindowTask(Window: HWND; ShowButton: Boolean; WindowType: Integer = 0);
|
|
var
|
|
ExStyle: Integer;
|
|
begin
|
|
if Window = 0 then
|
|
Exit;
|
|
ExStyle := GetWindowLongPtr(Window, GWL_EXSTYLE);
|
|
if ShowButton then
|
|
ExStyle := ExStyle or WS_EX_APPWINDOW
|
|
else
|
|
ExStyle := ExStyle and not WS_EX_APPWINDOW;
|
|
if WindowType > 0 then
|
|
ExStyle := ExStyle or WindowType;
|
|
SetWindowLongPtr(Window, GWL_EXSTYLE, ExStyle);
|
|
end;
|
|
|
|
class procedure TCommonMethods.ShowTaskbarButton(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
SetupWindowTask(GetWindowHandle(argc, argv), True);
|
|
end;
|
|
|
|
class procedure TCommonMethods.HideTaskbarButton(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
SetupWindowTask(GetWindowHandle(argc, argv), False);
|
|
end;
|
|
|
|
class procedure TCommonMethods.HideTaskbarButton2(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
SetupWindowTask(GetWindowHandle(argc, argv), False, WS_EX_NOACTIVATE);
|
|
end;
|
|
|
|
//procedure SetDesktopAsParent(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
//var
|
|
// Window: HWND;
|
|
//begin
|
|
// Window := GetWindowHandle(argc, argv, False);
|
|
// SetParent(Window, 0);
|
|
// SetWindowLongPtr(Window, GWLP_HWNDPARENT, 0);
|
|
//end;
|
|
|
|
class procedure TCommonMethods.SavePreviousWindow(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
PrevWnd := GetForegroundWindow;
|
|
end;
|
|
|
|
class procedure TCommonMethods.ClearPreviousWindow(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
PrevWnd := 0;
|
|
end;
|
|
|
|
class procedure TCommonMethods.SwitchToPreviousWindow(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
begin
|
|
if PrevWnd > 0 then
|
|
begin
|
|
SetForegroundWindow(PrevWnd);
|
|
PrevWnd := 0;
|
|
end;
|
|
end;
|
|
|
|
class procedure TCommonMethods.HTMLDecode(argc: UINT; argv: PSciterValue; retval: PSciterValue); cdecl;
|
|
var
|
|
Text: String;
|
|
begin
|
|
Text := THTMLEncoding.HTML.Decode(SciterVarToString(argv));
|
|
V2S(Text, retval);
|
|
end;
|
|
|
|
// TUI
|
|
|
|
constructor TUI.Create;
|
|
begin
|
|
inherited Create;
|
|
OnLoadData := LoadData;
|
|
OnScriptingCall := ScriptingCall;
|
|
end;
|
|
|
|
procedure TUI.CreateCL;
|
|
begin
|
|
CL := TContactList.Create;
|
|
CL.Root := HELEMENT(NativeInt(Call('createContactList')));
|
|
API.SciterGetElementHwnd(CL.Root, CL.Window, True);
|
|
if CL.Window = 0 then
|
|
raise ESciterException.Create('Cannot get CL window handle');
|
|
// Hide close button
|
|
// SetWindowLongPtr(CL.Window, GWL_STYLE, GetWindowLongPtr(CL.Window, GWL_STYLE) and not WS_SYSMENU);
|
|
|
|
// Remove icon and hide taskbar button
|
|
//SetupWindowTask(CL.Window, False, WS_EX_DLGMODALFRAME);
|
|
|
|
LastMonCnt := GetActiveMonitorCount;
|
|
CL.SavePositionForCurrentMonitorCount;
|
|
end;
|
|
|
|
procedure TUI.CreateChat;
|
|
begin
|
|
Chat := TChatBox.Create;
|
|
Chat.Root := HELEMENT(NativeInt(Call('createChat')));
|
|
API.SciterGetElementHwnd(Chat.Root, Chat.Window, True);
|
|
if Chat.Window = 0 then
|
|
raise ESciterException.Create('Cannot get chat window handle');
|
|
|
|
// Do not repaint under child windows (plugin tabs)
|
|
SetWindowLongPtr(Chat.Window, GWL_STYLE, GetWindowLongPtr(Chat.Window, GWL_STYLE) or WS_CLIPCHILDREN);
|
|
end;
|
|
|
|
procedure TUI.CreateLog;
|
|
begin
|
|
Log := TLog.Create;
|
|
Log.Root := HELEMENT(NativeInt(Call('createLog')));
|
|
API.SciterGetElementHwnd(Log.Root, Log.Window, True);
|
|
if Log.Window = 0 then
|
|
raise ESciterException.Create('Cannot get log window handle');
|
|
end;
|
|
|
|
procedure TUI.CreateTips;
|
|
begin
|
|
Tips := TTips.Create;
|
|
Tips.Root := HELEMENT(NativeInt(Call('createTips')));
|
|
API.SciterGetElementHwnd(Tips.Root, Tips.Window, True);
|
|
if Tips.Window = 0 then
|
|
raise ESciterException.Create('Cannot get tips window handle');
|
|
Tips.InitWndProc;
|
|
SetupWindowTask(Tips.Window, False, WS_EX_NOACTIVATE);
|
|
end;
|
|
|
|
function TUI.CallOnElement(Element: HELEMENT; const FuncName: AnsiString; Params: TArray |
|
var
|
|
RetVal: TSciterValue;
|
|
Handle: HWINDOW;
|
|
Res: SCDOM_RESULT;
|
|
begin
|
|
Result := Unassigned;
|
|
if Element = nil then Exit;
|
|
Res := API.SciterGetElementHwnd(Element, Handle, True);
|
|
if Res <> SCDOM_OK then
|
|
begin
|
|
ODS('CallOnElement failed: [' + FuncName + '] ' + IntToStr(Integer(res)));
|
|
Exit;
|
|
end;
|
|
if Handle = 0 then
|
|
begin
|
|
ODS('CallOnElement failed: handle is zero');
|
|
Exit;
|
|
end;
|
|
|
|
API.ValueInit(@RetVal);
|
|
if IsMethod then
|
|
begin
|
|
if (CallScriptMethod(Element, FuncName, Params, RetVal) = SCDOM_OK) then
|
|
S2V(@RetVal, Result, FuncName)
|
|
end else if (CallScriptFunction(Element, FuncName, Params, RetVal) = SCDOM_OK) then
|
|
S2V(@RetVal, Result, FuncName);
|
|
API.ValueClear(@RetVal);
|
|
end;
|
|
|
|
procedure TUI.FireOnElement(Element: HELEMENT; const name: String; data: Variant; async: Boolean = True);
|
|
begin
|
|
FireCustom(Element, name, data, async);
|
|
end;
|
|
|
|
procedure TUI.CallInWindow(const WindowID, FuncName: AnsiString; Params: TArray |
|
var
|
|
Doc: HELEMENT;
|
|
Res: Variant;
|
|
begin
|
|
Res := Call('findWindowDocument', [WindowID]);
|
|
if not VarIsNumeric(Res) or VarIsClear(Res) or VarIsEmpty(Res) or VarIsNull(Res) or (VarCompareValue(Res, Unassigned) = vrEqual) then
|
|
Exit;
|
|
Doc := Pointer(NativeInt(Res));
|
|
if Assigned(Doc) then
|
|
UI.CallOnElement(Doc, FuncName, Params);
|
|
end;
|
|
|
|
procedure TUI.MessageDialog(const Msg: String; Kind: TMsgDlgType);
|
|
begin
|
|
Call('showAlert', [Kind, Msg, False]);
|
|
end;
|
|
|
|
function TUI.InputQuery(const Caption, Text, Icon: String): String;
|
|
begin
|
|
Result := Call('inputQuery', [Caption, Text, Icon]);
|
|
end;
|
|
|
|
function TUI.GetFocused(Window: HWINDOW): HELEMENT;
|
|
begin
|
|
if not (API.SciterGetFocusElement(Window, Result) = SCDOM_OK) then
|
|
Result := nil;
|
|
end;
|
|
|
|
//function TUI.GetCurrentRoot: HELEMENT;
|
|
//begin
|
|
// if not (API.SciterGetRootElement(GetForegroundWindow, Result) = SCDOM_OK) then
|
|
// Result := nil;
|
|
//end;
|
|
|
|
procedure TUI.AppActivate(Sender: TObject);
|
|
begin
|
|
InactiveTime := 0;
|
|
if Assigned(UI) and Assigned(UI.Tips) then
|
|
UI.Tips.Reposition;
|
|
if Assigned(Account.AccProto) then
|
|
Account.AccProto.CheckEventSubscribe(6);
|
|
end;
|
|
|
|
procedure TUI.AppDeactivate(Sender: TObject);
|
|
begin
|
|
InactiveTime := 0;
|
|
CheckTopMost;
|
|
end;
|
|
|
|
procedure TUI.SystemSettingChange(Sender: TObject; Flag: Integer; const Section: string; var Result: Longint);
|
|
begin
|
|
case Flag of
|
|
SPI_SETMENUANIMATION, SPI_SETTOOLTIPANIMATION, SPI_SETSELECTIONFADE:
|
|
ApplySystemSettings;
|
|
end;
|
|
end;
|
|
|
|
procedure TUI.ApplySystemSettings;
|
|
var
|
|
AccentColors: TArray |
|
AccentInactiveColors: TArray |
|
begin
|
|
if UIAccentColor = 1 then
|
|
AccentColors := [GetRValue(UIAccentColorVal), GetGValue(UIAccentColorVal), GetBValue(UIAccentColorVal), 255]
|
|
else
|
|
AccentColors := [GetRValue(AccentColor), GetGValue(AccentColor), GetBValue(AccentColor), Byte(AccentColor shr 24)];
|
|
AccentInactiveColors := [GetRValue(AccentColorInactive), GetGValue(AccentColorInactive), GetBValue(AccentColorInactive), Byte(AccentColorInactive shr 24)];
|
|
|
|
Call('setSystemSettings', [AccentColors, AccentInactiveColors, MenuFadeEnabled, TooltipFadeEnabled, SelectionFadeEnabled]);
|
|
end;
|
|
|
|
function TUI.GetImageColors(var str: TMemoryStream): TParams;
|
|
var
|
|
img: Variant;
|
|
buf: Pointer;
|
|
|
|
// Freq, StartCount, StopCount: Int64;
|
|
// TimingSeconds: real;
|
|
begin
|
|
img := VarArrayCreate([0, str.Size - 1], varByte);
|
|
buf := VarArrayLock(img);
|
|
str.Seek(0, soFromBeginning);
|
|
str.ReadBuffer(buf^, str.Size);
|
|
VarArrayUnlock(img);
|
|
//QueryPerformanceFrequency(Freq);
|
|
//QueryPerformanceCounter(StartCount);
|
|
Result := Call('getImageColors', [img]);
|
|
//QueryPerformanceCounter(StopCount);
|
|
//TimingSeconds := (StopCount - StartCount) / Freq;
|
|
//ODS('Vibrant run: ' + floattostr(TimingSeconds));
|
|
end;
|
|
|
|
function TUI.EnterPassword(const Title: String; MaxLength: Integer = 0): String;
|
|
begin
|
|
Result := Call('enterPassword', [Title, MaxLength]);
|
|
end;
|
|
|
|
procedure TUI.EnterLockPassword(const Title, Hint: String; MaxLength: Integer = 0);
|
|
begin
|
|
Call('enterLockPassword', [Title, Hint, MaxLength]);
|
|
end;
|
|
|
|
function TUI.SwitchUser(ShowConflictMsg: Boolean = False): TUID;
|
|
begin
|
|
Result := Call('switchUser', [ShowConflictMsg]);
|
|
end;
|
|
|
|
function TUI.SelectContacts(const Caption, Btn: String; Options: TSCOptions; CheckUID: TUID = ''): TParams;
|
|
begin
|
|
Result := Call('openUINList', [Caption, Btn, Byte(Options), CheckUID]);
|
|
end;
|
|
|
|
procedure TUI.ReloadUsers;
|
|
begin
|
|
CallInWindow('users', 'reloadUsers');
|
|
end;
|
|
|
|
procedure TUI.ViewInfo(UID: TUID; const Caption: String; UpdateOnly: Boolean = False);
|
|
begin
|
|
Call('openViewInfo', [UID, Caption, UpdateOnly]);
|
|
end;
|
|
|
|
procedure TUI.OpenPrefs(const Page: String = ''; Full: Boolean = True);
|
|
begin
|
|
Call('openPrefs', [Page, Full]);
|
|
end;
|
|
|
|
procedure TUI.OpenHistorySearch;
|
|
begin
|
|
Call('openHistorySearch');
|
|
end;
|
|
|
|
procedure TUI.OpenUpdater;
|
|
begin
|
|
Call('openUpdater');
|
|
end;
|
|
|
|
function TUI.OpenLangs(Langs: Variant): Integer;
|
|
begin
|
|
Result := Call('openLangs', [Langs]);
|
|
end;
|
|
|
|
procedure TUI.UpdateViewInfoAnP(UID: TUID);
|
|
begin
|
|
CallInWindow('info:' + UID, 'updateAvatarAndPhoto');
|
|
end;
|
|
|
|
procedure TUI.UpdateOutbox;
|
|
begin
|
|
CallInWindow('outbox', 'updateList', [true]);
|
|
CallInWindow('outbox', 'updateText');
|
|
end;
|
|
|
|
procedure TUI.UpdateDB;
|
|
begin
|
|
CallInWindow('db', 'updateList');
|
|
end;
|
|
|
|
procedure TUI.UpdateSessions(Current: Boolean = False);
|
|
begin
|
|
CallInWindow('sessionsmgr', IfThen(Current, 'removeCurrent', 'updateSessionsList'));
|
|
end;
|
|
|
|
procedure TUI.UpdateTranslations;
|
|
begin
|
|
if Assigned(UI.CL) then
|
|
begin
|
|
UI.CL.UpdateTranslation;
|
|
UI.CL.InitMenus;
|
|
UI.CL.UpdateAdditionalImage;
|
|
UI.CL.UpdateVisibilityImage;
|
|
RebuildCL;
|
|
end;
|
|
if Assigned(UI.Chat) then
|
|
begin
|
|
UI.Chat.UpdateTranslation;
|
|
UI.Chat.UpdateHintsTraslation;
|
|
end;
|
|
if Assigned(UI.Log) then
|
|
UI.Log.UpdateTranslation;
|
|
end;
|
|
|
|
procedure TUI.CloseAllChildWindows;
|
|
begin
|
|
Call('closeChildWindows');
|
|
end;
|
|
|
|
function TUI.CreateDialog(const Msg: String; DlgType: TMsgDlgType; Buttons: TMsgDlgButtons; Seconds: Integer): Integer;
|
|
var
|
|
DefaultButton, CancelButton: TMsgDlgBtn;
|
|
DefaultButtonVar, CancelButtonVar: Variant;
|
|
ButtonsVar: TParams;
|
|
Title, Icon, ResultBtn: String;
|
|
begin
|
|
case DlgType of
|
|
mtWarning:
|
|
Icon := PIC_EXCLAMATION;
|
|
mtError:
|
|
Icon := PIC_HAND;
|
|
mtInformation:
|
|
Icon := PIC_ASTERISK;
|
|
mtConfirmation:
|
|
Icon := PIC_QUEST;
|
|
mtBuzz:
|
|
Icon := PIC_BUZZ;
|
|
mtCustom:
|
|
Icon := '';
|
|
end;
|
|
|
|
if DlgType <> mtCustom then
|
|
Title := GetTranslation(LoadResString(Captions[DlgType]))
|
|
else
|
|
Title := Application.Title;
|
|
if RnQUser > '' then
|
|
Title := Title + ' (' + RnQUser + ')';
|
|
|
|
for var Button in Buttons do
|
|
ButtonsVar := ButtonsVar + [SymbolToVar(GetEnumName(TypeInfo(TMsgDlgBtn), Ord(Button)))];
|
|
|
|
if mbOk in Buttons then
|
|
DefaultButton := mbOk
|
|
else if mbYes in Buttons then
|
|
DefaultButton := mbYes
|
|
else
|
|
DefaultButton := mbRetry;
|
|
|
|
if mbCancel in Buttons then
|
|
CancelButton := mbCancel
|
|
else if mbNo in Buttons then
|
|
CancelButton := mbNo
|
|
else
|
|
CancelButton := mbOk;
|
|
|
|
DefaultButtonVar := SymbolToVar(GetEnumName(TypeInfo(TMsgDlgBtn), Ord(DefaultButton)));
|
|
CancelButtonVar := SymbolToVar(GetEnumName(TypeInfo(TMsgDlgBtn), Ord(CancelButton)));
|
|
|
|
ResultBtn := Call('createDialog', [Icon, Title, Msg, False, ButtonsVar, DefaultButtonVar, CancelButtonVar, Seconds]);
|
|
|
|
if ResultBtn = 'mbYes' then Result := mrYes
|
|
else if ResultBtn = 'mbNo' then Result := mrNo
|
|
else if ResultBtn = 'mbOK' then Result := mrOK
|
|
else if ResultBtn = 'mbCancel' then Result := mrCancel
|
|
else if ResultBtn = 'mbAbort' then Result := mrAbort
|
|
else if ResultBtn = 'mbRetry' then Result := mrRetry
|
|
else if ResultBtn = 'mbIgnore' then Result := mrIgnore
|
|
else if ResultBtn = 'mbAll' then Result := mrAll
|
|
else if ResultBtn = 'mbNoToAll' then Result := mrNoToAll
|
|
else if ResultBtn = 'mbYesToAll' then Result := mrYesToAll
|
|
else if ResultBtn = 'mbHelp' then Result := mrHelp
|
|
else if ResultBtn = 'mbClose' then Result := mrClose
|
|
else Result := mrOK;
|
|
end;
|
|
|
|
procedure TUI.InitSettings;
|
|
var
|
|
Settings: TCommonSettings;
|
|
begin
|
|
Settings.supportAvatars := Account.AccProto.AvatarsSupport;
|
|
Settings.avatarShowInHint := AvatarShowInHint;
|
|
Settings.avatarUsePalette := AvatarUsePalette10;
|
|
Settings.animateWindows := AnimateWindows;
|
|
Settings.newSettings := NewSettingsDesign;
|
|
Settings.animatedScroll := AnimatedScroll;
|
|
Settings.quitConfirmation := QuitConfirmation;
|
|
Settings.alertTopMost := AlertTopMost;
|
|
Call('initCommonSettings', [RecordToVar(Settings)]);
|
|
end;
|
|
|
|
procedure TUI.LoadData(ASender: TObject; const URL: WideString; ResType: SciterResourceType; RequestId: Pointer; out Discard, Delay, Myself: Boolean);
|
|
begin
|
|
if (theme.token = 101) and (StartsText('themepic', url) or StartsText('pluginpic:', url) or StartsText('smile:', url)) then
|
|
Discard := True // Theme is not loaded yet
|
|
else
|
|
InitRequest(ASender, URL, ResType, RequestId, Discard, Delay, Myself);
|
|
end;
|
|
|
|
class procedure TCommonMethods.RegisterMethods(var ReturnValue: TSciterValue);
|
|
begin
|
|
AddMethod('GetWindowCaptionHeight', GetWindowCaptionHeight);
|
|
AddMethod('GetTranslation', GetTranslation);
|
|
AddMethod('GetTranslations', GetTranslations);
|
|
AddMethod('GetSpriteData', GetSpriteData);
|
|
AddMethod('GetImageBytes', GetImageBytes);
|
|
AddMethod('CheckOnline', CheckOnline);
|
|
AddMethod('SetLargeWindowIcon', SetLargeWindowIcon);
|
|
AddMethod('GetMaxPasswordLength', GetMaxPasswordLength);
|
|
AddMethod('GetPwd', GetPwd);
|
|
AddMethod('GetCurrentUserName', GetCurrentUserName);
|
|
AddMethod('GetCurrentUserAcc', GetCurrentUserAcc);
|
|
AddMethod('GetAccountPassword', GetAccountPassword);
|
|
AddMethod('SaveAccountPassword', SaveAccountPassword);
|
|
AddMethod('IsAIM', IsAIM);
|
|
AddMethod('HTMLDecode', HTMLDecode);
|
|
AddMethod('ShowTaskbarButton', ShowTaskbarButton);
|
|
AddMethod('HideTaskbarButton', HideTaskbarButton);
|
|
AddMethod('HideTaskbarButton2', HideTaskbarButton2);
|
|
AddMethod('SavePreviousWindow', SavePreviousWindow);
|
|
AddMethod('ClearPreviousWindow', ClearPreviousWindow);
|
|
AddMethod('SwitchToPreviousWindow', SwitchToPreviousWindow);
|
|
AddMethod('GetContactIdle', GetContactIdle);
|
|
AddMethod('GetContactImportant', GetContactImportant);
|
|
AddMethod('GetContactIgnored', GetContactIgnored);
|
|
AddMethod('GetGroupName', GetGroupName);
|
|
AddMethod('GetContactData', GetContactData);
|
|
AddMethod('SaveNewAccountPassword', SaveNewAccountPassword);
|
|
AddMethod('CheckLockPassword', CheckLockPassword);
|
|
AddMethod('OpenLink', OpenLink);
|
|
AddMethod('OpenPortal', OpenPortal);
|
|
AddMethod('IsOnline', IsOnline);
|
|
AddMethod('IsElevated', IsElevated);
|
|
AddMethod('IsWindows10', IsWindows10);
|
|
AddMethod('IsWindows8', IsWindows8);
|
|
AddMethod('ProcessMacro', ProcessMacro);
|
|
AddMethod('GetUploadServerName', GetUploadServerName);
|
|
AddMethod('GetUpdateInfo', GetUpdateInfo);
|
|
AddMethod('GetDoubleClickDelay', GetDoubleClickDelay);
|
|
AddMethod('GetWeekDayByNumber', GetWeekDayByNumber);
|
|
AddMethod('GetMonthNameByNumber', GetMonthNameByNumber);
|
|
AddMethod('PrettyPrint', PrettyPrint);
|
|
AddMethod('GetSystemAccentColors', GetSystemAccentColors);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TUI.ScriptingCall(ASender: TObject; const Args: TElementOnScriptingCallArgs);
|
|
var
|
|
CommonNative, MainNative, ChatNative, ViewInfoNative, PrefsNative: TSciterValue;
|
|
begin
|
|
if not (Args.Method = 'getNativeApis') then
|
|
Exit;
|
|
|
|
TCommonMethods.RegisterMethods(CommonNative);
|
|
TTipsMethods.RegisterMethods(CommonNative);
|
|
TUsersMethods.RegisterMethods(CommonNative);
|
|
TSearchMethods.RegisterMethods(CommonNative);
|
|
TOutboxMethods.RegisterMethods(CommonNative);
|
|
TDBMethods.RegisterMethods(CommonNative);
|
|
TUINListMethods.RegisterMethods(CommonNative);
|
|
|
|
TMainMethods.RegisterMethods(MainNative);
|
|
TCLMethods.RegisterMethods(MainNative);
|
|
TStatusMethods.RegisterMethods(MainNative);
|
|
TAboutMethods.RegisterMethods(MainNative);
|
|
Args.Handled := True;
|
|
|
|
TChatMethods.RegisterMethods(ChatNative);
|
|
|
|
TViewInfoMethods.RegisterMethods(ViewInfoNative);
|
|
|
|
TPrefsMethods.RegisterMethods(PrefsNative);
|
|
|
|
API.ValueNthElementValueSet(@Args.ReturnSciterValue, 0, @CommonNative);
|
|
API.ValueNthElementValueSet(@Args.ReturnSciterValue, 1, @MainNative);
|
|
API.ValueNthElementValueSet(@Args.ReturnSciterValue, 2, @ChatNative);
|
|
API.ValueNthElementValueSet(@Args.ReturnSciterValue, 3, @ViewInfoNative);
|
|
API.ValueNthElementValueSet(@Args.ReturnSciterValue, 4, @PrefsNative);
|
|
|
|
Args.Handled := True;
|
|
end;
|
|
|
|
end.
|