^ani.dZddlmZmZmZmZmZmZmZm Z m Z m Z m Z m Z mZddlmZddlmZddlmZddlmZGddeZd S) zh Sync Profile Editor Dialog Allows creating and editing sync profiles with source and destination paths ) QDialog QVBoxLayout QHBoxLayout QFormLayout QGroupBox QLineEdit QCheckBox QPushButton QTextEditQDialogButtonBox QFileDialog QMessageBoxQLabel)Qt)logger)Path)DatabasecXeZdZdZd dedeffd ZdZdZdZ d Z d e fd Z d Z xZS)SyncProfileDialogz)Dialog for creating/editing sync profilesNdb profile_idcBt|||_||_|du|_||jrdnd|dd||jr|dSdS)NzEdit Sync ProfilezNew Sync Profileii) super__init__rris_editsetWindowTitlesetMinimumSize _setup_ui_load_profile_data)selfparentrr __class__s .C:\PYTHON\Scheduler\gui\sync_profile_dialog.pyrzSyncProfileDialog.__init__s    $"-  4<W//EWXXX C%%%  < &  # # % % % % % & &c t|}|dtd}t|}t |_|jd|d|jt |_|jd|d|j| |td}t|}td}| d |d |t}t |_ |j d | |j td }|j|j| ||d |t} t |_|jd| |jtd } | j|j| | |d| t)d|_|jd|d |j| |td} t| } td} | | t/|_|jd|jd| |jtd}| d| |t)d|_|jd| |j| | td}| d| |t9t8jjt8jjz}|j |j!|j"|j#| |dS)zSetup dialog UIzBasic Informationz'e.g., WebDAV Sync, Network Share MirrorzProfile Name *:zOptional descriptionz Description:zSynchronization Settingsu⚠ Unidirectional mirror: Destination will be identical to Source. Files deleted from Source will be deleted from Destination.z"color: #ff6600; font-weight: bold;ze.g., C:\Documents or Z:\sharedz Browse...zSource Path *:ze.g., D:\backup or Z:\archivezDestination Path *:zEnable this profileTzExclusion Patternsz8Files and directories to exclude (one pattern per line):zExamples: venv/ # Exclude venv directory __pycache__/ # Exclude Python cache *.log # Exclude log files *.db # Exclude database files *.pyc # Exclude compiled PythonxzYUse folder/ for directories, *.ext for file patterns. Lines starting with # are comments.zcolor: #666; font-size: 10px;z%Protect excluded files in destinationaWhen enabled, files matching exclusion patterns won't be deleted from destination. Use this when syncing TO a machine that has its own local files (venv, database, etc.). When disabled (default), destination becomes a clean mirror - excluded files are deleted.z\Network paths (like Z:\) are supported. Files are compared by size for fast synchronization.N)$r setSpacingrrr name_editsetPlaceholderTextaddRowdescription_edit addWidgetr setStyleSheetr source_editr clickedconnect_browse_sourcedestination_edit_browse_destinationr enabled_check setCheckedr exclusions_editsetMaximumHeightprotect_excluded_check setToolTipr StandardButtonSaveCancelaccepted _save_profilerejectedreject)r layout basic_group basic_layoutsettings_groupsettings_layout info_label source_layoutbrowse_source_btn dest_layoutbrowse_dest_btnexclusions_groupexclusions_layoutexclusions_labelexclusions_help help_label button_boxs r#rzSyncProfileDialog._setup_ui%sT""" 344 ";// " ))*STTT-t~>>> )  001GHHHND,ABBB%%%##=>>%n55 J     !EFFFr:...$ $;; ++,OPPP 0111' 44!))$*=>>> 1222/???"mm )  001RSSSd3444%k22''(@AAAo...4kBBB&'<== %%d+++r4#5666(((%%9::'(899!"\]]##$4555({{ // 8    --c222##D$8999 g   %%&EFFF##O444'00W&X&X# #.. h   ##D$?@@@)*** k     !@AAA$$$&  + 0  + 2 3   ##D$6777##DK000$$$$$r$c |j|j}|s5tj|dd|jd|dS|j|d|j| dd|j |d|j |d |j | d d|jt!| d d |jt!|d dS#t$$rO}t'jd|tj|dd||Yd}~dSd}~wwxYw)zLoad profile data in edit modeErrorzProfile z not foundNname descriptionr' source_pathdestination_pathexclude_patternsprotect_excludedFenabledzError loading profile data: zFailed to load profile: )rget_sync_profilerrcriticalrBr*setTextr-getr0r4r8 setPlainTextr:r7boolr6 Exceptionrerror)r profilees r#rz$SyncProfileDialog._load_profile_datas g..t??G $T74Zt4Z4Z4Z[[[  N " "76? 3 3 3  ! ) )'++mR*H*H I I I   $ $W]%; < < <  ! ) )'2D*E F F F  - -gkk:Lb.Q.Q R R R  ' 2 24 DVX]8^8^3_3_ ` ` `   ) )$wy/A*B*B C C C C C    L;;; < < <  w0N10N0N O O O KKMMMMMMMMM s AE>D$E>> GAGGctj|d|jpd}|r|j|dSdS)zBrowse for source directoryzSelect Source Directoryr'N)r getExistingDirectoryr0textr^r directorys r#r3z SyncProfileDialog._browse_sourcesb4  %   ! ! # # )r   0   $ $Y / / / / / 0 0r$ctj|d|jpd}|r|j|dSdS)z Browse for destination directoryzSelect Destination Directoryr'N)r rgr4rhr^ris r#r5z%SyncProfileDialog._browse_destinationsb4  *  ! & & ( ( .B   5  ! ) )) 4 4 4 4 4 5 5r$returnc|js1tj|dd|jdS|js1tj|dd|jdS|js1tj|dd|jdSt|j}| s4tj|dd||jdSt|j} | | kr1tj|dd|jdSn#YnxYw ||j vrOtj|dd tj j tj jz}|tj jkrdS||j vrOtj|dd tj j tj jz}|tj jkrdSn#YnxYwd S) zValidate form inputszValidation ErrorzProfile name is requiredFzSource path is requiredzDestination path is requiredzSource path does not exist: z/Source and destination paths cannot be the sameWarningz\Destination is inside source directory. This may cause infinite recursion. Continue anyway?z]Source is inside destination directory. This may cause unexpected behavior. Continue anyway?T)r*rhstriprwarningsetFocusr0r4rexistsresolveparentsr<YesNo)r rW dest_pathreplys r#_validate_inputsz"SyncProfileDialog._validate_inputss~""$$**,,   &8:T U U U N # # % % %5$$&&,,..   &8:S T T T   % % ' ' '5$))++1133   &8:X Y Y Y  ! * * , , ,54+002288::;; !!##   "= ==      % % ' ' '5.3355;;==>>  ""$$ (9(9(;(;;;#&E %..000u<  D i///#+' .2[5O5RR K6999 5K///#+' .2[5O5RR K6999 5  Dts!AH**H.2AK# AK##K'c |sdS |j}|j}|j}|j}|j}|j }|j }|j rG|j |j|||||||t!jd|jd|n;|j |||||||}t!jd|d||dS#t($r;} t!jd| t-j|dd | Yd} ~ dSd} ~ wwxYw) zSave profile to databaseN)rrUrVrWrXrYrZr[zUpdated sync profile z: )rUrVrWrXrYrZr[zCreated sync profile zError saving profile: rTzFailed to save profile: )ryr*rhror-r0r4r8 toPlainTextr: isCheckedr6rrupdate_sync_profilerrinfocreate_sync_profileacceptrbrcrr]) r rUrVrWrXrYrZr[rres r#r@zSyncProfileDialog._save_profile s$$&&  F( P>&&((..00D/4466<<>>K*//117799K#499;;AACC #3??AA #:DDFF (2244G| J++# + +%5%5%5#,    MDOMMtMMNNNN"W88 + +%5%5%5#9  HJHH$HHIII KKMMMMM P P P L5!55 6 6 6  w0N10N0N O O O O O O O O O PsFF.. G380G..G3)N)__name__ __module__ __qualname____doc__rintrrrr3r5raryr@ __classcell__)r"s@r#rrs33&&8&&&&&&& o%o%o%b,000555I$IIIIV-P-P-P-P-P-P-Pr$rN)rPyQt6.QtWidgetsrrrrrrr r r r r rr PyQt6.QtCorerlogururpathlibr core.databaserrr$r#rs7  """"""fPfPfPfPfPfPfPfPfPfPr$