;script to display work timer when using work apps and not playing around ;based on Work.ahk by Neil Cicierega http://neilblr.com/post/58757345346 ; ;CHANGES TO THE ORIGINAL ARE BELOW: ;set up any number of work related apps, uses two timers, one for work, one for slack time ;change nItems in the INI file to how many program items you need, the default is 12 with a minimum of 6 ;now uses process names instead of Classes to greatly reduce how many Items are needed ;automatically resumes from last timers, menu option changed to Restart timers ;added Transparency menu option for the main window ; ;Michael Todd 10/03/16 #SingleInstance,Force global progmen,TimerActive,Waiting,nItems,UpdateSeconds=1.0,TimerActive=1,Ver=1.25 global H,M,S,H2,M2,S2,class,title,ver,IdleTime,prcname,prcname2,X,Y,mainID,Trans IniRead, IdleTime, WorkTimer.ini, section, Timeout, 10 IniRead, nItems, WorkTimer.ini, section, nItems, 12 ;read saved programs Loop,%nItems% IniRead, Program%A_Index%, WorkTimer.ini, section, Program%A_Index% IniRead, LastWorkTime, WorkTimer.ini, section, LastWorkTime, 00:00:00 IniRead, LastSlackTime, WorkTimer.ini, section, LastSlackTime, 00:00:00 IniRead, ColorAlert, WorkTimer.ini, section, ColorAlert, true IniRead, OnColor, WorkTimer.ini, section, OnColor, B0FFFF IniRead, OffColor, WorkTimer.ini, section, OffColor, F07070 IniRead, Trans, WorkTimer.ini, section, Trans,off IniRead, X, WorkTimer.ini, section, X, 10 IniRead, Y, WorkTimer.ini, section, Y, 10 IniWrite, %ColorAlert%, WorkTimer.ini, section, ColorAlert IniWrite, %OnColor%, WorkTimer.ini, section, OnColor IniWrite, %OffColor%, WorkTimer.ini, section, OffColor IniWrite, %nItems%, WorkTimer.ini, section, nItems ;check for Caffeine app process,exist,caffeine.exe if (ErrorLevel <> 0) { MsgBox,4,CAFFEIENE,Caffeine is running`, it will interfere with Idle times > 50 seconds.`nClick Yes if you would like to close it. IfMsgBox,Yes Process,Close,caffeine.exe } START: SetBatchLines, -1 ;timer GUI Gui +LastFound +AlwaysOnTop Gui, Color, %OnColor% Gui, Font, S20 CDefault Bold, Courier New Gui, Add, Text, x5 y5 vMyText, 00:00:00 Gui, Font, S8 CDefault, Courier New Gui, Add, Button, x140 y8 h20 gPopMenu, MENU Gui, Add, Text,xm y40 w120 Center vCurrentProgram,Active Program SetFormat, Float, 02.0 h := m := s := "00" ;work timer h2 := m2 := s2 := "00" ;slack timer Gui, -MinimizeBox -MaximizeBox Gui, Show,X%X% Y%Y% w185 h60, BACK TO WORK mainID := WinExist("A") WinGetPos,X,Y,,,ahk_ID %mainID% WinSet, Transparent, %Trans%, ahk_id %mainID% SetTimer, Update, % UpdateSeconds * 1000 Gosub, Update ;idle time GUI Gui, 2: +LastFound +AlwaysOnTop Gui, 2: Add, Text, x5 y5 vMyText, Enter idle timeout in seconds: Gui, 2: Add, Edit, y5 vNewTimeout w45,%IdleTime% Gui, 2: Add, Button, gSetTimeoutOK Default, Set ;number of Program Items GUI Gui, 3: +LastFound +AlwaysOnTop Gui, 3: Add, Text, x5 y5, Enter number of program items: Gui, 3: Add, Edit, y5 vnItems w25,%nItems% Gui, 3: Add, Button, gSetItemsOK Default, Set ;set Window Transparency GUI Gui, 4: +LastFound +AlwaysOnTop Gui, 4: Add, Text, x5 y5, Enter transparency (100-255 or Off): Gui, 4: Add, Edit, y5 vTrans w35,%Trans% Gui, 4: Add, Button, gSetTransOK Default, Set WinSet, Style, -0x20000 -0x10000 ;build progmen list Loop,%nItems% { p := Program%A_Index% progmen%A_Index% = Program %A_Index%: %p% } timemen = Idle Timeout (sec): %IdleTime% itemsmen = Program Items: %nItems% transmen = Transparency: %Trans% ;Menu, MyMenu, Add, Resume previous time, Prev Menu, MyMenu, Add, Restart Timers, RestartTimes Menu, MyMenu, Add ;build menu list Loop,%nItems% { p := progmen%A_Index% Menu, MyMenu, Add, %p%, SetProgram0 } Menu, MyMenu, Add Menu, MyMenu, Add, %timemen%, SetTimeout Menu, MyMenu, Add, %itemsmen%, SetItems Menu, MyMenu, Add, %transmen%, SetTrans Menu, MyMenu, Add Menu, MyMenu, Add, Color Alert, ChangeColor if (ColorAlert = "true") Menu, MyMenu, Check, Color Alert gosub,Prev ;use previous times return ;save timers on close GuiClose: WinGetPos,X,Y,,,ahk_id %mainID% IniWrite, %H%:%M%:%S%, WorkTimer.ini, section, LastWorkTime IniWrite, %H2%:%M2%:%S2%, WorkTimer.ini, section, LastSlackTime IniWrite, %X%, WorkTimer.ini, section, X IniWrite, %Y%, WorkTimer.ini, section, Y ExitApp ;set color change on/off ChangeColor: if (ColorAlert = "true"){ Menu, MyMenu, UnCheck, Color Alert ColorAlert = false IniWrite, false, WorkTimer.ini, section, ColorAlert Gui, Color, %OnColor% } else { Menu, MyMenu, Check, Color Alert ColorAlert = true IniWrite, true, WorkTimer.ini, section, ColorAlert Gui, Color, %OffColor% } return ;update and display popup menu PopMenu: Loop,%nItems% { if ((Program%A_Index% = "ERROR") or (Program%A_Index% = "")) progmen%A_Index%b = Program %A_Index%: (Not set) else { p := Program%A_Index% progmen%A_Index%b = Program %A_Index%: %p% } if (progmen%A_Index% != progmen%A_Index%B ){ p1 := progmen%A_Index% p2 := progmen%A_Index%B Menu,MyMenu,Rename,%p1%,%p2% progmen%A_Index% := progmen%A_Index%B } } timemenB = Idle Timeout (sec): %IdleTime% if (timemen != timemenB ){ Menu,MyMenu,Rename,%timemen%,%timemenB% timemen = %timemenB% } transmenB = Transparency: %Trans% if (transmen != transmenB ){ Menu,MyMenu,Rename,%transmen%,%transmenB% transmen = Transparency: %Trans% } Menu, MyMenu, Show return RestartTimes: MsgBox,4,RESTART,Reset Timers to Zero? IfMsgBox,No return h := m := s := "00" ;work timer h2 := m2 := s2 := "00" ;slack timer WinGetTitle, title,A if (title = "BACK TO WORK") GuiControl,, MyText, %H2%:%M2%:%S2% else GuiControl,, MyText, %H%:%M%:%S% return ;use previous timers Prev: StringSplit, LastWorkTimeA, LastWorkTime, `: StringSplit, LastSlackTimeA, LastSlackTime, `: ;retrieve work timer H = %LastWorkTimeA1% M = %LastWorkTimeA2% S = %LastWorkTimeA3% ;retrieve slack timer H2 = %LastSlackTimeA1% M2 = %LastSlackTimeA2% S2 = %LastSlackTimeA3% GuiControl,, MyText, %H%:%M%:%S% SetTimer, Update, % UpdateSeconds * 1000 return ;get all necessary Window Information GetWinInfo: ;check against valid work programs ID := DllCall("GetParent", UInt,WinExist("A")), ID := !ID ? WinExist("A") : ID WinGetClass, class, ahk_id %ID% ;get window Title in case it is an AutoHotkey app WinGetTitle, title, ahk_id %ID% WinGet,prcname,ProcessName, ahk_id %ID% WinGetPos,X,Y,,,ahk_id %mainID% StringTrimRight,prcname2,prcname,4 return ;set menu item to a program process name SetProgram: Gui, Font, S10 CDefault, Arial GuiControl, Font, MyText Waiting := 1 ;set Waiting flag to true GuiControl,, MyText,Awaiting program... SetTimer, Update, Off gosub,GetWinInfo while (class = "AutoHotkeyGUI") and ((title = "BACK TO WORK") or (title = "KEEP WORKING")) { gosub,GetWinInfo sleep,100 } Gui, Font, S20 CDefault Bold, Courier New GuiControl, Font, MyText GuiControl,, MyText, %H%:%M%:%S% Waiting := 0 ;clear Waiting flag SetTimer, Update, % UpdateSeconds * 1000 return ;save program class for selected menu item SetProgram0: Item := A_ThisMenuItemPos - 2 Gosub, SetProgram Program%Item% = %prcname% IniWrite, %prcname%, WorkTimer.ini, section, Program%Item% return ;display idle timeout GUI SetTimeout: Gui, 2: Show,w250, Set Idle Timeout return ;save idle timeout SetTimeoutOK: Gui, 2: Submit if NewTimeout is integer IdleTime = %NewTimeout% IniWrite, %IdleTime%, WorkTimer.ini, section, Timeout return ;display number of Program Items GUI SetItems: Gui, 3: Show,, Set Program Items return ;save number of items SetItemsOK: Gui, 3: Submit if nItems is integer { if nItems < 6 nItems := 6 IniWrite, %nItems%, WorkTimer.ini, section, nItems SplashTextOn,200,50,RESTARTING,Please wait sleep,1000 Reload } return ;set Transparency GUI SetTrans: Gui, 4: Show,, Set Window Transparency return ;save Trans SetTransOK: Gui, 4: Submit IniWrite, %Trans%, WorkTimer.ini, section, Trans WinSet, Transparent, %Trans%, ahk_ID %mainID% return ;one second updater Update: gosub,GetWinInfo ;check against valid work programs Progs = Loop,%nItems% Progs := Progs . Program%A_Index% IfInString, Progs, %prcname% ProgramActive = 1 else ProgramActive = 0 if (ProgramActive = 0) prcname2 = *%prcname2%* ;timer not active or program not valid, return if (TimerActive=0) and ((A_TimeIdle > IdleTime*1000) or (ProgramActive = 0)) { ;update Slack Timer GuiControl,, CurrentProgram, %prcname2% gosub,UpdateSlackTime return } ;idle time reached or not in a work program, set Back to Work if ((A_TimeIdle > IdleTime*1000) or (ProgramActive = 0)) { TimerActive = 0 if (ColorAlert = "true") Gui, Color, %OffColor% gosub,GetWinInfo GuiControl,, CurrentProgram, %prcname2% Gui, Show,X%X% Y%Y% w185 NA, BACK TO WORK ;update Slack Timer gosub,UpdateSlackTime return } ;timer running, in a valid work app TimerActive = 1 if (ColorAlert = "true") Gui, Color, %OnColor% gosub,GetWinInfo GuiControl,, CurrentProgram, %prcname2% Gui, Show,X%X% Y%Y% w185 NA, KEEP WORKING gosub,UpdateWorkTime return UpdateWorkTime: Menu,Tray,Tip,WORK TIMER (%ver%)`n`nWork: %H%:%M%:%S%`nSlack: %H2%:%M2%:%S2% ;update H:M:S timer in valid Work apps if (S >= 59) { if (M >= 59) { M = 00 H += 1.0 GuiControl,, MyText, %H%:%M%:%S% } else M += 1.0 S = 00 GuiControl,, MyText, %H%:%M%:%S% return } S += UpdateSeconds GuiControl,, MyText, %H%:%M%:%S% return UpdateSlackTime: Menu,Tray,Tip,WORK TIMER (%ver%)`n`nWork: %H%:%M%:%S%`nSlack: %H2%:%M2%:%S2% if (Waiting = 1) ;no updates to Timer while Waiting to add a program to the list return ;update H:M:S timer outside of valid Work apps if (S2 >= 59) { if (M2 >= 59) { M2 = 00 H2 += 1.0 GuiControl,, MyText, %H2%:%M2%:%S2% } else M2 += 1.0 S2 = 00 GuiControl,, MyText, %H2%:%M2%:%S2% return } S2 += UpdateSeconds GuiControl,, MyText, %H2%:%M2%:%S2% return