Xׯd.ddlmZGddeZGddeZGddeeZGdd eeZGd d eZ Gd d eZ dS)) log_debug3c&eZdZdZdZdZdZdS)ChangeNotifiercd|_dSN'_ChangeNotifier__change_notification_cbselfs ..\workbench\change_tracker.py__init__zChangeNotifier.__init__s(,%%%c||_dSrrr callbacks r set_notification_cbz"ChangeNotifier.set_notification_cbs(0%%%rc.|j|kr d|_dSdSrrrs r unset_notification_cbz$ChangeNotifier.unset_notification_cbs&  (H 4 4,0D ) ) ) 5 4rcF|jr||||dSdSrr)r changeattrvalues r notify_changezChangeNotifier.notify_change#s5  ( ?  ) )&$ > > > > > ? ?rN)__name__ __module__ __qualname__r rrrrr rrsP---111111?????rrc*eZdZdZdZdZdZdZdS) ChangeCounterz: This is a helper class to count changes reported cHt|d|_dSNr)rr change_countr s r r zChangeCounter.__init__,s$%%%rc`|rdnd}|xj|z c_||||dS)N)r"r)r rrr increments r count_changezChangeCounter.count_change1sD'AAR  Y& 64/////rc:||jdSr)rr'r sources r count_changes_onzChangeCounter.count_changes_on9s""4#455555rc:||jdSr)rr'r)s r stop_change_count_onz"ChangeCounter.stop_change_count_on<s$$T%677777rN)rrr__doc__r r'r+r-rrr rr(sZ 00066688888rrc<eZdZdZdZdZdZdZdZdZ dZ d S) ChangeNotifierLista1 Implementation of a list that keeps track of the changes occurred on its elements. To use this class the elements should met the next characteristics: - They must subclass ChangeTracker - They must implement __eq__ for item location on the list NOTE: Given the independence of the __eq__ operator on the items the item received as a parameter on the remove method is used ONLY for identification purposes. The object that gets actually removed/backed up is the one existing on the list. ct|t|g|_g|_dSr)listr r_ChangeNotifierList__additions_ChangeNotifierList__deletionsr s r r zChangeNotifierList.__init__Ps> dt$$$rc:|j|r|j|d}nd}|j|||dd||t||dSNFT)r4countremover3appendr'r+r2)r itemrs r r9zChangeNotifierList.appendWs   ! !$ ' ' *   # #D ) ) )FFF   # #D ) ) ) &$--- d### D$rc||r||}||}|j|rd}|j|nd}|j|||dd||t||dSdSr6) r7indexr3r8r4r9r'r-r2)r r:r<rs r r8zChangeNotifierList.removecs ::d   $JJt$$E;D%%d++ . ''---- ''---   fdD 1 1 1  % %d + + + KKd # # # # #! $ $rcd}|D]}|rd}|p/t|jdkpt|jdkS)NFTr) has_changedlenr4r3)r updatesr:s r r>zChangeNotifierList.has_changedws`  D!! P#d.//!3Ps4;K7L7Lq7PPrci}g}|D]W}|rA |j|2#t$r||YSwxYwX||d<|j|d<|j|d<|S)Nr@deletesadds)r>r3r< ValueErrorr9r4)r changesr@r:s r get_changeszChangeNotifierList.get_changess ) )D!! ))$**40000!)))NN4((((()  )% !- *s9AAc|D]*}|r|+|jdd}|D]}|||jdd}|D]}||dSr)r>revert_changesr4r9r3r8)r r:itemss r rHz!ChangeNotifierList.revert_changess & &D!! &##%%% #  D KK     #  D KK      rc||D]*}|r|+g|_g|_dSr)r> reset_changesr4r3)r r:s r rKz ChangeNotifierList.reset_changessN % %D!! %""$$$rN) rrrr.r r9r8r>rFrHrKrrr r0r0@s    $$$(QQQ"   rr0c4eZdZdZdZdZdZd dZdZdS) ChangeNotifierDictcpt||t|dSr)dictr r)r argss r r zChangeNotifierDict.__init__s0 dD!!!t$$$$$rcht|||||dS)zM All elements on this dictionary should notify about changes N)rO __setitem__r+)r keyvals r rRzChangeNotifierDict.__setitem__s8 sC((( c"""""rc.|dS)zh Resets the entire change tracking system, i.e. when the changes are committed. N_clear_changesr s r rKz ChangeNotifierDict.reset_changess rc0|ddS)zQ Undoes all the changes done on the elements of this dictionary. TNrVr s r rHz!ChangeNotifierDict.revert_changess D!!!!!rFc|jr[t|D];}|r||||:dSdSr)r"r2keysrHrK)r revertr:s r rWz!ChangeNotifierDict._clear_changessz   /TYY[[)) / //J--////J,,....  / / / /rci}t|D]9}||r||||<:|Sr)r2rZr>rF)r rErSs r rFzChangeNotifierDict.get_changess] $$ 7 7CCy$$&& 7#Cy4466 rN)F) rrrr rRrKrHrWrFrrr rMrMss%%% ###""" ////rrMcFeZdZdZdZdZdZd dZd dZdZ d Z d Z dS) ChangeTrackera ChangeTracker is a class in charge of keeping track of the changes done to the attributes in a subclass. As 'change' we understand any change done from a starting point which by default is after __init__ is called (not necessarily). i.e. when an attribue is created by the first time that is considered it's starting point, from there, if the value is changed it is already considered a change. The starting point can be also re-defined by calling reset_changes. cdt|i|_d|_d|_dSr!)rr _ChangeTracker__changed_ChangeTracker__ignoring)_ChangeTracker__value_set_notification_cbr s r r zChangeTracker.__init__s2%%%+/(((rc P||jvr|dkr |dkr|dkr|dkr|dkr|dkr|js|j||krd|d|j|d |d |d }||jdvrI|jd||kr1|jd|=|d ||d |d |d |d }n2|j||jd|<|d|||jr|||t d|z||j|<dS)Nr`ra#_ChangeTracker__notify_value_set_cbrbr _ChangeCounterchange_countzChanged z from z to z at  FzReverted change on Tz%s )__dict__rarrbr)r namer log_messages r __setattr__zChangeTracker.__setattr__s 4= , , , - - - 8 8 8 > > > < < < / / / 0 = % ' ' '@DdmTXFYFYFY[`[`[`bfbfbfgK t}%>???=!:;DAUJJ &?@F&&udE::::KO44QVQVQVX\X\X\"]K BFtAT 78>""4u555/ >00u=== v + , , ,$ drc||_dSr)rbrs r set_value_set_notificationz(ChangeTracker.set_value_set_notifications+3(((rNcH|r ||jvSt|jdkS)z Verifies if there are changes on the class attributes. If name is given it will verify for changes on that specific attribute. If not, will verify for changes on any attribute. r)r`r?r rhs r r>zChangeTracker.has_changeds.  +4>) )t~&&* *rc|r#|jvrj|j|fS|'tjrfdjDSdS)a* Retrieves the changes on the class attributes as tuples. If name is given it will return a tuple containing the (initial, current) values If not, it will return a list of tuples as (attribute, initial, current) If there are no changes it will return None. NcFg|]}|j|j|fSr)r`rg).0attr s r z-ChangeTracker.get_changes...s.]]]sS$.-t}S/AB]]]r)r`rgr?rns` r rFzChangeTracker.get_changes#sf  DDN**N4($-*=> > \c$.11\]]]]dn]]] ]4rc0|rdnd}|j|z|_dS)zF Used to turn ON/OFF the change detection mechanism. r$r%N)ra)r rincreases r set_ignoringzChangeTracker.set_ignoring2s$%112/H4rct|jD]$}|d||j|%i|_dS)zO Clears any registered changes to create a new starting point. FN)r2r`rZrrgr rs r rKzChangeTracker.reset_changes9sX,,..// A AD   udDM$,? @ @ @ @rct|jD]#}|||j|$dS)z. Reverts the changes applied. N)r2r`rZrjrxs r rHzChangeTracker.revert_changesCsS,,..// 9 9D   T4>$#7 8 8 8 8 9 9rr) rrrr.r rjrlr>rFrvrKrHrrr r^r^s  000 +$+$+$Z444 + + + +    55599999rr^c$eZdZdZdZdZdZdS)ignore_changesz IgnoreChanges Decorator It's purpose is to add the decorator on those methods for which the change detection will be turned off. It will only have effect on those classes childs of ChangeTracker. c"||_d|_dSr)funcinstance)r r}s r r zignore_changes.__init__Rs  rct|jtr@|jd|j|}|jd|SdS)NTF) isinstancer~r^rvr})r rPret_vals r __call__zignore_changes.__call__Vs_ dm] 3 3  M & &t , , ,di&G M & &u - - -N   rcN||_ddl}||j|Sr!)r~ functoolspartialr)r objobjtypers r __get__zignore_changes.__get__]s-   444rN)rrrr.r rrrrr r{r{JsK55555rr{N) workbench.logrobjectrrr2r0rOrMr^r{rrr rs6,%$$$$$ ? ? ? ? ?V ? ? ? 88888N8880ccccc}cccL,,,,,},,,\t9t9t9t9t9Nt9t9t9l55555V55555r