Files
VisionFlowAutomator/__pycache__/main.cpython-313.pyc
T

712 lines
135 KiB
Plaintext
Raw Normal View History

2025-07-31 12:52:28 +02:00
ó
…V‹hÜzã
2025-07-31 12:52:28 +02:00
óxSSKrSSKrSSKrSSKrSSKrSSKrSSKrSSKrSSKrSSK r SSK
J r SSK J
r
JrJr SSKrSSKrSSKrSSKrSSKJr SSKrSSKJrJrJr S\lS\lS\l Sr!\RDRG\!5(d\RH"\!5 \RJ"\RLS \RN"\RDRQ\!S
5S S 9\RR"5/S
9 \RT"S5r+\+RY\RZ5 \RT"\.5r/Sr0\RDRG\05(d\RH"\05 "SS5r1\1"5r2"SS5r3Sr4"SS\
Rj5r6"SS\
Rn5r8"SS\
Rn5r9"SS\
Rn5r:\.S:XaT\
Rv"\Rx5r=\6"5r>\>R5 \R€"\=Rƒ55 gg)éN)Ú lru_cache)Ú QtWidgetsÚQtGuiÚQtCore)Úkeyboard)Ú ImageGrabÚImageÚImageTkFç{®Gáz„?Úlogsz([%(asctime)s] %(levelname)s: %(message)szscenario_automation.logzutf-8)Úencoding)ÚlevelÚformatÚhandlersÚ performanceÚ scenarioscó8\rSrSrSrS SjrS
SjrSrSrSr g) Ú
TemplateCacheé3z•
Cache for template images to avoid reloading them repeatedly.
Uses weak references to allow garbage collection when templates are no longer needed.
có,0UlXl0Ulg©N)Ú_cacheÚ _max_sizeÚ
_access_times)ÚselfÚmax_sizes Úmain.pyÚ__init__ÚTemplateCache.__init__8s؈Œ ØØˆÕócóŒU(dXR;a~[UR5URaUR5 [R
"U5nUb0X0RU'[ R "5URU'U$[ R "5URU'URU$)z)Get template image from cache or load it.)rÚlenrÚ_cleanup_old_entriesÚcv2ÚimreadÚtimer)rÚpathÚ force_reloadÚtemplates rÚ get_templateÚTemplateCache.get_template=sæ ˜4§{¡{Ó4—; 4§>¡>Ó×—zz 'ˆÑ#Ø$,— ˜!Ü+/¯9ª9«;×" ˆOä'+§y¢y£{ˆD× Ñ ˜ —;‘;˜tÑ $r cóUR(dg[URR5SS9n[U5S-nUSUH=up4URR US5 URR US5 M? g)z#Remove least recently used entries.Ncó US$)©)Úxs rÚ<lambda>Ú4TemplateCache._cleanup_old_entries.<locals>.<lambda>RsÈ!ÈAÊ$r )Úkeyé)rÚsortedÚitemsr"rÚpop)rÚsorted_entriesÚentries_to_remover'Ú_s rr#Ú"TemplateCache._cleanup_old_entriesLsxà×!× ô  × 2Ñ 2× 8Ñ 8Ó :ÁÑÜ Ó/°1Ñà%Ð&8Ð'8Ó9‰Gˆ K‰KO‰O˜D  × Ñ × " Ö :r có–URR5 URR5 [R"5 g)zClear all cached templates.N)rÚclearrÚgcÚcollect©rs rr=ÚTemplateCache.clearYs-à ×ÑÔØ ×Ñ× Ñ Ô
Š
r )rrrN)é2©F)
Ú__name__Ú
__module__Ú __qualname__Ú__firstlineno__Ú__doc__rr*r#r=Ú__static_attributes__r/r rrr3sñô ô
 r rcód\rSrSrSrS SjrSr\S5rSr Sr
\S 5r \S
5r S r
g)
ÚScenarioébzy
Represents a scenario, which consists of a name and a list of steps.
Handles saving/loading scenario data to/from disk.
Ncó0XlU=(d /Ulg)z7
Initialize a Scenario with a name and optional steps.
ÚnameÚsteps)rrOrPs rrÚScenario.__init__gsðŒ Ø—[˜bˆ
r có4URURS.$)z5
Return a dictionary representation of the scenario.
rNrNr@s rÚto_dictÚScenario.to_dictns🠙 ¨D¯J©JÑ7r có@[USURS/55$)z-
Create a Scenario object from a dictionary.
rOrP)rKÚget)Údatas rÚ from_dictÚScenario.from_dictts ô
˜˜V™  d§h¡h¨w¸Ó&;Ó<r có^[RR[UR5$)z6
Return the directory path for this scenario's files.
)Úosr'ÚjoinÚ
CONFIG_DIRrOr@s rÚget_scenario_dirÚScenario.get_scenario_dir{sôw‰w|‰|œJ¨¯ © Ó2r có(UR5n[RRU5(d[R"U5 [ [RR
US5S5n[R"UR5USS9 SSS5 [RSURS35 g!,(df  N2=f![a/n[RSURS U35 SnAgSnAff=f)
z+
Save the scenario to disk as a JSON file.
ú
scenario.jsonÚ)ÚindentNú
Scenario 'z' saved.zFailed to save scenario 'ú': )r^r[r'ÚexistsÚmakedirsÚopenr\ÚjsonÚdumprSÚloggerÚinforOÚ ExceptionÚerror)rÚ scenario_dirÚes rÚsaveÚ
Scenario.saveð HØ×2ˆ—77—>> ,× ˜”b—g‘g—l‘l <°ÓAÀ3ÔGÈ1Ü— ’ ˜$Ÿ,™,›.¨!°AÒHä K‰K˜* T§Y¡Y K¨xÐ HÕGûôó HÜ L‰LÐ4°T·Y±Y°K¸sÀ1À#Ð Gûð Hús0A4CÁ6%CÂ+CÃ
CÃCÃ
DÃ"%D Ä DcóÀ[RR[U5n[ [RRUS5S5n[
R
[R"U55nSSS5 [RSUS35 W$!,(df  N)=f![a%n[RSUSU35 SnAgSnAff=f)z$
Load a scenario from disk by name.
raÚrNrez ' loaded.zFailed to load scenario 'rf)
r[r'r\r]rirKrXrjÚloadrlrmrnro)rOrprqÚscenariorrs rrwÚ
Scenario.loadð
 ÜŸ7™7Ÿ<™<¬
°DÓ9ˆ”b—gg—ll ÓAÀ3ÔGÈ1Ü#×-¬d¯iªi¸«lÓ;÷Hä K‰K˜* T F¨)Ð ˆO÷HÕGûôó Ü L‰LÐ4°T°F¸#¸a¸SÐ ûð ús0AB.Á*BÁ:"B.Â
B+Â'B.Â.
CÂ8CÃCc óò[R"[5Vs/sHMn[RR [RR [U55(dMKUPMO sn$s snf)z
List all scenario directories.
)r[Úlistdirr]r'Úisdirr\)Úds rÚlist_allÚScenario.list_allŸsGô
Ÿ:š:¤jÔ1a´R·W±W·]±]Ä2Ç7Á7Ç<Á<ÔPZÐ\]ÓC^×5_—Ñ`ùÒ`s A
A4Á+A4rNr)rDrErFrGrHrrSÚ staticmethodrXr^rsrwr~rIr/r rrKrKbsZñô ñð 
Hðñ óð ðñaóóar rKcóŽ^^^^^ ^
^ ^ [R"5m T RSS5 T RSS5 T RSS5 T RT 5 T R SS5 T R S5 [R "T SSS 9mTRS
SS 9 S mS m S m S m
TRT R5S
-SSSSS9mUUUU U 4SjnUUU U 4SjnU U
U U 4SjnU U
4SjmU4SjnTRSU5 TRSU5 TRSU5 T RST5 T RSU5 T R5 T R5 T R5 T R#5 T
$![a$n[R!SU35 S m
S nAN<S nAff=f![a#n[R%SU35 S nAT
$S nAff=f!T R#5 f![a"n[R%SU35 S nAfS nAff=f=f)
Use Tkinter to let the user select a region of the screen for a screenshot.
2025-07-31 12:52:28 +02:00
Optimized for better performance and memory usage.
Returns a dict with x, y, width, height, or None.
2025-07-31 12:52:28 +02:00
z-alphaç333333Ó?z -fullscreenTz-topmostFÚcrossr)ÚcursorÚhighlightthicknessÚboth)ÚfillÚexpandNrcrBz3Click and drag to select area. Press ESC to cancel.Úwhite)ÚArialé)Útextr‡Úfontc ó€>URmURmTRT5 TRTTTTSSS9mg)redrc)ÚoutlineÚwidth)r0ÚdeleteÚcreate_rectangle)ÚeventÚcanvasÚinstruction_textÚrectÚstart_xÚstart_ys €€€€€rÚon_button_pressÚ5take_screenshot_with_tkinter.<locals>.on_button_pressÅsAø€à—''ˆØ—''ˆà
Ð×& ¸À'ÐSXÐ`aÐb‰r có|>T(a4Tb0Tb,URURp!TRTTTX5 ggggr)r0rÚcoords)r•Úcur_xÚcur_yrr˜r™s €€€€rÚ
on_mouse_dragÚ3take_screenshot_with_tkinter.<locals>.on_mouse_dragÍs<ø€æ '¨GÑ,?Ø Ÿ7™7 E§G¡G M‰M˜$ ¨°%Õ -@Ð'ˆ4r cóø>T bfT bcURURp![T U5n[T U5n[T U5n[T U5nXS-
nXd-
nUS:”a US:”aX4XxS.m
OSm
T R 5 g)
)r0rrÚheight)r0rÚminÚmaxÚquit)
r•Úend_xÚend_yÚx1Úy1Úx2Úy2rÚrootÚselection_rectr™s
€€€€rÚon_button_releaseÚ7take_screenshot_with_tkinter.<locals>.on_button_releaseÓsø€à Ñ  7Ñ#6Ø Ÿ7™7 E§G¡GW˜eÓ$ˆW˜$ˆBÜW˜eÓ$ˆBÜW˜eÓ$ˆBà‘GˆEØ‘Wˆrz˜f rkØ')¸UÑ!Uà!%à r có*>SmTR5 gr))r•s €€rÚ on_escapeÚ/take_screenshot_with_tkinter.<locals>.on_escapeèsø€àˆØ r có8>URS:Xa T"U5 gg)Escape)Úkeysym)r•r´s €rÚ on_key_pressÚ2take_screenshot_with_tkinter.<locals>.on_key_pressísø€Ø <‰<˜  ð $r z<ButtonPress-1>z <B1-Motion>z<ButtonRelease-1>z<Escape>z
<KeyPress>zError in screenshot selection: z!Error destroying tkinter window: )ÚtkÚTkÚ
attributesÚwait_visibilityÚ resizableÚoverrideredirectÚCanvasÚpackÚ create_textÚwinfo_screenwidthÚbindÚ focus_setÚ focus_forceÚmainlooprnrlroÚdestroyÚwarning)
rrrrr—r´r˜r™s
@@@@@@@@rÚtake_screenshot_with_tkinterr˦sÿ€ô 5Š57€D؇OOH˜‡OOM ‡OOÔ×јÔð ‡NN5˜%Ô Ø×ј$Ôä
YŠYt Ñ
B€FØ
‡KKV D€KÑ €DØ€GØ€GØ€Nð× ×ÑÓ  AÑ% rØ
˜=ðÐ÷ cñc÷@ð@÷ ðö*õ
ð
 ‡K! 
‡KK
˜
‡K#Ð%6Ô‡IIˆj˜‡IIˆl˜LÔ ‡NØ×ÑÔð DØ
Œð
 DØ L‰LŒNð Ðøô óÜ Ð6°q°cÐûðûô ó DÜ N‰NÐ>¸q¸ Ðûð Dûð DØ L‰LNøÜó DÜ N‰NÐ>¸q¸B× Cûð DýslÅ>F!ÆGÆ!
GÆ+G
ÇHÇ
GÇHÇ
G?ÇG:Ç:G?ÈIÈHÈIÈ
IÈH<È7IÈ<IÉIcó˜^\rSrSrSrSrSrSrSrSr Sr
S r S
r S r
S rS
rSrSrU4SjrSrSrSrSrSrSrSrSrSrSrSrSrSrSr Sr!S r"S!r#S"r$S#r%S$r&S%r'S&r(S'r)S(r*S)r+S*r,S+r-S,r.S-r/S.r0S/r1S0r2S1r3S2r4S3r5S4r6S5r7S6r8S7r9S8r:S9r;S:r<S;r=S<r>SAS=jr?S>r@S?rAS@rBU=rC$)BÚ
MainWindowi zo
Main application window for Scenario Image Automation.
Handles UI, scenario management, and automation logic.
cóz[RS5 Sn[R"5nUR(G[R"5nUS-S:XaUR S5 UR 5nUc[R "S5 MlUupVnSn[R"5n [URR5up«U RSS U
35n XÀR;aXRU -
S
:aM@URXµXg5n
URX½5(dMjS UlUR S U 35 [RS
U 35 URX½5nU(aXRU 'S nSUl O [R"5U-
nUR!U5 US-
nUS-S:XaUR#5 U(d[%SSU-
5OSn[R "U5 UR(aGSUlUR S5 [RS5 g![&a"n[R)SU35 SnANUSnAff=f!SUlUR S5 [RS5 f=f)zP
Optimized automation loop with memory management and performance improvements.
zAutomation loop started.rúLooking for matchesNçš™™™™™¹?FrOÚstep_çð?TzPerforming step: zExecuting step: r.édçš™™™™™©?gš™™™™™É?zAutomation loop error: ÚPausedzAutomation loop ended.)rlrmr&ÚrunningÚ set_stateÚ_get_optimized_screenshotÚsleepÚ enumerateÚcurrent_scenariorPrVÚ_step_cooldownÚ_process_step_imagesÚ_check_step_triggerÚ_processing_stepÚ_execute_step_actionsÚ_update_performance_statsÚ_periodic_cleanupr§rnro)rÚ frame_countÚ last_gc_timeÚloop_start_timeÚ screen_dataÚ screen_npÚoffset_xÚoffset_yÚ
step_executedÚ current_timeÚstep_idxÚstepÚ step_nameÚ
detectionsÚsuccessÚ loop_timeÚ
sleep_timerrs rÚautomation_loopÚMainWindow.automation_loopsbô  Ј Ü—y’y“{ˆ ð@—,—,,Ü"&§)¢)£+ð Ñ# —NNÐ#8Ô#×> ØÑ—JJ˜s”OÙà0;Ñ-  !&
Ü#Ÿyšy{ ä&/°×0EÑ0E×0KÑ0KÖ&LNHà $§¡¨°5¸¸
Ð1CÓ D ×$7Ñ$7Ó'×*=Ñ*=¸iÑ*HÑHÈ3Ó"&×!:Ñ!:¸4ÈHÓ!_××AØ04˜ÔŸÐ):¸9¸+Ð'FÔŸ Ð&6°y°kÐ$BÔ#'×"<Ñ"<¸TÓ"N˜æ"Ø=I×/° Ñ:Ø,0˜Mà05˜Ôñ1'Mô6!ŸIšIK¨/Ñ9 Ø×.¨yÔ˜qÑ Ø ÑÓ×@MœS  s¨Y¡Ô7ÐRU
Ü
˜&ðq—,—,,ðz%*ˆ N‰N˜8Ô K‰KÐ 1øô ó L‰LÐ2°1°#Ð6× 7ûð 8ûð%*ˆDÔ N‰N˜ K‰KÐ 1ús1®D
IÄ?C,IÉ
JÉ&JÉ>J ÊJÊJ Ê /J:cóø[R"5nURb9UR(d(XR-
UR:a UR$UR
R
5nUS:Xa[R"5nSupEOêSn[R"5HnURU:XdMUn O UURS:”URS:”a|URURURUR4up‰p«USa+U Sa%U
S:”aU S:”a[R"X‰X«4S9nX‰pTO3[R"5nSupEO[R"5nSupE[ R""[$R&"U5[ R(5n XÄU4n
XÐlXlAU
$![*a"n[,R/SU35 SnAgSnAff=f)z:
Get screenshot with caching to reduce memory allocation.
Entire Screen©rrr)ÚregionzError capturing screenshot: )r&Ú_last_screenshotrßÚ_last_screenshot_timeÚ_screenshot_cache_durationÚ window_comboÚ currentTextÚ pyautoguiÚ
screenshotÚgwÚ
getAllWindowsÚtitlerÚleftÚtopr$ÚcvtColorÚnpÚarrayÚ
COLOR_RGB2BGRrnrlro)rÚselected_windowÚscreenrèÚwinrbr0rÚw_Úh_rçrrs rÚ$MainWindow._get_optimized_screenshotXs¸ô—y’y“{ˆ ð
× × × ×8WÑ8WÓ × ) Ø"×/×=ˆ "×/Ø%)Ñ"˜Ü×+—w‘w /Õ˜Ùñ
‘? s§y¡y°1£}¸¿¹Àa»Ø#&§8¡8¨S¯W©W°c·i±iÀÇÁÐ#KLA˜˜A“v ! q£&¨R°!«V¸¸Ü!*×!5Ò!5¸aÀB¸^Ñ!L˜Ø-.¡(ä!*×!5Ò!5Ó!7˜Ø-1Ñ*˜ &×3FØ)-Ñ&Ÿ š ¤R§X¢X¨fÓ%5´s×7HÑ7HÓIˆÐ9ˆKØ$/Ô !Ø)5Ô àÐ øäó Ü L‰LаsÐ ûð ús ÁA"G
ÃD G
Ç
G9ÇG4Ç4G9c ó&0nURS/5n[RUS5nUc[R SUS35 M<[
R "X'[
R5n[
R"U5upšp¼URSS5n
X­:”a#U SU-U SU-4nXçRU
4XVS 'A U$![a6n[RS
URS S 5S U35 SnASnAff=f)
z,
Process step images with template caching.
Úimagesr'NzCould not load template image: Ú sensitivityçÍÌÌÌÌÌì?rr.rOzError in image detection for Úunknownú: ) rVÚtemplate_cacher*rlr$Ú
matchTemplateÚTM_CCOEFF_NORMEDÚ minMaxLocÚshapernro)rÚimgr)ÚresÚmin_valÚmax_valÚmin_locÚmax_locrÚabs_locrrs rÚMainWindow._process_step_imagessðˆ
à—8‘8˜H bÖ)ˆCð
`ä6°s¸6±{ÓCØÑ—N‘NÐ%DÀSÈÁ[ÀMÐ#RÔô×'¨ ¼S×=QÑ=QÓRÜ58·]²]À3Ó5GÑ2 !Ÿg™g m°SÓ9 ØÓ& q™z¨HÑ4°g¸a±jÀ8Ñ6KÐLGØ/6¿¹ÈÐ.PJ 6™{Ññ'*ð0Ðøôó
`Ü Ð<¸S¿W¹WÀVÈYÓ=WÐ<XÐXZÐ[\ÐZ]Ð^×_ûð
`ús™6CÁA9CÃ
DÃ+D Ä Dcó
URS/5nU(dgUVs/sHoDRS5U;dMUPM nnURSS5nUS:Xa[U5[U5:H$[U5S:„$s snf)z8
Check if step should be triggered based on detections.
rFrOÚ conditionÚORÚANDr)rVr")rÚ step_imagesrÚfoundr#s rÚMainWindow._check_step_trigger¯s{ð—h‘h˜x¨Ó ÞØá +Ó ˜¯w©w°v«À*Ñ/L—¡ ˆÐ—H‘H˜[¨$Ó/ˆ à ˜Ó Üu“:¤ [Ó!1Ñ u“:  !ùò
Ns
ŸB»Bcó˜URS/5Vs/sHo3RS5U;dMUPM nnU(aUUSnURURS5S5upgnURS/5Hn URXU5 M gg s snf![a"n
[R SU
35 Sn
A
g Sn
A
ff=f)
2025-07-31 12:52:28 +02:00
z+
Execute step actions with error handling.
rrOr))rrrrÚactionsTzError executing step actions: NF)rVÚ_perform_step_actionrnrlro) rrÚ found_imagesÚref_imgÚlocrÚ
confidenceÚactionrrs rÚ MainWindow._execute_step_actions¿ð
?Ø+/¯8©8°H¸bÔ+AÓcÒ+A CÇWÁWÈVÃ_ÐXbÑEbŸCÑ+Aˆà& q™/Ø)3¯©¸¿ ¹ ÀFÓ8KÐMcÓ)dÑ&˜"Ÿh™h y°"Ö5×-¨f¸ððùòdøôó L‰LÐ9¸!¸Ð=× ûð ?ús-BB²B¸ABÂBÂ
2025-07-31 12:52:28 +02:00
C Â'CÃC cóNURRU5 [UR5UR:”aURR S5 [ UR5[UR5- nUS:”a[ RSUSS35 gg)z/
Update performance statistics for monitoring.
rçà?z(Performance warning: Average loop time: ú.3fÚsN)Ú _loop_timesÚappendr"Ú_max_loop_time_samplesr7Úsumrl)rÚavg_times rÚ$MainWindow._update_performance_statsÔð
×Ñ×Ñ  Ô ˆt×ÑÓ  4×#>Ñ#>Ó × Ñ × Ñ  Ô t×(¬3¨t×/?Ñ/?Ó+@Ñ@ˆØ c N‰NÐEÀhÈsÀ^ÐSTÐ  r cóSUl[R"5nURR5VVs/sHup#X-
S:”dMUPM nnnUHnURU M [R
2025-07-31 12:52:28 +02:00
"5 gs snnf)z3
Perform periodic cleanup to prevent memory leaks.
Né,)r&r6r>r?)rrOÚ timestampÚ
old_cooldownss rÚMainWindow._periodic_cleanupászð
!%ˆÔô—yy“{ˆ Ø59×5HÑ5H×5NÑ5NÔ5Pô;Ò5P¡/ 3°cÑÑ5Pˆ
ñ!ˆDØ×# 
2025-07-31 12:52:28 +02:00
Š
ùó
2025-07-31 12:52:28 +02:00
;s ºBÁ Bc
ó¼USnUSn[RSUSUSUSU35 US:XURSS 5nUS :XaUS
US S --nUS US
S --nOkUS
:Xa1US
URSS
2025-07-31 12:52:28 +02:00
5-nUS URSS
5-nO4US:Xa%URSS
5nURSS
5nO US
US p‡URSS5n [RSUSUSU 35 [R
"XxU S9 g(US:XaAURSS5n
[RSU
35 [R "U
5 g(US:Xa}URSS
5n URSS5n [RS U S!U 35 U S:Xa[R"U 5 g([R"[U 5*5 g(US":XaBURS#S 5n
[RS$U
S%35 [R"U
5 g(g(![a%n[RS&US'U35 S(nAg(S(nAff=f))zQ
Perform a single step action (click, key, scroll, delay) at the given location.
ÚtypeÚparamsúPerforming step action: ú , params=ú, loc=ú, shape=ÚclickÚpos_typeÚcenterrr.rcÚrelativeÚrel_xÚrel_yÚabsoluteÚabs_xÚabs_yÚbuttonrú
Clicking at (ú, ú) with button ©rQr3ÚenterúPressing key: ÚscrollÚamountÚ directionÚupú Scrolling: ú direction: ÚdelayÚdurationú
Delay for ú secondsúError performing step action r
rlÚdebugrVrmrHÚpressrXÚabsr&rnro©rr0r.rÚact_typerCrIr0rrQr3rYrZr_rrs rr+ÚMainWindow._perform_step_actionòóSð˜&‘>ˆØ˜ÑÜ Ð¨z¸À6À(È&ÐQTÐPUÐU]Ð^cÐ]dÐ" Jؘ!Ÿ:™: j°(Ó;ؘ˜A™  q¡¨Q¡Ñ.˜A™  q¡¨Q¡Ñ.‘AØ Ó˜A™ §¡¨G°QÓ!7Ñ7˜A™ §¡¨G°QÓ!7Ñ7‘AØ ÓŸ
 7¨AÓ.Ÿ
 7¨AÓ.˜q™6 3 q¡6Ÿ H¨fÓ5Ü ˜m¨A¨3¨b°°°>À&ÀР¨VÓ˜UÓ—j‘j ¨Ó0Ü ˜n¨S¨EР՘XÓŸ H¨aÓ0Ø"ŸJ™J {°DÓ9 Ü ˜k¨&¨°¸i¸[РÓ×$ VÕ×$¤c¨&£k ˜!Ÿ:™: j°!Ó4Ü ˜j¨¨
°(Ð
˜8Õ%øôó JÜ L‰Lи
À"ÀQÀCÐH× Iûð Júó3­C+H,ÄAH,Å A!H,Ç H,Ç#AH,È,
IÈ6IÉIcóLXlURRSU35 g)z#
Update the state label in the UI.
zState: N)Ú
state_textÚ state_labelÚsetText)rs rr×ÚMainWindow.set_states$ðŒØ ×Ñ× Ñ  7¨4¨&Ð!1Õ2r có$UR(aUR5 g[R"5nXR-
S:a7[R S5 [ RRUSS5 gUR5 g)z„
Toggle the automation state (start/stop). A debounce delay is added only
when changing from stop to start, not from start to stop.
éz9Start toggle ignored: pressed too quickly after stopping.ÚWaitz5Please wait at least 5 seconds before starting again.N)
Ústop_automationr&Úlast_toggle_timerlrmrÚ QMessageBoxÚ informationÚstart_automation)rÚnows rÚtoggle_automationÚMainWindow.toggle_automation#shð
< × Ñ Õ —)’)“+ˆCØ×*¨QÓ Ð×1°$¸Ð@wÔØ × #r cóx[RS5 UR(aUR(a[R S5 gSUlUR R5 [R"5 URR5 SUlURS5 URRSURR5S35 [ R""UR$SS9UlUR&R)5 [*R,"URUR.05UlUR0R)5 [RS
2025-07-31 12:52:28 +02:00
5 g![2a"n[R5S U35 SnAN=SnAff=f) zF
Start the automation process and worker thread with resource checks.
2025-07-31 12:52:28 +02:00
zStarting automation.z:Start Automation: No scenario selected or already running.NTrÏzStop (Ú))ÚtargetÚdaemonz!Failed to setup hotkey listener: z Automation started successfully.)rlrmr=r>r?r6r×Úbtn_start_stoproÚhotkeyÚupperÚ threadingÚThreadróÚworkerÚstartrÚ
GlobalHotKeysrtÚlistenerrnro©rrrs rrxÚMainWindow.start_automation2sGô  Ðׯ ¯ Ü N‰NÐ ð!%ˆÔØ ×Ñ×
Š
Œ ð
×Ñ×ÑÔ ðˆŒ Ø Ð ×Ñ×# f¨T¯[©[×->Ñ->Ó-@Ð,AÀÐ$CÔ ×&¨d×.BÑ.BÈ4ÑŒ Ø ×ÑÔð BÜ2°D·K±KÀ×AUÑAUÐ3VÓWˆDŒMØ M‰M× Ñ Ô
 Ð7øô ó BÜ L‰LÐ<¸Q¸@× Aûð BúsÄ,A F
Æ
F9ÆF4Æ4F9c óÄSSKnUR5nUR5nUR5nUR 5nUR
S- S- UR
5UURURS- S- S- [[S5(a[[R5OS[US5(a[UR5OSSS.$![ab SSSSS[[S5(a[[R5OS[US5(a[UR5OSSS.s$[an[ R#S U35 SSSSS[[S5(a[[R5OS[US5(a[UR5OSS[%U5S
. sSnA$SnAff=f) z6
Get current memory usage information for monitoring.
rNirT)Úprocess_memory_mbÚprocess_memory_percentÚ cpu_percentÚsystem_memory_percentÚsystem_memory_available_gbÚtemplate_cache_sizeÚcooldown_entriesÚ
has_psutilFzError getting memory usage: ) rŒrrrrrr“ro)ÚpsutilÚProcessÚ memory_inforŽÚvirtual_memoryÚrssÚmemory_percentÚpercentÚ availableÚhasattrrr"rÚ ImportErrorrnrlÚstr)rr”ÚprocessrÚ
system_memoryrrs rÚget_memory_usageÚMainWindow.get_memory_usageVs¸ð+ Û Ø—n&ˆ!×/ˆ/ˆKð#×3ˆ&1§_¡_°tÑ%;¸dÑ%BØ*1×*@Ñ*@Ó*BØ*Ø)6×)>Ñ)>Ø.;×.EÑ.EÈÑ.LÈtÑ.SÐVZÑ.ZÜELÌ^Ð]e×EfÑEf¤s¬>×+@Ñ+@Ô'AÐlmÜ@GÈÐN^×@_Ñ@_¤C¨×(;Ñ(;Ô$<ÐefØ ð
øôó ð&'Ø*+Ø Ø)*Ø./ÜELÌ^Ð]e×EfÑEf¤s¬>×+@Ñ+@Ô'AÐlmÜ@GÈÐN^×@_Ñ@_¤C¨×(;Ñ(;Ô$<ÐefØ ò
ôó Ü N‰NÐ9¸!¸Ð >à%&Ø*+Ø Ø)*Ø./ÜELÌ^Ð]e×EfÑEf¤s¬>×+@Ñ+@Ô'AÐlmÜ@GÈÐN^×@_Ñ@_¤C¨×(;Ñ(;Ô$<ÐefؘQñ
õ
ûð ús&CC Ã A)GÅ GÅBGÇGÇGcó[RS5 SUl[R"5UlUR S5 UR RSURR5S35 UR(a"URR5 SUl
UR(atURR5(aUURR!SS 9 URR5(a[RS
5 SUlSUlSUlUR&R)5 [*R,"5 [RS 5 g![a#n[RSU35 SnAGNSnAff=f!SUl
f=f![a"n[RS U35 SnAN½SnAff=f!SUlf=f)
zD
Stop the automation process and worker thread with proper cleanup.
zStopping automation.FrÕúStart (r}z Error stopping hotkey listener: Ng@)Útimeoutz)Worker thread did not stop within timeoutzError joining worker thread: z,Automation stopped and resources cleaned up.)rlrmr&rur×r€rorrrˆÚstoprnr…Úis_aliver\r=r>r?r‰s rrtÚMainWindow.stop_automation‡s‡ô  ЈŒ Ü $§ ¢ £ ˆÔØ  Ø ×Ñ×# g¨d¯k©k×.?Ñ.?Ó.AÐ-BÀ!Ð$DÔ =

×!%
ð ;;˜4Ÿ;™;×/×
 × Ñ ¨Ð Ñ—;;×'×—NNÐ#NÔ# ð!&ˆÔØ $ˆÔØ ×Ñ×
Š
Œ ä ÐCøô1ó
GÜÐ!AÀ!ÀÐFûð
Gûð!%
ûôó
DÜÐ!>¸q¸Cûð
Dûð# úsUÂF
Ã#A
GÆ
2025-07-31 12:52:28 +02:00
F7ÆF2Æ,F:Æ2F7Æ7F:Æ: GÇ
G2ÇG-Ç(G5Ç-G2Ç2G5Ç5 G>có>[TU]5 URS5 SnSnURX5 UR SSX5 SUlSUlSUlSUlSUl SUl
SUl SUl SUl
SUlSUl0Ul/UlS UlUR'5 UR)5 UR+[,R.R0R25 [,R4"5UlUR6R8R;UR<5 UR6R?S
5 [,R4RASUR<5 g) z5
Initialize the main window, UI, and load scenarios.
zScenario Image Automationi€Fz<f9>Nr)!ÚsuperrÚsetWindowTitleÚsetMinimumSizeÚ setGeometryrÖrrˆr…Úselected_step_idxrur6r8Úinit_uiÚload_scenariosÚ setAttributerÚQtÚWidgetAttributeÚWA_DeleteOnCloseÚQTimerÚ
monitor_timerr¥ÚconnectÚ_monitor_performancer†Ú
singleShot)rÚ min_widthÚ
min_heightÚ __class__s €rrÚMainWindow.__init__¯sNø€ô ÑÔØ ×ÑЈ ؈
Ø ×јIÔ ×ј˜c 9ÔˆŒ ؈Œ ؈Œ
؈Œ Ø $ˆÔØ!%ˆÔØ !ˆÔð!%ˆÔØ%&ˆÔ"Ø*.ˆÔ'Ø %ˆÔØ ˆÔðˆÔØ&(ˆÔ ŒØ ×ÑÔð
×Ñœ&Ÿ)™)×3×$Ÿ]š]›_ˆÔØ ×Ñ×"×*¨4×+DÑ+DÔ ×Ñ× Ñ  Ô 
2025-07-31 12:52:28 +02:00
× Ñ   d×&?Ñ&?Õ@r cóUR5nURU5 UR([US5(aUR(a[ UR5[
UR5- nUS:”a[RSUSS35 URSS5S:”a[RS USS
35 g g g g g ![a"n[RS U35 S nAg S nAff=f)
z3
Monitor application performance and memory usage.
r6z%Performance issue: Average loop time r4r5rrézTemplate cache has z entrieszPerformance monitoring error: N)
Ú_update_resource_displayrÖr6r9r"rlrVrmrnrd)rrÚ
avg_loop_timerrs rr¸ÚMainWindow._monitor_performanceÛð×1ˆKð
× )¨+Ô |¨¨m× <Ñ <À×AQ×AQÜ # D×$4Ñ$4Ó 5¼¸D×<LÑ<LÓ8MÑ M
ð! —NNÐ%JÈ=ÐY\ÐJ]Ð]^Ð#_Ô—??Ð#8¸<¸—KKÐ"5°kÐBWÑ6XÐ5YÐYaÐ bÕBðBRÐ <ˆ|øôó L‰LÐ9¸!¸Ð=× >ûð ?úsCCÃ
DÃ"C?Ã?Dcó²^URSS5(aSUSSSUSSS3nUSS :”aS
OS nOS nS
nTRRU5 TRRSUS35 URSS5(dfU4SjTRlTRR [ R"[RRR55 URSS5(aSUSSS3nUSS:”aS
OS nOSnSnTRRU5 TRRSUS35 URSS5(aSUSSSUSSS3nUSS:”aS
2025-07-31 12:52:28 +02:00
OS nOSnSnTRRU5 TRRSUS35 SUSS US!S"3nUSS#:”aS
OS$n TRRU5 TRRSU S35 [TS%5(aQTR (a@[#TR 5[%TR 5- n
S&U
S'-S(S)3n U
S*:”aS
OS n OS+n Sn TR&RU 5 TR&RSU S35 S,U;aATR&RS-US,S.SS/35 TR&RS05 g.g.![(n
2025-07-31 12:52:28 +02:00
[*R-S1U
35 TRRS25 TRRS35 TRRS45 TRRS55 TR&RS6[/U
5S.S7S/35 S.n
A
g.S.n
A
ff=f)8z.
2025-07-31 12:52:28 +02:00
Update the resource usage display in the UI.
r“FzMemory: rŒz.1fzMB (rz%)r¤z#d9534fz#5cb85czMemory: N/A (psutil needed)z#f0ad4ezfont-size: 9pt; color: Ú;có$>TR5$r)Ú_show_psutil_info)r•rs €rr1Ú5MainWindow._update_resource_display.<locals>.<lambda>sø€À$×BXÑBXÔBZr zCPU: rŽÚ%rBzCPU: N/Az#777zSystem: rz% (rzGB free)éUz System: N/AzCache: rz templates, rz
2025-07-31 12:52:28 +02:00
cooldownsr¿z#5bc0der6z
Performance: ièz.0fzms avg loop timer3zPerformance: Not runningrozError: Nz...zfont-size: 9pt; color: #d9534f;z!Error updating resource display: z
2025-07-31 12:52:28 +02:00
Memory: Errorz
CPU: Errorz
2025-07-31 12:52:28 +02:00
System: Errorz Cache: ErrorzDisplay Error: é)rVÚ memory_labelroÚ
setStyleSheetÚmousePressEventÚ setCursorrÚQCursorrÚ CursorShapeÚPointingHandCursorÚ cpu_labelÚsystem_memory_labelÚ cache_labelrœr6r9r"Úperformance_labelrnrlrd)rrÚ memory_textÚ memory_colorÚcpu_textÚ cpu_colorÚ system_textÚ system_colorÚ
2025-07-31 12:52:28 +02:00
cache_textÚ cache_colorr:Ú perf_textÚ
perf_colorrrs` rÚ#MainWindow._update_resource_displayôø€ðF Oà˜|¨U×3Ø (¨Ð5HÑ)IÈ#Ð(NÈdÐS^Ð_wÑSxÐy|ÐR}Ð}ðA Ø,7Ð8PÑ,QÐTVÓ,V™yÐ\e à; Ø( à × Ñ × % kÔ × Ñ × +Ð.EÀlÀ^ÐSTÐ,UÔ —?? ×7Ü4Z××!×+¬E¯MªM¼&¿)¹)×:OÑ:O×:bÑ:bÓ,cÔ˜|¨U×" ;¨}Ñ#=¸cÐ"BÀ!ÐDØ)4°]Ñ)CÀbÓ)H™IÈi à%Ø" à N‰N× "  N‰N× (Ð+BÀ9À+ÈQÐ)OÔ ˜|¨U×3Ø (¨Ð5LÑ)MÈcÐ(RÐRUÐVaÐb~ÑVðADðVEðEMðN Ø,7Ð8OÑ,PÐSUÓ,U™yÐ[d à+ Ø% à × ,¨[Ô × $× 2Ð5LÈ\ÈNÐZ[Ð3\Ô # ;Ð/DÑ#EÐ"FÀlÐS^Ð_qÑSrÐRsÐs}Ð~ˆJØ'2Ð3HÑ'IÈBÓ'N™)ÐT]ˆ × Ñ × $ ZÔ × Ñ × *Ð-DÀ[ÀMÐQRÐ+SÔ t˜]××0@×0@ܘt×0´3°t×7GÑ7GÓ3HÑHØ+¨H°T©M¸#Ð+>Ð>NÐO Ø*2°S«.™Y¸i
2025-07-31 12:52:28 +02:00
à6 Ø#
à × "× *¨9Ô × "× 0Ð3JÈ:È,ÐVWÐ1XÔ ˜×&׸ÀWÑ9MÈcÈrÐ9RÐ8SÐSVÐ/WÔ×&×4Ð5VÕ&øôó OÜ L‰LÐ<¸Q¸ × Ñ × %  N‰N× "  × $× ,¨_Ô × Ñ × $  × "× *¨_¼SÀ»VÀCÀR¸[¸MÈÐ+M× Nûð OúsƒLLÌ
2025-07-31 12:52:28 +02:00
OÌB/OÏOcó€[US5(a-UR(aURR5 ggg)z"Stop performance monitoring timer.r¶N)r@s rÚstop_monitoringÚMainWindow.stop_monitoring@s2ä 4˜× )¨d×.@×.@Ø × Ñ × /AÐ )r có¸UR(URR5 URR5 URR5 UR
R5 UR R5 URRS5 SUlgURR5 URR5 URR5 UR
2025-07-31 12:52:28 +02:00
R5 UR R5 URRS5 SUlg)z0Toggle the visibility of resource usage widgets.zShow ResourcesFúHide ResourcesTN)
Úresource_widgets_visiblerËÚhiderÒÚtoggle_resources_btnroÚshowr@s rÚ_toggle_resource_displayÚ#MainWindow._toggle_resource_displayEà × (× × Ñ × N‰N× Ñ Ô × × Ñ × × "× × %× -Ð.>Ô ?Ø,1ˆ 
× Ñ × N‰N× Ñ Ô × × Ñ × × "× × %× -Ð.>Ô ?Ø,0ˆ )r có‚[R"U5nURS5 UR[RRR
5 UR
S5 URS5 UR[RRR5 UR5 g)zAShow information about installing psutil for enhanced monitoring.zEnhanced Resource Monitoringz/Install psutil for detailed resource monitoringu4For detailed CPU, memory, and system resource monitoring, install the psutil package:
pip install psutil
2025-07-31 12:52:28 +02:00
This will enable:
• Process memory usage in MB and percentage
• CPU usage percentage
2025-07-31 12:52:28 +02:00
• System memory statistics
• Available system memory
2025-07-31 12:52:28 +02:00
Without psutil, only basic cache information is shown.N) rrvÚsetIconÚIconÚ InformationroÚsetInformativeTextÚsetStandardButtonsÚStandardButtonÚOkÚexec)rÚmsgs rÚMainWindow._show_psutil_infoZsä×# DÓØ ×ÑÐ ”I× Ð ×Ñð
2025-07-31 12:52:28 +02:00
Eô
ð ×Ñœy× 
2025-07-31 12:52:28 +02:00
r cóDUR5 UR5 g)z3Handle application close event with proper cleanup.N)Úcleanup_resourcesÚaccept©rr•s rÚ
closeEventÚMainWindow.closeEventmsà ×ÑÔ Ø
2025-07-31 12:52:28 +02:00
r cóœUR(aUR5 UR5 [R 5 SUl[
US5(aURR 5 [
2025-07-31 12:52:28 +02:00
US5(aURR 5 [R"5 [RS5 g)z+Clean up resources to prevent memory leaks.Nr6z!Resources cleaned up successfully)
rtrr=r6r>r?rlrmr@s rÚMainWindow.cleanup_resourcesrs”à < × Ñ Ô 
2025-07-31 12:52:28 +02:00
×ÑÔô ×ÑÔð!%ˆÔô 4˜× × Ñ × )× × Ñ × 
Š
2025-07-31 12:52:28 +02:00
Œ ä Ð8r có~ [R"5nURS5 URU5 SnUR U5 [
R "S5nUR[
RRR[
RRR5 [
R"5n[
R"5UlURRS5 URR R#UR$5 UR'UR5 [
2025-07-31 12:52:28 +02:00
R"5UlUR(RS5 [
R "S5nUR[
RRR[
2025-07-31 12:52:28 +02:00
RRR5 [
R*"5nUR(RS5 UR(R R#UR,5 [
2025-07-31 12:52:28 +02:00
R."S5UlUR0R3S5 UR0R4R#UR65 UR'UR(5 UR'UR05 UR9U5 UR;5 [
R."S5UlUR<R3S 5 UR<R4R#UR>5 [
R."S
5Ul UR@R3S 5 UR@R4R#URB5 [
R."S 5Ul"URDR3S
2025-07-31 12:52:28 +02:00
5 URDR4R#URF5 [
R."S5Ul$URHR3S5 URHR4R#URJ5 [
R."S5Ul&URLR3S5 URLR4R#URN5 [
R*"5nURQS5 URSSSSS5 UR'UR<5 UR'UR@5 UR'URD5 UR'URH5 UR'URL5 URUU5 UR9U5 [
2025-07-31 12:52:28 +02:00
R "S5n[
R"5n [
2025-07-31 12:52:28 +02:00
RV"5Ul,URXR[S5 URXR\R#UR^5 U R'URX5 [
R."S5Ul0UR`R3S5 UR`R4R#URb5 [
2025-07-31 12:52:28 +02:00
R."S5Ul2URdR3S5 URdR4R#URf5 [
R."S5Ul4URhR3S5 URhR4R#URj5 [
R."S5Ul6URlR3S5 URlR4R#URn5 [
R."S5Ul8URpR3S5 URpR4R#URr5 [
2025-07-31 12:52:28 +02:00
R."S5Ul:URtR3S5 URtR4R#URv5 [
R*"5n
U
RQS5 U
RSSSSS5 U
R'UR`5 U
R'URd5 U
R'URh5 U
R'URl5 U
R'URp5 U
R'URt5 U RUU
5 UR9U 5 [
2025-07-31 12:52:28 +02:00
R."SURxR{5S 35Ul>UR|RS!5 UR|R4R#UR~5 [
R€"S"5UlAURR S#5 URR…[†Rˆ[†Rˆ-5 [
R "S$5UlHURR[
2025-07-31 12:52:28 +02:00
RRR[
RRR5 [
R"5n U RQS5 U RSS%S%S%S%5 [
R."S&5UlJUR”R—S'5 UR”R3S(5 UR”R4R#UR˜5 U R'UR”S)S*S+S+5 [
2025-07-31 12:52:28 +02:00
R€"S,5UlMUR S-5 U R'US)S)5 [
R€"S.5UlNUR S-5 U R'US)S+5 [
R€"S/5UlOUR S-5 U R'US+S)5 [
R€"S05UlPUR R S-5 U R'UR S+S+5 [
R€"S15UlQUR S-5 U R'US*S)S+S25 URR9U 5 S3UlR[
R"5n U S%5 U S5 U RSS4S4S4S45 U R'US)S)S+S55 U S)S)5 U R'US+S)S+S55 U R'US*S)S2S55 U R'URS5S)S+S55 U S5S)5 [
R "5n
U
R­S65 U
2025-07-31 12:52:28 +02:00
R[
RRR[
RRR5 [
2025-07-31 12:52:28 +02:00
R*"5nURQS%5 UR'UR|5 UR'UR5 US+5 U
R9U5 U R'U
S%S)S+S55 U S%S)5 [
"5nUR9U 5 UU5 g7)8zw
Initializes the main UI components and layouts.
Sets up scenario and window dropdowns, step list, and action buttons.
é aN
QPushButton, QComboBox, QListWidget, QLabel {
font-size: 9pt;
2025-07-31 12:52:28 +02:00
min-height: 20px;
padding: 2px 6px;
}
QComboBox { min-width: 90px; }
QPushButton { min-width: 70px; }
QListWidget { min-width: 200px; min-height: 120px; }
2025-07-31 12:52:28 +02:00
rKéZz
Target WindowÚRefreshzRefresh open windows listÚNewzCreate new scenarioÚImportzImport scenarioÚExportzExport scenarioÚRenamezRename scenarioÚDeletezDelete current scenarior4z3Steps (Up = Higher Priority, Down = Lower Priority)éxÚAddzAdd stepÚEditz Edit stepz Delete stepz Rename stepúMove UpzMove step up (higher priority)ú Move DownzMove step down (lower priority)r¤r}éPz
State: Pausedz3font-weight: bold; font-size: 11pt; color: #0055aa;zResource UsageézJToggle resource usage display. Install psutil for detailed system metrics.rrcr.z
Memory: --zfont-size: 9pt; color: #333;zCPU: --z
System: --z Cache: --zPerformance: --érrÚN)ZrÚQFontÚ setPointSizeÚsetFontrÌrÚ QGroupBoxÚ
setSizePolicyÚ QSizePolicyÚPolicyÚ PreferredÚFixedÚ QVBoxLayoutÚ QComboBoxÚcomboÚsetMinimumWidthÚcurrentIndexChangedr·Ú_log_combo_scenarioÚ addWidgetrüÚ QHBoxLayoutÚ_log_combo_windowÚ QPushButtonÚbtn_refresh_windowsÚ
setToolTipÚclickedÚ_log_btn_refresh_windowsÚ setLayoutÚrefresh_window_listÚbtn_newÚ _log_btn_newÚ
btn_importÚ_log_btn_importÚ
btn_exportÚ_log_btn_exportÚbtn_rename_scenarioÚ_log_btn_rename_scenarioÚbtn_delete_scenarioÚ_log_btn_delete_scenarioÚ
setSpacingÚsetContentsMarginsÚ addLayoutÚ QListWidgetÚ
steps_listÚsetMinimumHeightÚcurrentRowChangedÚ_log_steps_listÚ btn_add_stepÚ_log_btn_add_stepÚ
btn_edit_stepÚ_log_btn_edit_stepÚ btn_del_stepÚ_log_btn_del_stepÚbtn_rename_stepÚ_log_btn_rename_stepÚbtn_move_up_stepÚ_log_btn_move_up_stepÚbtn_move_down_stepÚ_log_btn_move_down_steprrr€Ú_log_btn_start_stopÚQLabelrnÚ setAlignmentrÚ
AlignmentFlagÚ AlignLeftÚ AlignVCenterÚresource_groupÚ QGridLayoutrèÚsetMaximumWidthrêÚsetHorizontalSpacingÚsetVerticalSpacingÚ
setRowStretchÚsetTitleÚ
addStretchÚQWidgetÚsetCentralWidget)rrÚstyleÚscenario_group_boxÚscenario_group_layoutÚwindow_group_boxÚwindow_group_layoutÚscenario_btn_group_layoutÚsteps_group_boxÚsteps_group_layoutÚstep_btn_group_layoutÚresource_layoutÚlayoutÚstart_state_groupÚstart_state_layoutÚcentrals rÚMainWindow.init_uis ô {Š{‹}ˆØ ×ј!ÔØ ð  ˆð
×ј'×ÓØ××)>Ñ)>×)EÑ)E×)OÑ)OÔQZ×QfÑQf×QmÑQm×QsÑQsÔtÜ )× 5Ò 5Ó 7ÐÜ׌
Ø
×" 
×&×.¨t×/GÑ/GÔׯ
2025-07-31 12:52:28 +02:00
©
ÔÔØ ×Ñ×)¨"Ô$×ÓØ×&¤y×'<Ñ'<×'CÑ'C×'MÑ'MÌy×OdÑOd×OkÑOk×OqÑOqÔ'ר ×Ñ×)¨"Ô ×Ñ×-×5°d×6LÑ6LÔMÜ#,×#8Ò#8¸Ó#CˆÔ Ø × Ñ ×+Ð,GÔ × Ñ ××1NÑ1NÔ×% d×&7Ñ&7Ô×% d×&>Ñ&>Ô×"Ð#6Ô × Ñ Ô ×,¨UÓŒ Ø ×ÑÐ 5Ô ×Ñ×$ T×%6Ñ%6ÔÓŒØ ×"Ð#4Ô ×Ñ××(<Ñ(<Ô#×Ó9ˆŒØ ×"Ð#4Ô ×Ñ××(<Ñ(<Ô=Ü#,×#8Ò#8¸Ó#BˆÔ Ø × Ñ ×+Ð,=Ô × Ñ ×(××1NÑ1NÔOÜ#,×#8Ò#8¸Ó#BˆÔ Ø × Ñ ×+Ð,EÔ × Ñ ×(××1NÑ1NÔOÜ$-×$9Ò$9Ó$;Ð!×,¨QÔ4°Q¸¸1¸aÔ+¨D¯L©LÔ!×+¨D¯O©OÔ!×+¨D¯O©OÔ!×+¨D×,DÑ,DÔ!×+¨D×,DÑ,DÔ×'Ð(AÔ×$Ð%:Ô$×-Ð.cÓdˆÜ&×ÜŒØ ×Ô ×1°$×2FÑ2FÔ×$ T§_¡_Ô1°%ÓÔØ ×Ñ×$ ZÔ ×Ñ×)¨$×*@Ñ*@Ô&×2°6ÓÔØ ×Ñ×% kÔ ×Ñ×"×*¨4×+BÑ+BÔ1°(ÓÔØ ×Ñ×$ ]Ô ×Ñ×)¨$×*@Ñ*@Ô(×4°XÓ>ˆÔØ ×Ñ×
Ô ×Ñ×,¨T×-FÑ-FÔGÜ )× 5Ò 5°iÓ @ˆÔØ ×Ñ×(Ð)IÔ ×Ñ×%×-¨d×.HÑ.HÔIÜ"+×"7Ò"7¸ Ó"DˆÔØ ×Ñ×*Ð+LÔ ×Ñ×'××0LÑ0LÔMÜ )× 5Ò 5Ó 7ÐØ×Ô×°A°q¸××(9Ñ(9Ô××(:Ñ(:Ô××(9Ñ(9Ô××(<Ñ(<Ô××(=Ñ(=Ô××(?Ñ(?Ô×$Ð%:Ô×!Ð"4Ô(×3°g¸d¿k¹k×>OÑ>OÓ>QÐ=RÐRSÐ4TÓUˆÔØ ×Ñ×+¨BÔ ×Ñ×+¨D×,DÑ,DÔ%×+¨OÓ<ˆÔØ ×Ñ×&Ð'\Ô ×Ñ×%¤f§i¡i×&=Ñ&=×&GÑ&GÌ&Ï)É)×JaÑJa×JnÑJnÑ&nÔ(×1Ð2BÓÔØ ×Ñ×)¬)×*?Ñ*?×*FÑ*F×*PÑ*PÔR[×RgÑRg×RnÑRn×RtÑRtÔ#×1ˆØ×" ×*¨1¨a°°AÔ%.×$9Ò$9Ð:JÓ$KˆÔ ×1°#Ô ×,Ð-yÔ ×!×)×1°$×2OÑ2OÔ×! $×";Ñ";¸À1ÀaÔ,¨\Ó:ˆÔØ ×Ñ×'Ð(FÔ×! $×"3Ñ"3°Q¸Ô#×)¨)ÓŒØ ×$Ð%CÔ×! $§.¡.°!°QÔ$-×#3Ò#3°LÓ#AˆÔ Ø × Ñ ×.Ð/MÔ×! $×":Ñ":¸A¸%×+¨KÓÔØ ×Ñ×&Ð'EÔ×! $×"2Ñ"2°A°qÔ"+×!1Ò!1Ð2CÓ!DˆÔØ ×Ñ×,Ð-KÔ×! $×"8Ñ"8¸!¸À1Ô ×Ñ×% oÔ6Ø(,ˆÔ×(ˆØ×# ×! ×! ! Q¨¨1Ô ×ÑÐ+¨Q°°1°aÔ×јQ Ô×ÑÐ)¨1¨a°°AÔ×ј¨!¨Q°°1Ô ×ј×,¨a°°A°qÔ×јQ Ô&ר×" ××(=Ñ(=×(DÑ(D×(NÑ(NÔPY×PeÑPe×PlÑPl×PrÑPrÔ&ר×% aÔ×$ T×%8Ñ%8Ô×$ T×%5Ñ%5Ô×% ×#Ð$6Ô×ÑÐ*¨A¨q°!°QÔ×јQ Ô×%ˆØ×ј&Ô ×ј&r cóN[RS5 UR5 g)Nz"UI: Refresh Windows button pressed)rlrmr*r@s rr(Ú#MainWindow._log_btn_refresh_windowsPsÜ Ð × Ñ Õ"r cóŒ[RSUSURR5S35 UR 5 g)z9
Log scenario combo box change and call select_scenario.
z$UI: Scenario combo changed to index ú (r}N)rlrmrÚselect_scenario©rÚidxs rr ÚMainWindow._log_combo_scenarioTs;ô  Ð:¸3¸%¸rÀ$Ç*Á*×BXÑBXÓBZÐA[Ð[\Ð ×ÑÕr cóŒ[RSUSURR5S35 UR 5 g)z<
Log window combo box change and call save_selected_window.
z"UI: Window combo changed to index rkr}N)rlrmÚsave_selected_windowrms rr#ÚMainWindow._log_combo_window[s=ô  Ð8¸¸¸RÀ×@QÑ@Q×@]Ñ@]Ó@_Ð?`Ð`aÐ ×#r cóN[RS5 UR5 g)z9
Log New Scenario button press and call create_scenario.
zUI: New Scenario button pressedN)rlrmÚcreate_scenarior@s rr,ÚMainWindow._log_btn_newbsô  Ð ×ÑÕr cóN[RS5 UR5 g)z<
Log Import Scenario button press and call import_scenario.
z"UI: Import Scenario button pressedN)rlrmÚimport_scenarior@s rr.ÚMainWindow._log_btn_importióô  Ð ×ÑÕr cóN[RS5 UR5 g)z<
Log Export Scenario button press and call export_scenario.
z"UI: Export Scenario button pressedN)rlrmÚexport_scenarior@s rr0ÚMainWindow._log_btn_exportpryr cóN[RS5 UR5 g)z<
Log Rename Scenario button press and call rename_scenario.
z"UI: Rename Scenario button pressedN)rlrmÚrename_scenarior@s rr2Ú#MainWindow._log_btn_rename_scenariowryr cóN[RS5 UR5 g)z<
Log Delete Scenario button press and call delete_scenario.
2025-07-31 12:52:28 +02:00
z"UI: Delete Scenario button pressedN)rlrmÚdelete_scenarior@s rr4Ú#MainWindow._log_btn_delete_scenario~ryr có4UR(dgURRn[RR USSUS3[RR
R [RR
R-5nU[RR
R :Xa…URR5n[RRU5(a[R"U5 [RSU35 SUlUR!5 gg!["aIn[R%SUSU35 [RR'USS U35 SnAgSnAff=f)
z1
Delete the current scenario after confirmation.
NzDelete Scenarioz.Are you sure you want to delete the scenario 'z'? This cannot be undone.zDeleted scenario: zFailed to delete scenario 'rfz Delete ErrorzFailed to delete scenario.
2025-07-31 12:52:28 +02:00
)rOrrvÚquestionròÚYesÚNor^r[r'rgÚshutilÚrmtreerlrmrnroÚcritical)rrOÚreplyrprrs rrÚMainWindow.delete_scenario…sKð× Ø×Ü× Ø Ø<¸T¸FÐB[Ð × !× 0× 4´y×7LÑ7L×7[Ñ7[×7^Ñ7^Ñ 
ˆð ”I×)×8× 
iØG Ü—77—>> ,×—MM ,Ô Ð°Ð8Ø(,Ô× =øôó
iÜ Ð:¸4¸&ÀÀAÀ3Ð×%×.¨t°^ÐGcÐdeÐcfÐEg×hûð
iúsÂ?BEÅ
2025-07-31 12:52:28 +02:00
FÅ?FÆFcóV[RSU35 URU5 g)z1
Log steps list row change and call select_step.
zUI: Steps list row changed to N)rlrmÚ select_steprms rr<ÚMainWindow._log_steps_listžs&ô  Ð4°S°EÐ ×јÕr cóN[RS5 UR5 g)z.
Log Add Step button press and call add_step.
zUI: Add Step button pressedN)rlrmÚadd_stepr@s rr>ÚMainWindow._log_btn_add_step¥sô  Ð
2025-07-31 12:52:28 +02:00
r cóN[RS5 UR5 g)z0
Log Edit Step button press and call edit_step.
zUI: Edit Step button pressedN)rlrmÚ edit_stepr@s rr@ÚMainWindow._log_btn_edit_step¬sô  Ð Õr cóN[RS5 UR5 g)z4
Log Delete Step button press and call delete_step.
zUI: Delete Step button pressedN)rlrmÚ delete_stepr@s rrBÚMainWindow._log_btn_del_step³óô  Ð ×ÑÕr cóN[RS5 UR5 g)z4
Log Rename Step button press and call rename_step.
2025-07-31 12:52:28 +02:00
zUI: Rename Step button pressedN)rlrmÚ rename_stepr@s rrDÚMainWindow._log_btn_rename_stepºr˜r cóN[RS5 UR5 g)z9
Log Start/Stop button press and call toggle_automation.
zUI: Start/Stop button pressedN)rlrmrzr@s rrIÚMainWindow._log_btn_start_stopÁsô  Ð ×ÑÕ r cóN[RS5 UR5 g)z6
Log Move Up Step button press and call move_up_step.
zUI: Move Up Step button pressedN)rlrmÚ move_up_stepr@s rrFÚ MainWindow._log_btn_move_up_stepÈsô  Ð ×ÑÕr cóN[RS5 UR5 g)z:
Log Move Down Step button press and call move_down_step.
2025-07-31 12:52:28 +02:00
z!UI: Move Down Step button pressedN)rlrmÚmove_down_stepr@s rrHÚ"MainWindow._log_btn_move_down_stepÏsô  Ð ×ÑÕr cóURnUR(UUS:”U[URR5:URRUURRUS-
sURRUS-
'URRU'URR 5 UR 5 UR RUS-
5 US-
2025-07-31 12:52:28 +02:00
Ulggggg)z@
Move the selected step up in the steps list (higher priority).
Nrr.©r"rPrsÚ
refresh_listsr9Ú
setCurrentRowrms rÚMainWindow.move_up_stepÖð×à × Øa“Ø”c˜$××+¨CÑ×+¨C°!©GÑ
SˆD× !× ¨a©Ñ 0°$×2GÑ2G×2MÑ2MÈcÑ2Rð
2025-07-31 12:52:28 +02:00
× !× × Ñ Ô Ø O‰O× )¨#°©'Ô 2Ø%(¨1¡Wˆ ð ð
"r cóURnUR(UUSU[URR5S-
:URRUURRUS-sURRUS-'URRU'URR 5 UR 5 UR RUS-5 US-Ulggggg)zA
Move the selected step down in the steps list (lower priority).
Nrr.rms rÚMainWindow.move_down_stepêð×à × Øq“Ø”c˜$×Ñ×+¨CÑ×+¨C°!©GÑ
SˆD× !× ¨a©Ñ 0°$×2GÑ2G×2MÑ2MÈcÑ2Rð
× !× × Ñ Ô Ø O‰O× )¨#°©'Ô 2Ø%(¨1¡Wˆ ð ð
"r cóXlg)z(
Set the selected step index in the UI.
N)rms rrÚMainWindow.select_stepþs
ð"%Õr có¶[U5UlURRRUR5 URR 5 g)z<
Open the dialog to add a new step to the current scenario.
2025-07-31 12:52:28 +02:00
N)Ú
StepDialogÚ _step_dialogÚacceptedr·Ú_on_add_step_acceptedrér@s rrÚMainWindow.add_stepsCô' tÓ,ˆÔØ ×Ñ×"×*¨4×+EÑ+EÔ ×Ñ×ÑÕ r cóHURR5nURRR U5 URR 5 UR
5 [RSU35 URR5 SUlg)Nz Added step: )
2025-07-31 12:52:28 +02:00
Úget_steprÛrPr7rsrlrmÚ deleteLater)rs rÚ MainWindow._on_add_step_accepted s{Ø× Ñ ×Ø ×Ñ×*¨4Ô ×Ñ× ×ÑÔÜ l 4 &Ð ×Ñ× ˆÕr cóV^^TRmTb)TS:d#T[TRR5agTRRTn[ TU5TlTR
R RUU4Sj5 TR
R5 g)zD
Open the dialog to edit the selected step in the current scenario.
Nrcó&>TRT5$r)Ú_on_edit_step_accepted)rnrs€€rr1Ú&MainWindow.edit_step.<locals>.<lambda>sø€°4×3NÑ3NÈsÔ3Sr ) r®r"rP)rrns` @rr“ÚMainWindow.edit_stepsˆù€ðר ‰;˜# ' S¬C°×0EÑ0E×0KÑ0KÓ,LÓ%LØ Ø×$×*¨3Ñ/ˆÜ& t¨TÓ2ˆÔØ ×Ñ×"×*Õ+SÔ ×Ñ×ÑÕ r có,URR5URRU'URR 5 UR 5 [ RSU35 URR5 SUlg)NzEdited step at idx ) r¯r´rPrsrlrmrms rÚ!MainWindow._on_edit_step_accepted!ssØ+/×+<Ñ+<×+EÑ+EÓ+Gˆ×Ñ×# CÑ ×Ñ× ×ÑÔÜ Ð)¨#¨Ð ×Ñ× ˆÕr có(URnUb)US:d#U[URR5agURRU URR 5 UR 5 [ RSU35 g)z5
Delete the selected step from the current scenario.
2025-07-31 12:52:28 +02:00
NrzDeleted step at idx )r"rPrsrlrmrms rrÚMainWindow.delete_step)s{ð×$ˆØ ‰;˜# ' S¬C°×0EÑ0E×0KÑ0KÓ,LÓ%LØ Ø × !× Ð  ×Ñ× ×ÑÔÜ Ð*¨3¨%Ð1r có[[RR[S5S5nUR U5 SSS5 g!,(df  g=f![ a"n[RSU35 SnAgSnAff=f)z6
Save the name of the last selected scenario to disk.
2025-07-31 12:52:28 +02:00
úlast_scenario.txtrbNzCould not save last scenario: ) rir[r'r\r]Úwriternrlro)rrOrqrrs rÚsave_last_scenarioÚMainWindow.save_last_scenario5sað”b—gg—l‘l¤:Ð/BÓCÀSÔIÈQؘ
÷J×Iûäó L‰LÐ9¸!¸Ð=× >ûð ?ús4.A°A ÁAÁ
AÁAÁAÁ
2025-07-31 12:52:28 +02:00
BÁ&BÂBcó~[RR[S5n[RR U5(dg[ US5nUR
5R5sSSS5 $!,(df  g=f![a"n[RSU35 SnAgSnAff=f)z8
Read the name of the last selected scenario from disk.
NrvzCould not read last scenario: ) r[r'r\r]rgriÚreadÚstriprnrlro)rr'rqrrs rÚread_last_scenarioÚMainWindow.read_last_scenario?s}ð Ü—77—<
2025-07-31 12:52:28 +02:00
Ð,?Ó@ˆ—77—>> $×Üd˜C” —vv“x—~‘~Ó!—ûäó Ü L‰LÐ9¸!¸Ð ûð ús<ABÁ BÁA?Á5 BÁ?
B
2025-07-31 12:52:28 +02:00
 BÂ
BÂ
B<ÂB7Â7B<cóú[RS5 URR5 [R 5nUHnURR
U5 M UR5 U(G[R"U5nURS5 URS5 URS[RRR5nURS[RRR5nUR!U5 UR#5 UR%5nXd:X[R&R)USS5up'U(aqU(aj[R+SU35 [ U5nUR-5 URR
U5 URR/U5 g
2025-07-31 12:52:28 +02:00
UR15 g
Xe:XaUR35 g
UR15 g
UR55n U (a!X;aURR/U 5 g
URR7S 5 g
) z9
Load all scenarios and populate the scenario combo box.
zLoading scenarios...zNo Scenarios FoundzJNo scenarios found. Would you like to create a new scenario or import one?z
Create Newrú New Scenarioz%Enter a name for your first scenario:úCreating new scenario: rN)rlrdrr=rKr~ÚaddItemr*rrvroÚ addButtonÚ
ButtonRoleÚ
AcceptRoleÚ
ActionRoleÚsetDefaultButtonrôÚ
clickedButtonÚ QInputDialogÚgetTextrmrsÚsetCurrentTextr¦rwÚsetCurrentIndex)
rrrOÚ
2025-07-31 12:52:28 +02:00
choice_dialogÚ
create_btnÚ
import_btnr'Úokr5Úlast_scenario_names
rÚMainWindow.load_scenariosMô  Ð
2025-07-31 12:52:28 +02:00
×ÑÔÜ×'ˆ Ûˆ J‰J× Ñ ˜tÖ ð
× Ñ ÔÜ1°$Ó7ˆ × (Ð)=Ô × !Ð"nÔ &×¼y×?TÑ?T×?_Ñ?_×?jÑ?jÓkˆ&×¼9×;PÑ;P×;[Ñ;[×;fÑ;fÓgˆ × *¨:Ô × Ñ Ô Ø3ˆGØÓ9¸$ÀÐPwÓx‘Þž$Ü—KKÐ"9¸$¸Ð @Ô  —F‘F”HØ—JJ×& —JJ×-¨dÕ×Ó××$à!%×!8Ñ!8Ó!:Ð Þ!Ð&8Ó&EØ
2025-07-31 12:52:28 +02:00
×)Ð*<Õ
2025-07-31 12:52:28 +02:00
×*¨1Õ-r cóURR5n[RSU35 U(aL[R U5UlURU5 UR5 UR5 gg)z/
Load the selected scenario and update the UI.
2025-07-31 12:52:28 +02:00
zScenario selected: N)
rrlrmrKrwÚ load_selected_window_from_config)rrOs rrlÚMainWindow.select_scenariowsiðz‰z×Ü Ð)¨$¨Ð Ü$,§M¡M°$Ó$7ˆ × # DÔ × Ñ Ô Ø × r có&[RRUSS5upU(agU(a_[R SU35 [ U5nUR
5 UR5 URRU5 ggg)z)
Open a dialog to create a new scenario.
zEnter scenario name:rÌN)
rrlrmrKrsr)rrOr5s rrtÚMainWindow.create_scenarioƒsqô×1°$¸ÐH^Ó_‰ˆÞ
2025-07-31 12:52:28 +02:00
–$Ü K‰KÐ1°$°Ð ˜ˆAØ
F‰FŒHØ × Ñ Ô J‰J× %  ˆ2r có¤UR(dgURRn[RR USSUS9up#U(Ga+U(Ga"X!:wGa[
R R[U5n[
R R[U5n[
R RU5(d[SUS35e[
2025-07-31 12:52:28 +02:00
R RU5(a[SUS35e[
R"XE5 X RlURR%5 UR'5 UR(R+U5 gggg![aFn[RS U35 [R R#US
2025-07-31 12:52:28 +02:00
S U35 SnAgSnAff=f) z/
Open a dialog to rename the current scenario.
NzRename Scenarioú New name:©zScenario directory 'z' does not exist.zA scenario named 'z' already exists.z#Error renaming scenario directory: ÚErrorz%Could not rename scenario directory.
2025-07-31 12:52:28 +02:00
)rOrr[r'r\r]rgÚFileNotFoundErrorÚFileExistsErrorÚrenameÚOSErrorrlrorvr‰rsr)rÚold_nameÚnew_namerÛÚold_dirÚnew_dirrrs rr~ÚMainWindow.rename_scenariosmð× à×Ü ×-×5°dÐ<MÈ{ÐaiÐj‰ ˆç
—(˜
ÜŸ'™'Ÿ,™,¤z°8Ó<ÜŸ'™'Ÿ,™,¤z°8Ó<Ü—ww—~~ g×+Ð.BÀ7À)ÐK\Ð,]Ó—77—>> '×)Ð,>¸x¸jÐHYÐ*ZÓ ˜*2× × !× 
2025-07-31 12:52:28 +02:00
× Ñ Ô J‰J× % hÕ /ð+ 4(ˆ2øôó
Ü ÐBÀ1À#Ð×%×.¨t°WÐ@fÐghÐfiÐ>jÔûð
úsÁ"CE?Å?
2025-07-31 12:52:28 +02:00
GÆ <G
Ç
2025-07-31 12:52:28 +02:00
GcóxUR(a
URcgURRURnURSS5n[R
R
USSUS9up4U(a=U(a5X2:wa/X1S'URR5 UR5 gggg)z,
Open a dialog to rename the selected step.
NrOú Unnamed Stepz Rename Steprä) rÛrPrVrrs)rs rÚMainWindow.rename_step°ð×$××(>Ñ(>Ñ(FØ à×$×*¨4×+AÑ+AÑØ—8‘8˜F NÓÜ ×5°d¸MÈ;Ð]eÐf‰ ˆæ
–(˜xÓ#‰LØ × !× × Ñ Õ ð 4(ˆ2r c
ó([RRUSSS5upU(G[R"US5n[
R R[S5n[
R RU5(a[R"U5 URU5 [
R"U5Vs/sHHn[
R R[
R RXE55(dMFUPMJ nnU(d [S5eUSn[
2025-07-31 12:52:28 +02:00
R RXG5n[
R R[U5n [
R RU 5(a[R"U 5 [R "X‰5 [R"U5 SSS5 ["R%S U35 UR'5 UR(R+W5 ggs snf!,(df  NX=f![aFn
["R-S
U
2025-07-31 12:52:28 +02:00
35 [R.R1US S U
35 Sn
A
gSn
A
ff=f)
z:
2025-07-31 12:52:28 +02:00
Open a file dialog to import a scenario from a zip file.
zImport ScenariorúZIP Files (*.zip)rvÚ _temp_importz,No scenario directory found in the zip file.rNzImported scenario from zFailed to import scenario: z Import ErrorzFailed to import scenario.
)rÚ QFileDialogÚgetOpenFileNameÚzipfileÚZipFiler[r'r\r]rgr‡rˆÚ
extractallr{r|rnÚmoverlrmrrorvr‰) rr'r:Úzip_refÚtemp_dirr}Úextracted_dirsÚ
scenario_nameÚsrc_pathÚ dest_pathrrs rrwÚMainWindow.import_scenarioÀô×'×7¸Ð>OÐQSÐUhÓi‰ˆß ð
2025-07-31 12:52:28 +02:00
iÜ—__ T¨3Ô/°7ä!Ÿw™wŸ|™|¬J¸ÓG—w‘w—~‘~ hן
š
 ×& 24·²¸HÔ1EÓ%rÒ1E¨AÌÏÉÏÉÔWY×W^ÑW^×WcÑWcÐdlÓWp×Iq§aÑ1ENÐ%rÞ'Ð(VÓWØ$2°1Ñ$5 "Ÿw™wŸ|™|¨HÓDHÜ "§¡§ ¡ ¬Z¸Ó G—w‘w—~‘~ iן
š
2025-07-31 12:52:28 +02:00
 iÔ—K’K Ô—M’M (Ô+÷)0ô, Ð5°d°VÐ×
×)¨-Õ8ð5 ùò&s÷/ûô2ó
iÜ Ð:¸1¸#Ð×%×.¨t°^ÐGcÐdeÐcfÐEg×hûð
iúsK®IÁBH0Ã
AH+ÄH+ÄCH0ÇA IÈ+H0È0
2025-07-31 12:52:28 +02:00
H>È:IÉ
JÉ <J Ê Jcó^UR(d[RS5 gURR5n[R
R
2025-07-31 12:52:28 +02:00
USURRS3S5up#U([R"US[R5n[R"U5HcupSnUHWn[RRXW5n[RRU[ 5n UR#X‰5 MY Me SSS5 [R%SU35 gg!,(df  N(=f![&aFn
[R)SU
2025-07-31 12:52:28 +02:00
35 [R*R-US S
U
35 Sn
A
2025-07-31 12:52:28 +02:00
gSn
A
ff=f) zB
2025-07-31 12:52:28 +02:00
Open a file dialog to export the current scenario to a zip file.
z No scenario selected for export.NzExport Scenarioz.ziprôrbzExported scenario to zFailed to export scenario: z Export ErrorzFailed to export scenario.
)rlr^rÚgetSaveFileNamerOÚ ZIP_DEFLATEDr[Úwalkr'r\Úrelpathr]rmrnrorvr‰) rrpr'r:Úzipfr¯ÚfilesÚfileÚ file_pathÚarcnamerrs rr{ÚMainWindow.export_scenarioäsWð×$× N‰NÐ à×,×?ˆ Ü×'×7¸Ð>OÐTX×TiÑTi×TnÑTnÐSoÐosÐQtðwJóKˆæ ð
iÜ—_’_ T¨3´×0DÑ0DÔÜ*,¯'ª'°,Ö*?™˜ Û$)˜DÜ(*¯©¯ © °TÓ(@˜IÜ&(§g¡g§o¡o°iÄÓ&L˜ ŸJ™J %*ñ+@÷Fô  Ð3°D°6Ð çEûôó
iÜ Ð:¸1¸#Ð×%×.¨t°^ÐGcÐdeÐcfÐEg×hûð
2025-07-31 12:52:28 +02:00
iús1Â&EÂ+A>E Ä) EÅ
EÅEÅ
F,Å&<F'Æ'F,cóˆ[RS5 [XRR5nUR 5(axUR
5nURRRU5 URR5 UR5 [RSU35 gg)z2
Open the dialog to add a new action to the step.
z"Add Action: Opening action dialog.zAction added: N) rlrdÚ ActionDialogrÛrÚ
get_actionr*r7rsrm)rÚdlgr0s rÚ
add_actionÚMainWindow.add_actionýs“ð ô  И4×!6Ñ!6×!=Ñ!=Ó>ˆØ 8‰8:‰:Ø—^‘^Ó%ˆFØ × Ô × !× × Ñ Ô Ü K‰K˜.¨¨Ð r c óœ[RS5 URR5 UR(dgURR
nUR
SS5nUR
SS5nSRUR
S/5Vs/sH,nUR
SS 5S
UR
S S 5S
S3PM. sn5nSRUR
2025-07-31 12:52:28 +02:00
S/5Vs/sHofR
SS5PM sn5nURRUSUSUSU35 gs snfs snf)zA
Refresh the step list widget with the current scenario's steps.
zRefreshing steps list.NrOr#r$Ú,rrrkrrz.2fr}r*rBr0z [z] imgs: z
actions: ) rlrdr9r=rPrVr\)rrOÚcondrÚimgsÚactss rÚMainWindow.refresh_lists
s(ô  Ð ×ÑÔØ× Ø×/ˆDØ—8‘8˜F NÓ3ˆDØ—8‘8˜K¨Ó.ˆDØ—8‘8àŸ8™8 H¨bÔâ1—77˜6 *¨"¨S¯W©W°]ÀCÓ-HÈÐ,MÈQÓóˆDð—88¸d¿h¹hÀyÐRTÔ>UÓVÒ>U¸ŸU™U 6¨8Ö4Ñ>UÑWˆ O‰O× # t f¨B¨t¨f°H¸T¸FÀ*ÈTÈFÐ$SÖ 0ùòùòWs Â3E
Ã7E
có´URRS5 U(aURR5OSnURR5 URR S5 [
R "5nUH5nUR5(dMURR U5 M7 U(aCU(a<URRU5nUS:waURRU5 URRS5 g![a"n[RSU35 SnANSnAff=f)z
Populate the window selection dropdown with all open windows and 'Entire Screen'.
If keep_selection is True, try to keep the current selection.
TNrözError listing windows: éÿÿÿÿF)
Ú blockSignalsrýr=rÚ getAllTitlesrÇrnrlroÚfindTextr×)rÚkeep_selectionÚcurrentÚwindowsrrrrns rr*ÚMainWindow.refresh_window_listsð
2025-07-31 12:52:28 +02:00
×Ñ×& ,Þ5C$×#×ˆØ ×Ñ×ÑÔ ×Ñ×! /Ô—o'ˆ Ø—;;—=“=Ø×-¨eÖ
žgØ×,¨WÓ5ˆCØb‹yØ×1°#Ô ×Ñ×& -øô
ó L‰LÐ2°1°#Ð6× 7ûð 8úsÁ5-D+Â&D+Ä+
EÄ5EÅEcó®UR(a„URR5nURR5n[R
R
2025-07-31 12:52:28 +02:00
US5n[US5n[R"SU0U5 SSS5 gg!,(df  g=f![a"n[RSU35 SnAgSnAff=f)zC
Save the currently selected window to the scenario's config file.
úwindow_config.jsonrbr Nz!Failed to save window selection: )
r^r[r'r\rirjrkrnrlro)rr rpÚ config_pathrqrrs rrqÚMainWindow.save_selected_window5ð × × Ø/×=ˆ×0×CˆŸ'™'Ÿ,™, |Ð5IÓJˆ
Fܘ+ sÔ+¨qÜ—I’IÐ0°/ÐBÀAÔ
2025-07-31 12:52:28 +02:00
+ûäó
FÜ ÐÀÐEûð
Fús6Á' B(Á3BÂ
B(Â
B%Â!B(Â%B(Â(
CÂ2CÃCcó6^^TR(TRR5n[RR US5nSm[RR U5(a>[
US5n[R"U5nURSS5mSSS5 UU4Sjn[RRSU5 gg!,(df  N7=f![a"n[RSU35 SnANaSnAff=f) zS