)i01dZddlZddlmZmZmZmZmZmZm Z m Z m Z m Z m Z mZmZmZddlmZddlmZddlmZGddeZdS) zq Backup Profile Editor Dialog Allows creating and editing backup profiles with source paths and exclude patterns N)QDialog QVBoxLayout QHBoxLayout QFormLayout QGroupBox QLineEditQSpinBox QCheckBox QListWidget QPushButtonQDialogButtonBox QFileDialog QMessageBoxQLabel)Qt)logger)DatabasecpeZdZdZddedeffd ZdZdZdZ d Z d Z d Z d Z d ZdefdZdZxZS)BackupProfileDialogz+Dialog for creating/editing backup profilesNdb profile_idcBt|||_||_|du|_||jrdnd|dd||jr|dSdS)NzEdit Backup ProfilezNew Backup ProfileiiX) super__init__rris_editsetWindowTitlesetMinimumSize _setup_ui_load_profile_data)selfparentrr __class__s 0C:\PYTHON\Scheduler\gui\backup_profile_dialog.pyrzBackupProfileDialog.__init__s    $"-  T\[11G[\\\ C%%%  < &  # # % % % % % & &cV t|}|dtd}t|}t |_|jd|d|jt |_|jd|d|j| |td}t|}t}t |_ |j d| |j td }|j |j| ||d |t!|_|jd d |jd |jd|d|jt+d|_|jd|d|j| |td}t|} t1d} | | t3|_|jt2jj| |jt} td} | j |j| | td} | j |j| | | | !| | |td}t|}t1d}| |t3|_"|j"t2jj| |j"t}td}|j |j#| |td}|j |j$| |td}|j |j%| || |!|| |tMtLj'j(tLj'j)z}|j*|j+|j,|j-| |dS)zSetup dialog UIzBasic Informationz"e.g., Daily Backup, Weekly ArchivezProfile Name *:zOptional descriptionz Description:zBackup Settingsze.g., D:\backupsz Browse...zBackup Root *:imz daysz Retention:zEnable this profileTz Source Pathsz0Directories to backup (at least one required) *:zAdd Directory...zRemove SelectedzExclude Patternsz'File patterns to exclude (glob syntax):zAdd Pattern...zAdd Common PatternsN).r setSpacingrrr name_editsetPlaceholderTextaddRowdescription_edit addWidgetrbackup_root_editr clickedconnect_browse_backup_rootr retention_spinsetRangesetValue setSuffixr enabled_check setCheckedrr sources_listsetSelectionMode SelectionModeSingleSelection _add_source_remove_source addStretch addLayout patterns_list _add_pattern_remove_pattern_add_common_patternsr StandardButtonSaveCancelaccepted _save_profilerejectedreject)r layout basic_group basic_layoutsettings_groupsettings_layoutbackup_root_layoutbrowse_root_btn sources_groupsources_layout sources_labelsources_buttons_layoutadd_source_btnremove_source_btn exclude_groupexclude_layout exclude_labelpatterns_buttons_layoutadd_pattern_btnremove_pattern_btnadd_common_btn button_boxs r#rzBackupProfileDialog._setup_ui%srT""" 344 ";// " ))*NOOO-t~>>> )  001GHHHND,ABBB%%%##455%n55)]] )  001DEEE$$T%:;;;%k22''(@AAA$$_555/1CDDD&jj $$Q,,, $$R((( %%g...|T-@AAA&'<== %%d+++r4#5666(((".11 $]33QRR   ///'MM **;+D+TUUU  !2333!,$%788&&t'7888((888'(9::!))$*=>>>(():;;;))+++  !7888'''""455 $]33HII   ///(]] ++K,E,UVVV  !3444"---%&677''(9:::))/:::():;;"**4+?@@@))*<===$%:;;&&t'@AAA)).999**,,,  !8999'''&  + 0  + 2 3   ##D$6777##DK000$$$$$r$c> |j|j}|s5tj|dd|jd|dS|j|d|j| dd|j |d|j |d |j t|d |d }t!|t"rt%j|}|D]}|j|| d g}t!|t"rt%j|}|D]}|j|dS#t.$rO}t1jd |tj|dd||Yd}~dSd}~wwxYw)zLoad profile data in edit modeErrorzProfile z not foundNname descriptionr) backup_rootretention_daysenabledsourcesexclude_patternszError loading profile data: zFailed to load profile: )rget_backup_profilerrcriticalrLr+setTextr.getr0r4r6r8r9bool isinstancestrjsonloadsr:addItemrB Exceptionrerror)r profilerisourcepatternspatternes r#rz&BackupProfileDialog._load_profile_datas( g00AAG $T74Zt4Z4Z4Z[[[  N " "76? 3 3 3  ! ) )'++mR*H*H I I I  ! ) )'-*@ A A A   ( (1A)B C C C   ) )$wy/A*B*B C C Ci(G'3'' .*W--! 2 2!))&1111{{#5r::H(C(( 0:h//# 4 4"**73333 4 4    L;;; < < <  w0N10N0N O O O KKMMMMMMMMM s AGE)G H AHHctj|d|jpd}|r|j|dSdS)z Browse for backup root directoryzSelect Backup Root Directoryr)N)rgetExistingDirectoryr0textrm)r directorys r#r3z'BackupProfileDialog._browse_backup_rootsb4  *  ! & & ( ( .B   5  ! ) )) 4 4 4 4 4 5 5r$c tjdd}|rjfdtjD}||vrj|dSt jdddSdS)zAdd source directoryzSelect Source Directoryr)chg|].}j|/Sr:itemr~.0ir s r# z3BackupProfileDialog._add_source..s6```!T&++A..3355```r$ Duplicatez%This directory is already in the listN)rr}ranger:countrtr information)r ritemss` r#r>zBackupProfileDialog._add_sources4  %    d````uTEVE\E\E^E^?_?_```E%%!)))44444'k;bccccc  d dr$c||j}|dkr|j|dSdS)z Remove selected source directoryrN)r: currentRowtakeItemr currents r#r?z"BackupProfileDialog._remove_sourcesC#..00 a<<   & &w / / / / / .s6bbb1T',,Q//4466bbbr$rz#This pattern is already in the listN) PyQt6.QtWidgetsrgetTextstriprrBrrtrr)r rrzokrs` r#rCz BackupProfileDialog._add_patterns000000"**  ! C    b'--// bmmooGbbbbdFXF^F^F`F`@a@abbbEe##"**733333'k;`aaaaa b b b br$c||j}|dkr|j|dSdS)zRemove selected exclude patternrN)rBrrrs r#rDz#BackupProfileDialog._remove_patternsC$//11 a<<   ' ' 0 0 0 0 0 .s6aaa!D&++A..3355aaar$rr'zPatterns AddedzAdded z common pattern(s)z No Changesz+All common patterns are already in the listN)rrBrrtrr)r common_patternsexisting added_countrzs` r#rEz(BackupProfileDialog._add_common_patternss    baaauTEWE]E]E_E_?`?`aaa & ! !Gh&&"**7333q ??  # 8888       #=     r$returnc|js1tj|dd|jdS|js1tj|dd|jdS|jdkrtj|dddSdS)zValidate form inputszValidation ErrorzProfile name is requiredFz!Backup root directory is requiredrz)At least one source directory is requiredT) r+r~rrwarningsetFocusr0r:r)r s r#_validate_inputsz$BackupProfileDialog._validate_inputss~""$$**,,   &8:T U U U N # # % % %5$))++1133   &8:] ^ ^ ^  ! * * , , ,5   " " $ $ ) )  ";    5tr$c .sdS j}j}j}j}j }fdtj D}fdtj D}jrGjj|||||||t%jdjd|n;j|||||||}t%jd|d|dS#t,$r;} t%jd | t1jd d | Yd} ~ dSd} ~ wwxYw) zSave profile to databaseNchg|].}j|/Srrrs r#rz5BackupProfileDialog._save_profile..:sF!&&q))..00r$chg|].}j|/Srrrs r#rz5BackupProfileDialog._save_profile..@sF   "''**//11   r$)rrdrfrirerjrgrhzUpdated backup profile z: )rdrfrirerjrgrhzCreated backup profile zError saving profile: rczFailed to save profile: )rr+r~rr.r0r4valuer8 isCheckedrr:rrBrrupdate_backup_profilerrinfocreate_backup_profileacceptrurvrrl) r rdrerfrgrhrirjrr{s ` r#rJz!BackupProfileDialog._save_profile,si$$&&  F2 P>&&((..00D/4466<<>>K/4466<<>>K!06688N(2244Gt0668899G     t17799::     | L--# +# +%5#1#.    OdoOOOOPPPP"W:: +# +%5#1#;  JjJJDJJKKK KKMMMMM P P P L5!55 6 6 6  w0N10N0N O O O O O O O O O PsF4G H0HH)N)__name__ __module__ __qualname____doc__rintrrrr3r>r?rCrDrErorrJ __classcell__)r"s@r#rrs 55&&8&&&&&&& n%n%n%`   D555 d d d000 bbb&111 """H$27P7P7P7P7P7P7Pr$r)rrrrrrrrrrr r r r r rrr PyQt6.QtCorerlogurur core.databaserrrr$r#rs:   """"""QPQPQPQPQP'QPQPQPQPQPr$