0,0 → 1,746 |
// akTimeLog v3.0 |
// Copyright (c) 1999-2000 Anatoli Klassen |
unit MainUnit; |
|
interface |
|
uses |
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, |
StdCtrls, ComCtrls, Menus, ShellApi, ExtCtrls, ImgList, AMAutoRun, |
UtilsUnit, LogInfoUnit; |
|
const |
AK_NOTIFYICON = WM_USER + 2; |
ID_ICON = 1; |
|
type |
TakTimeLogMainForm = class(TForm) |
MainMenu: TMainMenu; |
FileMenu: TMenuItem; |
ExitItem: TMenuItem; |
HelpMenu: TMenuItem; |
AboutItem: TMenuItem; |
StatusBar: TStatusBar; |
IconPopupMenu: TPopupMenu; |
ShowPopupItem: TMenuItem; |
PopupMenuLine03: TMenuItem; |
ExitPopupItem: TMenuItem; |
Timer: TTimer; |
MenuLine01: TMenuItem; |
ChangePasswordItem: TMenuItem; |
OptionsItem: TMenuItem; |
HelpContentsItem: TMenuItem; |
MenuImageList: TImageList; |
PopupMenuLine01: TMenuItem; |
ChangePasswordPopupItem: TMenuItem; |
OptionsPopupItem: TMenuItem; |
PopupMenuLine02: TMenuItem; |
AboutPopupItem: TMenuItem; |
HelpContentsPopupItem: TMenuItem; |
AutoRun: TAMAutoRun; |
TimeTree: TTreeView; |
TreePopupMenu: TPopupMenu; |
DeleteBranchPopupItem: TMenuItem; |
EditMenu: TMenuItem; |
DeleteBranchItem: TMenuItem; |
procedure FormCreate(Sender: TObject); |
procedure ExitItemClick(Sender: TObject); |
procedure AboutItemClick(Sender: TObject); |
procedure ShowPopupItemClick(Sender: TObject); |
procedure FormHide(Sender: TObject); |
procedure TimerTimer(Sender: TObject); |
procedure FormDestroy(Sender: TObject); |
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); |
procedure ChangePasswordItemClick(Sender: TObject); |
procedure OptionsItemClick(Sender: TObject); |
procedure HelpContentsItemClick(Sender: TObject); |
procedure DeleteBranchItemClick(Sender: TObject); |
procedure TimeTreeChange(Sender: TObject; Node: TTreeNode); |
procedure TimeTreeKeyUp(Sender: TObject; var Key: Word; |
Shift: TShiftState); |
private |
FShow : boolean; |
FExit : boolean; // Exit item was clicked |
FProgStart : TDateTime; |
procedure IconCallBack(var WMN : TWMNotify); message AK_NOTIFYICON; |
procedure SendParams(var WMN : TWMNotify); message AK_SENDPARAM; |
procedure EndSession(var WMN : TWMNotify); message WM_QUERYENDSESSION; |
procedure AddIcon; |
procedure DeleteIcon; |
procedure ModifyIcon(Tip : string); |
procedure AppMinimize(Sender : TObject); |
procedure CalcTime; |
procedure DeleteTimeBranch(Branch : TTreeNode); |
procedure DeleteTime(ATime : TDateTime; Kind : TInfoType); |
function EncodeTime(Pwd : string; |
Time : TDateTime; Position : longint) : Int64; |
function DecodeTime(Pwd : string; |
Code : Int64; Position : longint) : TDateTime; |
public |
procedure ShowWindow; |
end; |
|
var |
akTimeLogMainForm: TakTimeLogMainForm; |
|
implementation |
|
uses AboutUnit, Registry, OptionsUnit, ChangePasswordUnit, PasswordUnit; |
|
{$R *.DFM} |
|
//= TakTimeLogMainForm ========================================================= |
|
procedure TakTimeLogMainForm.FormCreate(Sender: TObject); |
var |
Reg : TRegIniFile; |
LogFile : file of Int64; |
StartCode : Int64; |
StopCode : Int64; |
Pwd : string; |
|
begin |
try |
Reg := TRegIniFile.Create(RegistryRoot); |
|
Top := Reg.ReadInteger('Main Window', 'Top', Top); |
Left := Reg.ReadInteger('Main Window', 'Left', Left); |
Width := Reg.ReadInteger('Main Window', 'Width', Width); |
Height := Reg.ReadInteger('Main Window', 'Height', Height); |
|
Reg.Free; |
except |
end; |
|
Application.OnMinimize := AppMinimize; |
FExit := False; |
FShow := False; |
AddIcon; |
|
if WriteLog then |
try |
System.Assign(LogFile, LogFileName); |
try |
System.Reset(LogFile); |
System.Seek(LogFile, FileSize(LogFile)); |
except |
System.Rewrite(LogFile); |
end; |
|
Pwd := DecodePassword(Password); |
FProgStart := Now; |
StartCode := EncodeTime(Pwd, FProgStart, System.FilePos(LogFile)); |
StopCode := EncodeTime(Pwd, FProgStart, System.FilePos(LogFile)+1); |
|
Write(LogFile, StartCode); |
Write(LogFile, StopCode); |
System.Close(LogFile); |
ModifyIcon('akTimeLog - Started ' + DateTimeToStr(FProgStart)); |
except |
MessageBox(0, PChar('Error writting ' + LogFileName), |
'akTimeLog', MB_ICONERROR or MB_OK); |
end; |
|
Timer.Enabled := True; |
ShowPopupItem.Enabled := not Application.ShowMainForm; |
end; |
|
procedure TakTimeLogMainForm.CalcTime; |
procedure AddItem(Info : TLogInfo); |
var |
Node : TTreeNode; |
|
begin |
case Info.InfoType of |
itYear: Node := nil; |
|
itMonth: begin |
Node := TimeTree.Items.GetFirstNode; |
while (Node <> nil) and not (((TLogInfo(Node.Data)).InfoType = itYear) |
and ((TLogInfo(Node.Data)).Year = Info.Year)) |
do Node := Node.GetNext; |
end; |
|
itDay: begin |
Node := TimeTree.Items.GetFirstNode; |
while (Node <> nil) and not (((TLogInfo(Node.Data)).InfoType = itMonth) |
and ((TLogInfo(Node.Data)).Month = Info.Month)) |
do Node := Node.GetNext; |
end; |
|
itTime: begin |
Node := TimeTree.Items.GetFirstNode; |
while (Node <> nil) and not (((TLogInfo(Node.Data)).InfoType = itDay) |
and ((TLogInfo(Node.Data)).Day = Info.Day)) |
do Node := Node.GetNext; |
end; |
|
else Exit; |
end; |
|
Node := TimeTree.Items.AddChild(Node, ''); |
Node.Data := Info; |
end; |
|
procedure UpdateItems; |
var |
Node : TTreeNode; |
Y, M, D : word; |
|
begin |
DecodeDate(Now, Y, M, D); |
Node := TimeTree.Items.GetFirstNode; |
while Node <> nil do |
with TLogInfo(Node.Data) do begin |
Node.Text := ToString; |
|
case InfoType of |
itYear : if Year = Y then Node.Expand(False); |
itMonth : if Month = M then Node.Expand(False); |
itDay : if Day = D then Node.Expand(False); |
end; |
|
Node := Node.GetNext; |
end; |
end; |
|
var |
Pwd : string; |
LogFile : file of Int64; |
StartCode : Int64; |
StopCode : Int64; |
StartTime : TDateTime; |
StopTime : TDateTime; |
Time1 : TDateTime; |
Time2 : TDateTime; |
Year, Month, Day, Time, Total : TLogInfo; |
|
begin |
DeleteTimeBranch(nil); |
|
try |
System.Assign(LogFile, LogFileName); |
System.Reset(LogFile); |
|
Pwd := DecodePassword(Password); |
|
Total := nil; |
Year := nil; |
Month := nil; |
Day := nil; |
|
while not EoF(LogFile) do begin |
Read(LogFile, StartCode, StopCode); |
|
StartTime := DecodeTime(Pwd, StartCode, System.FilePos(LogFile)-2); |
StopTime := DecodeTime(Pwd, StopCode, System.FilePos(LogFile)-1); |
|
if StopTime < StartTime then begin |
Application.MessageBox(PChar('Incorrect record in ' + LogFileName), |
'akTimeLog', MB_OK or MB_ICONERROR); |
Break; |
end; |
|
Time1 := StartTime; |
Time2 := Trunc(Time1)+1; |
|
repeat |
if Time2 > StopTime then Time2 := StopTime; |
|
Time := TLogInfo.Create(itTime, Time1, Time2); |
|
if Total = nil then Total := TLogInfo.Create(itTotal, Time1, Time1); |
|
if (Year = nil) or (Year.Year <> Time.Year) then begin |
Year := TLogInfo.Create(itYear, Time1, Time1); |
AddItem(Year); |
end; |
|
if (Month = nil) or (Month.Month <> Time.Month) then begin |
Month := TLogInfo.Create(itMonth, Time1, Time1); |
AddItem(Month); |
end; |
|
if (Day = nil) or (Day.Day <> Time.Day) then begin |
Day := TLogInfo.Create(itDay, Time1, Time1); |
AddItem(Day); |
end; |
|
AddItem(Time); |
|
Total.AddTime(Time.Duration); |
Year.AddTime(Time.Duration); |
Month.AddTime(Time.Duration); |
Day.AddTime(Time.Duration); |
|
if Time2 >= StopTime then Break; |
Time1 := Trunc(Time1)+1; |
Time2 := Trunc(Time1)+1; |
until False; |
end; |
|
System.Close(LogFile); |
UpdateItems; |
|
StatusBar.Panels[0].Text := Total.ToString; |
Total.Free; |
except |
Application.MessageBox(PChar('Error reading ' + LogFileName), |
'akTimeLog', MB_OK or MB_ICONERROR); |
end; |
end; |
|
procedure TakTimeLogMainForm.DeleteTimeBranch(Branch : TTreeNode); |
var |
Node, Node2 : TTreeNode; |
|
begin |
if Branch = nil then |
Node := TimeTree.Items.GetFirstNode |
else |
Node := Branch.GetFirstChild; |
|
while Node <> nil do begin |
DeleteTimeBranch(Node); |
if Node.Data <> nil then TLogInfo(Node.Data).Free; |
Node2 := Node.GetNextSibling; |
Node.Delete; |
Node := Node2; |
end; |
end; |
|
procedure TakTimeLogMainForm.AddIcon; |
var |
ID : TNotifyIconData; |
|
begin |
if not WriteLog then Exit; |
|
ID.cbSize := SizeOf(ID); |
ID.Wnd := Handle; |
|
ID.uID := ID_ICON; |
ID.uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP; |
ID.uCallbackMessage := AK_NOTIFYICON; |
ID.hIcon := Icon.Handle; |
ID.szTip := 'akTimeLog'; |
Shell_NotifyIcon(NIM_ADD, @ID); |
end; |
|
procedure TakTimeLogMainForm.ModifyIcon(Tip : string); |
var |
ID : TNotifyIconData; |
|
begin |
if not WriteLog then Exit; |
|
ID.cbSize := SizeOf(ID); |
ID.Wnd := Handle; |
|
ID.uID := ID_ICON; |
ID.uFlags := NIF_TIP; |
StrPCopy(ID.szTip, Copy(Tip, 1, 62)); |
Shell_NotifyIcon(NIM_MODIFY, @ID); |
end; |
|
procedure TakTimeLogMainForm.DeleteIcon; |
var |
ID : TNotifyIconData; |
|
begin |
if not WriteLog then Exit; |
|
ID.cbSize := SizeOf(ID); |
ID.Wnd := Handle; |
ID.uID := ID_ICON; |
Shell_NotifyIcon(NIM_DELETE, @ID); |
end; |
|
procedure TakTimeLogMainForm.IconCallBack; |
var |
p : TPoint; |
|
begin |
inherited; |
case longint(WMN.NMHdr) of |
WM_RBUTTONUP: begin |
GetCursorPos(p); |
IconPopupMenu.Popup(p.x, p.y); |
end; |
|
WM_LBUTTONDBLCLK: begin |
ShowWindow; |
Application.Restore; |
Application.BringToFront; |
end; |
end; |
end; |
|
procedure TakTimeLogMainForm.AppMinimize(Sender : TObject); |
begin |
if WriteLog then Hide; |
end; |
|
procedure TakTimeLogMainForm.ShowPopupItemClick(Sender: TObject); |
begin |
ShowWindow; |
Application.Restore; |
Application.BringToFront; |
end; |
|
procedure TakTimeLogMainForm.FormHide(Sender: TObject); |
begin |
ShowPopupItem.Enabled := True; |
end; |
|
procedure TakTimeLogMainForm.DeleteTime(ATime : TDateTime; Kind : TInfoType); |
type |
TTimes = array[0..MaxInt div 32] of TLogInfo; |
|
var |
LogFile : file of Int64; |
Times : ^TTimes; |
n, i, k : longint; |
Code1, Code2 : Int64; |
Pwd : string; |
CurWritten : boolean; |
TimeNow : TDateTime; |
ControlTime : TLogInfo; |
|
begin |
try |
Pwd := DecodePassword(Password); |
CurWritten := False; |
|
System.Assign(LogFile, LogFileName); |
System.Reset(LogFile); |
GetMem(Times, System.FileSize(LogFile) * SizeOf(Pointer) div 2); |
|
n := 0; |
while not EoF(LogFile) do begin |
Read(LogFile, Code1, Code2); |
Times^[n] := TLogInfo.Create(itTime, |
DecodeTime(Pwd, Code1, n*2), |
DecodeTime(Pwd, Code2, n*2+1)); |
Inc(n); |
end; |
System.Close(LogFile); |
|
ControlTime := TLogInfo.Create(itTime, ATime, ATime); |
System.Rewrite(LogFile); |
k := 0; |
for i := 0 to n-1 do begin |
case Kind of |
itTotal : Continue; |
itYear : if Times^[i].Year = ControlTime.Year then Continue; |
itMonth : if Times^[i].Month = ControlTime.Month then Continue; |
itDay : if Times^[i].Day = ControlTime.Day then Continue; |
itTime : if Times^[i].Start = ControlTime.Start then Continue; |
end; |
|
if Times^[i].Start = FProgStart then CurWritten := True; |
Code1 := EncodeTime(Pwd, Times^[i].Start, k*2); |
Code2 := EncodeTime(Pwd, Times^[i].Stop, k*2+1); |
Write(LogFile, Code1, Code2); |
Inc(k); |
end; |
|
if not CurWritten then begin |
TimeNow := Now; |
Code1 := EncodeTime(Pwd, TimeNow, k*2); |
Code2 := EncodeTime(Pwd, TimeNow, k*2+1); |
|
Write(LogFile, Code1, Code2); |
end; |
|
System.Close(LogFile); |
FreeMem(Times, System.FileSize(LogFile) * SizeOf(Int64)); |
except |
end; |
end; |
|
procedure TakTimeLogMainForm.TimerTimer(Sender: TObject); |
var |
LogFile : file of Int64; |
CurTime : Int64; |
Pwd : string; |
|
begin |
if WriteLog then |
try |
System.Assign(LogFile, LogFileName); |
System.Reset(LogFile); |
System.Seek(LogFile, FileSize(LogFile)-1); |
|
Pwd := DecodePassword(Password); |
CurTime := EncodeTime(Pwd, Now, System.FilePos(LogFile)); |
|
Write(LogFile, CurTime); |
System.Close(LogFile); |
|
CalcTime; |
except |
MessageBox(0, PChar('Error writting ' + LogFileName), |
'akTimeLog', MB_ICONERROR or MB_OK); |
end; |
end; |
|
procedure TakTimeLogMainForm.FormDestroy(Sender: TObject); |
var |
Reg : TRegIniFile; |
|
begin |
Timer.Enabled := False; |
TimerTimer(Sender); |
DeleteIcon; |
|
try |
Reg := TRegIniFile.Create(RegistryRoot); |
|
Reg.WriteInteger('Main Window', 'Top', Top); |
Reg.WriteInteger('Main Window', 'Left', Left); |
Reg.WriteInteger('Main Window', 'Width', Width); |
Reg.WriteInteger('Main Window', 'Height', Height); |
|
Reg.Free; |
except |
end; |
end; |
|
procedure TakTimeLogMainForm.FormCloseQuery(Sender: TObject; |
var CanClose: Boolean); |
begin |
if WriteLog and not FExit then begin |
CanClose := False; |
Hide; |
end |
else |
CanClose := True; |
end; |
|
function TakTimeLogMainForm.EncodeTime |
(Pwd : string; Time : TDateTime; Position : longint) : Int64; |
var |
i, p : longint; |
PwdArray : array[1..8] of char; |
PwdPart : int64 absolute PwdArray; |
TimeInt : int64 absolute Time; |
|
begin |
Inc(Position); |
if Pwd = '' then |
Result := TimeInt |
else begin |
for i := 1 to 8 do begin |
p := (Position+i-2) mod Length(Pwd) + 1; |
PwdArray[i] := Pwd[p]; |
end; |
|
Result := TimeInt xor PwdPart; |
end |
end; |
|
function TakTimeLogMainForm.DecodeTime |
(Pwd : string; Code : Int64; Position : longint) : TDateTime; |
var |
i, p : longint; |
PwdArray : array[1..8] of char; |
PwdPart : int64 absolute PwdArray; |
Time : TDateTime absolute Code; |
|
begin |
Inc(Position); |
if Pwd = '' then |
Result := Time |
else begin |
for i := 1 to 8 do begin |
p := (Position+i-2) mod Length(Pwd) + 1; |
PwdArray[i] := Pwd[p]; |
end; |
|
Code := Code xor PwdPart; |
Result := Time; |
end |
end; |
|
procedure TakTimeLogMainForm.ChangePasswordItemClick(Sender: TObject); |
type |
TTimeCodes = array[0..MaxInt div 16] of Int64; |
|
var |
OldPwd, NewPwd : string; |
RetypeNewPwd : string; |
LogFile : file of Int64; |
TimeCodes : ^TTimeCodes; |
n, i : longint; |
TimeCode : Int64; |
|
begin |
if not ChangePasswordForm.Execute(OldPwd, NewPwd, RetypeNewPwd) then Exit; |
|
if DecodePassword(Password) <> OldPwd then begin |
Application.MessageBox('Incorrect old password', |
'akTimeLog', MB_OK or MB_ICONERROR); |
Exit; |
end; |
|
if (NewPwd <> '') and (NewPwd <> RetypeNewPwd) then begin |
Application.MessageBox('You''ve entered not equal new passwords', |
'akTimeLog', MB_OK or MB_ICONERROR); |
Exit; |
end; |
|
if DecodePassword(Password) = NewPwd then Exit; |
|
Password := EncodePassword(NewPwd); |
|
try |
System.Assign(LogFile, LogFileName); |
System.Reset(LogFile); |
GetMem(TimeCodes, System.FileSize(LogFile) * SizeOf(Int64)); |
n := 0; |
while not EoF(LogFile) do begin |
Read(LogFile, TimeCodes^[n], TimeCodes^[n+1]); |
Inc(n, 2); |
end; |
System.Close(LogFile); |
|
System.Rewrite(LogFile); |
for i := 0 to n-1 do begin |
TimeCode := EncodeTime(NewPwd, DecodeTime(OldPwd, TimeCodes^[i], i), i); |
Write(LogFile, TimeCode); |
end; |
System.Close(LogFile); |
FreeMem(TimeCodes, System.FileSize(LogFile) * SizeOf(Int64)); |
except |
end; |
end; |
|
procedure TakTimeLogMainForm.OptionsItemClick(Sender: TObject); |
begin |
OptionsForm.Execute; |
end; |
|
procedure TakTimeLogMainForm.ExitItemClick(Sender: TObject); |
begin |
FExit := True; |
Close; |
end; |
|
procedure TakTimeLogMainForm.HelpContentsItemClick(Sender: TObject); |
begin |
; |
end; |
|
procedure TakTimeLogMainForm.AboutItemClick(Sender: TObject); |
begin |
AboutBox.ShowModal; |
end; |
|
procedure TakTimeLogMainForm.SendParams(var WMN : TWMNotify); |
var |
Params : string; |
LogFile : file of Int64; |
StartCode : Int64; |
StopCode : Int64; |
StartTime : TDateTime; |
Pwd : string; |
|
begin |
if MapHandle = 0 then Exit; |
|
Params := MapFile; |
DeleteIcon; |
ParseParamsString(Params); |
AddIcon; |
|
if WriteLog then |
try |
System.Assign(LogFile, LogFileName); |
try |
System.Reset(LogFile); |
System.Seek(LogFile, FileSize(LogFile)); |
except |
System.Rewrite(LogFile); |
end; |
|
Pwd := DecodePassword(Password); |
StartTime := Now; |
StartCode := EncodeTime(Pwd, StartTime, System.FilePos(LogFile)); |
StopCode := EncodeTime(Pwd, StartTime, System.FilePos(LogFile)+1); |
|
Write(LogFile, StartCode); |
Write(LogFile, StopCode); |
System.Close(LogFile); |
ModifyIcon('akTimeLog - Started ' + DateTimeToStr(StartTime)); |
except |
MessageBox(0, PChar('Error writting ' + LogFileName), |
'akTimeLog', MB_ICONERROR or MB_OK); |
end |
else |
Show; |
end; |
|
procedure TakTimeLogMainForm.EndSession(var WMN : TWMNotify); |
begin |
FExit := True; |
WMN.Result := 1; |
end; |
|
procedure TakTimeLogMainForm.ShowWindow; |
var |
Pwd, Control : string; |
|
begin |
DeleteTimeBranch(nil); |
ShowPopupItem.Enabled := False; |
|
if Password <> '' then begin |
Pwd := PasswordForm.Execute; |
if Pwd = '' then Exit; |
|
try |
Control := DecodePassword(Password); |
except |
Application.MessageBox('Error during decoding the password', |
'akTimeLog', MB_OK or MB_ICONERROR); |
end; |
|
if Pwd <> Control then begin |
Application.MessageBox('Password Incorrect', 'akTimeLog', |
MB_OK or MB_ICONERROR); |
Exit; |
end; |
end; |
|
DeleteBranchItem.Enabled := False; |
DeleteBranchPopupItem.Enabled := False; |
CalcTime; |
Show; |
end; |
|
procedure TakTimeLogMainForm.DeleteBranchItemClick(Sender: TObject); |
begin |
if Application.MessageBox('Delete selected branch?', 'akTimeLog', |
MB_YESNO or MB_ICONWARNING) = IDYES |
then begin |
with TLogInfo(TimeTree.Selected.Data) do |
DeleteTime(Start, InfoType); |
CalcTime; |
end; |
end; |
|
procedure TakTimeLogMainForm.TimeTreeChange(Sender: TObject; |
Node: TTreeNode); |
begin |
DeleteBranchItem.Enabled := True; |
DeleteBranchPopupItem.Enabled := True; |
end; |
|
procedure TakTimeLogMainForm.TimeTreeKeyUp(Sender: TObject; var Key: Word; |
Shift: TShiftState); |
begin |
if Key = VK_DELETE then DeleteBranchItemClick(Sender); |
end; |
|
end. |