Added TODO and DEVELOPMENT.
[faces-project.git] / faces / faces.leo
blobd2b669971613c7e40e4fc3b68bed7145a54648a4
1 <?xml version="1.0" encoding="UTF-8"?>
2 <?xml-stylesheet ekr_test?>
3 <leo_file>
4 <leo_header file_format="2" tnodes="0" max_tnode_index="0" clone_windows="0"/>
5 <globals body_outline_ratio="0.568965517241">
6 <global_window_position top="10" left="10" height="1044" width="1301"/>
7 <global_log_window_position top="0" left="0" height="0" width="0"/>
8 </globals>
9 <preferences/>
10 <find_panel_settings/>
11 <vnodes>
12 <v t="michael.20070926121838"><vh>@chapters</vh></v>
13 <v t="mr7771.20060608154252" a="ETV"><vh>code</vh>
14 <v t="michael.20061230173452" a="E"><vh>Todos</vh>
15 <v t="michael.20061230174132"><vh>Refactorings</vh></v>
16 <v t="michael.20061230173452.1"><vh>Bugs</vh></v>
17 </v>
18 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
19 <v t="mr7771.20060608164004" a="E"><vh>Base</vh>
20 <v t="michael.20060717214039" tnodeList="michael.20060717214039,mr7771.20060609151433"><vh>@file __init__.py</vh>
21 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
22 </v>
23 <v t="michael.20060619145551" tnodeList="michael.20060619145551,mr7771.20060609151433,michael.20060619145551.1,michael.20060619145930,michael.20060619145551.4,michael.20060619145551.5,michael.20060619145551.6,michael.20060619145551.7,michael.20060619145551.8,michael.20060619145551.9,michael.20060619145930.1,michael.20060619145551.10,michael.20060619145551.11,michael.20060619145551.12,michael.20060619145551.13,michael.20060619145551.14,michael.20061119143304,michael.20060619145551.15,michael.20060619145551.16,michael.20060619145551.17,michael.20060619145551.18,michael.20060619145551.19,michael.20060619145551.20,michael.20060619145551.21,michael.20060619145551.22,michael.20060619145551.23,michael.20060619145551.24,michael.20060619145551.25,michael.20060619150413,michael.20060619145551.30,michael.20060619145551.31,michael.20060623161820,michael.20060623161820.1,michael.20060623161820.2,michael.20060619145551.32,michael.20060623160939,michael.20060623160939.1,michael.20060623160939.3,michael.20060623160939.4,michael.20060623160939.5,michael.20060623160939.6,michael.20060623160939.7,michael.20060623160939.8,michael.20060619150413.1,michael.20060619145551.26,michael.20060619145551.27,michael.20060619145551.28,michael.20060619145551.29,michael.20061119143714,michael.20060619145551.35,michael.20060619145551.36,michael.20060619145551.37,michael.20061109181208,michael.20060619145551.38,michael.20060619145551.39,michael.20070115204524,michael.20060619145551.40,michael.20060619145551.41,michael.20060619145551.42,michael.20061123163317,michael.20060619145551.43,michael.20070115161719,michael.20060619145551.44,michael.20060619145551.45,michael.20060619145551.46,michael.20060619145551.47,michael.20060619145551.48,michael.20060619145551.49,michael.20060619145551.50,michael.20060619145551.51,michael.20060619145551.52,michael.20060619145551.53,michael.20060619145551.54,michael.20060619145551.55,michael.20060619145551.56,michael.20060619145551.57,michael.20060619145551.58,michael.20060619145551.59,michael.20060619145551.60,michael.20060619145551.61,michael.20060619145551.62,michael.20060619145551.63,michael.20060619145551.64,michael.20060619145551.65,michael.20060619145551.66,michael.20060619145551.67,michael.20060619145551.68,michael.20060619145551.69,michael.20060619145551.70,michael.20060619145551.71,michael.20060619145551.72,michael.20060619145551.73,michael.20060619145551.74,michael.20060619145551.75,michael.20060619145551.76,michael.20060619145551.77,michael.20060619145551.78,michael.20060619145551.79,michael.20060619145551.80,michael.20060619145551.81,michael.20060619145551.82,michael.20060619145551.83,michael.20060619145551.84,michael.20060619150519,michael.20060619145551.2,michael.20060619145551.85,michael.20060619145551.86,michael.20060619145551.87,michael.20060619145551.88,michael.20060619145551.107,michael.20060915184406,michael.20060915190443,michael.20060619145551.106,michael.20060915184406.1,michael.20060619145551.108,michael.20060619145551.109,michael.20061118232041,michael.20060619145551.110,michael.20060619145551.111,michael.20060930013205,michael.20060619145930.2,michael.20070112120451,michael.20060619145551.33,michael.20060619145551.34,michael.20060619145551.89,michael.20060619145551.90,michael.20060619145551.91,michael.20060619145551.92,michael.20060619145551.93,michael.20060619145551.94,michael.20060814190211,michael.20060814190211.1,michael.20060814190211.2,michael.20060814190211.3,michael.20060814190211.4,michael.20060619145551.95,michael.20060619145551.96,michael.20060619145551.97,michael.20060619145551.98,michael.20060619145551.99,michael.20060619145551.100,michael.20060619145551.101,michael.20060619145551.102,michael.20060619145551.103,michael.20060619145551.104,michael.20060619145551.105,michael.20060619145930.3,michael.20060619145551.115,michael.20061027121652,michael.20060619145551.117,michael.20061027121652,michael.20060619145551.119,michael.20061027121652,michael.20060619145551.121,michael.20061027121652,michael.20060619150542,michael.20060619145551.123,michael.20060619145551.124,michael.20060619145551.125,michael.20060619145551.126,michael.20060619145551.127,michael.20060619145551.128,michael.20060619145551.129,michael.20060720224306,michael.20060619145551.130,michael.20060619145551.131,michael.20060619145551.132,michael.20060619145551.133,michael.20060619145551.134,michael.20060619145551.194,michael.20060619145551.135,michael.20061027224620,michael.20060623154957,michael.20060619145551.136,michael.20060619145551.137,michael.20060619145551.138,michael.20060619145551.139,michael.20060619145551.140,michael.20060619145551.141,michael.20060619145551.144,michael.20060619145551.148,michael.20060619145551.150,michael.20060619145551.142,michael.20060619145551.143,michael.20060623154957.1,michael.20060619145551.146,michael.20060619145551.151,michael.20060619145551.152,michael.20060619145551.187,michael.20060619145551.188,michael.20060619145551.147,michael.20060623154957.2,michael.20060619145551.153,michael.20060619145551.154,michael.20060619145551.155,michael.20060713212925,michael.20060619145551.156,michael.20061027120904,michael.20061027120904.2,michael.20061027120904.3,michael.20060623154040,michael.20060619145551.159,michael.20061109182534,michael.20061109182534.1,michael.20061109182534.2,michael.20061121143813,michael.20060619145551.160,michael.20061121143813.1,michael.20061121143813.2,michael.20061121143813.3,michael.20061121143813.4,michael.20061121143813.5,michael.20061121143813.6,michael.20061121143813.7,michael.20061121143813.8,michael.20061121143813.9,michael.20060619145551.161,michael.20060619145551.162,michael.20060619145551.163,michael.20060619145551.164,michael.20060619145551.165,michael.20060619145551.166,michael.20060619145551.167,michael.20060619145551.168,michael.20060619145551.169,michael.20060619145551.170,michael.20060619145551.171,michael.20060619145551.172,michael.20060619145551.173,michael.20060619145551.191,michael.20061109182534.3,michael.20060724150058,michael.20060724135631,michael.20060619145551.200,michael.20060724164954,michael.20060619145551.204,michael.20060619145551.205,michael.20060619145551.206,michael.20060619145551.208,michael.20060619145551.209,michael.20060619145551.210,michael.20060619145551.211,michael.20060619145551.212,michael.20060619145551.213,michael.20060619145551.214,michael.20060619145551.215,michael.20060619145551.216,michael.20060619145551.217,michael.20060619145551.207,michael.20060623154957.3,michael.20060619145551.145,michael.20060619145551.174,michael.20060619145551.175,michael.20060623154040.1,michael.20061230152555,michael.20061201004146,michael.20060619145551.177,michael.20060713212925,michael.20060623154040.2,michael.20060619145551.178,michael.20060713212925,michael.20060623154040.2,michael.20060619145551.179,michael.20060619145551.180,michael.20060619145551.181,michael.20060619145551.182,michael.20060619145551.183,michael.20060619145551.184,michael.20060619153005,michael.20060619153005.1,michael.20060619153005.2,michael.20060619145551.185,michael.20060619145551.186,michael.20060623154957.4,michael.20060619145551.157,michael.20060619145551.158,michael.20060619145551.189,michael.20060619145551.149,michael.20060623154957.5,michael.20060619145551.190,michael.20060619145551.192,michael.20060619145551.193,michael.20060619150055,michael.20060619145551.195,michael.20060619145551.196,michael.20060619145551.197,michael.20060619145551.198,michael.20060621123928,michael.20060619145551.201,michael.20060619145551.202,michael.20060619145551.218,michael.20060619145551.219,michael.20060619145551.220,michael.20060619145551.221,michael.20060619145551.222,michael.20060619145551.223,michael.20060619145551.224,michael.20060619145551.225,michael.20060619145551.226,michael.20060619145551.227,michael.20060619145551.228,michael.20060619145551.229,michael.20061129124501,michael.20060619145551.230,michael.20060619145551.231,michael.20060619145551.232,michael.20060619145551.233,michael.20060619151509,michael.20060619151509.1,michael.20060619151509.2,michael.20060619151509.3,michael.20060619151846"><vh>@file task.py</vh>
24 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
25 <v t="michael.20060619145551.1"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
26 <v t="michael.20060619145930"><vh>Exceptions</vh>
27 <v t="michael.20060619145551.4"><vh>class AttributeError</vh>
28 <v t="michael.20060619145551.5"><vh>&lt;&lt; class AttributeError declarations &gt;&gt;</vh></v>
29 </v>
30 <v t="michael.20060619145551.6"><vh>class RecursionError</vh>
31 <v t="michael.20060619145551.7"><vh>&lt;&lt; class RecursionError declarations &gt;&gt;</vh></v>
32 </v>
33 <v t="michael.20060619145551.8"><vh>class _IncompleteError</vh>
34 <v t="michael.20060619145551.9"><vh>__init__</vh></v>
35 </v>
36 </v>
37 <v t="michael.20060619145930.1"><vh>Proxies for self referencing</vh>
38 <v t="michael.20060619145551.10"><vh>class _MeProxy</vh>
39 <v t="michael.20060619145551.11"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
40 <v t="michael.20060619145551.12"><vh>__init__</vh></v>
41 <v t="michael.20060619145551.13"><vh>__getattr__</vh></v>
42 <v t="michael.20060619145551.14"><vh>__setattr__</vh></v>
43 <v t="michael.20061119143304"><vh>__iter__</vh></v>
44 <v t="michael.20060619145551.15"><vh>add_attrib</vh></v>
45 </v>
46 <v t="michael.20060619145551.16"><vh>class _MeProxyRecalc</vh>
47 <v t="michael.20060619145551.17"><vh>__setattr__</vh></v>
48 </v>
49 <v t="michael.20060619145551.18"><vh>class _MeProxyError</vh>
50 <v t="michael.20060619145551.19"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
51 <v t="michael.20060619145551.20"><vh>__init__</vh></v>
52 <v t="michael.20060619145551.21"><vh>__setattr__</vh></v>
53 </v>
54 <v t="michael.20060619145551.22"><vh>class _MeProxyWarn</vh>
55 <v t="michael.20060619145551.23"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
56 <v t="michael.20060619145551.24"><vh>__init__</vh></v>
57 <v t="michael.20060619145551.25"><vh>__setattr__</vh></v>
58 </v>
59 </v>
60 <v t="michael.20060619150413"><vh>Task instrumentation</vh>
61 <v t="michael.20060619145551.30"><vh>_int_to_arg</vh></v>
62 <v t="michael.20060619145551.31"><vh>_correct_labels</vh>
63 <v t="michael.20060623161820"><vh>&lt;&lt; localize dot variables &gt;&gt;</vh></v>
64 <v t="michael.20060623161820.1"><vh>&lt;&lt; loop initialization &gt;&gt;</vh></v>
65 <v t="michael.20060623161820.2"><vh>&lt;&lt; add label if necessary &gt;&gt;</vh></v>
66 </v>
67 <v t="michael.20060619145551.32" a="M"><vh>_instrument</vh>
68 <v t="michael.20060623160939"><vh>&lt;&lt; localize dot variables &gt;&gt;</vh></v>
69 <v t="michael.20060623160939.1"><vh>&lt;&lt; define local functions list_to_dict and is_local &gt;&gt;</vh></v>
70 <v t="michael.20060623160939.3" a="M"><vh>&lt;&lt; loop initialization &gt;&gt;</vh></v>
71 <v t="michael.20060623160939.4"><vh>&lt;&lt; calculate new tab point &gt;&gt;</vh></v>
72 <v t="michael.20060623160939.5"><vh>&lt;&lt; calculate argument &gt;&gt;</vh></v>
73 <v t="michael.20060623160939.6"><vh>&lt;&lt; change "store fast" to "store attribute" &gt;&gt;</vh></v>
74 <v t="michael.20060623160939.7"><vh>&lt;&lt; change "load fast" to "load attribute" &gt;&gt;</vh></v>
75 <v t="michael.20060623160939.8"><vh>&lt;&lt; create new code and function objects and return &gt;&gt;</vh></v>
76 </v>
77 </v>
78 <v t="michael.20060619150413.1"><vh>Wrappers</vh>
79 <v t="michael.20060619145551.26"><vh>class _Path</vh>
80 <v t="michael.20060619145551.27"><vh>__init__</vh></v>
81 <v t="michael.20060619145551.28"><vh>__getattr__</vh></v>
82 <v t="michael.20060619145551.29"><vh>__str__</vh></v>
83 <v t="michael.20061119143714"><vh>__iter__</vh></v>
84 </v>
85 <v t="michael.20060619145551.35"><vh>_val</vh></v>
86 <v t="michael.20060619145551.36"><vh>_ref</vh></v>
87 <v t="michael.20060619145551.37"><vh>_sref</vh></v>
88 <v t="michael.20061109181208"><vh>_refsum</vh></v>
89 <v t="michael.20060619145551.38"><vh>class _ValueWrapper</vh>
90 <v t="michael.20060619145551.39"><vh>__init__</vh></v>
91 <v t="michael.20070115204524" a="M"><vh>unicode</vh></v>
92 <v t="michael.20060619145551.40"><vh>_vw</vh></v>
93 <v t="michael.20060619145551.41"><vh>_cmp</vh></v>
94 <v t="michael.20060619145551.42"><vh>__getattr__</vh></v>
95 <v t="michael.20061123163317"><vh>__getitem__</vh></v>
96 <v t="michael.20060619145551.43"><vh>__str__</vh></v>
97 <v t="michael.20070115161719"><vh>__unicode__</vh></v>
98 <v t="michael.20060619145551.44"><vh>__repr__</vh></v>
99 <v t="michael.20060619145551.45"><vh>__nonzero__</vh></v>
100 <v t="michael.20060619145551.46"><vh>__lt__</vh></v>
101 <v t="michael.20060619145551.47"><vh>__le__</vh></v>
102 <v t="michael.20060619145551.48"><vh>__eq__</vh></v>
103 <v t="michael.20060619145551.49"><vh>__ne__</vh></v>
104 <v t="michael.20060619145551.50"><vh>__gt__</vh></v>
105 <v t="michael.20060619145551.51"><vh>__ge__</vh></v>
106 <v t="michael.20060619145551.52"><vh>__add__</vh></v>
107 <v t="michael.20060619145551.53"><vh>__sub__</vh></v>
108 <v t="michael.20060619145551.54"><vh>__mul__</vh></v>
109 <v t="michael.20060619145551.55"><vh>__floordiv__</vh></v>
110 <v t="michael.20060619145551.56"><vh>__mod__</vh></v>
111 <v t="michael.20060619145551.57"><vh>__divmod__</vh></v>
112 <v t="michael.20060619145551.58"><vh>__pow__</vh></v>
113 <v t="michael.20060619145551.59"><vh>__lshift__</vh></v>
114 <v t="michael.20060619145551.60"><vh>__rshift__</vh></v>
115 <v t="michael.20060619145551.61"><vh>__and__</vh></v>
116 <v t="michael.20060619145551.62"><vh>__xor__</vh></v>
117 <v t="michael.20060619145551.63"><vh>__or__</vh></v>
118 <v t="michael.20060619145551.64"><vh>__div__</vh></v>
119 <v t="michael.20060619145551.65"><vh>__radd__</vh></v>
120 <v t="michael.20060619145551.66"><vh>__rsub__</vh></v>
121 <v t="michael.20060619145551.67"><vh>__rmul__</vh></v>
122 <v t="michael.20060619145551.68"><vh>__rdiv__</vh></v>
123 <v t="michael.20060619145551.69"><vh>__rtruediv__</vh></v>
124 <v t="michael.20060619145551.70"><vh>__rfloordiv__</vh></v>
125 <v t="michael.20060619145551.71"><vh>__rmod__</vh></v>
126 <v t="michael.20060619145551.72"><vh>__rdivmod__</vh></v>
127 <v t="michael.20060619145551.73"><vh>__rpow__</vh></v>
128 <v t="michael.20060619145551.74"><vh>__rlshift__</vh></v>
129 <v t="michael.20060619145551.75"><vh>__rrshift__</vh></v>
130 <v t="michael.20060619145551.76"><vh>__rand__</vh></v>
131 <v t="michael.20060619145551.77"><vh>__rxor__</vh></v>
132 <v t="michael.20060619145551.78"><vh>__ror__</vh></v>
133 <v t="michael.20060619145551.79"><vh>__int__</vh></v>
134 <v t="michael.20060619145551.80"><vh>__long__</vh></v>
135 <v t="michael.20060619145551.81"><vh>__float__</vh></v>
136 <v t="michael.20060619145551.82"><vh>__len__</vh></v>
137 <v t="michael.20060619145551.83"><vh>__iter__</vh></v>
138 <v t="michael.20060619145551.84"><vh>__hash__</vh></v>
139 </v>
140 </v>
141 <v t="michael.20060619150519"><vh>Utilities</vh>
142 <v t="michael.20060619145551.2"><vh>class _NEVER_USED_</vh></v>
143 <v t="michael.20060619145551.85"><vh>class _StringConverter</vh>
144 <v t="michael.20060619145551.86"><vh>__init__</vh></v>
145 <v t="michael.20060619145551.87"><vh>__getitem__</vh></v>
146 <v t="michael.20060619145551.88"><vh>__getattr__</vh></v>
147 </v>
148 <v t="michael.20060619145551.107"><vh>Multi</vh></v>
149 <v t="michael.20060915184406" a="M"><vh>create_relative_path</vh></v>
150 <v t="michael.20060915190443" a="M"><vh>create_absolute_path</vh></v>
151 <v t="michael.20060619145551.106"><vh>_split_path</vh></v>
152 <v t="michael.20060915184406.1"><vh>_to_datetime</vh></v>
153 <v t="michael.20060619145551.108"><vh>_get_tasks_of_sources</vh></v>
154 <v t="michael.20060619145551.109"><vh>_build_balancing_list</vh>
155 <v t="michael.20061118232041" a="M"><vh>&lt;&lt; define inspect_depends_on &gt;&gt;</vh></v>
156 </v>
157 <v t="michael.20060619145551.110"><vh>_as_string</vh></v>
158 <v t="michael.20060619145551.111"><vh>_step_tasks</vh></v>
159 </v>
160 <v t="michael.20060930013205"><vh>Cache</vh></v>
161 <v t="michael.20060619145930.2"><vh>Resource Allocators</vh>
162 <v t="michael.20070112120451"><vh>VariableLoad</vh></v>
163 <v t="michael.20060619145551.33"><vh>_calc_load</vh></v>
164 <v t="michael.20060619145551.34"><vh>_calc_maxload</vh></v>
165 <v t="michael.20060619145551.89"><vh>class AllocationAlgorithm</vh>
166 <v t="michael.20060619145551.90"><vh>test_allocation</vh></v>
167 <v t="michael.20060619145551.91"><vh>allocate</vh></v>
168 </v>
169 <v t="michael.20060619145551.92"><vh>class StrictAllocator</vh>
170 <v t="michael.20060619145551.93"><vh>_distribute_len_loads</vh></v>
171 <v t="michael.20060619145551.94"><vh>test_allocation</vh>
172 <v t="michael.20060814190211"><vh>&lt;&lt; correct length &gt;&gt;</vh></v>
173 <v t="michael.20060814190211.1"><vh>&lt;&lt; correct duration &gt;&gt;</vh></v>
174 <v t="michael.20060814190211.2"><vh>&lt;&lt; check end &gt;&gt;</vh></v>
175 <v t="michael.20060814190211.3"><vh>&lt;&lt; correct effort and (re)calculate length &gt;&gt;</vh></v>
176 <v t="michael.20060814190211.4"><vh>&lt;&lt; set adjust_date and delta &gt;&gt;</vh></v>
177 </v>
178 <v t="michael.20060619145551.95"><vh>allocate</vh></v>
179 <v t="michael.20060619145551.96"><vh>balance</vh></v>
180 </v>
181 <v t="michael.20060619145551.97"><vh>class SmartAllocator</vh>
182 <v t="michael.20060619145551.98" a="M"><vh>balance</vh></v>
183 </v>
184 <v t="michael.20060619145551.99"><vh>class SloppyAllocator</vh>
185 <v t="michael.20060619145551.100"><vh>test_allocation</vh></v>
186 <v t="michael.20060619145551.101"><vh>test_allocation_length</vh></v>
187 <v t="michael.20060619145551.102"><vh>test_allocation_effort</vh></v>
188 <v t="michael.20060619145551.103"><vh>allocate</vh></v>
189 <v t="michael.20060619145551.104"><vh>allocate_length</vh></v>
190 <v t="michael.20060619145551.105"><vh>allocate_effort</vh></v>
191 </v>
192 </v>
193 <v t="michael.20060619145930.3"><vh>Load Calculators</vh>
194 <v t="michael.20060619145551.115"><vh>YearlyMax</vh>
195 <v t="michael.20061027121652"><vh>&lt;&lt; calculate calendar and time_diff &gt;&gt;</vh></v>
196 </v>
197 <v t="michael.20060619145551.117"><vh>WeeklyMax</vh>
198 <v t="michael.20061027121652"><vh>&lt;&lt; calculate calendar and time_diff &gt;&gt;</vh></v>
199 </v>
200 <v t="michael.20060619145551.119"><vh>MonthlyMax</vh>
201 <v t="michael.20061027121652"><vh>&lt;&lt; calculate calendar and time_diff &gt;&gt;</vh></v>
202 </v>
203 <v t="michael.20060619145551.121"><vh>DailyMax</vh>
204 <v t="michael.20061027121652"><vh>&lt;&lt; calculate calendar and time_diff &gt;&gt;</vh></v>
205 </v>
206 </v>
207 <v t="michael.20060619150542"><vh>Task</vh>
208 <v t="michael.20060619145551.123"><vh>class _TaskProperty</vh>
209 <v t="michael.20060619145551.124"><vh>__init__</vh></v>
210 <v t="michael.20060619145551.125"><vh>__get__</vh></v>
211 </v>
212 <v t="michael.20060619145551.126"><vh>class _RoundingTaskProperty</vh>
213 <v t="michael.20060619145551.127"><vh>__init__</vh></v>
214 <v t="michael.20060619145551.128"><vh>__get__</vh></v>
215 </v>
216 <v t="michael.20060619145551.129"><vh>class Task</vh>
217 <v t="michael.20060720224306" a="M"><vh>&lt;&lt; description &gt;&gt;</vh></v>
218 <v t="michael.20060619145551.130"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
219 <v t="michael.20060619145551.131"><vh>__init__</vh></v>
220 <v t="michael.20060619145551.132"><vh>__iter__</vh></v>
221 <v t="michael.20060619145551.133"><vh>__repr__</vh></v>
222 <v t="michael.20060619145551.134"><vh>__cmp__</vh></v>
223 <v t="michael.20060619145551.194"><vh>__getattr__</vh></v>
224 <v t="michael.20060619145551.135"><vh>_idendity_</vh></v>
225 <v t="michael.20061027224620" a="M"><vh>_set_hook</vh></v>
226 <v t="michael.20060623154957"><vh>Public methods</vh>
227 <v t="michael.20060619145551.136"><vh>to_string</vh></v>
228 <v t="michael.20060619145551.137"><vh>indent_name</vh></v>
229 <v t="michael.20060619145551.138"><vh>costs</vh></v>
230 <v t="michael.20060619145551.139"><vh>sum</vh></v>
231 <v t="michael.20060619145551.140"><vh>min</vh></v>
232 <v t="michael.20060619145551.141"><vh>max</vh></v>
233 <v t="michael.20060619145551.144"><vh>all_resources</vh></v>
234 <v t="michael.20060619145551.148"><vh>get_task</vh></v>
235 <v t="michael.20060619145551.150"><vh>snapshot</vh></v>
236 <v t="michael.20060619145551.142"><vh>is_inherited</vh></v>
237 <v t="michael.20060619145551.143"><vh>formatter</vh></v>
238 </v>
239 <v t="michael.20060623154957.1"><vh>Resource allocation Methods</vh>
240 <v t="michael.20060619145551.146"><vh>_all_resources_as_dict</vh></v>
241 <v t="michael.20060619145551.151"><vh>_test_allocation</vh></v>
242 <v t="michael.20060619145551.152"><vh>_allocate</vh></v>
243 <v t="michael.20060619145551.187"><vh>_convert_performed</vh></v>
244 <v t="michael.20060619145551.188"><vh>_allocate_performed</vh></v>
245 <v t="michael.20060619145551.147"><vh>_iter_booked_resources</vh></v>
246 </v>
247 <v t="michael.20060623154957.2"><vh>Compile Methods</vh>
248 <v t="michael.20060619145551.153"><vh>_generate</vh></v>
249 <v t="michael.20060619145551.154"><vh>_recalc_properties</vh></v>
250 <v t="michael.20060619145551.155"><vh>_compile</vh>
251 <v t="michael.20060713212925"><vh>&lt;&lt; raise child recursion error &gt;&gt;</vh></v>
252 </v>
253 <v t="michael.20060619145551.156"><vh>__compile_function</vh>
254 <v t="michael.20061027120904" a="M"><vh>&lt;&lt; set function global values &gt;&gt;</vh></v>
255 <v t="michael.20061027120904.2"><vh>&lt;&lt; set me in global functions &gt;&gt;</vh></v>
256 <v t="michael.20061027120904.3" a="M"><vh>&lt;&lt; eval function &gt;&gt;</vh></v>
257 </v>
258 </v>
259 <v t="michael.20060623154040"><vh>Setting methods</vh>
260 <v t="michael.20060619145551.159" a="M"><vh>_set_attrib</vh>
261 <v t="michael.20061109182534"><vh>&lt;&lt; add child task &gt;&gt;</vh></v>
262 <v t="michael.20061109182534.1"><vh>&lt;&lt; set standard attribute &gt;&gt;</vh></v>
263 <v t="michael.20061109182534.2"><vh>&lt;&lt; set userdefined attribute &gt;&gt;</vh></v>
264 </v>
265 <v t="michael.20061121143813"><vh>read only attributes</vh>
266 <v t="michael.20060619145551.160"><vh>_set_name</vh></v>
267 <v t="michael.20061121143813.1"><vh>_set_done</vh></v>
268 <v t="michael.20061121143813.2"><vh>_set_performed_work_time</vh></v>
269 <v t="michael.20061121143813.3"><vh>_set_booked_resource</vh></v>
270 <v t="michael.20061121143813.4"><vh>_set_performed_effort</vh></v>
271 <v t="michael.20061121143813.5"><vh>_set_children</vh></v>
272 <v t="michael.20061121143813.6"><vh>_set_depth</vh></v>
273 <v t="michael.20061121143813.7"><vh>_set_index</vh></v>
274 <v t="michael.20061121143813.8"><vh>_set_scenario</vh></v>
275 <v t="michael.20061121143813.9"><vh>_set_buffer</vh></v>
276 </v>
277 <v t="michael.20060619145551.161"><vh>_set_start</vh></v>
278 <v t="michael.20060619145551.162"><vh>_set_end</vh></v>
279 <v t="michael.20060619145551.163"><vh>_set_max_load</vh></v>
280 <v t="michael.20060619145551.164"><vh>_set_load</vh></v>
281 <v t="michael.20060619145551.165"><vh>_set_length</vh></v>
282 <v t="michael.20060619145551.166"><vh>_set_effort</vh></v>
283 <v t="michael.20060619145551.167"><vh>_set_duration</vh></v>
284 <v t="michael.20060619145551.168"><vh>_set_complete</vh></v>
285 <v t="michael.20060619145551.169"><vh>_set_done</vh></v>
286 <v t="michael.20060619145551.170"><vh>_set_todo</vh></v>
287 <v t="michael.20060619145551.171"><vh>_set_milestone</vh></v>
288 <v t="michael.20060619145551.172"><vh>_set_resource</vh></v>
289 <v t="michael.20060619145551.173"><vh>_set_copy_src</vh></v>
290 <v t="michael.20060619145551.191" a="M"><vh>__set_sources</vh>
291 <v t="michael.20061109182534.3" a="M"><vh>&lt;&lt; find references &gt;&gt;</vh></v>
292 </v>
293 <v t="michael.20060724150058"><vh>Calendar Setters</vh>
294 <v t="michael.20060724135631"><vh>_set_calendar</vh></v>
295 <v t="michael.20060619145551.200"><vh>__renew_dates</vh></v>
296 <v t="michael.20060724164954"><vh>__make_calendar</vh></v>
297 <v t="michael.20060619145551.204"><vh>_set_vacation</vh></v>
298 <v t="michael.20060619145551.205"><vh>_set_extra_work</vh></v>
299 <v t="michael.20060619145551.206" a="M"><vh>_set_working_days</vh></v>
300 <v t="michael.20060619145551.208"><vh>_set_minimum_time_unit</vh></v>
301 <v t="michael.20060619145551.209"><vh>_get_minimum_time_unit</vh></v>
302 <v t="michael.20060619145551.210"><vh>_set_working_days_per_week</vh></v>
303 <v t="michael.20060619145551.211"><vh>_get_working_days_per_week</vh></v>
304 <v t="michael.20060619145551.212"><vh>_set_working_days_per_month</vh></v>
305 <v t="michael.20060619145551.213"><vh>_get_working_days_per_month</vh></v>
306 <v t="michael.20060619145551.214"><vh>_set_working_days_per_year</vh></v>
307 <v t="michael.20060619145551.215"><vh>_get_working_days_per_year</vh></v>
308 <v t="michael.20060619145551.216"><vh>_set_working_hours_per_day</vh></v>
309 <v t="michael.20060619145551.217"><vh>_get_working_hours_per_day</vh></v>
310 <v t="michael.20060619145551.207"><vh>_set_now</vh></v>
311 </v>
312 </v>
313 <v t="michael.20060623154957.3"><vh>Freezer Methods</vh>
314 <v t="michael.20060619145551.145"><vh>_unfreeze</vh></v>
315 <v t="michael.20060619145551.174"><vh>_wrap_attrib</vh></v>
316 <v t="michael.20060619145551.175"><vh>_find_frozen</vh></v>
317 </v>
318 <v t="michael.20060623154040.1"><vh>Calculation Methods</vh>
319 <v t="michael.20061230152555"><vh>__calc_performed_effort</vh></v>
320 <v t="michael.20061201004146"><vh>__calc_estimated_effort</vh></v>
321 <v t="michael.20060619145551.177"><vh>__calc_start</vh>
322 <v t="michael.20060713212925"><vh>&lt;&lt; raise child recursion error &gt;&gt;</vh></v>
323 <v t="michael.20060623154040.2"><vh>&lt;&lt; raise recursion error &gt;&gt;</vh></v>
324 </v>
325 <v t="michael.20060619145551.178"><vh>__calc_end</vh>
326 <v t="michael.20060713212925"><vh>&lt;&lt; raise child recursion error &gt;&gt;</vh></v>
327 <v t="michael.20060623154040.2"><vh>&lt;&lt; raise recursion error &gt;&gt;</vh></v>
328 </v>
329 <v t="michael.20060619145551.179"><vh>__calc_load</vh></v>
330 <v t="michael.20060619145551.180"><vh>__calc_length</vh></v>
331 <v t="michael.20060619145551.181"><vh>__calc_duration</vh></v>
332 <v t="michael.20060619145551.182"><vh>__calc_effort</vh></v>
333 <v t="michael.20060619145551.183"><vh>__calc_done</vh></v>
334 <v t="michael.20060619145551.184"><vh>__calc_buffer</vh>
335 <v t="michael.20060619153005"><vh>&lt;&lt; find all tasks, that depend on my end &gt;&gt;</vh></v>
336 <v t="michael.20060619153005.1"><vh>&lt;&lt; define unfreeze_parents &gt;&gt;</vh></v>
337 <v t="michael.20060619153005.2"><vh>&lt;&lt; calculate buffer to descendant 'd' &gt;&gt;</vh></v>
338 </v>
339 <v t="michael.20060619145551.185"><vh>__calc_complete</vh></v>
340 <v t="michael.20060619145551.186"><vh>__calc_todo</vh></v>
341 </v>
342 <v t="michael.20060623154957.4"><vh>Check Methods</vh>
343 <v t="michael.20060619145551.157"><vh>__check_task</vh></v>
344 <v t="michael.20060619145551.158"><vh>__check_milestone</vh></v>
345 <v t="michael.20060619145551.189"><vh>_check_completion</vh></v>
346 <v t="michael.20060619145551.149"><vh>check</vh></v>
347 </v>
348 <v t="michael.20060623154957.5"><vh>Error Methods</vh>
349 <v t="michael.20060619145551.190"><vh>__assert</vh></v>
350 <v t="michael.20060619145551.192"><vh>_warn</vh></v>
351 <v t="michael.20060619145551.193"><vh>_raise</vh></v>
352 </v>
353 </v>
354 </v>
355 <v t="michael.20060619150055"><vh>Projects</vh>
356 <v t="michael.20060619145551.195"><vh>class _ProjectBase</vh>
357 <v t="michael.20060619145551.196"><vh>&lt;&lt; class _ProjectBase declarations &gt;&gt;</vh></v>
358 <v t="michael.20060619145551.197"><vh>__init__</vh></v>
359 <v t="michael.20060619145551.198"><vh>_idendity_</vh></v>
360 <v t="michael.20060621123928" a="M"><vh>_restore_globals</vh></v>
361 <v t="michael.20060619145551.201"><vh>free</vh></v>
362 <v t="michael.20060619145551.202"><vh>_get_balancing_list</vh></v>
363 <v t="michael.20060619145551.218"><vh>snapshot</vh></v>
364 </v>
365 <v t="michael.20060619145551.219"><vh>class Project</vh>
366 <v t="michael.20060619145551.220"><vh>&lt;&lt; class Project declarations &gt;&gt;</vh></v>
367 <v t="michael.20060619145551.221"><vh>__init__</vh></v>
368 </v>
369 <v t="michael.20060619145551.222"><vh>class _AllocationPoject</vh>
370 <v t="michael.20060619145551.223"><vh>unfreeze_parents</vh></v>
371 </v>
372 <v t="michael.20060619145551.224"><vh>class BalancedProject</vh>
373 <v t="michael.20060619145551.225"><vh>&lt;&lt; class BalancedProject declarations &gt;&gt;</vh></v>
374 <v t="michael.20060619145551.226"><vh>__init__</vh></v>
375 <v t="michael.20060619145551.227"><vh>allocate_snapshot</vh></v>
376 <v t="michael.20060619145551.228"><vh>allocate</vh></v>
377 <v t="michael.20060619145551.229" a="M"><vh>_distribute_performed</vh>
378 <v t="michael.20061129124501"><vh>&lt;&lt; extract task in activity path &gt;&gt;</vh></v>
379 </v>
380 </v>
381 <v t="michael.20060619145551.230"><vh>class AdjustedProject</vh>
382 <v t="michael.20060619145551.231"><vh>&lt;&lt; class AdjustedProject declarations &gt;&gt;</vh></v>
383 <v t="michael.20060619145551.232"><vh>__init__</vh></v>
384 <v t="michael.20060619145551.233" a="M"><vh>allocate</vh>
385 <v t="michael.20060619151509"><vh>&lt;&lt; free the resources, we have to rebook &gt;&gt;</vh></v>
386 <v t="michael.20060619151509.1"><vh>&lt;&lt; copy the attribs of complete tasks &gt;&gt;</vh></v>
387 <v t="michael.20060619151509.2"><vh>&lt;&lt; allocate performed data &gt;&gt;</vh></v>
388 <v t="michael.20060619151509.3" a="M"><vh>&lt;&lt; allocate tasks, that have not begun yet &gt;&gt;</vh></v>
389 <v t="michael.20060619151846"><vh>&lt;&lt; allocate tasks, that are allready at work &gt;&gt;</vh></v>
390 </v>
391 </v>
392 </v>
393 </v>
394 <v t="michael.20060619191608" tnodeList="michael.20060619191608,mr7771.20060609151433,michael.20060619191608.1,michael.20060619191608.2,michael.20060619191608.3,michael.20060619191608.4,michael.20060619191608.5,michael.20060619191608.6,michael.20060619191608.7,michael.20060619191608.8,michael.20060619191608.9,michael.20060619191608.10,michael.20060619191608.11,michael.20070117163707,michael.20060619191608.12,michael.20060619191608.13,michael.20060619191608.14,michael.20060619191608.15,michael.20060619191608.16,michael.20060619191608.17,michael.20060619191608.18,michael.20060619191608.19,michael.20060619191608.20,michael.20060619191608.21,michael.20060619191608.22,michael.20060619191608.23,michael.20060619191608.24,michael.20060619191608.25,michael.20060619191608.26,michael.20060619191608.27,michael.20060619191608.28,michael.20060619191608.32,michael.20060619191608.33,michael.20060619191608.34,michael.20060619191608.35,michael.20060619191608.29,michael.20070115204909,michael.20060619191608.30,michael.20060619191608.31,michael.20060619191608.36,michael.20060619191608.37,michael.20060619191608.38,michael.20060619191608.39,michael.20060619191608.40,michael.20060619191608.41,michael.20060619191608.42,michael.20060619191608.43,michael.20060619191608.44,michael.20060619191608.45"><vh>@file report.py</vh>
395 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
396 <v t="michael.20060619191608.1"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
397 <v t="michael.20060619191608.2"><vh>Private</vh>
398 <v t="michael.20060619191608.3"><vh>_val</vh></v>
399 <v t="michael.20060619191608.4"><vh>_has_ref</vh></v>
400 <v t="michael.20060619191608.5"><vh>class _ReportValueWrapper</vh>
401 <v t="michael.20060619191608.6"><vh>__init__</vh></v>
402 <v t="michael.20060619191608.7"><vh>_vw</vh></v>
403 <v t="michael.20060619191608.8"><vh>_cmp</vh></v>
404 <v t="michael.20060619191608.9"><vh>__call__</vh></v>
405 <v t="michael.20060619191608.10"><vh>__repr__</vh></v>
406 <v t="michael.20060619191608.11"><vh>type</vh></v>
407 <v t="michael.20070117163707" a="M"><vh>unicode</vh></v>
408 </v>
409 <v t="michael.20060619191608.12"><vh>class _TaskWrapper</vh>
410 <v t="michael.20060619191608.13"><vh>__init__</vh></v>
411 <v t="michael.20060619191608.14"><vh>__getattr__</vh></v>
412 <v t="michael.20060619191608.15"><vh>__iter__</vh></v>
413 <v t="michael.20060619191608.16"><vh>__str__</vh></v>
414 </v>
415 <v t="michael.20060619191608.17"><vh>class _ToStringWrapper</vh>
416 <v t="michael.20060619191608.18"><vh>__init__</vh></v>
417 <v t="michael.20060619191608.19"><vh>__getattr__</vh></v>
418 <v t="michael.20060619191608.20"><vh>__getitem__</vh></v>
419 </v>
420 <v t="michael.20060619191608.21"><vh>class _ReportIter</vh>
421 <v t="michael.20060619191608.22"><vh>__init__</vh></v>
422 <v t="michael.20060619191608.23"><vh>__iter__</vh></v>
423 <v t="michael.20060619191608.24"><vh>next</vh></v>
424 </v>
425 </v>
426 <v t="michael.20060619191608.25"><vh>Public</vh>
427 <v t="michael.20060619191608.26" a="M"><vh>class Cell</vh>
428 <v t="michael.20060619191608.27"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
429 <v t="michael.20060619191608.28"><vh>__init__</vh></v>
430 <v t="michael.20060619191608.32"><vh>__str__</vh></v>
431 <v t="michael.20060619191608.33"><vh>__unicode__</vh></v>
432 <v t="michael.20060619191608.34"><vh>__nonzero__</vh></v>
433 <v t="michael.20060619191608.35"><vh>__cmp__</vh></v>
434 <v t="michael.20060619191608.29"><vh>get_label</vh></v>
435 <v t="michael.20070115204909"><vh>unicode</vh></v>
436 <v t="michael.20060619191608.30"><vh>get_type</vh></v>
437 <v t="michael.20060619191608.31"><vh>get_ref</vh></v>
438 <v t="michael.20060619191608.36"><vh>native</vh></v>
439 </v>
440 <v t="michael.20060619191608.37"><vh>class Report</vh>
441 <v t="michael.20060619191608.38"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
442 <v t="michael.20060619191608.39"><vh>__init__</vh></v>
443 <v t="michael.20060619191608.40"><vh>_raise</vh></v>
444 <v t="michael.20060619191608.41"><vh>make_report</vh></v>
445 <v t="michael.20060619191608.42"><vh>prepare_data</vh></v>
446 <v t="michael.20060619191608.43"><vh>instrument_data</vh></v>
447 <v t="michael.20060619191608.44"><vh>modify_row</vh></v>
448 <v t="michael.20060619191608.45"><vh>__iter__</vh></v>
449 </v>
450 </v>
451 </v>
452 <v t="michael.20060622082846" tnodeList="michael.20060622082846,mr7771.20060609151433,michael.20060622082846.1,michael.20060622082846.2,michael.20060622082846.3,michael.20060822214147"><vh>@file observer.py</vh>
453 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
454 <v t="michael.20060622082846.1"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
455 <v t="michael.20060622082846.2"><vh>class Observer</vh>
456 <v t="michael.20060622082846.3"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
457 <v t="michael.20060822214147"><vh>register_editors</vh></v>
458 </v>
459 </v>
460 <v t="michael.20060626133545" tnodeList="michael.20060626133545,mr7771.20060609151433,michael.20060626133545.1,michael.20060626133545.2,michael.20060626133545.3,michael.20060626133545.4,michael.20060626133545.5,michael.20060626133545.6,michael.20060626133545.7,michael.20080106130453,michael.20060718000534,michael.20060718001417,michael.20060718001417.1,michael.20060718001417.2,michael.20060718005323,michael.20060718005402,michael.20060626133545.8,michael.20060626133545.9,michael.20060626133545.10,michael.20060626133545.11,michael.20060626133545.12,michael.20060626133545.13,michael.20060626133545.14,michael.20060626133545.15,michael.20060626133545.16,michael.20060626133545.17,michael.20060626133839,michael.20060626133545.18,michael.20060626133545.19,michael.20060626133545.20,michael.20060626133545.21,michael.20060626133545.22,michael.20060626133545.23,michael.20060626133545.24,michael.20060626133545.25,michael.20060626133545.26,michael.20060626133545.27,michael.20060626133545.28,michael.20060626133545.29,michael.20060626133545.30,michael.20060626133545.31,michael.20060626133545.32,michael.20060724142145,michael.20060724153604,michael.20060626133545.33,michael.20060626133545.34,michael.20060626133545.35,michael.20060626133545.37,michael.20060626133545.38,michael.20060626133545.39,michael.20060626133545.40,michael.20060626133545.41,michael.20060626133545.36,michael.20060626133545.42,michael.20060626133545.43"><vh>@file pcalendar.py</vh>
461 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
462 <v t="michael.20060626133545.1"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
463 <v t="michael.20060626133545.2"><vh>to_time_range</vh></v>
464 <v t="michael.20060626133545.3"><vh>to_datetime</vh></v>
465 <v t="michael.20060626133545.4"><vh>_to_days</vh></v>
466 <v t="michael.20060626133545.5"><vh>_add_to_time_spans</vh></v>
467 <v t="michael.20060626133545.6"><vh>to_timedelta</vh></v>
468 <v t="michael.20060626133545.7"><vh>timedelta_to_str</vh></v>
469 <v t="michael.20080106130453" a="M"><vh>strftime</vh></v>
470 <v t="michael.20060718000534" a="E"><vh>union</vh>
471 <v t="michael.20060718001417"><vh>&lt;&lt; check arguments &gt;&gt;</vh></v>
472 <v t="michael.20060718001417.1"><vh>&lt;&lt; intersect vacations &gt;&gt;</vh></v>
473 <v t="michael.20060718001417.2"><vh>&lt;&lt; unify extra worktime &gt;&gt;</vh></v>
474 <v t="michael.20060718005323"><vh>&lt;&lt; unify working times &gt;&gt;</vh></v>
475 <v t="michael.20060718005402"><vh>&lt;&lt; create result calendar &gt;&gt;</vh></v>
476 </v>
477 <v t="michael.20060626133545.8" a="E"><vh>class _CalendarItem</vh>
478 <v t="michael.20060626133545.9"><vh>&lt;&lt; class _CalendarItem declarations &gt;&gt;</vh></v>
479 <v t="michael.20060626133545.10"><vh>__new__</vh></v>
480 <v t="michael.20060626133545.11"><vh>round</vh></v>
481 </v>
482 <v t="michael.20060626133545.12"><vh>class _Minutes</vh>
483 <v t="michael.20060626133545.13"><vh>&lt;&lt; class _Minutes declarations &gt;&gt;</vh></v>
484 <v t="michael.20060626133545.14"><vh>__new__</vh></v>
485 <v t="michael.20060626133545.15"><vh>__cmp__</vh></v>
486 <v t="michael.20060626133545.16"><vh>__add__</vh></v>
487 <v t="michael.20060626133545.17"><vh>__sub__</vh></v>
488 <v t="michael.20060626133839"><vh>to_timedelta</vh></v>
489 <v t="michael.20060626133545.18"><vh>strftime</vh></v>
490 </v>
491 <v t="michael.20060626133545.19"><vh>class _WorkingDateBase</vh>
492 <v t="michael.20060626133545.20"><vh>&lt;&lt; class _WorkingDateBase declarations &gt;&gt;</vh></v>
493 <v t="michael.20060626133545.21"><vh>__new__</vh></v>
494 <v t="michael.20060626133545.22"><vh>__repr__</vh></v>
495 <v t="michael.20060626133545.23"><vh>to_datetime</vh></v>
496 <v t="michael.20060626133545.24"><vh>to_starttime</vh></v>
497 <v t="michael.20060626133545.25"><vh>to_endtime</vh></v>
498 <v t="michael.20060626133545.26"><vh>__cmp__</vh></v>
499 <v t="michael.20060626133545.27"><vh>__add__</vh></v>
500 <v t="michael.20060626133545.28"><vh>__sub__</vh></v>
501 <v t="michael.20060626133545.29"><vh>strftime</vh></v>
502 </v>
503 <v t="michael.20060626133545.30"><vh>class Calendar</vh>
504 <v t="michael.20060626133545.31"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
505 <v t="michael.20060626133545.32"><vh>__init__</vh></v>
506 <v t="michael.20060724142145"><vh>__or__</vh></v>
507 <v t="michael.20060724153604"><vh>clone</vh></v>
508 <v t="michael.20060626133545.33"><vh>set_working_days</vh></v>
509 <v t="michael.20060626133545.34"><vh>set_vacation</vh></v>
510 <v t="michael.20060626133545.35"><vh>set_extra_work</vh></v>
511 <v t="michael.20060626133545.37"><vh>from_datetime</vh></v>
512 <v t="michael.20060626133545.38"><vh>split_time</vh></v>
513 <v t="michael.20060626133545.39"><vh>to_starttime</vh></v>
514 <v t="michael.20060626133545.40"><vh>to_endtime</vh></v>
515 <v t="michael.20060626133545.41"><vh>get_working_times</vh></v>
516 <v t="michael.20060626133545.36"><vh>_build_mapping</vh></v>
517 <v t="michael.20060626133545.42"><vh>_recalc_working_time</vh></v>
518 <v t="michael.20060626133545.43"><vh>_make_classes</vh></v>
519 </v>
520 </v>
521 <v t="michael.20061026133329" tnodeList="michael.20061026133329,mr7771.20060609151433,michael.20061026133329.1,michael.20061026133329.2,michael.20061026133329.3,michael.20061026133329.4,michael.20061026133329.5,michael.20061026133329.6,michael.20061026133329.7,michael.20061026133329.8,michael.20061026133329.9,michael.20061026133329.10,michael.20061026133329.11,michael.20061026133329.12,michael.20061026133329.13,michael.20061026133329.14,michael.20061026133329.15,michael.20061026133329.16,michael.20061026133329.17,michael.20061026133329.18,michael.20061026133329.19,michael.20061026133329.20,michael.20061026133329.21,michael.20061026133329.22,michael.20061026133329.23,michael.20070710231245,michael.20061026133329.24,michael.20061026133329.25,michael.20061026133329.26,michael.20061026133329.27,michael.20061026133329.28,michael.20061026133329.29,michael.20061026133329.30,michael.20061026133329.31,michael.20061026133329.32,michael.20061026133329.33,michael.20061026133329.34,michael.20061026133329.35,michael.20061026133329.36,michael.20061026133329.37,michael.20061026133329.38,michael.20061026133329.39,michael.20061026133329.40,michael.20061026133329.41,michael.20061026133329.42,michael.20061026133329.43,michael.20061026133329.44,michael.20061026133329.45,michael.20061026133329.46,michael.20061026133329.47,michael.20061026133329.48,michael.20061026133329.49,michael.20061026133329.50,michael.20061026133329.51,michael.20061026133329.52,michael.20061026133329.53,michael.20061026133329.54,michael.20061026133329.55,michael.20061026133329.56,michael.20061026133329.57,michael.20061026133329.58,michael.20061026133329.59,michael.20061026133329.60,michael.20061026133329.61,michael.20061026133329.62,michael.20061026133329.63,michael.20061026133329.64,michael.20061026133329.65,michael.20061026133329.66,michael.20061026133329.67,michael.20061026133329.68,michael.20061026133329.69,michael.20061026133329.70,michael.20061026133329.71,michael.20061026133329.72,michael.20061026133329.73,michael.20061026133329.74,michael.20061026133329.75,michael.20061026133329.76"><vh>@file resource.py</vh>
522 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
523 <v t="michael.20061026133329.1"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
524 <v t="michael.20061026133329.2"><vh>_isattrib</vh></v>
525 <v t="michael.20061026133329.3"><vh>class ResourceCalendar</vh>
526 <v t="michael.20061026133329.4"><vh>__init__</vh></v>
527 <v t="michael.20061026133329.5"><vh>__str__</vh></v>
528 <v t="michael.20061026133329.6"><vh>__repr__</vh></v>
529 <v t="michael.20061026133329.7"><vh>add_load</vh></v>
530 <v t="michael.20061026133329.8"><vh>end_of_booking_interval</vh></v>
531 <v t="michael.20061026133329.9" a="M"><vh>find_free_time</vh></v>
532 <v t="michael.20061026133329.10"><vh>get_bookings</vh></v>
533 <v t="michael.20061026133329.11"><vh>get_load</vh></v>
534 </v>
535 <v t="michael.20061026133329.12"><vh>class _ResourceBase</vh></v>
536 <v t="michael.20061026133329.13"><vh>class _MetaResource</vh>
537 <v t="michael.20061026133329.14"><vh>__init__</vh></v>
538 <v t="michael.20061026133329.15"><vh>__or__</vh></v>
539 <v t="michael.20061026133329.16"><vh>__and__</vh></v>
540 <v t="michael.20061026133329.17"><vh>__cmp__</vh></v>
541 <v t="michael.20061026133329.18"><vh>__repr__</vh></v>
542 <v t="michael.20061026133329.19"><vh>__str__</vh></v>
543 <v t="michael.20061026133329.20"><vh>__set_vacation</vh></v>
544 <v t="michael.20061026133329.21"><vh>__add_resource</vh></v>
545 <v t="michael.20061026133329.22"><vh>get_members</vh></v>
546 <v t="michael.20061026133329.23"><vh>add_vacation</vh></v>
547 <v t="michael.20070710231245"><vh>calendar</vh></v>
548 </v>
549 <v t="michael.20061026133329.24"><vh>make_team</vh></v>
550 <v t="michael.20061026133329.25"><vh>class Booking</vh>
551 <v t="michael.20061026133329.26"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
552 <v t="michael.20061026133329.27"><vh>__init__</vh></v>
553 <v t="michael.20061026133329.28"><vh>__cmp__</vh></v>
554 <v t="michael.20061026133329.29"><vh>path</vh></v>
555 <v t="michael.20061026133329.30"><vh>_idendity_</vh></v>
556 <v t="michael.20061026133329.31"><vh>__getattr__</vh></v>
557 </v>
558 <v t="michael.20061026133329.32"><vh>class ResourceList</vh>
559 <v t="michael.20061026133329.33"><vh>__init__</vh></v>
560 </v>
561 <v t="michael.20061026133329.34"><vh>class Resource</vh>
562 <v t="michael.20061026133329.35"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
563 <v t="michael.20061026133329.36"><vh>__init__</vh></v>
564 <v t="michael.20061026133329.37"><vh>_idendity_</vh></v>
565 <v t="michael.20061026133329.38"><vh>__repr__</vh></v>
566 <v t="michael.20061026133329.39"><vh>__str__</vh></v>
567 <v t="michael.20061026133329.40"><vh>__call__</vh></v>
568 <v t="michael.20061026133329.41"><vh>__hash__</vh></v>
569 <v t="michael.20061026133329.42"><vh>__cmp__</vh></v>
570 <v t="michael.20061026133329.43"><vh>__or__</vh></v>
571 <v t="michael.20061026133329.44"><vh>__and__</vh></v>
572 <v t="michael.20061026133329.45"><vh>_permutation_count</vh></v>
573 <v t="michael.20061026133329.46"><vh>_get_resources</vh></v>
574 <v t="michael.20061026133329.47"><vh>all_members</vh></v>
575 <v t="michael.20061026133329.48"><vh>unbook_tasks_of_project</vh></v>
576 <v t="michael.20061026133329.49"><vh>unbook_task</vh></v>
577 <v t="michael.20061026133329.50"><vh>correct_bookings</vh></v>
578 <v t="michael.20061026133329.51"><vh>book_task</vh></v>
579 <v t="michael.20061026133329.52"><vh>length_of</vh></v>
580 <v t="michael.20061026133329.53"><vh>done_of</vh></v>
581 <v t="michael.20061026133329.54"><vh>todo_of</vh></v>
582 <v t="michael.20061026133329.55"><vh>get_bookings</vh></v>
583 <v t="michael.20061026133329.56"><vh>get_bookings_at</vh></v>
584 <v t="michael.20061026133329.57"><vh>find_free_time</vh></v>
585 <v t="michael.20061026133329.58"><vh>get_load</vh></v>
586 <v t="michael.20061026133329.59"><vh>end_of_booking_interval</vh></v>
587 <v t="michael.20061026133329.60"><vh>snapshot</vh></v>
588 </v>
589 <v t="michael.20061026133329.61"><vh>class _ResourceGroup</vh>
590 <v t="michael.20061026133329.62"><vh>__init__</vh></v>
591 <v t="michael.20061026133329.63"><vh>all_members</vh></v>
592 <v t="michael.20061026133329.64"><vh>_permutation_count</vh></v>
593 <v t="michael.20061026133329.65"><vh>_refactor</vh></v>
594 <v t="michael.20061026133329.66"><vh>__append</vh></v>
595 <v t="michael.20061026133329.67"><vh>__str__</vh></v>
596 </v>
597 <v t="michael.20061026133329.68"><vh>class _OrResourceGroup</vh>
598 <v t="michael.20061026133329.69"><vh>_get_resources</vh></v>
599 <v t="michael.20061026133329.70"><vh>_permutation_count</vh></v>
600 </v>
601 <v t="michael.20061026133329.71"><vh>class _AndResourceGroup</vh>
602 <v t="michael.20061026133329.72"><vh>__init__</vh></v>
603 <v t="michael.20061026133329.73"><vh>_refactor</vh></v>
604 <v t="michael.20061026133329.74"><vh>_permutation_count</vh></v>
605 <v t="michael.20061026133329.75"><vh>_get_resources</vh></v>
606 <v t="michael.20061026133329.76"><vh>_has_duplicates</vh></v>
607 </v>
608 </v>
609 </v>
610 <v t="mr7771.20060608164004.452"><vh>Library</vh>
611 <v t="michael.20060621125711" tnodeList="michael.20060621125711,mr7771.20060609151433"><vh>@file lib/__init__.py</vh>
612 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
613 </v>
614 <v t="michael.20060619193106" a="M" tnodeList="michael.20060619193106,mr7771.20060609151433,michael.20060619193106.1,michael.20060619193106.2,michael.20060828215008,michael.20060619193106.4,michael.20060619193106.5,michael.20060619193106.6,michael.20060619193106.7,michael.20060619193106.8,michael.20060619193106.9,michael.20060619193106.10,michael.20060901185516,michael.20060619193106.11,michael.20060619193106.12,michael.20060619193106.13,michael.20060619193106.14,michael.20060619200744,michael.20060619193106.15,michael.20060619193106.16,michael.20060619193106.17,michael.20060619193106.18,michael.20060619194944,michael.20060619194944.1,michael.20060619200005,michael.20060619200005.1,michael.20060619200005.2,michael.20060619193106.21,michael.20060619193106.22,michael.20060619193106.23,michael.20060619193106.24"><vh>@file lib/report.py</vh>
615 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
616 <v t="michael.20060619193106.1"><vh>&lt;&lt; imports &gt;&gt;</vh></v>
617 <v t="michael.20060619193106.2"><vh>class Standard</vh>
618 <v t="michael.20060828215008"><vh>register_editors</vh></v>
619 <v t="michael.20060619193106.4"><vh>make_report</vh></v>
620 </v>
621 <v t="michael.20060619193106.5"><vh>class Titles</vh>
622 <v t="michael.20060619193106.6"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
623 <v t="michael.20060619193106.7"><vh>modify_row</vh></v>
624 </v>
625 <v t="michael.20060619193106.8"><vh>class Critical</vh>
626 <v t="michael.20060619193106.9"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
627 <v t="michael.20060619193106.10"><vh>__init__</vh></v>
628 <v t="michael.20060901185516"><vh>register_editors</vh></v>
629 <v t="michael.20060619193106.11"><vh>modify_row</vh></v>
630 </v>
631 <v t="michael.20060619193106.12"><vh>class Calendar</vh>
632 <v t="michael.20060619193106.13"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
633 <v t="michael.20060619193106.14"><vh>instrument_data</vh>
634 <v t="michael.20060619200744"><vh>&lt;&lt; define insert_task &gt;&gt;</vh></v>
635 </v>
636 <v t="michael.20060619193106.15"><vh>get_dates</vh></v>
637 <v t="michael.20060619193106.16"><vh>make_cell</vh></v>
638 <v t="michael.20060619193106.17"><vh>modify_cell</vh></v>
639 <v t="michael.20060619193106.18" a="M"><vh>make_report</vh>
640 <v t="michael.20060619194944"><vh>&lt;&lt; define add_row &gt;&gt;</vh></v>
641 <v t="michael.20060619194944.1" a="M"><vh>&lt;&lt; define add_date &gt;&gt;</vh></v>
642 <v t="michael.20060619200005"><vh>&lt;&lt; create day header cells &gt;&gt;</vh></v>
643 <v t="michael.20060619200005.1"><vh>&lt;&lt; create day data cells &gt;&gt;</vh></v>
644 <v t="michael.20060619200005.2"><vh>&lt;&lt; adjust borders &gt;&gt;</vh></v>
645 </v>
646 <v t="michael.20060619193106.21" a="M"><vh>get_start_text</vh></v>
647 <v t="michael.20060619193106.22" a="M"><vh>get_end_text</vh></v>
648 <v t="michael.20060619193106.23"><vh>_create_columns</vh></v>
649 <v t="michael.20060619193106.24"><vh>_create_headers</vh></v>
650 </v>
651 </v>
652 <v t="michael.20060619225419" tnodeList="michael.20060619225419,mr7771.20060609151433,michael.20060619225419.1,michael.20060619225419.2,michael.20060619225419.3,michael.20060619225419.4,michael.20060804153528,michael.20060619225419.5,michael.20060619225419.6,michael.20060619225419.8,michael.20060619225419.9,michael.20060619225419.11,michael.20060619225419.12,michael.20060804154418,michael.20060619225419.7,michael.20060619225419.10,michael.20060619225419.13,michael.20060619225419.14,michael.20060619225419.15,michael.20060619225419.16,michael.20060804154418.1,michael.20060619225419.17,michael.20060619225419.18,michael.20060619225419.19,michael.20060619225419.20,michael.20060619225419.21,michael.20060619230125,michael.20060804154418.2,michael.20060804154609,michael.20060619225419.22,michael.20060619225419.23,michael.20060804163807,michael.20060619225419.24,michael.20060619225419.25,michael.20060619225419.26,michael.20060619225419.27,michael.20060804154017,michael.20060619225419.28"><vh>@file lib/gantt.py</vh>
653 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
654 <v t="michael.20060619225419.1"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
655 <v t="michael.20060619225419.2"><vh>&lt;&lt; Declarations &gt;&gt;</vh></v>
656 <v t="michael.20060619225419.3"><vh>class Gantt</vh>
657 <v t="michael.20060619225419.4"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
658 <v t="michael.20060619230125"><vh>&lt;&lt; set __all__ attribute &gt;&gt;</vh></v>
659 <v t="michael.20060804153528" a="M"><vh>register_editors</vh></v>
660 <v t="michael.20060619225419.5"><vh>create_all_widgets</vh></v>
661 <v t="michael.20060619225419.6"><vh>create_objects</vh></v>
662 <v t="michael.20060619225419.8"><vh>get_property_group</vh></v>
663 <v t="michael.20060619225419.9"><vh>calc_title</vh></v>
664 <v t="michael.20060619225419.11"><vh>create_widget</vh></v>
665 <v t="michael.20060619225419.12"><vh>modify_widget</vh></v>
666 <v t="michael.20060804154418"><vh>Shape Methods</vh>
667 <v t="michael.20060619225419.7"><vh>get_shape_name</vh></v>
668 <v t="michael.20060619225419.10"><vh>make_shape</vh></v>
669 <v t="michael.20060619225419.13"><vh>make_combined_shape</vh></v>
670 <v t="michael.20060619225419.14"><vh>make_symbol_shape</vh></v>
671 <v t="michael.20060619225419.15"><vh>make_bar_shape</vh></v>
672 <v t="michael.20060619225419.16"><vh>make_brace_shape</vh></v>
673 </v>
674 <v t="michael.20060804154418.1"><vh>Connector Methods</vh>
675 <v t="michael.20060619225419.17"><vh>find_path</vh></v>
676 <v t="michael.20060619225419.18"><vh>create_connectors</vh></v>
677 <v t="michael.20060619225419.19"><vh>modify_connector</vh></v>
678 </v>
679 <v t="michael.20060619225419.20"><vh>get_tip</vh></v>
680 <v t="michael.20060619225419.21"><vh>get_task_tip</vh></v>
681 </v>
682 <v t="michael.20060804154418.2"><vh>class Standard</vh>
683 <v t="michael.20060804154609"><vh>register_editors</vh></v>
684 </v>
685 <v t="michael.20060619225419.22"><vh>class Critical</vh>
686 <v t="michael.20060619225419.23"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
687 <v t="michael.20060804163807"><vh>register_editors</vh></v>
688 <v t="michael.20060619225419.24"><vh>__init__</vh></v>
689 <v t="michael.20060619225419.25"><vh>modify_widget</vh></v>
690 </v>
691 <v t="michael.20060619225419.26"><vh>class Compare</vh>
692 <v t="michael.20060619225419.27"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
693 <v t="michael.20060804154017"><vh>register_editors</vh></v>
694 <v t="michael.20060619225419.28"><vh>create_objects</vh></v>
695 </v>
696 </v>
697 <v t="michael.20061002003849" tnodeList="michael.20061002003849,mr7771.20060609151433,michael.20061002003849.1,michael.20061002003849.2,michael.20061002003849.3,michael.20061002004356,michael.20061002003849.4,michael.20061002003849.5,michael.20061002003849.6,michael.20061002003849.7,michael.20061002003849.8,michael.20061002003849.9,michael.20061002003849.10,michael.20061002003849.11,michael.20061002003849.12,michael.20061002003849.13,michael.20061002003849.14"><vh>@file lib/resource.py</vh>
698 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
699 <v t="michael.20061002003849.1"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
700 <v t="michael.20061002003849.2"><vh>class Standard</vh>
701 <v t="michael.20061002003849.3"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
702 <v t="michael.20061002004356" a="M"><vh>register_editors</vh></v>
703 <v t="michael.20061002003849.4"><vh>__init__</vh></v>
704 <v t="michael.20061002003849.5"><vh>create_all_widgets</vh></v>
705 <v t="michael.20061002003849.6"><vh>create_row</vh></v>
706 <v t="michael.20061002003849.7"><vh>modify_row</vh></v>
707 <v t="michael.20061002003849.8"><vh>add_load_line</vh></v>
708 <v t="michael.20061002003849.9"><vh>load_offset</vh></v>
709 <v t="michael.20061002003849.10"><vh>create_bar</vh></v>
710 <v t="michael.20061002003849.11"><vh>modify_bar</vh></v>
711 <v t="michael.20061002003849.12"><vh>get_color</vh></v>
712 <v t="michael.20061002003849.13"><vh>create_bars</vh></v>
713 <v t="michael.20061002003849.14"><vh>get_tip</vh></v>
714 </v>
715 </v>
716 </v>
717 <v t="mr7771.20060608164004.453"><vh>Charting</vh>
718 <v t="michael.20070716145002" tnodeList="michael.20070716145002,mr7771.20060609151433"><vh>@file charting/__init__.py</vh>
719 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
720 </v>
721 <v t="michael.20060619222451" tnodeList="michael.20060619222451,mr7771.20060609151433,michael.20060619222451.1,michael.20060619223120,michael.20060619222451.8,michael.20060619222451.9,michael.20060619222451.10,michael.20060804121345,michael.20060619222451.11,michael.20060619222451.12,michael.20060619222451.13,michael.20060619222451.14,michael.20060619222451.15,michael.20060619222451.16,michael.20060619222451.17,michael.20060619222451.18,michael.20060619222451.19,michael.20060804132135,michael.20060619222451.20,michael.20060619222451.21,michael.20060619222451.22,michael.20060619222451.23,michael.20060619222451.24,michael.20060619222451.25,michael.20060619222451.26,michael.20060619222451.27,michael.20060619222451.28,michael.20060619222451.29,michael.20060619222451.30,michael.20060619222451.31,michael.20060619222451.32,michael.20060619222451.33,michael.20060619222451.34,michael.20060619222451.35,michael.20060619222451.36,michael.20060619222451.37,michael.20060619222451.38,michael.20060619222451.39,michael.20060619222451.40,michael.20060619222451.41,michael.20060619222451.42,michael.20060619222451.43,michael.20060804133122,michael.20060619222451.44,michael.20060619222451.45,michael.20060619222451.46,michael.20060619222451.47,michael.20060619222451.48,michael.20060619222451.49,michael.20060619222451.50,michael.20060619222451.51,michael.20060619222451.52,michael.20060619222451.53,michael.20060619222451.54,michael.20060619222451.55,michael.20060619222451.56,michael.20060804152844,michael.20060619222451.57,michael.20060619222451.58,michael.20060619222451.59,michael.20060619222451.60,michael.20060619222451.61,michael.20060619222451.62,michael.20060619222451.63,michael.20060619222451.64,michael.20060619222451.65,michael.20060619222451.66,michael.20060619222451.67,michael.20060619222451.68,michael.20060619222451.69,michael.20060619222451.70,michael.20060619222451.71,michael.20060619222451.72,michael.20060619222451.73,michael.20060619222451.74,michael.20060619222451.75,michael.20060619222451.76,michael.20060619222451.77,michael.20060619222451.78,michael.20060619222451.79,michael.20060619222451.80,michael.20060619222451.81,michael.20060619222451.82,michael.20060619222451.83,michael.20060619222451.84,michael.20060619222451.85,michael.20060619222451.86,michael.20060619222451.87,michael.20060619222451.88,michael.20060619222451.89"><vh>@file charting/charts.py</vh>
722 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
723 <v t="michael.20060619222451.1" a="M"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
724 <v t="michael.20060619223120"><vh>Matplotlib Redirections</vh></v>
725 <v t="michael.20060619222451.8"><vh>class MatplotChart</vh>
726 <v t="michael.20060619222451.9"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
727 <v t="michael.20060619222451.10"><vh>printer</vh></v>
728 <v t="michael.20060804121345" a="M"><vh>register_editors</vh></v>
729 <v t="michael.20060619222451.11"><vh>__init__</vh></v>
730 <v t="michael.20060619222451.12"><vh>_add_decorations</vh></v>
731 <v t="michael.20060619222451.13"><vh>add_decorations</vh></v>
732 <v t="michael.20060619222451.14"><vh>create_axes</vh></v>
733 <v t="michael.20060619222451.15"><vh>create</vh></v>
734 <v t="michael.20060619222451.16"><vh>get_tip</vh></v>
735 <v t="michael.20060619222451.17"><vh>setup_axes_interface</vh></v>
736 </v>
737 <v t="michael.20060619222451.18"><vh>class TimeWidgetChart</vh>
738 <v t="michael.20060619222451.19"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
739 <v t="michael.20060804132135"><vh>register_editors</vh></v>
740 <v t="michael.20060619222451.20"><vh>__init__</vh></v>
741 <v t="michael.20060619222451.21"><vh>to_date</vh></v>
742 <v t="michael.20060619222451.22"><vh>create_axes</vh></v>
743 <v t="michael.20060619222451.23"><vh>create</vh></v>
744 <v t="michael.20060619222451.24"><vh>create_all_widgets</vh></v>
745 <v t="michael.20060619222451.25"><vh>_finalize_row_widgets</vh></v>
746 </v>
747 <v t="michael.20060619222451.26"><vh>class TimePlotChart</vh>
748 <v t="michael.20060619222451.27"><vh>&lt;&lt; class TimePlotChart declarations &gt;&gt;</vh></v>
749 <v t="michael.20060619222451.28"><vh>__init__</vh></v>
750 <v t="michael.20060619222451.29"><vh>create_axes</vh></v>
751 <v t="michael.20060619222451.30"><vh>create</vh></v>
752 <v t="michael.20060619222451.31"><vh>create_plot</vh></v>
753 </v>
754 <v t="michael.20060619222451.32"><vh>class TimeMultiChart</vh>
755 <v t="michael.20060619222451.33"><vh>&lt;&lt; class TimeMultiChart declarations &gt;&gt;</vh></v>
756 <v t="michael.20060619222451.34"><vh>__init__</vh></v>
757 <v t="michael.20060619222451.35"><vh>create_axes</vh></v>
758 <v t="michael.20060619222451.36"><vh>create</vh></v>
759 <v t="michael.20060619222451.37"><vh>add_TimeWidgetAxes</vh></v>
760 <v t="michael.20060619222451.38"><vh>add_TimePlotAxes</vh></v>
761 <v t="michael.20060619222451.39"><vh>add_chart</vh></v>
762 <v t="michael.20060619222451.40"><vh>get_tip</vh></v>
763 <v t="michael.20060619222451.41"><vh>create_chart</vh></v>
764 </v>
765 <v t="michael.20060619222451.42"><vh>class TimeAxisChart</vh>
766 <v t="michael.20060619222451.43"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
767 <v t="michael.20060804133122" a="M"><vh>register_editors</vh></v>
768 <v t="michael.20060619222451.44"><vh>create</vh></v>
769 <v t="michael.20060619222451.45"><vh>set_time_axis</vh></v>
770 </v>
771 <v t="michael.20060619222451.46"><vh>class TimeAxisWidgetChart</vh>
772 <v t="michael.20060619222451.47"><vh>&lt;&lt; class TimeAxisWidgetChart declarations &gt;&gt;</vh></v>
773 <v t="michael.20060619222451.48"><vh>printer</vh></v>
774 </v>
775 <v t="michael.20060619222451.49"><vh>class TimeAxisPlotChart</vh>
776 <v t="michael.20060619222451.50"><vh>&lt;&lt; class TimeAxisPlotChart declarations &gt;&gt;</vh></v>
777 <v t="michael.20060619222451.51"><vh>printer</vh></v>
778 </v>
779 <v t="michael.20060619222451.52"><vh>class TimeAxisMultiChart</vh>
780 <v t="michael.20060619222451.53"><vh>&lt;&lt; class TimeAxisMultiChart declarations &gt;&gt;</vh></v>
781 <v t="michael.20060619222451.54"><vh>printer</vh></v>
782 </v>
783 <v t="michael.20060619222451.55"><vh>class TableChart</vh>
784 <v t="michael.20060619222451.56"><vh>&lt;&lt; class TableChart declarations &gt;&gt;</vh></v>
785 <v t="michael.20060804152844"><vh>register_editors</vh></v>
786 <v t="michael.20060619222451.57"><vh>printer</vh></v>
787 <v t="michael.20060619222451.58"><vh>__init__</vh></v>
788 <v t="michael.20060619222451.59"><vh>create_axes</vh></v>
789 <v t="michael.20060619222451.60"><vh>create</vh></v>
790 <v t="michael.20060619222451.61"><vh>get_col</vh></v>
791 <v t="michael.20060619222451.62"><vh>get_row</vh></v>
792 <v t="michael.20060619222451.63"><vh>add_cell</vh></v>
793 <v t="michael.20060619222451.64"><vh>create_all_widgets</vh></v>
794 <v t="michael.20060619222451.65"><vh>_finalize_row_widgets</vh></v>
795 <v t="michael.20060619222451.66"><vh>_finalize_col_widgets</vh></v>
796 </v>
797 <v t="michael.20060619222451.67"><vh>class _DescriptionTable</vh>
798 <v t="michael.20060619222451.68"><vh>&lt;&lt; class _DescriptionTable declarations &gt;&gt;</vh></v>
799 <v t="michael.20060619222451.69"><vh>__init__</vh></v>
800 <v t="michael.20060619222451.70"><vh>get_col</vh></v>
801 <v t="michael.20060619222451.71"><vh>create_all_widgets</vh></v>
802 <v t="michael.20060619222451.72"><vh>create_header</vh></v>
803 <v t="michael.20060619222451.73"><vh>_finalize_row_widgets</vh></v>
804 <v t="michael.20060619222451.74"><vh>modify_header_widget</vh></v>
805 <v t="michael.20060619222451.75"><vh>modify_widget</vh></v>
806 </v>
807 <v t="michael.20060619222451.76"><vh>class TimeTabledChart</vh>
808 <v t="michael.20060619222451.77"><vh>&lt;&lt; class TimeTabledChart declarations &gt;&gt;</vh></v>
809 <v t="michael.20060619222451.78"><vh>printer</vh></v>
810 <v t="michael.20060619222451.79"><vh>__init__</vh></v>
811 <v t="michael.20060619222451.80"><vh>setup_axes_interface</vh></v>
812 <v t="michael.20060619222451.81"><vh>_check_limits</vh></v>
813 <v t="michael.20060619222451.82"><vh>_widget_at</vh></v>
814 <v t="michael.20060619222451.83"><vh>_mark_widget</vh></v>
815 <v t="michael.20060619222451.84"><vh>create_axes</vh></v>
816 <v t="michael.20060619222451.85"><vh>create</vh></v>
817 <v t="michael.20060619222451.86"><vh>get_tip</vh></v>
818 <v t="michael.20060619222451.87"><vh>create_chart</vh></v>
819 </v>
820 <v t="michael.20060619222451.88"><vh>class TimeAxisTabledChart</vh>
821 <v t="michael.20060619222451.89"><vh>&lt;&lt; class TimeAxisTabledChart declarations &gt;&gt;</vh></v>
822 </v>
823 </v>
824 <v t="michael.20060619230818" tnodeList="michael.20060619230818,mr7771.20060609151433,michael.20060619230818.1,michael.20060619230818.2,michael.20060619230818.3,michael.20060619230818.4,michael.20060619230818.5,michael.20060619230818.6,michael.20060619230818.7,michael.20060619230818.8,michael.20060619230818.9,michael.20060619230818.10,michael.20060619230818.11,michael.20060619230818.12,michael.20060619230818.13,michael.20060619230818.14,michael.20060619230818.15,michael.20060619230818.16,michael.20060619230818.17,michael.20060619230818.18,michael.20060619230818.19,michael.20060619230818.20,michael.20060619230818.21,michael.20060619230818.22,michael.20060619230818.23,michael.20060619230818.24,michael.20060619230818.25,michael.20060619230818.26,michael.20060619230818.27,michael.20060619230818.28,michael.20060619230818.29,michael.20060619230818.30,michael.20060619230818.31,michael.20060619230818.32,michael.20060619230818.33,michael.20060619230818.34,michael.20060619230818.35,michael.20060619230818.36,michael.20060619230818.37,michael.20060619230818.38,michael.20060619230818.39,michael.20060619230818.40,michael.20060619230818.41,michael.20060619230818.42,michael.20060619230818.43,michael.20060619230818.44,michael.20060619230818.45,michael.20060619230818.46,michael.20060619230818.47,michael.20060619230818.48,michael.20060619230818.49,michael.20060619230818.50,michael.20060619230818.51,michael.20060619230818.52,michael.20060619230818.53,michael.20060619230818.54,michael.20060619230818.55,michael.20060619230818.56,michael.20060619230818.57,michael.20060619230818.58,michael.20060619230818.59,michael.20060619230818.60,michael.20060619230818.61,michael.20060619230818.62,michael.20060619230818.63,michael.20060619230818.64,michael.20060619230818.65,michael.20060619230818.66,michael.20060619230818.67,michael.20060619230818.68,michael.20061028181551,michael.20061028181551.1,michael.20061028181551.2,michael.20061028181551.4,michael.20061028181551.3,michael.20061114193915,michael.20061113154308.1,michael.20061113154308.2,michael.20061028181551.5,michael.20061028181551.6,michael.20061114193915.1,michael.20060619230818.69,michael.20060619230818.70,michael.20061028181843,michael.20060619230818.71,michael.20060619230818.72,michael.20061028124110,michael.20061028124110.1,michael.20060619230818.73,michael.20061114194524,michael.20060619230818.74,michael.20060619230818.75,michael.20060619230818.76,michael.20060619230818.77,michael.20060619230818.78,michael.20060619230818.79,michael.20060619230818.80,michael.20060619230818.81,michael.20060703181442,michael.20060619230818.82,michael.20060619230818.83,michael.20060619230818.84,michael.20060619230818.85,michael.20060619230818.86,michael.20060619230818.87,michael.20060619230818.88,michael.20060619230818.89,michael.20060619230818.90,michael.20060619230818.91,michael.20060619230818.92"><vh>@file charting/widgets.py</vh>
825 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
826 <v t="michael.20060619230818.1"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
827 <v t="michael.20060619230818.2"><vh>class LazyText</vh>
828 <v t="michael.20060619230818.3"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
829 <v t="michael.20060619230818.4"><vh>__init__</vh></v>
830 <v t="michael.20060619230818.5"><vh>get_prop_tup</vh></v>
831 <v t="michael.20060619230818.6"><vh>draw</vh></v>
832 <v t="michael.20060619230818.7" a="M"><vh>get_bottom_top</vh></v>
833 <v t="michael.20060619230818.8"><vh>get_window_extent</vh></v>
834 </v>
835 <v t="michael.20060619230818.9"><vh>class _PropertyType</vh>
836 <v t="michael.20060619230818.10"><vh>__init__</vh></v>
837 </v>
838 <v t="michael.20060619230818.11" a="M"><vh>check_property</vh></v>
839 <v t="michael.20060619230818.12"><vh>class _PropertyAware</vh>
840 <v t="michael.20060619230818.13"><vh>&lt;&lt; class _PropertyAware declarations &gt;&gt;</vh></v>
841 <v t="michael.20060619230818.14"><vh>__init__</vh></v>
842 <v t="michael.20060619230818.15"><vh>set_property</vh></v>
843 <v t="michael.20060619230818.16"><vh>remove_property</vh></v>
844 <v t="michael.20060619230818.17"><vh>_find_property_in_chain</vh></v>
845 <v t="michael.20060619230818.18"><vh>_find_property</vh></v>
846 <v t="michael.20060619230818.19"><vh>get_font</vh></v>
847 <v t="michael.20060619230818.20"><vh>get_property</vh></v>
848 <v t="michael.20060619230818.21"><vh>set_gc</vh></v>
849 <v t="michael.20060619230818.22"><vh>get_patch</vh></v>
850 </v>
851 <v t="michael.20060619230818.23"><vh>class Widget</vh>
852 <v t="michael.20060619230818.24"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
853 <v t="michael.20060619230818.25"><vh>__init__</vh></v>
854 <v t="michael.20060619230818.26"><vh>_extend_text_properties</vh></v>
855 <v t="michael.20060619230818.27"><vh>clear</vh></v>
856 <v t="michael.20060619230818.28"><vh>text</vh></v>
857 <v t="michael.20060619230818.29"><vh>set_figure</vh></v>
858 <v t="michael.20060619230818.30"><vh>set_transform</vh></v>
859 <v t="michael.20060619230818.31"><vh>set_clip_box</vh></v>
860 <v t="michael.20060619230818.32"><vh>all_artists</vh></v>
861 <v t="michael.20060619230818.33"><vh>add_artist</vh></v>
862 <v t="michael.20060619230818.34"><vh>set_font_factor</vh></v>
863 <v t="michael.20060619230818.35"><vh>prepare_draw</vh></v>
864 <v t="michael.20060619230818.36"><vh>overlaps</vh></v>
865 <v t="michael.20060619230818.37"><vh>contains</vh></v>
866 <v t="michael.20060619230818.38"><vh>get_bounds</vh></v>
867 </v>
868 <v t="michael.20060619230818.39"><vh>class Row</vh>
869 <v t="michael.20060619230818.40"><vh>&lt;&lt; class Row declarations &gt;&gt;</vh></v>
870 <v t="michael.20060619230818.41"><vh>__init__</vh></v>
871 <v t="michael.20060619230818.42"><vh>update_height</vh></v>
872 <v t="michael.20060619230818.43"><vh>draw</vh></v>
873 <v t="michael.20060619230818.44"><vh>set_y</vh></v>
874 <v t="michael.20060619230818.45"><vh>full_height</vh></v>
875 <v t="michael.20060619230818.46"><vh>next_y</vh></v>
876 <v t="michael.20060619230818.47"><vh>reset_height</vh></v>
877 <v t="michael.20060619230818.48"><vh>contains</vh></v>
878 <v t="michael.20060619230818.49"><vh>prepare_draw</vh></v>
879 <v t="michael.20060619230818.50"><vh>get_bounds</vh></v>
880 </v>
881 <v t="michael.20060619230818.51"><vh>class Column</vh>
882 <v t="michael.20060619230818.52"><vh>&lt;&lt; class Column declarations &gt;&gt;</vh></v>
883 <v t="michael.20060619230818.53"><vh>__init__</vh></v>
884 <v t="michael.20060619230818.54"><vh>update_width</vh></v>
885 <v t="michael.20060619230818.55"><vh>draw</vh></v>
886 <v t="michael.20060619230818.56"><vh>set_x</vh></v>
887 <v t="michael.20060619230818.57"><vh>full_width</vh></v>
888 <v t="michael.20060619230818.58"><vh>next_x</vh></v>
889 <v t="michael.20060619230818.59"><vh>reset_width</vh></v>
890 <v t="michael.20060619230818.60"><vh>contains</vh></v>
891 <v t="michael.20060619230818.61"><vh>prepare_draw</vh></v>
892 <v t="michael.20060619230818.62"><vh>get_bounds</vh></v>
893 </v>
894 <v t="michael.20060619230818.63"><vh>class CellWidget</vh>
895 <v t="michael.20060619230818.64"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
896 <v t="michael.20060619230818.65"><vh>__init__</vh></v>
897 <v t="michael.20060619230818.66"><vh>get_bounds</vh></v>
898 <v t="michael.20060619230818.67"><vh>prepare_draw</vh></v>
899 <v t="michael.20060619230818.68"><vh>draw</vh></v>
900 </v>
901 <v t="michael.20061028181551" a="M"><vh>class BoxedTextWidget</vh>
902 <v t="michael.20061028181551.1"><vh>__init__</vh></v>
903 <v t="michael.20061028181551.2"><vh>get_bounds</vh></v>
904 <v t="michael.20061028181551.4"><vh>prepare_draw (stage2)</vh></v>
905 <v t="michael.20061028181551.3" a="M"><vh>prepare_draw (stage1)</vh></v>
906 <v t="michael.20061114193915" a="M"><vh>calc_bounding_box</vh>
907 <v t="michael.20061113154308.1"><vh>&lt;&lt; calculate bbox based on self.text &gt;&gt;</vh></v>
908 <v t="michael.20061113154308.2"><vh>&lt;&lt; calculate bbox with all artists &gt;&gt;</vh></v>
909 </v>
910 <v t="michael.20061028181551.5"><vh>set_pos</vh></v>
911 <v t="michael.20061028181551.6"><vh>draw</vh></v>
912 <v t="michael.20061114193915.1" a="M"><vh>check_font_factor</vh></v>
913 </v>
914 <v t="michael.20060619230818.69"><vh>class TableWidget</vh>
915 <v t="michael.20060619230818.70"><vh>__init__</vh></v>
916 <v t="michael.20061028181843"><vh>set_cell</vh></v>
917 <v t="michael.20060619230818.71"><vh>get_bounds</vh></v>
918 <v t="michael.20060619230818.72"><vh>prepare_draw (stage1)</vh></v>
919 <v t="michael.20061028124110"><vh>prepare_draw (stage2)</vh></v>
920 <v t="michael.20061028124110.1"><vh>set_pos</vh></v>
921 <v t="michael.20060619230818.73"><vh>draw</vh></v>
922 <v t="michael.20061114194524"><vh>check_font_factor</vh></v>
923 </v>
924 <v t="michael.20060619230818.74"><vh>class TimeWidget</vh>
925 <v t="michael.20060619230818.75"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
926 <v t="michael.20060619230818.76"><vh>__init__</vh></v>
927 <v t="michael.20060619230818.77"><vh>set_shape</vh></v>
928 <v t="michael.20060619230818.78"><vh>all_artists</vh></v>
929 <v t="michael.20060619230818.79"><vh>finalized_row</vh></v>
930 <v t="michael.20060619230818.80"><vh>inside_text</vh></v>
931 <v t="michael.20060619230818.81"><vh>get_bounds</vh>
932 <v t="michael.20060703181442"><vh>&lt;&lt; check if inside text fits into the shape &gt;&gt;</vh></v>
933 </v>
934 <v t="michael.20060619230818.82"><vh>overlaps</vh></v>
935 <v t="michael.20060619230818.83"><vh>prepare_draw</vh></v>
936 <v t="michael.20060619230818.84"><vh>draw</vh></v>
937 <v t="michael.20060619230818.85"><vh>prepare_inside_text</vh></v>
938 </v>
939 <v t="michael.20060619230818.86"><vh>class GanttWidget</vh></v>
940 <v t="michael.20060619230818.87"><vh>class ResourceBarWidget</vh>
941 <v t="michael.20060619230818.88"><vh>&lt;&lt; class ResourceBarWidget declarations &gt;&gt;</vh></v>
942 <v t="michael.20060619230818.89"><vh>__init__</vh></v>
943 <v t="michael.20060619230818.90"><vh>prepare_draw</vh></v>
944 <v t="michael.20060619230818.91"><vh>prepare_inside_text</vh></v>
945 <v t="michael.20060619230818.92"><vh>get_bounds</vh></v>
946 </v>
947 </v>
948 <v t="michael.20060621125853" tnodeList="michael.20060621125853,mr7771.20060609151433,michael.20060621125853.1,michael.20060621125853.2,michael.20061028160826,michael.20061028180706,michael.20061028180706.1,michael.20061028145753,michael.20061026224624,michael.20060621125853.3,michael.20060621125853.4,michael.20060621125853.5,michael.20060621125853.6,michael.20060621125853.7,michael.20060621125853.8,michael.20060621125853.9,michael.20060621125853.10,michael.20060621125853.11,michael.20060621125853.12,michael.20060621125853.13,michael.20060621125853.14,michael.20060621125853.15,michael.20060621125853.16,michael.20060621125853.17,michael.20060621125853.18,michael.20060621125853.19,michael.20060621125853.20,michael.20060621125853.21,michael.20060621125853.22,michael.20060621125853.23,michael.20060621125853.24,michael.20060621125853.25,michael.20060621125853.26,michael.20060621125853.27,michael.20060621125853.28,michael.20060621125853.29,michael.20060621125853.30,michael.20060621125853.31,michael.20060621125853.32,michael.20060621125853.33,michael.20060621125853.34,michael.20060621125853.35,michael.20060621125853.36,michael.20060621125853.37,michael.20060621125853.38,michael.20061028151207,michael.20061028151207.1,michael.20061028151207.2,michael.20061028151207.3,michael.20061028151207.4,michael.20061028151207.5,michael.20061028180926,michael.20061028180926.1,michael.20061028151207.6,michael.20061028180926.2"><vh>@file charting/connector.py</vh>
949 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
950 <v t="michael.20060621125853.1"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
951 <v t="michael.20060621125853.2"><vh>get_arrow</vh></v>
952 <v t="michael.20061028160826" a="M"><vh>intersect</vh>
953 <v t="michael.20061028180706"><vh>&lt;&lt; extract coordinates &gt;&gt;</vh></v>
954 <v t="michael.20061028180706.1" a="M"><vh>&lt;&lt; define calc &gt;&gt;</vh></v>
955 </v>
956 <v t="michael.20061028145753"><vh>GanttConnector</vh>
957 <v t="michael.20061026224624"><vh>Classes for calculating a line path</vh>
958 <v t="michael.20060621125853.3" a="M"><vh>class ConnectorPath</vh>
959 <v t="michael.20060621125853.4"><vh>calc_start_end</vh></v>
960 <v t="michael.20060621125853.5"><vh>get_lines</vh></v>
961 <v t="michael.20060621125853.6" a="M"><vh>point_near</vh></v>
962 <v t="michael.20060621125853.7"><vh>find_y_pos</vh></v>
963 <v t="michael.20060621125853.8"><vh>get_edges</vh></v>
964 </v>
965 <v t="michael.20060621125853.9" a="M"><vh>class StartEndPath</vh>
966 <v t="michael.20060621125853.10"><vh>calc_x_ends</vh></v>
967 <v t="michael.20060621125853.11" a="M"><vh>get_edges</vh></v>
968 </v>
969 <v t="michael.20060621125853.12"><vh>class StartStartPath</vh>
970 <v t="michael.20060621125853.13"><vh>calc_x_ends</vh></v>
971 <v t="michael.20060621125853.14" a="M"><vh>get_edges</vh></v>
972 </v>
973 <v t="michael.20060621125853.15"><vh>class EndStartPath</vh>
974 <v t="michael.20060621125853.16"><vh>calc_x_ends</vh></v>
975 <v t="michael.20060621125853.17"><vh>get_edges</vh></v>
976 </v>
977 <v t="michael.20060621125853.18"><vh>class EndEndPath</vh>
978 <v t="michael.20060621125853.19"><vh>calc_x_ends</vh></v>
979 <v t="michael.20060621125853.20" a="M"><vh>get_edges</vh></v>
980 </v>
981 <v t="michael.20060621125853.21" a="M"><vh>class ShortestPath</vh>
982 <v t="michael.20060621125853.22"><vh>calc_x_ends</vh></v>
983 </v>
984 </v>
985 <v t="michael.20060621125853.23"><vh>class GanttConnector</vh>
986 <v t="michael.20060621125853.24"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
987 <v t="michael.20060621125853.25"><vh>__init__</vh></v>
988 <v t="michael.20060621125853.26"><vh>set_path</vh></v>
989 <v t="michael.20060621125853.27"><vh>set_property</vh></v>
990 <v t="michael.20060621125853.28"><vh>get_bounds</vh></v>
991 <v t="michael.20060621125853.29"><vh>contains</vh></v>
992 <v t="michael.20060621125853.30"><vh>prepare_draw</vh></v>
993 <v t="michael.20060621125853.31"><vh>draw</vh></v>
994 </v>
995 </v>
996 <v t="michael.20060621125853.32"><vh>class WBKConnector</vh>
997 <v t="michael.20060621125853.33"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
998 <v t="michael.20060621125853.34"><vh>__init__</vh></v>
999 <v t="michael.20060621125853.35"><vh>get_bounds</vh></v>
1000 <v t="michael.20060621125853.36"><vh>contains</vh></v>
1001 <v t="michael.20060621125853.37"><vh>prepare_draw</vh></v>
1002 <v t="michael.20060621125853.38"><vh>draw</vh></v>
1003 </v>
1004 <v t="michael.20061028151207"><vh>class ShortConnector</vh>
1005 <v t="michael.20061028151207.1"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
1006 <v t="michael.20061028151207.2"><vh>__init__</vh></v>
1007 <v t="michael.20061028151207.3"><vh>get_bounds</vh></v>
1008 <v t="michael.20061028151207.4"><vh>contains</vh></v>
1009 <v t="michael.20061028151207.5" a="M"><vh>prepare_draw</vh>
1010 <v t="michael.20061028180926"><vh>&lt;&lt; calc arrow position &gt;&gt;</vh>
1011 <v t="michael.20061028180926.1"><vh>&lt;&lt; calc line equations &gt;&gt;</vh></v>
1012 </v>
1013 </v>
1014 <v t="michael.20061028151207.6" a="M"><vh>draw</vh>
1015 <v t="michael.20061028180926.2"><vh>&lt;&lt; draw arrow &gt;&gt;</vh></v>
1016 </v>
1017 </v>
1018 </v>
1019 <v t="michael.20060621130232" tnodeList="michael.20060621130232,mr7771.20060609151433,michael.20060621130232.1,michael.20060621130232.2,michael.20060621130232.3,michael.20060621130232.4,michael.20060621130232.5,michael.20060621130232.6,michael.20060621130232.7,michael.20060621130232.8"><vh>@file charting/shapes.py</vh>
1020 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
1021 <v t="michael.20060621130232.1"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
1022 <v t="michael.20060621130232.2"><vh>bar</vh></v>
1023 <v t="michael.20060621130232.3"><vh>brace</vh></v>
1024 <v t="michael.20060621130232.4"><vh>combibar</vh></v>
1025 <v t="michael.20060621130232.5"><vh>diamond</vh></v>
1026 <v t="michael.20060621130232.6"><vh>circle</vh></v>
1027 <v t="michael.20060621130232.7"><vh>wedge</vh></v>
1028 <v t="michael.20060621130232.8"><vh>house</vh></v>
1029 </v>
1030 <v t="michael.20060703173916" tnodeList="michael.20060703173916,mr7771.20060609151433,michael.20060703173916.1,michael.20060703173916.3,michael.20060703173916.4,michael.20060703173916.5,michael.20060703173916.6,michael.20060703173916.7,michael.20060703173916.8,michael.20060703173916.9,michael.20060703173916.10,michael.20060703173916.11,michael.20060703173916.12,michael.20060703173916.13,michael.20060703173916.14,michael.20060703173916.15,michael.20060703173916.16,michael.20060703173916.17,michael.20060703173916.18,michael.20060703173916.19,michael.20060703173916.20,michael.20060703173916.21,michael.20060703173916.22,michael.20060703173916.23,michael.20060703173916.24,michael.20060703173916.25,michael.20060703173916.26,michael.20060703173916.27,michael.20060703173916.28,michael.20060703173916.29,michael.20060703173916.30,michael.20060703173916.31,michael.20060703173916.32,michael.20060703173916.33,michael.20060703173916.34,michael.20060703173916.35,michael.20060703173916.36,michael.20060703173916.37,michael.20060703173916.38,michael.20060703173916.39,michael.20060703173916.40,michael.20060703173916.41,michael.20060703173916.42,michael.20060703173916.43,michael.20060703173916.44,michael.20060703173916.45,michael.20060703173916.46,michael.20060703173916.47,michael.20060703173916.48,michael.20060703173916.49,michael.20060703173916.50,michael.20060703173916.51,michael.20060703173916.52,michael.20060703173916.53,michael.20060703173916.54,michael.20060703173916.55,michael.20060703173916.56,michael.20060703173916.57,michael.20060703173916.58,michael.20060703173916.59,michael.20060703173916.60,michael.20060703173916.61,michael.20060703173916.62,michael.20060703173916.63,michael.20060703173916.64"><vh>@file charting/faxes.py</vh>
1031 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
1032 <v t="michael.20060703173916.1"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
1033 <v t="michael.20060703173916.3"><vh>_cint</vh></v>
1034 <v t="michael.20060703173916.4"><vh>cut_canvas</vh></v>
1035 <v t="michael.20060703173916.5"><vh>class _WidgetCollection</vh>
1036 <v t="michael.20060703173916.6"><vh>&lt;&lt; class _WidgetCollection declarations &gt;&gt;</vh></v>
1037 <v t="michael.20060703173916.7"><vh>__init__</vh></v>
1038 <v t="michael.20060703173916.8"><vh>draw</vh></v>
1039 </v>
1040 <v t="michael.20060703173916.9"><vh>_get_margin</vh></v>
1041 <v t="michael.20060703173916.10"><vh>class MarginAxes</vh>
1042 <v t="michael.20060703173916.11"><vh>__init__</vh></v>
1043 <v t="michael.20060703173916.12"><vh>build_margin_transform</vh></v>
1044 <v t="michael.20060703173916.13"><vh>_set_lim_and_transforms</vh></v>
1045 <v t="michael.20060703173916.14"><vh>in_axes</vh></v>
1046 <v t="michael.20060703173916.15"><vh>cla</vh></v>
1047 <v t="michael.20060703173916.16"><vh>draw</vh></v>
1048 </v>
1049 <v t="michael.20060703173916.17"><vh>class WidgetAxes</vh>
1050 <v t="michael.20060703173916.18"><vh>__init__</vh></v>
1051 <v t="michael.20060703173916.19"><vh>cla</vh></v>
1052 <v t="michael.20060703173916.20"><vh>check_limits</vh></v>
1053 <v t="michael.20060703173916.21"><vh>reset_limits</vh></v>
1054 <v t="michael.20060703173916.22"><vh>_get_renderer</vh></v>
1055 <v t="michael.20060703173916.23"><vh>add_widget</vh></v>
1056 <v t="michael.20060703173916.24"><vh>mark_widget</vh></v>
1057 <v t="michael.20060703173916.25"><vh>find_widget</vh></v>
1058 <v t="michael.20060703173916.26"><vh>widget_at</vh></v>
1059 <v t="michael.20060703173916.27"><vh>set_focused_on</vh></v>
1060 <v t="michael.20060703173916.28"><vh>set_focused_off</vh></v>
1061 <v t="michael.20060703173916.29"><vh>set_marker</vh></v>
1062 <v t="michael.20060703173916.30"><vh>widget_x_visible</vh></v>
1063 <v t="michael.20060703173916.31"><vh>widget_y_visible</vh></v>
1064 <v t="michael.20060703173916.32"><vh>zoomx</vh></v>
1065 <v t="michael.20060703173916.33"><vh>zoomy</vh></v>
1066 <v t="michael.20060703173916.34"><vh>_calc_hsep</vh></v>
1067 <v t="michael.20060703173916.35"><vh>_draw_widgets</vh></v>
1068 <v t="michael.20060703173916.36"><vh>clear_speed_cache</vh></v>
1069 <v t="michael.20060703173916.37"><vh>speed_up</vh></v>
1070 <v t="michael.20060703173916.38"><vh>draw</vh></v>
1071 <v t="michael.20060703173916.39"><vh>_set_lim_and_transforms</vh></v>
1072 </v>
1073 <v t="michael.20060703173916.40"><vh>class PointAxes</vh>
1074 <v t="michael.20060703173916.41"><vh>__init__</vh></v>
1075 <v t="michael.20060703173916.42"><vh>cla</vh></v>
1076 <v t="michael.20060703173916.43"><vh>check_limits</vh></v>
1077 <v t="michael.20060703173916.44"><vh>autoscale_view</vh></v>
1078 </v>
1079 <v t="michael.20060703173916.45"><vh>class TimeAxes</vh>
1080 <v t="michael.20060703173916.46"><vh>&lt;&lt; class TimeAxes declarations &gt;&gt;</vh></v>
1081 <v t="michael.20060703173916.47"><vh>set_time_axis</vh></v>
1082 <v t="michael.20060703173916.48"><vh>xaxis_timescale</vh></v>
1083 <v t="michael.20060703173916.49"><vh>set_time_lim</vh></v>
1084 <v t="michael.20060703173916.50"><vh>get_time_lim</vh></v>
1085 <v t="michael.20060703173916.51"><vh>format_coord</vh></v>
1086 <v t="michael.20060703173916.52"><vh>update_time_axis</vh></v>
1087 <v t="michael.20060703173916.53"><vh>unshare</vh></v>
1088 </v>
1089 <v t="michael.20060703173916.54"><vh>class TimePlotAxes</vh>
1090 <v t="michael.20060703173916.55"><vh>&lt;&lt; class TimePlotAxes declarations &gt;&gt;</vh></v>
1091 <v t="michael.20060703173916.56"><vh>__init__</vh></v>
1092 <v t="michael.20060703173916.57"><vh>draw</vh></v>
1093 </v>
1094 <v t="michael.20060703173916.58"><vh>class TimeWidgetAxes</vh>
1095 <v t="michael.20060703173916.59"><vh>&lt;&lt; class TimeWidgetAxes declarations &gt;&gt;</vh></v>
1096 <v t="michael.20060703173916.60"><vh>__init__</vh></v>
1097 <v t="michael.20060703173916.61"><vh>set_auto_scale_y</vh></v>
1098 <v t="michael.20060703173916.62"><vh>check_limits</vh></v>
1099 <v t="michael.20060703173916.63"><vh>autoscale_view</vh></v>
1100 <v t="michael.20060703173916.64"><vh>widget_at</vh></v>
1101 </v>
1102 </v>
1103 <v t="michael.20060910114955" a="E" tnodeList="michael.20060910114955,mr7771.20060609151433,michael.20060910114955.1,michael.20060910115214,michael.20060910114955.2,michael.20060910114955.3,michael.20060910114955.4,michael.20060910114955.5,michael.20071111221700,michael.20060910114955.6,michael.20060910114955.7,michael.20060910114955.8,michael.20060910114955.9,michael.20060910114955.10,michael.20060910114955.11,michael.20060910114955.12,michael.20060910114955.13,michael.20060910114955.14,michael.20060910114955.15,michael.20060910114955.16,michael.20060910114955.17,michael.20060910114955.18,michael.20060910114955.19,michael.20060910114955.20,michael.20060910114955.21,michael.20060910114955.22,michael.20060910114955.23,michael.20060910114955.24,michael.20060910114955.25,michael.20060910114955.26,michael.20060910114955.27,michael.20060910114955.28,michael.20060910114955.29,michael.20060910114955.30,michael.20060910114955.31,michael.20060910114955.32,michael.20060910114955.33,michael.20060910114955.34,michael.20060910114955.35,michael.20060910114955.36,michael.20060910114955.37,michael.20060910114955.38,michael.20060910114955.39,michael.20060910114955.40,michael.20060910114955.41,michael.20060910114955.42,michael.20060910114955.43,michael.20060910114955.44,michael.20060910114955.45,michael.20060910114955.46,michael.20060910114955.47,michael.20060910114955.48,michael.20060910114955.49,michael.20060910114955.50,michael.20060910114955.51,michael.20060910114955.52,michael.20060910114955.53,michael.20060910114955.54,michael.20060910114955.55,michael.20060910114955.56"><vh>@file charting/taxis.py</vh>
1104 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
1105 <v t="michael.20060910114955.1"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
1106 <v t="michael.20060910115214" a="E"><vh>Locators</vh>
1107 <v t="michael.20060910114955.2"><vh>class Locator</vh>
1108 <v t="michael.20060910114955.3"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
1109 <v t="michael.20060910114955.4"><vh>__init__</vh></v>
1110 <v t="michael.20060910114955.5"><vh>get_marks</vh></v>
1111 <v t="michael.20071111221700"><vh>build_mark</vh></v>
1112 <v t="michael.20060910114955.6"><vh>fits</vh></v>
1113 <v t="michael.20060910114955.7"><vh>prepare</vh></v>
1114 <v t="michael.20060910114955.8"><vh>_calc_sizes</vh></v>
1115 <v t="michael.20060910114955.9"><vh>_delta</vh></v>
1116 <v t="michael.20060910114955.10"><vh>_get_format</vh></v>
1117 <v t="michael.20060910114955.11" a="M"><vh>_calc_markers</vh></v>
1118 <v t="michael.20060910114955.12"><vh>is_free</vh></v>
1119 </v>
1120 <v t="michael.20060910114955.13"><vh>class DecadeLocator</vh>
1121 <v t="michael.20060910114955.14"><vh>_delta</vh></v>
1122 <v t="michael.20060910114955.15"><vh>_calc_sizes</vh></v>
1123 <v t="michael.20060910114955.16"><vh>__call__</vh></v>
1124 </v>
1125 <v t="michael.20060910114955.17"><vh>class YearLocator</vh>
1126 <v t="michael.20060910114955.18"><vh>_delta</vh></v>
1127 <v t="michael.20060910114955.19" a="M"><vh>_calc_sizes</vh></v>
1128 <v t="michael.20060910114955.20"><vh>__call__</vh></v>
1129 </v>
1130 <v t="michael.20060910114955.21"><vh>class QuaterLocator</vh>
1131 <v t="michael.20060910114955.22"><vh>_delta</vh></v>
1132 <v t="michael.20060910114955.23" a="M"><vh>_calc_sizes</vh></v>
1133 <v t="michael.20060910114955.24"><vh>__call__</vh></v>
1134 </v>
1135 <v t="michael.20060910114955.25"><vh>class MonthLocator</vh>
1136 <v t="michael.20060910114955.26"><vh>_delta</vh></v>
1137 <v t="michael.20060910114955.27" a="M"><vh>_calc_sizes</vh></v>
1138 <v t="michael.20060910114955.28"><vh>__call__</vh></v>
1139 </v>
1140 <v t="michael.20060910114955.29" a="E"><vh>class WeekLocator</vh>
1141 <v t="michael.20060910114955.30"><vh>_delta</vh></v>
1142 <v t="michael.20060910114955.31" a="M"><vh>_calc_sizes</vh></v>
1143 <v t="michael.20060910114955.32" a="M"><vh>__call__</vh></v>
1144 </v>
1145 <v t="michael.20060910114955.33"><vh>class DayLocator</vh>
1146 <v t="michael.20060910114955.34"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
1147 <v t="michael.20060910114955.35"><vh>_delta</vh></v>
1148 <v t="michael.20060910114955.36"><vh>_calc_sizes</vh></v>
1149 <v t="michael.20060910114955.37"><vh>__call__</vh></v>
1150 <v t="michael.20060910114955.38"><vh>is_free</vh></v>
1151 </v>
1152 <v t="michael.20060910114955.39"><vh>class SlotLocator</vh>
1153 <v t="michael.20060910114955.40"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
1154 <v t="michael.20060910114955.41"><vh>_delta</vh></v>
1155 <v t="michael.20060910114955.42"><vh>__call__</vh></v>
1156 <v t="michael.20060910114955.43"><vh>_calc_sizes</vh></v>
1157 <v t="michael.20060910114955.44"><vh>get_marks</vh></v>
1158 <v t="michael.20060910114955.45"><vh>is_free</vh></v>
1159 </v>
1160 </v>
1161 <v t="michael.20060910114955.46"><vh>_zigzag_lines</vh></v>
1162 <v t="michael.20060910114955.47"><vh>class TimeAxis</vh>
1163 <v t="michael.20060910114955.48"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
1164 <v t="michael.20060910114955.49"><vh>__init__</vh></v>
1165 <v t="michael.20060910114955.50"><vh>calc_height</vh></v>
1166 <v t="michael.20060910114955.51"><vh>set_transform</vh></v>
1167 <v t="michael.20060910114955.52"><vh>draw</vh></v>
1168 <v t="michael.20060910114955.53"><vh>find_ticker</vh></v>
1169 <v t="michael.20060910114955.54"><vh>draw_scale</vh></v>
1170 <v t="michael.20060910114955.55"><vh>draw_grid</vh></v>
1171 <v t="michael.20060910114955.56"><vh>draw_text</vh></v>
1172 </v>
1173 </v>
1174 </v>
1175 <v t="mr7771.20060608164004.454" a="E"><vh>Gui</vh>
1176 <v t="michael.20070115170252" tnodeList="michael.20070115170252,mr7771.20060609151433,michael.20070115170327,michael.20060623001958.2,michael.20060623001958.3,michael.20060623001958.4"><vh>@file gui/patches.py</vh>
1177 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
1178 <v t="michael.20070115170327"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
1179 <v t="michael.20060623001958.2"><vh>class PatchedDialog</vh>
1180 <v t="michael.20060623001958.3"><vh>&lt;&lt; gtk patched dialog &gt;&gt;</vh></v>
1181 <v t="michael.20060623001958.4"><vh>&lt;&lt; original dialog &gt;&gt;</vh></v>
1182 </v>
1183 </v>
1184 <v t="mr7771.20060608165446" a="E"><vh>Editor</vh>
1185 <v t="mr7771.20060609151433.1" a="E" tnodeList="mr7771.20060609151433.1,mr7771.20060609151433,mr7771.20060609151433.2,mr7771.20060609151433.3,michael.20060704235642,michael.20060705002353,michael.20060705013905,michael.20060705002353.1,mr7771.20060609151433.4,mr7771.20060609151433.5,michael.20060923141119,michael.20060901185155,mr7771.20060609151433.7,michael.20060705164052,michael.20060705164052.1,mr7771.20060609151433.8,mr7771.20060609151433.9,mr7771.20060609151433.10"><vh>@file gui/editor/__init__.py</vh>
1186 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
1187 <v t="mr7771.20060609151433.2"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
1188 <v t="mr7771.20060609151433.3"><vh>is_bool_option</vh></v>
1189 <v t="michael.20060704235642" a="M"><vh>class PlanEditorProxy</vh>
1190 <v t="michael.20060705002353" a="M"><vh>__init__</vh>
1191 <v t="michael.20060705013905"><vh>&lt;&lt; redirect methods &gt;&gt;</vh></v>
1192 </v>
1193 <v t="michael.20060705002353.1"><vh>Destroy</vh></v>
1194 </v>
1195 <v t="mr7771.20060609151433.4" a="M"><vh>class PlanEditor</vh>
1196 <v t="mr7771.20060609151433.5"><vh>__init__</vh>
1197 <v t="michael.20060923141119"><vh>&lt;&lt; redirect methods &gt;&gt;</vh></v>
1198 </v>
1199 <v t="michael.20060901185155"><vh>_on_shash_pos_change</vh></v>
1200 <v t="mr7771.20060609151433.7"><vh>_on_unsplit</vh></v>
1201 <v t="michael.20060705164052"><vh>show</vh></v>
1202 <v t="michael.20060705164052.1"><vh>hide</vh></v>
1203 <v t="mr7771.20060609151433.8"><vh>toggle_browser</vh></v>
1204 <v t="mr7771.20060609151433.9"><vh>goto_line</vh></v>
1205 <v t="mr7771.20060609151433.10"><vh>find_in_source</vh></v>
1206 </v>
1207 </v>
1208 <v t="michael.20060623001958" tnodeList="michael.20060623001958,mr7771.20060609151433,michael.20060623001958.1,michael.20060623002701,michael.20060623152229,michael.20060623152229.1,michael.20060623152229.2,michael.20060628145509,michael.20060623152229.3,michael.20060628145509.1"><vh>@file gui/editor/editorlib.py</vh>
1209 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
1210 <v t="michael.20060623001958.1"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
1211 <v t="michael.20060623002701" a="M"><vh>class MainView</vh>
1212 <v t="michael.20060623152229"><vh>__init__</vh></v>
1213 <v t="michael.20060623152229.1" a="M"><vh>button_cancel</vh></v>
1214 <v t="michael.20060623152229.2"><vh>button_ok</vh></v>
1215 <v t="michael.20060628145509"><vh>button_refresh</vh></v>
1216 <v t="michael.20060623152229.3"><vh>layout</vh></v>
1217 <v t="michael.20060628145509.1" a="M"><vh>get_stock_control</vh></v>
1218 </v>
1219 </v>
1220 <v t="mr7771.20060614140603" tnodeList="mr7771.20060614140603,mr7771.20060609151433,mr7771.20060614140603.1,mr7771.20060614140603.2,mr7771.20060614141538,mr7771.20060614142353,mr7771.20060614141538.1"><vh>@file gui/editor/classifiers.py</vh>
1221 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
1222 <v t="mr7771.20060614140603.1"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
1223 <v t="mr7771.20060614140603.2"><vh>is_task</vh></v>
1224 <v t="mr7771.20060614141538"><vh>is_resource</vh></v>
1225 <v t="mr7771.20060614142353"><vh>is_observer</vh></v>
1226 <v t="mr7771.20060614141538.1"><vh>lightweight classifiers</vh></v>
1227 </v>
1228 <v t="mr7771.20060609231152" a="E" tnodeList="mr7771.20060609231152,mr7771.20060609151433,mr7771.20060609231152.1,michael.20060616213907,michael.20060703235820,michael.20060915183222,mr7771.20060609231152.2,mr7771.20060609231152.3,michael.20060621180747,michael.20060621183054,michael.20060621183003,michael.20060621203738,michael.20070116120608,michael.20060707121238,michael.20060707181914,michael.20060707125319,michael.20060707130205,mr7771.20060609231152.4,michael.20060703235036,mr7771.20060609231152.5,mr7771.20060609231152.7,mr7771.20060609232136.1,mr7771.20060609232136,mr7771.20060609231152.9,mr7771.20060609235111,mr7771.20060609231152.10,mr7771.20060609231152.11,michael.20060703170652,michael.20060703235036.2,michael.20060703235036.3,mr7771.20060609231152.13,mr7771.20060609231152.14,mr7771.20060609231152.15,mr7771.20060609231152.16,mr7771.20060609231152.17,mr7771.20060609231152.18,mr7771.20060609231152.19,michael.20060616153549,michael.20060919150828,michael.20060919150828.1,michael.20060919150620,michael.20070926130714,michael.20060919150620.1,michael.20061110182612,michael.20060919150620.2,michael.20060919150620.3,michael.20060919150620.4,michael.20060919153708,michael.20060919150620.6,michael.20060919150620.5,michael.20061002030802,mr7771.20060609231152.20,mr7771.20060609231152.22,mr7771.20060609231152.23,mr7771.20060609231152.24,mr7771.20060609231152.25,mr7771.20060609231152.26,mr7771.20060609231152.27,mr7771.20060609231152.28,mr7771.20060609231152.29,mr7771.20060609231152.30,mr7771.20060609231152.31,mr7771.20060609231152.32,mr7771.20060609231152.33,mr7771.20060609231152.49,mr7771.20060609231152.39,mr7771.20060613224409,michael.20060619163321,michael.20060903115207,michael.20060619164749,michael.20060619163321.1,mr7771.20060616091420,michael.20060616170952,mr7771.20060609231152.45,mr7771.20060614120349,mr7771.20060616091420.1,mr7771.20060609231152.43,michael.20060724204442,mr7771.20060609231152.44,mr7771.20060609231152.46,mr7771.20060614114501,michael.20060616162635,mr7771.20060614121509,michael.20060616151822,mr7771.20060614121949,mr7771.20060609231152.42,michael.20060616171654,mr7771.20060613102529,michael.20060704001500,michael.20060704001244,michael.20060704001124,michael.20060703235912,mr7771.20060609231152.37,michael.20060704001124.4,michael.20060704001124.1,michael.20060704001124.2,michael.20060704001124.3,michael.20060704001124.4,michael.20060704001124.6,michael.20060703235853,michael.20060913121250,michael.20060913121250.1,michael.20060913121250.2,mr7771.20060614141538.2,mr7771.20060614090309,michael.20060616185633,michael.20060616185633.1,michael.20060708104315,michael.20060616185633.2,michael.20060616185633.3,mr7771.20060609231152.36,michael.20060621182829,michael.20061110184924,michael.20061110184924.1,michael.20061110184924.2,michael.20060622092032,michael.20060923124429,michael.20060923124429.1,michael.20060929232917,michael.20060915105317,michael.20061031174101.1,michael.20060923154026,michael.20060923154026.1,michael.20061031174101,michael.20060826120325,michael.20060826121701,michael.20060704020852,michael.20060622092054,michael.20060622105356,michael.20060622105356.1,michael.20060622103212,michael.20070116154322,michael.20060622112139,michael.20060622112139.1,michael.20060622105715,michael.20060628231054,michael.20060929220600,michael.20060831002737,michael.20060929220600.2"><vh>@file gui/editor/editor.py</vh>
1229 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
1230 <v t="mr7771.20060609231152.1"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
1231 <v t="michael.20060616213907"><vh>&lt;&lt; Editor Completions &gt;&gt;</vh></v>
1232 <v t="michael.20060703235820"><vh>project_names</vh></v>
1233 <v t="michael.20060915183222"><vh>Task CodeItem Functions</vh></v>
1234 <v t="mr7771.20060609231152.2"><vh>class SearchTool</vh>
1235 <v t="mr7771.20060609231152.3"><vh>__init__</vh></v>
1236 </v>
1237 <v t="michael.20060621180747"><vh>class ContextButton</vh>
1238 <v t="michael.20060621183054"><vh>__init__</vh></v>
1239 <v t="michael.20060621183003"><vh>set_bitmap</vh></v>
1240 <v t="michael.20060621203738"><vh>hide</vh></v>
1241 <v t="michael.20070116120608"><vh>move</vh></v>
1242 </v>
1243 <v t="michael.20060707121238"><vh>class ShadowStyler</vh>
1244 <v t="michael.20060707181914"><vh>__init__</vh></v>
1245 <v t="michael.20060707125319"><vh>StyleSetSpec</vh></v>
1246 <v t="michael.20060707130205"><vh>highlite</vh></v>
1247 </v>
1248 <v t="mr7771.20060609231152.4"><vh>class Editor</vh>
1249 <v t="michael.20060703235036"><vh>&lt;&lt; _parse_evaluation &gt;&gt;</vh></v>
1250 <v t="mr7771.20060609231152.5"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
1251 <v t="mr7771.20060609231152.7"><vh>__init__</vh>
1252 <v t="mr7771.20060609232136.1"><vh>&lt;&lt; Editor Adjustments &gt;&gt;</vh></v>
1253 <v t="mr7771.20060609232136"><vh>&lt;&lt; Bind Events &gt;&gt;</vh></v>
1254 </v>
1255 <v t="mr7771.20060609231152.9"><vh>wxPython Methods</vh>
1256 <v t="mr7771.20060609235111"><vh>_on_pos_changed</vh></v>
1257 <v t="mr7771.20060609231152.10"><vh>_on_get_focus</vh></v>
1258 <v t="mr7771.20060609231152.11"><vh>_on_change</vh>
1259 <v t="michael.20060703170652"><vh>&lt;&lt; make backup if necessary &gt;&gt;</vh></v>
1260 <v t="michael.20060703235036.2"><vh>&lt;&lt; change the context button if neccessary &gt;&gt;</vh></v>
1261 <v t="michael.20060703235036.3"><vh>&lt;&lt; renew the context &gt;&gt;</vh></v>
1262 </v>
1263 <v t="mr7771.20060609231152.13"><vh>_on_find_close</vh></v>
1264 <v t="mr7771.20060609231152.14"><vh>_on_find</vh></v>
1265 <v t="mr7771.20060609231152.15"><vh>_on_right_down</vh></v>
1266 <v t="mr7771.20060609231152.16"><vh>_on_new_char</vh></v>
1267 <v t="mr7771.20060609231152.17"><vh>_on_macro_notify</vh></v>
1268 <v t="mr7771.20060609231152.18"><vh>_on_insert_completion</vh></v>
1269 </v>
1270 <v t="mr7771.20060609231152.19"><vh>Menu Methods</vh>
1271 <v t="michael.20060616153549"><vh>set_menus</vh>
1272 <v t="michael.20060919150828"><vh>&lt;&lt; create help menu &gt;&gt;</vh></v>
1273 <v t="michael.20060919150828.1"><vh>&lt;&lt; create snapshot menu &gt;&gt;</vh></v>
1274 <v t="michael.20060919150620"><vh>&lt;&lt; create basic edit menus &gt;&gt;</vh>
1275 <v t="michael.20070926130714"><vh>&lt;&lt; copy &amp; cut patch &gt;&gt;</vh></v>
1276 </v>
1277 <v t="michael.20060919150620.1"><vh>&lt;&lt; create comment menus &gt;&gt;</vh></v>
1278 <v t="michael.20061110182612"><vh>&lt;&lt; create bookmark menus &gt;&gt;</vh></v>
1279 <v t="michael.20060919150620.2"><vh>&lt;&lt; create find menus &gt;&gt;</vh></v>
1280 <v t="michael.20060919150620.3"><vh>&lt;&lt; create macro menus &gt;&gt;</vh></v>
1281 <v t="michael.20060919150620.4"><vh>&lt;&lt; create context menu &gt;&gt;</vh></v>
1282 <v t="michael.20060919153708"><vh>&lt;&lt; create correct code menu &gt;&gt;</vh></v>
1283 <v t="michael.20060919150620.5"><vh>&lt;&lt; create fold menus &gt;&gt;</vh></v>
1284 <v t="michael.20061002030802"><vh>&lt;&lt; create Generate HTML menu &gt;&gt;</vh></v>
1285 <v t="michael.20060919150620.6"><vh>&lt;&lt; create menu separators &gt;&gt;</vh></v>
1286 </v>
1287 <v t="mr7771.20060609231152.20"><vh>menu_snapshot</vh></v>
1288 <v t="mr7771.20060609231152.22"><vh>menu_insert_date</vh></v>
1289 <v t="mr7771.20060609231152.23"><vh>menu_uncomment_selection</vh></v>
1290 <v t="mr7771.20060609231152.24"><vh>menu_comment_selection</vh></v>
1291 <v t="mr7771.20060609231152.25"><vh>menu_find_forward</vh></v>
1292 <v t="mr7771.20060609231152.26"><vh>menu_find_backward</vh></v>
1293 <v t="mr7771.20060609231152.27"><vh>menu_replace</vh></v>
1294 <v t="mr7771.20060609231152.28"><vh>menu_goto_line</vh></v>
1295 </v>
1296 <v t="mr7771.20060609231152.29"><vh>Macro Methods</vh>
1297 <v t="mr7771.20060609231152.30"><vh>no_record_call</vh></v>
1298 <v t="mr7771.20060609231152.31"><vh>start_macro</vh></v>
1299 <v t="mr7771.20060609231152.32"><vh>stop_macro</vh></v>
1300 <v t="mr7771.20060609231152.33"><vh>execute_macro</vh></v>
1301 <v t="mr7771.20060609231152.49"><vh>smart_replace_selection</vh></v>
1302 <v t="mr7771.20060609231152.39"><vh>inspect_indent_char</vh></v>
1303 </v>
1304 <v t="mr7771.20060613224409"><vh>Completion and Calltip Methods</vh>
1305 <v t="michael.20060619163321"><vh>guess_object</vh>
1306 <v t="michael.20060903115207"><vh>&lt;&lt; calculate search end &gt;&gt;</vh></v>
1307 <v t="michael.20060619164749"><vh>&lt;&lt; find context start line &gt;&gt;</vh></v>
1308 <v t="michael.20060619163321.1"><vh>&lt;&lt; define find_last &gt;&gt;</vh></v>
1309 </v>
1310 <v t="mr7771.20060616091420"><vh>make_attrib_list</vh></v>
1311 <v t="michael.20060616170952"><vh>get_dot_object</vh></v>
1312 <v t="mr7771.20060609231152.45"><vh>get_doc_object</vh></v>
1313 <v t="mr7771.20060614120349"><vh>get_word_at</vh></v>
1314 <v t="mr7771.20060616091420.1"><vh>get_session_completions</vh></v>
1315 <v t="mr7771.20060609231152.43"><vh>get_resource_completions</vh></v>
1316 <v t="michael.20060724204442"><vh>get_calendar_completions</vh></v>
1317 <v t="mr7771.20060609231152.44"><vh>get_evaluation_completions</vh></v>
1318 <v t="mr7771.20060609231152.46"><vh>show_completion</vh>
1319 <v t="mr7771.20060614114501"><vh>&lt;&lt; check style &gt;&gt;</vh></v>
1320 <v t="michael.20060616162635"><vh>&lt;&lt; try to create dot completion list &gt;&gt;</vh></v>
1321 <v t="mr7771.20060614121509"><vh>&lt;&lt; create non dot completion list &gt;&gt;</vh></v>
1322 <v t="michael.20060616151822"><vh>&lt;&lt; find an alternative completion list &gt;&gt;</vh></v>
1323 <v t="mr7771.20060614121949"><vh>&lt;&lt; show list &gt;&gt;</vh></v>
1324 </v>
1325 <v t="mr7771.20060609231152.42"><vh>show_call_tip</vh>
1326 <v t="michael.20060616171654"><vh>&lt;&lt; calculate obj and attrib &gt;&gt;</vh></v>
1327 </v>
1328 </v>
1329 <v t="mr7771.20060613102529"><vh>Misc Methods</vh>
1330 <v t="michael.20060704001500"><vh>show_task</vh></v>
1331 <v t="michael.20060704001244"><vh>show_object</vh></v>
1332 <v t="michael.20060704001124"><vh>check_modified</vh></v>
1333 <v t="michael.20060703235912"><vh>sync_text</vh></v>
1334 <v t="mr7771.20060609231152.37"><vh>refresh</vh>
1335 <v t="michael.20060704001124.1"><vh>&lt;&lt; save current position &gt;&gt;</vh></v>
1336 <v t="michael.20060704001124.2"><vh>&lt;&lt; create new document &gt;&gt;</vh></v>
1337 <v t="michael.20060704001124.3"><vh>&lt;&lt; misc document settings &gt;&gt;</vh></v>
1338 <v t="michael.20060704001124.4"><vh>&lt;&lt; module settings &gt;&gt;</vh></v>
1339 <v t="michael.20060704001124.6"><vh>&lt;&lt; restore position &gt;&gt;</vh></v>
1340 </v>
1341 <v t="michael.20060703235853"><vh>update_code_info</vh>
1342 <v t="michael.20060913121250"><vh>&lt;&lt; assign tasks to code_items &gt;&gt;</vh></v>
1343 <v t="michael.20060913121250.1"><vh>&lt;&lt; assign observers and resources to code_items &gt;&gt;</vh></v>
1344 <v t="michael.20060913121250.2"><vh>&lt;&lt; assign evaluations to code_items &gt;&gt;</vh></v>
1345 </v>
1346 <v t="mr7771.20060614141538.2"><vh>get_module</vh></v>
1347 <v t="mr7771.20060614090309"><vh>check_context</vh>
1348 <v t="michael.20060616185633"><vh>&lt;&lt; find and activate the current context &gt;&gt;</vh></v>
1349 <v t="michael.20060616185633.1"><vh>&lt;&lt; update browser and refresh &gt;&gt;</vh></v>
1350 <v t="michael.20060616185633.2"><vh>&lt;&lt; calculate attribute name &gt;&gt;</vh></v>
1351 <v t="michael.20060616185633.3"><vh>&lt;&lt; update my siblings &gt;&gt;</vh></v>
1352 <v t="michael.20060708104315"><vh>&lt;&lt; highlite context &gt;&gt;</vh></v>
1353 </v>
1354 <v t="mr7771.20060609231152.36"><vh>__find</vh></v>
1355 <v t="michael.20060621182829"><vh>move_context_button</vh></v>
1356 <v t="michael.20061110184924"><vh>toggle_bookmark</vh></v>
1357 <v t="michael.20061110184924.1"><vh>goto_next_bookmark</vh></v>
1358 <v t="michael.20061110184924.2"><vh>goto_prev_bookmark</vh></v>
1359 </v>
1360 <v t="michael.20060622092032"><vh>Methods for external editing</vh>
1361 <v t="michael.20060923124429"><vh>find_resource_references</vh></v>
1362 <v t="michael.20060923124429.1"><vh>find_task_references</vh></v>
1363 <v t="michael.20060929232917"><vh>find_evaluation_references</vh></v>
1364 <v t="michael.20060915105317"><vh>correct_code</vh></v>
1365 <v t="michael.20061031174101.1"><vh>correct_task_code</vh>
1366 <v t="michael.20060923154026"><vh>&lt;&lt; change all relative paths of my sources &gt;&gt;</vh></v>
1367 <v t="michael.20060923154026.1"><vh>&lt;&lt; change the path in all tasks that depend on me &gt;&gt;</vh></v>
1368 </v>
1369 <v t="michael.20061031174101"><vh>correct_resource_code</vh></v>
1370 <v t="michael.20060826120325"><vh>get_attribs</vh>
1371 <v t="michael.20060826121701"><vh>&lt;&lt; filter out child code &gt;&gt;</vh></v>
1372 </v>
1373 <v t="michael.20060704020852"><vh>eval_expression</vh></v>
1374 <v t="michael.20060622092054"><vh>get_expression_range</vh>
1375 <v t="michael.20060622105356"><vh>&lt;&lt; find start of expression &gt;&gt;</vh></v>
1376 <v t="michael.20060622105356.1"><vh>&lt;&lt; find end of expression &gt;&gt;</vh></v>
1377 </v>
1378 <v t="michael.20060622103212"><vh>find_parent_line</vh>
1379 <v t="michael.20060622112139"><vh>&lt;&lt; check if pos is not in a string or comment &gt;&gt;</vh></v>
1380 <v t="michael.20060622112139.1"><vh>&lt;&lt; check if pos is at the end of an expression &gt;&gt;</vh></v>
1381 <v t="michael.20070116154322"><vh>&lt;&lt; check if pos ident is smaller &gt;&gt;</vh></v>
1382 </v>
1383 <v t="michael.20060622105715"><vh>get_expression</vh></v>
1384 <v t="michael.20060628231054"><vh>replace_expression</vh>
1385 <v t="michael.20060929220600"><vh>&lt;&lt; auto indent text &gt;&gt;</vh></v>
1386 </v>
1387 <v t="michael.20060831002737"><vh>insert_expression</vh>
1388 <v t="michael.20060929220600.2"><vh>&lt;&lt; auto indent text &gt;&gt;</vh></v>
1389 </v>
1390 </v>
1391 </v>
1392 </v>
1393 <v t="mr7771.20060608165446.4" tnodeList="mr7771.20060608165446.4,mr7771.20060609151433,mr7771.20060609222452,michael.20060619184051,michael.20060729171506,michael.20060801124835,michael.20060801124835.1,michael.20060801124835.2,michael.20060913150931,michael.20060622093608,michael.20060616193412,michael.20060616193412.1,michael.20060616193412.2,michael.20060616193412.3,michael.20060619235739,michael.20060619234514,mr7771.20060609225045,michael.20061026113601,michael.20060616141344,michael.20060918130215,michael.20060914094858,michael.20060914113429,michael.20060828221603,mr7771.20060614203356,michael.20060616143205,michael.20060616143938,michael.20060616163019,michael.20060621173535,michael.20060616143205.1,michael.20060919173141,michael.20060616141400.1,michael.20060919173141.1,michael.20060919173151,michael.20060919173151.1,michael.20060919173151.2,michael.20060919173151.3,mr7771.20060614124044,mr7771.20060614124044.1,michael.20061026113601.1,michael.20060616163651,michael.20060616163651.1,mr7771.20060614124118,michael.20060907105636,mr7771.20060614124301,mr7771.20060614124952,michael.20061114113543,mr7771.20060614124751,mr7771.20060614124751.1,mr7771.20060614124301.1,mr7771.20060609224238.3,michael.20060828221821,michael.20060918132012,michael.20060828221821.1,michael.20060616144838,mr7771.20060610004423.1,mr7771.20060614134507,mr7771.20060614134507.1,mr7771.20060609223152,michael.20060616204036,michael.20060828221643,michael.20061109163439,michael.20061109173515,michael.20060616204036.1,michael.20060616144838.1,mr7771.20060610005033.6,mr7771.20060614124751.2,michael.20060619232254,mr7771.20060609223152.1,michael.20060901114003,michael.20060918131942,michael.20060901114003.1,michael.20060616144838.2,mr7771.20060610005713.1,mr7771.20060609224238.5,michael.20060828221856,michael.20060918130628,michael.20060828221856.1,michael.20060616144838.3,mr7771.20060614203713.1,mr7771.20060614203713,michael.20060822215648,mr7771.20060614203713.2,michael.20060616175302,michael.20060619164503,michael.20060901205413,michael.20060901205826,michael.20060619164503.2,michael.20060619192815,michael.20060619193517,michael.20060616175302.1,michael.20060616175302.2,mr7771.20060609223152.2,michael.20060619183441,michael.20060918132238,michael.20060828221931,michael.20060619183441.1,michael.20060616144322,mr7771.20060609224238.1,mr7771.20060609224238.2,mr7771.20060610005033,mr7771.20060610005033.1,michael.20060616212150,mr7771.20060613111615,michael.20060616203047,michael.20060616203047.1,michael.20060616144322.1,mr7771.20060613111615.2,mr7771.20060613174236,michael.20060616144322.2,mr7771.20060613174515.1,mr7771.20060609224238.4,michael.20060918131528,michael.20061028120746,michael.20060918131528.1,michael.20060918131528.2,michael.20060616175116,michael.20060616181548,michael.20060616181548.1,michael.20060616182813,michael.20060616175207,michael.20060616175207.1,michael.20060616192508,michael.20060616202740,michael.20060616202740.1,michael.20060616192508.1,michael.20060616192508.2"><vh>@file gui/editor/context.py</vh>
1394 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
1395 <v t="mr7771.20060609222452"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
1396 <v t="michael.20060619184051" a="M"><vh>get_observer_pseudo</vh></v>
1397 <v t="michael.20060729171506"><vh>create_editor_menu</vh>
1398 <v t="michael.20060801124835" a="M"><vh>&lt;&lt; define improve_duplicate_names &gt;&gt;</vh></v>
1399 <v t="michael.20060801124835.1" a="M"><vh>&lt;&lt; define make_groups &gt;&gt;</vh></v>
1400 <v t="michael.20060801124835.2"><vh>&lt;&lt; define create_menu &gt;&gt;</vh>
1401 <v t="michael.20060913150931"><vh>&lt;&lt; extract menu position from title &gt;&gt;</vh></v>
1402 </v>
1403 </v>
1404 <v t="michael.20060622093608"><vh>class ItemEditor</vh></v>
1405 <v t="michael.20060616193412"><vh>class PTask</vh>
1406 <v t="michael.20060616193412.1" a="M"><vh>__init__</vh></v>
1407 <v t="michael.20060616193412.2"><vh>root</vh></v>
1408 <v t="michael.20060616193412.3" a="M"><vh>up</vh></v>
1409 <v t="michael.20060619235739"><vh>__getattr__</vh></v>
1410 <v t="michael.20060619234514" a="M"><vh>_get__all__</vh></v>
1411 </v>
1412 <v t="mr7771.20060609225045" a="M"><vh>class Context</vh>
1413 <v t="michael.20061026113601"><vh>Methods</vh>
1414 <v t="michael.20060616141344"><vh>Interface</vh>
1415 <v t="michael.20060918130215"><vh>get_last_code_item</vh></v>
1416 <v t="michael.20060914094858" a="M"><vh>append_item</vh></v>
1417 <v t="michael.20060914113429"><vh>insert_item</vh></v>
1418 <v t="michael.20060828221603"><vh>make_browser_menu</vh></v>
1419 <v t="mr7771.20060614203356"><vh>activate</vh></v>
1420 <v t="michael.20060616143205"><vh>get_main_completion_list</vh></v>
1421 <v t="michael.20060616143938"><vh>get_sub_completion_list</vh></v>
1422 <v t="michael.20060616163019"><vh>find_object</vh></v>
1423 <v t="michael.20060621173535" a="M"><vh>make_button</vh></v>
1424 </v>
1425 <v t="michael.20060616143205.1"><vh>Methods to Overwrite</vh>
1426 <v t="michael.20060919173141"><vh>get_editors</vh></v>
1427 <v t="michael.20060616141400.1"><vh>can_activate</vh></v>
1428 </v>
1429 <v t="michael.20060919173141.1"><vh>Tool Methods</vh>
1430 <v t="michael.20060919173151"><vh>amend_browser_menu</vh>
1431 <v t="michael.20060919173151.1"><vh>&lt;&lt; insert "Add Attributes" menu &gt;&gt;</vh></v>
1432 <v t="michael.20060919173151.2"><vh>&lt;&lt; insert "Edit Attributes" menu &gt;&gt;</vh></v>
1433 <v t="michael.20060919173151.3" a="M"><vh>&lt;&lt; insert "Remove Attributes" menu &gt;&gt;</vh></v>
1434 </v>
1435 </v>
1436 </v>
1437 <v t="mr7771.20060614124044"><vh>Subclasses</vh>
1438 <v t="mr7771.20060614124044.1"><vh>class CStructureContext</vh>
1439 <v t="michael.20061026113601.1"><vh>Methods</vh>
1440 <v t="michael.20060616163651"><vh>Tool Methods</vh>
1441 <v t="michael.20060616163651.1"><vh>get_object</vh></v>
1442 </v>
1443 <v t="mr7771.20060614124118"><vh>Context Interface</vh>
1444 <v t="michael.20060907105636" a="M"><vh>activate</vh></v>
1445 <v t="mr7771.20060614124301" a="M"><vh>get_main_completion_list</vh></v>
1446 <v t="mr7771.20060614124952"><vh>get_sub_completion_list</vh></v>
1447 <v t="michael.20061114113543"><vh>find_object</vh></v>
1448 </v>
1449 <v t="mr7771.20060614124751"><vh>Methods to Overwrite</vh>
1450 <v t="mr7771.20060614124751.1"><vh>get_default_pseudo</vh></v>
1451 </v>
1452 </v>
1453 <v t="mr7771.20060614124301.1"><vh>Subclasses</vh>
1454 <v t="mr7771.20060609224238.3" a="M"><vh>class CResource</vh>
1455 <v t="michael.20060828221821"><vh>Context Interface</vh>
1456 <v t="michael.20060918132012"><vh>get_last_code_item</vh></v>
1457 <v t="michael.20060828221821.1" a="M"><vh>make_browser_menu</vh></v>
1458 </v>
1459 <v t="michael.20060616144838"><vh>Overwrites (Context)</vh>
1460 <v t="mr7771.20060610004423.1"><vh>can_activate</vh></v>
1461 </v>
1462 <v t="mr7771.20060614134507"><vh>Overwrites (CStructureContext)</vh>
1463 <v t="mr7771.20060614134507.1"><vh>get_default_pseudo</vh></v>
1464 </v>
1465 </v>
1466 <v t="mr7771.20060609223152"><vh>class CTask</vh>
1467 <v t="michael.20060616204036"><vh>Context Interface</vh>
1468 <v t="michael.20060828221643"><vh>make_browser_menu</vh></v>
1469 <v t="michael.20061109163439"><vh>get_main_completion_list</vh>
1470 <v t="michael.20061109173515"><vh>&lt;&lt; add user defined task completions &gt;&gt;</vh></v>
1471 </v>
1472 <v t="michael.20060616204036.1"><vh>get_sub_completion_list</vh></v>
1473 </v>
1474 <v t="michael.20060616144838.1"><vh>Overwrites (Context)</vh>
1475 <v t="mr7771.20060610005033.6"><vh>can_activate</vh></v>
1476 </v>
1477 <v t="mr7771.20060614124751.2"><vh>Overwrites (CStructureContext)</vh>
1478 <v t="michael.20060619232254"><vh>get_object</vh></v>
1479 </v>
1480 </v>
1481 <v t="mr7771.20060609223152.1"><vh>class CProjectDeclaration</vh>
1482 <v t="michael.20060901114003"><vh>Context Interface</vh>
1483 <v t="michael.20060918131942"><vh>get_last_code_item</vh></v>
1484 <v t="michael.20060901114003.1" a="M"><vh>make_browser_menu</vh></v>
1485 </v>
1486 <v t="michael.20060616144838.2"><vh>Overwrites (Context)</vh>
1487 <v t="mr7771.20060610005713.1" a="M"><vh>can_activate</vh></v>
1488 </v>
1489 </v>
1490 <v t="mr7771.20060609224238.5" a="M"><vh>class CObserver</vh>
1491 <v t="michael.20060828221856"><vh>Context Interface</vh>
1492 <v t="michael.20060918130628"><vh>get_last_code_item</vh></v>
1493 <v t="michael.20060828221856.1"><vh>make_browser_menu</vh></v>
1494 </v>
1495 <v t="michael.20060616144838.3"><vh>Overwrites (Context)</vh>
1496 <v t="mr7771.20060614203713.1"><vh>can_activate</vh></v>
1497 </v>
1498 <v t="mr7771.20060614203713"><vh>Overwrites (CStructureContext)</vh>
1499 <v t="michael.20060822215648"><vh>get_editors</vh></v>
1500 <v t="mr7771.20060614203713.2"><vh>get_default_pseudo</vh></v>
1501 </v>
1502 </v>
1503 </v>
1504 </v>
1505 <v t="michael.20060616175302" a="M"><vh>class CObserverFunc</vh>
1506 <v t="michael.20060619164503"><vh>Context Interface</vh>
1507 <v t="michael.20060901205413" a="M"><vh>make_button</vh>
1508 <v t="michael.20060901205826" a="M"><vh>&lt;&lt; get editors &gt;&gt;</vh></v>
1509 </v>
1510 <v t="michael.20060619164503.2" a="M"><vh>find_object</vh>
1511 <v t="michael.20060619192815"><vh>&lt;&lt; define get_observer &gt;&gt;</vh></v>
1512 <v t="michael.20060619193517"><vh>&lt;&lt; get argument description &gt;&gt;</vh></v>
1513 </v>
1514 </v>
1515 <v t="michael.20060616175302.1"><vh>Overwrites (Context)</vh>
1516 <v t="michael.20060616175302.2"><vh>can_activate</vh></v>
1517 </v>
1518 </v>
1519 <v t="mr7771.20060609223152.2" a="M"><vh>class CImport</vh>
1520 <v t="michael.20060619183441"><vh>Interface</vh>
1521 <v t="michael.20060918132238"><vh>get_last_code_item</vh></v>
1522 <v t="michael.20060828221931"><vh>make_browser_menu</vh></v>
1523 <v t="michael.20060619183441.1"><vh>get_main_completion_list</vh></v>
1524 </v>
1525 <v t="michael.20060616144322"><vh>Overwrites (Context)</vh>
1526 <v t="mr7771.20060609224238.1"><vh>can_activate</vh></v>
1527 </v>
1528 </v>
1529 <v t="mr7771.20060609224238.2"><vh>class CMisc</vh>
1530 <v t="mr7771.20060610005033"><vh>Context Interface</vh>
1531 <v t="mr7771.20060610005033.1"><vh>activate</vh></v>
1532 <v t="michael.20060616212150"><vh>get_main_completion_list</vh></v>
1533 </v>
1534 </v>
1535 <v t="mr7771.20060613111615" a="M"><vh>class CResourceOrTask</vh>
1536 <v t="michael.20060616203047"><vh>Context Interface</vh>
1537 <v t="michael.20060616203047.1" a="M"><vh>get_main_completion_list</vh></v>
1538 </v>
1539 <v t="michael.20060616144322.1"><vh>Overwrites (Context)</vh>
1540 <v t="mr7771.20060613111615.2"><vh>can_activate</vh></v>
1541 </v>
1542 </v>
1543 <v t="mr7771.20060613174236" a="M"><vh>class CTaskOrEvaluation</vh>
1544 <v t="michael.20060616144322.2"><vh>Overwrites (Context)</vh>
1545 <v t="mr7771.20060613174515.1"><vh>can_activate</vh></v>
1546 </v>
1547 </v>
1548 <v t="mr7771.20060609224238.4"><vh>class CEvaluation</vh>
1549 <v t="michael.20060918131528"><vh>Interface</vh>
1550 <v t="michael.20061028120746"><vh>activate</vh></v>
1551 <v t="michael.20060918131528.1"><vh>get_last_code_item</vh></v>
1552 <v t="michael.20060918131528.2"><vh>make_browser_menu</vh></v>
1553 </v>
1554 </v>
1555 <v t="michael.20060616175116"><vh>class CBetweenObservers</vh>
1556 <v t="michael.20060616181548"><vh>Context Interface</vh>
1557 <v t="michael.20060616181548.1" a="M"><vh>get_main_completion_list</vh>
1558 <v t="michael.20060616182813" a="M"><vh>&lt;&lt; get_observers &gt;&gt;</vh></v>
1559 </v>
1560 </v>
1561 <v t="michael.20060616175207"><vh>Overwrites (Context)</vh>
1562 <v t="michael.20060616175207.1"><vh>can_activate</vh></v>
1563 </v>
1564 </v>
1565 <v t="michael.20060616192508" a="M"><vh>class CBetweenResource</vh>
1566 <v t="michael.20060616202740"><vh>Context Interface</vh>
1567 <v t="michael.20060616202740.1" a="M"><vh>get_main_completion_list</vh></v>
1568 </v>
1569 <v t="michael.20060616192508.1"><vh>Overwrites (Context)</vh>
1570 <v t="michael.20060616192508.2"><vh>can_activate</vh></v>
1571 </v>
1572 </v>
1573 </v>
1574 </v>
1575 </v>
1576 <v t="mr7771.20060609154937" tnodeList="mr7771.20060609154937,mr7771.20060609151433,mr7771.20060609154937.1,mr7771.20060609154937.2,mr7771.20060609154937.3,mr7771.20060609154937.4,mr7771.20060609155425,mr7771.20060609165227.2,michael.20060927165817,michael.20060927165817.1,michael.20061119042333,michael.20061018160639,michael.20061018160639.1,michael.20061018160639.2,michael.20061018160639.3,michael.20061018160639.4,mr7771.20060609175617,mr7771.20060609154937.17,mr7771.20060609154937.18,mr7771.20060609154937.19,mr7771.20060609154937.22,michael.20060930032329,michael.20061018180317,michael.20061018180317.1,michael.20061018180317.2,michael.20061018180317.3,mr7771.20060609155616,mr7771.20060609154937.14,mr7771.20060609223152.3,mr7771.20060609223152.4,mr7771.20060609223152.5,mr7771.20060609223152.6,michael.20060919151956,michael.20060921000959,michael.20060921135700,mr7771.20060609154937.5,mr7771.20060609154937.7,mr7771.20060609154937.8,mr7771.20060609154937.11,mr7771.20060609154937.15,mr7771.20060609154937.10,mr7771.20060614145216,mr7771.20060614145216.1,mr7771.20060614150422,mr7771.20060609154937.20,mr7771.20060609154937.23,mr7771.20060609160624,michael.20060927171146,michael.20060919202707,michael.20060912164103,mr7771.20060609154937.12,mr7771.20060609222057,mr7771.20060609222057.1,mr7771.20060609222057.2,mr7771.20060609154937.21"><vh>@file gui/editor/browser.py</vh>
1577 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
1578 <v t="mr7771.20060609154937.1"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
1579 <v t="mr7771.20060609154937.2"><vh>class Browser</vh>
1580 <v t="mr7771.20060609154937.3"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
1581 <v t="mr7771.20060609154937.4" a="M"><vh>__init__</vh></v>
1582 <v t="mr7771.20060609155425"><vh>wxPython Methods</vh>
1583 <v t="mr7771.20060609165227.2"><vh>get_prev_visible</vh></v>
1584 <v t="michael.20060927165817"><vh>_on_change</vh>
1585 <v t="michael.20060927165817.1" a="M"><vh>&lt;&lt; define internal insert function &gt;&gt;</vh></v>
1586 <v t="michael.20061018160639"><vh>&lt;&lt; remove item &gt;&gt;</vh>
1587 <v t="michael.20061018160639.1"><vh>&lt;&lt; reinsert still existing children under new parent &gt;&gt;</vh></v>
1588 </v>
1589 <v t="michael.20061018160639.2"><vh>&lt;&lt; insert item &gt;&gt;</vh>
1590 <v t="michael.20061018160639.3" a="M"><vh>&lt;&lt; insert children and modify their old parent &gt;&gt;</vh></v>
1591 </v>
1592 <v t="michael.20061018160639.4" a="M"><vh>&lt;&lt; change item &gt;&gt;</vh></v>
1593 <v t="michael.20061119042333"><vh>&lt;&lt; split and sort changed items list &gt;&gt;</vh></v>
1594 </v>
1595 <v t="mr7771.20060609175617"><vh>_on_idle</vh></v>
1596 <v t="mr7771.20060609154937.17"><vh>_on_size</vh></v>
1597 <v t="mr7771.20060609154937.18"><vh>_on_refresh</vh></v>
1598 <v t="mr7771.20060609154937.19"><vh>_on_sel_changed</vh></v>
1599 <v t="mr7771.20060609154937.22"><vh>_on_right_click</vh></v>
1600 <v t="michael.20060930032329"><vh>_on_begin_drag</vh>
1601 <v t="michael.20061018180317"><vh>&lt;&lt; define temporary event handlers &gt;&gt;</vh></v>
1602 <v t="michael.20061018180317.1" a="M"><vh>&lt;&lt; check if drag_item is moved to a valid position &gt;&gt;</vh></v>
1603 <v t="michael.20061018180317.2"><vh>&lt;&lt; move drag_item &gt;&gt;</vh></v>
1604 <v t="michael.20061018180317.3" a="M"><vh>&lt;&lt; copy extended CodeItem attributes to new items &gt;&gt;</vh></v>
1605 </v>
1606 </v>
1607 <v t="mr7771.20060609155616"><vh>Internal Tool Methods</vh>
1608 <v t="mr7771.20060609154937.14"><vh>init_tree</vh>
1609 <v t="mr7771.20060609223152.3"><vh>&lt;&lt; Create Columns &gt;&gt;</vh></v>
1610 <v t="mr7771.20060609223152.4"><vh>&lt;&lt; Insert Header Nodes &gt;&gt;</vh></v>
1611 <v t="mr7771.20060609223152.5"><vh>&lt;&lt; Set Header Node Fonts &gt;&gt;</vh></v>
1612 <v t="mr7771.20060609223152.6"><vh>&lt;&lt; Set Header Node Titles &gt;&gt;</vh></v>
1613 </v>
1614 <v t="michael.20060919151956"><vh>create_context_menu</vh></v>
1615 <v t="michael.20060921000959"><vh>append_display_eval_data_menu</vh></v>
1616 <v t="michael.20060921135700" a="M"><vh>get_display_eval_data</vh></v>
1617 <v t="mr7771.20060609154937.5"><vh>get_image_index</vh></v>
1618 <v t="mr7771.20060609154937.7"><vh>set_image</vh></v>
1619 <v t="mr7771.20060609154937.8"><vh>get_item_font</vh></v>
1620 <v t="mr7771.20060609154937.11"><vh>get_section</vh></v>
1621 <v t="mr7771.20060609154937.15"><vh>calc_column_widths</vh></v>
1622 <v t="mr7771.20060609154937.10"><vh>modify_item</vh>
1623 <v t="mr7771.20060614145216"><vh>&lt;&lt; make task &gt;&gt;</vh></v>
1624 <v t="mr7771.20060614145216.1"><vh>&lt;&lt; make resource &gt;&gt;</vh></v>
1625 <v t="mr7771.20060614150422"><vh>&lt;&lt; make observer &gt;&gt;</vh></v>
1626 </v>
1627 <v t="mr7771.20060609154937.20"><vh>select_item</vh></v>
1628 <v t="mr7771.20060609154937.23"><vh>move_caret_to_end</vh></v>
1629 </v>
1630 <v t="mr7771.20060609160624"><vh>Public Methods</vh>
1631 <v t="michael.20060927171146"><vh>bind_events</vh></v>
1632 <v t="michael.20060919202707"><vh>on_make_menu</vh></v>
1633 <v t="michael.20060912164103" a="M"><vh>update_menus</vh></v>
1634 <v t="mr7771.20060609154937.12" a="M"><vh>refresh</vh>
1635 <v t="mr7771.20060609222057"><vh>&lt;&lt; Delete children &gt;&gt;</vh></v>
1636 <v t="mr7771.20060609222057.1"><vh>&lt;&lt; Declarations &gt;&gt;</vh></v>
1637 <v t="mr7771.20060609222057.2" a="M"><vh>&lt;&lt; Insert Nodes &gt;&gt;</vh></v>
1638 </v>
1639 <v t="mr7771.20060609154937.21"><vh>update_selection</vh></v>
1640 </v>
1641 </v>
1642 </v>
1643 <v t="michael.20060621134201" tnodeList="michael.20060621134201,mr7771.20060609151433,michael.20060621134201.1,michael.20060621134201.2,michael.20060621134201.3,michael.20060621134201.4,michael.20060621134201.5,michael.20060621134201.6,michael.20060621134201.7,michael.20060621134201.8,michael.20060621134201.9,michael.20060621134201.10,michael.20060621134201.11,michael.20060621134201.12,michael.20060621134220,michael.20060621134201.13,michael.20060621134201.14,michael.20060621134201.15,michael.20060621134201.16,michael.20060621134201.17,michael.20060910154312,michael.20060910154430,michael.20060910160841,michael.20060621134201.18,michael.20060621134201.19,michael.20060621134201.20"><vh>@file gui/editor/docparser.py</vh>
1644 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
1645 <v t="michael.20060621134201.1"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
1646 <v t="michael.20060621134201.2"><vh>_get_indentdation</vh></v>
1647 <v t="michael.20060621134201.3"><vh>unescape</vh></v>
1648 <v t="michael.20060621134201.4"><vh>class DocParser</vh>
1649 <v t="michael.20060621134201.5"><vh>__init__</vh></v>
1650 <v t="michael.20060621134201.6"><vh>clear</vh></v>
1651 <v t="michael.20060621134201.7"><vh>parse_fields</vh></v>
1652 <v t="michael.20060621134201.8"><vh>parse_methods</vh></v>
1653 <v t="michael.20060621134201.9"><vh>parse_description</vh></v>
1654 </v>
1655 <v t="michael.20060621134201.10"><vh>class DocBase</vh>
1656 <v t="michael.20060621134201.11"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
1657 <v t="michael.20060621134201.12"><vh>argspec</vh></v>
1658 <v t="michael.20060621134220"><vh>get_doc</vh></v>
1659 </v>
1660 <v t="michael.20060621134201.13"><vh>class ClassDoc</vh>
1661 <v t="michael.20060621134201.14"><vh>__init__</vh></v>
1662 <v t="michael.20060621134201.15"><vh>get_doc</vh></v>
1663 <v t="michael.20060621134201.16"><vh>constructor</vh></v>
1664 <v t="michael.20060621134201.17"><vh>parse_methods</vh></v>
1665 </v>
1666 <v t="michael.20060910154312"><vh>class ModuleDoc</vh>
1667 <v t="michael.20060910154430"><vh>__init__</vh></v>
1668 <v t="michael.20060910160841"><vh>constructor</vh></v>
1669 </v>
1670 <v t="michael.20060621134201.18"><vh>class FunctionDoc</vh>
1671 <v t="michael.20060621134201.19"><vh>__init__</vh></v>
1672 <v t="michael.20060621134201.20"><vh>constructor</vh></v>
1673 </v>
1674 </v>
1675 <v t="michael.20060910151243"><vh>Attribute Editing</vh>
1676 <v t="michael.20060726163212" tnodeList="michael.20060726163212,mr7771.20060609151433,michael.20060726163212.1,michael.20060727171134,michael.20060727171740,michael.20060727171307.1,michael.20060728153537,michael.20060728153537.1,michael.20060804141028,michael.20060804165131,michael.20060804180304,michael.20060804180304.1,michael.20060804180304.2,michael.20060726163359,michael.20060727172857,michael.20060727172857.1,michael.20060727172857.2,michael.20060727174639,michael.20060727172857.6,michael.20060727172857.7,michael.20060727172857.8,michael.20060727172857.10,michael.20060727172857.12,michael.20060727172857.13,michael.20060727180105.1,michael.20060726163359.1,michael.20060726163359.2,michael.20060726163359.3,michael.20060726163359.4,michael.20060726163359.5,michael.20060726163359.6,michael.20060726163359.7,michael.20060726163359.8,michael.20060726163359.9,michael.20060726163359.10,michael.20060726164252,michael.20060726164252,michael.20060726163359.11,michael.20060726163359.12,michael.20060727180230,michael.20060727180230.1,michael.20060727180230.2,michael.20060727180230.3,michael.20060727180230.4,michael.20060728142041,michael.20060728142041.1,michael.20060728142041.2,michael.20060728142041.3,michael.20060728142041.4,michael.20060727180601,michael.20060727180601.1,michael.20060727180601.2,michael.20060727180601.3,michael.20060727180601.4,michael.20060726163359.13,michael.20060726163359.14,michael.20060726163359.15,michael.20060726163359.16,michael.20060726163359.17,michael.20060804165454,michael.20060804171822,michael.20060726163359.33,michael.20060726163359.34,michael.20060726163359.35,michael.20060726163359.36,michael.20060726163359.37,michael.20060726163359.38,michael.20060726163359.39,michael.20060726163359.40,michael.20060726163359.41,michael.20060726163359.42,michael.20060726163359.43,michael.20060726163359.44,michael.20060726163359.45,michael.20060726163359.46,michael.20060726163359.47,michael.20060726163359.48,michael.20060726163359.49,michael.20060727133714,michael.20060728153749,michael.20060728153749.1,michael.20060728153749.2,michael.20060728153749.3,michael.20060728153749.4,michael.20060728153749.5,michael.20060728153909,michael.20060804143857,michael.20060804143857.1,michael.20060804160034,michael.20060804160034.1,michael.20060804160034.2,michael.20060804143857.2,michael.20060804143857.3,michael.20060804155401,michael.20060804161145,michael.20060804161145.1,michael.20060804161145.2,michael.20060804161145.3,michael.20061002010322,michael.20061002010322.1,michael.20061002010322.2,michael.20061002010322.3,michael.20061002010322.4,michael.20060804162848,michael.20060804162848.1,michael.20060804162848.2,michael.20060804162848.3,michael.20060804162848.4,michael.20060727171038,michael.20060921012719,michael.20060921013326,michael.20060921012812,michael.20060921012921,michael.20060921013128,michael.20060921013326.1,michael.20060921144959,michael.20060921013326.2,michael.20060921013326.3,michael.20060921013128.1,michael.20061002011136,michael.20060921011201,michael.20060929233107,michael.20060929233300,michael.20060929233300.1,michael.20060929233300.2,michael.20060929233300.3,michael.20060929234312,michael.20060929234312.1,michael.20060929234312.2,michael.20060929234312.3,michael.20060927211426,michael.20060929093536,michael.20060929093536.1,michael.20060929093536.2,michael.20061028111855,michael.20060927211706,michael.20060929085858,michael.20060929093303,michael.20060927190516,michael.20061028114303,michael.20060927192936,michael.20060927192936.1,michael.20060927193132,michael.20060927193132.1,michael.20060927193132.2,michael.20060927193132.3,michael.20060927193132.5,michael.20060927193132.6,michael.20060929093150,michael.20060927205317,michael.20060927190516.1,michael.20060927203751,michael.20060927203751.1,michael.20060927185257,michael.20060927203751.2,michael.20060927203751.3,michael.20060927212238,michael.20060927204924,michael.20060927204614,michael.20060927211820,michael.20060929085928,michael.20060927211820.1,michael.20060927204614.1,michael.20060929224036,michael.20061028114303,michael.20060929225058,michael.20060929225128,michael.20060929231203,michael.20060929225233,michael.20060929231103,michael.20060929231329,michael.20061028111855,michael.20060929231415,michael.20060929231534,michael.20060929093303,michael.20060929230703,michael.20060929230703.1,michael.20060929230703.2,michael.20060929230703.3,michael.20060930115815,michael.20060930115917,michael.20060930115917.1,michael.20060930115917.2,michael.20060930115917.3,michael.20060930120528,michael.20060930120528.1,michael.20060930120528.2,michael.20060930120528.3,michael.20060930120528.4,michael.20060921225322,michael.20060921225442,michael.20060921225442.1,michael.20060921225442.2,michael.20060921225442.3,michael.20060921225442.4,michael.20060921225700,michael.20060921230629,michael.20060921230629.1,michael.20060921230629.2,michael.20060921230629.3,michael.20061031175127,michael.20060727171438,michael.20060727171438.1,michael.20060727171438.2,michael.20060907133950,michael.20060727171438.3,michael.20060927174723"><vh>@file gui/editor/attribedit.py</vh>
1677 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
1678 <v t="michael.20060726163212.1"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
1679 <v t="michael.20060727171134"><vh>Token definitions</vh></v>
1680 <v t="michael.20060727171740" a="M"><vh>get_code_root</vh></v>
1681 <v t="michael.20060727171307.1" a="M"><vh>class Evaluator</vh></v>
1682 <v t="michael.20060728153537"><vh>Types</vh>
1683 <v t="michael.20060728153537.1"><vh>class ResourceNames</vh></v>
1684 <v t="michael.20060804141028"><vh>class EvaluationNames</vh></v>
1685 </v>
1686 <v t="michael.20060804165131"><vh>Widgets</vh>
1687 <v t="michael.20060804180304"><vh>class SymbolCombo</vh></v>
1688 <v t="michael.20060804180304.1"><vh>class ShapeCombo</vh></v>
1689 <v t="michael.20060804180304.2"><vh>class BoolEnum</vh></v>
1690 </v>
1691 <v t="michael.20060726163359"><vh>Models and Views</vh>
1692 <v t="michael.20060727172857"><vh>SimpleContainer</vh>
1693 <v t="michael.20060727172857.1"><vh>class SimpleContainer</vh>
1694 <v t="michael.20060727172857.2"><vh>__init__</vh>
1695 <v t="michael.20060727174639" a="M"><vh>&lt;&lt; calculate attribute value &gt;&gt;</vh></v>
1696 </v>
1697 <v t="michael.20060727172857.6" a="M"><vh>show</vh></v>
1698 <v t="michael.20060727172857.7"><vh>code</vh></v>
1699 <v t="michael.20060727172857.8"><vh>realize</vh></v>
1700 </v>
1701 <v t="michael.20060727172857.10" a="M"><vh>class SimpleView</vh>
1702 <v t="michael.20060727172857.12"><vh>prepare</vh></v>
1703 <v t="michael.20060727172857.13"><vh>constitute</vh></v>
1704 </v>
1705 </v>
1706 <v t="michael.20060727180105.1"><vh>Values</vh>
1707 <v t="michael.20060726163359.1"><vh>Delta</vh>
1708 <v t="michael.20060726163359.2" a="M"><vh>class Delta</vh>
1709 <v t="michael.20060726163359.3" a="M"><vh>__init__</vh>
1710 <v t="michael.20060726163359.4"><vh>&lt;&lt; find best value &gt;&gt;</vh></v>
1711 </v>
1712 <v t="michael.20060726163359.5"><vh>__str__</vh></v>
1713 </v>
1714 <v t="michael.20060726163359.6"><vh>class Duration</vh></v>
1715 <v t="michael.20060726163359.7" a="M"><vh>class DeltaView</vh></v>
1716 </v>
1717 <v t="michael.20060726163359.8"><vh>Date</vh>
1718 <v t="michael.20060726163359.9" a="M"><vh>class Date</vh>
1719 <v t="michael.20060726163359.10" a="M"><vh>__init__</vh>
1720 <v t="michael.20060726164252"><vh>&lt;&lt; try alternatives &gt;&gt;</vh></v>
1721 </v>
1722 <v t="michael.20060726163359.11" a="M"><vh>__str__</vh></v>
1723 </v>
1724 <v t="michael.20060726163359.12"><vh>class DateView</vh></v>
1725 </v>
1726 <v t="michael.20060727180230"><vh>Float</vh>
1727 <v t="michael.20060727180230.1" a="M"><vh>class Float</vh>
1728 <v t="michael.20060727180230.2"><vh>__init__</vh></v>
1729 <v t="michael.20060727180230.3" a="M"><vh>__str__</vh></v>
1730 </v>
1731 <v t="michael.20060727180230.4"><vh>class FloatView</vh></v>
1732 </v>
1733 <v t="michael.20060728142041"><vh>Int</vh>
1734 <v t="michael.20060728142041.1" a="M"><vh>class Int</vh>
1735 <v t="michael.20060728142041.2"><vh>__init__</vh></v>
1736 <v t="michael.20060728142041.3" a="M"><vh>__str__</vh></v>
1737 </v>
1738 <v t="michael.20060728142041.4"><vh>class IntView</vh></v>
1739 </v>
1740 <v t="michael.20060727180601"><vh>Boolean</vh>
1741 <v t="michael.20060727180601.1" a="M"><vh>class Boolean</vh>
1742 <v t="michael.20060727180601.2"><vh>__init__</vh></v>
1743 <v t="michael.20060727180601.3" a="M"><vh>__str__</vh></v>
1744 </v>
1745 <v t="michael.20060727180601.4" a="M"><vh>class BooleanView</vh></v>
1746 </v>
1747 <v t="michael.20060726163359.13"><vh>String</vh>
1748 <v t="michael.20060726163359.14" a="M"><vh>class String</vh>
1749 <v t="michael.20060726163359.15"><vh>__init__</vh></v>
1750 <v t="michael.20060726163359.16" a="M"><vh>__str__</vh></v>
1751 </v>
1752 <v t="michael.20060726163359.17"><vh>class StringView</vh></v>
1753 </v>
1754 <v t="michael.20060804165454"><vh>Symbol</vh></v>
1755 <v t="michael.20060804171822"><vh>Shape</vh></v>
1756 <v t="michael.20060726163359.33"><vh>MultiText</vh>
1757 <v t="michael.20060726163359.34" a="M"><vh>class MultiText</vh>
1758 <v t="michael.20060726163359.35"><vh>__init__</vh></v>
1759 <v t="michael.20060726163359.36"><vh>__str__</vh></v>
1760 </v>
1761 <v t="michael.20060726163359.37" a="M"><vh>class MultiTextView</vh>
1762 <v t="michael.20060726163359.38"><vh>prepare</vh></v>
1763 </v>
1764 </v>
1765 <v t="michael.20060726163359.39"><vh>DateTimeRanges</vh>
1766 <v t="michael.20060726163359.40"><vh>class DateTimeRange</vh>
1767 <v t="michael.20060726163359.41"><vh>__init__</vh></v>
1768 <v t="michael.20060726163359.42"><vh>_set_start</vh></v>
1769 <v t="michael.20060726163359.43"><vh>__str__</vh></v>
1770 </v>
1771 <v t="michael.20060726163359.44" a="M"><vh>class DateTimeRanges</vh>
1772 <v t="michael.20060726163359.45"><vh>__init__</vh></v>
1773 <v t="michael.20060726163359.46"><vh>__str__</vh></v>
1774 </v>
1775 <v t="michael.20060726163359.47" a="M"><vh>class TimeRangesView</vh>
1776 <v t="michael.20060726163359.48"><vh>create_controls</vh></v>
1777 <v t="michael.20060726163359.49"><vh>prepare</vh></v>
1778 </v>
1779 </v>
1780 <v t="michael.20060727133714"><vh>WorkingTimes</vh>
1781 <v t="michael.20060728153749" a="M"><vh>WorkingTime</vh></v>
1782 <v t="michael.20060728153749.1" a="M"><vh>WorkingTimes</vh>
1783 <v t="michael.20060728153749.2" a="M"><vh>__init__</vh></v>
1784 <v t="michael.20060728153749.3"><vh>__str__</vh></v>
1785 </v>
1786 <v t="michael.20060728153749.4" a="M"><vh>WorkingTimesView</vh></v>
1787 <v t="michael.20060728153749.5"><vh>WorkingTimeGrid</vh></v>
1788 </v>
1789 <v t="michael.20060728153909"><vh>Resources</vh>
1790 <v t="michael.20060804143857" a="M"><vh>class Resource</vh></v>
1791 <v t="michael.20060804143857.1" a="M"><vh>class ResourceSet</vh>
1792 <v t="michael.20060804160034" a="M"><vh>__init__</vh></v>
1793 <v t="michael.20060804160034.1"><vh>__str__</vh></v>
1794 <v t="michael.20060804160034.2" a="M"><vh>check_constraints</vh></v>
1795 </v>
1796 <v t="michael.20060804143857.2" a="M"><vh>class ResourceSetView</vh></v>
1797 <v t="michael.20060804143857.3"><vh>class ResourceGrid</vh></v>
1798 </v>
1799 <v t="michael.20060804155401"><vh>ColorSet</vh>
1800 <v t="michael.20060804161145"><vh>class Color</vh></v>
1801 <v t="michael.20060804161145.1"><vh>class ColorGrid</vh></v>
1802 <v t="michael.20060804161145.2"><vh>class ColorSet</vh></v>
1803 <v t="michael.20060804161145.3" a="M"><vh>class ColorSetView</vh></v>
1804 </v>
1805 <v t="michael.20061002010322"><vh>TwoColorSet</vh>
1806 <v t="michael.20061002010322.1"><vh>class TwoColor</vh></v>
1807 <v t="michael.20061002010322.2"><vh>class TwoColorGrid</vh></v>
1808 <v t="michael.20061002010322.3"><vh>class TwoColorSet</vh></v>
1809 <v t="michael.20061002010322.4" a="M"><vh>class ColorSetView</vh></v>
1810 </v>
1811 <v t="michael.20060804162848"><vh>ColorMap</vh>
1812 <v t="michael.20060804162848.1"><vh>class ColorLimit</vh></v>
1813 <v t="michael.20060804162848.2"><vh>class ColorLimitGrid</vh></v>
1814 <v t="michael.20060804162848.3"><vh>class ColorMap</vh></v>
1815 <v t="michael.20060804162848.4" a="M"><vh>class ColorMapView</vh></v>
1816 </v>
1817 </v>
1818 </v>
1819 <v t="michael.20060727171038"><vh>Editors</vh>
1820 <v t="michael.20060921012719" a="M"><vh>SingletonEditor</vh>
1821 <v t="michael.20060921013326"><vh>Editor Interface</vh>
1822 <v t="michael.20060921012812"><vh>apply</vh></v>
1823 <v t="michael.20060921012921"><vh>apply_browser_menu</vh></v>
1824 <v t="michael.20060921013128" a="M"><vh>activate</vh></v>
1825 </v>
1826 <v t="michael.20060921013326.1"><vh>Internals</vh>
1827 <v t="michael.20060921144959"><vh>realize</vh></v>
1828 <v t="michael.20060921013326.2"><vh>cancel</vh></v>
1829 </v>
1830 <v t="michael.20060921013326.3"><vh>Overwrites</vh>
1831 <v t="michael.20060921013128.1"><vh>init_attributes</vh></v>
1832 <v t="michael.20061002011136"><vh>realize_code</vh></v>
1833 </v>
1834 </v>
1835 <v t="michael.20060921011201"><vh>Evaluation Editors</vh>
1836 <v t="michael.20060929233107" a="M"><vh>print_evaluation_references</vh></v>
1837 <v t="michael.20060929233300"><vh>class EvaluationReferencePrinter</vh>
1838 <v t="michael.20060929233300.1"><vh>apply</vh></v>
1839 <v t="michael.20060929233300.2"><vh>apply_browser_menu</vh></v>
1840 <v t="michael.20060929233300.3"><vh>activate</vh></v>
1841 </v>
1842 <v t="michael.20060929234312" a="M"><vh>class EvaluationRemover</vh>
1843 <v t="michael.20060929234312.1"><vh>apply</vh></v>
1844 <v t="michael.20060929234312.2"><vh>apply_browser_menu</vh></v>
1845 <v t="michael.20060929234312.3" a="M"><vh>activate</vh></v>
1846 </v>
1847 <v t="michael.20060927211426"><vh>class ProjectEditorMixin</vh>
1848 <v t="michael.20060929093536"><vh>Attribute Manipulation</vh>
1849 <v t="michael.20060929093536.1"><vh>_set_project</vh></v>
1850 <v t="michael.20060929093536.2"><vh>_set_scenario</vh></v>
1851 </v>
1852 <v t="michael.20061028111855"><vh>apply</vh></v>
1853 <v t="michael.20060927211706"><vh>apply_browser_menu</vh></v>
1854 <v t="michael.20060929085858"><vh>init_attributes</vh></v>
1855 <v t="michael.20060929093303"><vh>realize_code</vh></v>
1856 </v>
1857 <v t="michael.20060927190516"><vh>class ProjectCreator</vh>
1858 <v t="michael.20061028114303"><vh>apply</vh></v>
1859 <v t="michael.20060927192936"><vh>apply_browser_menu</vh></v>
1860 <v t="michael.20060927192936.1"><vh>init_attributes</vh></v>
1861 <v t="michael.20060927193132"><vh>Attribute Manipulation</vh>
1862 <v t="michael.20060927193132.1"><vh>_construct_name</vh></v>
1863 <v t="michael.20060927193132.2"><vh>_set_project</vh></v>
1864 <v t="michael.20060927193132.3" a="M"><vh>_set_scenario</vh></v>
1865 </v>
1866 <v t="michael.20060927193132.5"><vh>check_constraints</vh></v>
1867 <v t="michael.20060927193132.6"><vh>realize_code</vh></v>
1868 <v t="michael.20060929093150"><vh>__str__</vh></v>
1869 </v>
1870 <v t="michael.20060927205317" a="M"><vh>class ProjectEditor</vh></v>
1871 <v t="michael.20060927190516.1" a="M"><vh>class ProjectView</vh>
1872 <v t="michael.20060927203751"><vh>prepare</vh></v>
1873 <v t="michael.20060927203751.1" a="M"><vh>constitute</vh>
1874 <v t="michael.20060927185257" a="M"><vh>&lt;&lt; fill project combo &gt;&gt;</vh></v>
1875 </v>
1876 <v t="michael.20060927203751.2"><vh>state_changed</vh></v>
1877 </v>
1878 <v t="michael.20060927203751.3" a="M"><vh>class BalancedProjectCreator</vh>
1879 <v t="michael.20060927212238"><vh>init_attributes</vh></v>
1880 <v t="michael.20060927204924"><vh>__str__</vh></v>
1881 <v t="michael.20060927204614" a="M"><vh>check_constraints</vh></v>
1882 </v>
1883 <v t="michael.20060927211820"><vh>class BalancedProjectEditor</vh>
1884 <v t="michael.20060929085928"><vh>apply_browser_menu</vh></v>
1885 <v t="michael.20060927211820.1"><vh>init_attributes</vh></v>
1886 </v>
1887 <v t="michael.20060927204614.1"><vh>class BalancedProjectView</vh></v>
1888 <v t="michael.20060929224036"><vh>class AdjustedProjectCreator</vh>
1889 <v t="michael.20061028114303"><vh>apply</vh></v>
1890 <v t="michael.20060929225058"><vh>apply_browser_menu</vh></v>
1891 <v t="michael.20060929225128"><vh>init_attributes</vh></v>
1892 <v t="michael.20060929231203"><vh>check_constraints</vh></v>
1893 <v t="michael.20060929225233"><vh>realize_code</vh></v>
1894 <v t="michael.20060929231103"><vh>__str__</vh></v>
1895 </v>
1896 <v t="michael.20060929231329"><vh>class AdjustedProjectEditor</vh>
1897 <v t="michael.20061028111855"><vh>apply</vh></v>
1898 <v t="michael.20060929231415"><vh>apply_browser_menu</vh></v>
1899 <v t="michael.20060929231534"><vh>init_attributes</vh></v>
1900 <v t="michael.20060929093303"><vh>realize_code</vh></v>
1901 </v>
1902 <v t="michael.20060929230703" a="M"><vh>class AdjustedProjectView</vh>
1903 <v t="michael.20060929230703.1"><vh>prepare</vh></v>
1904 <v t="michael.20060929230703.2"><vh>constitute</vh>
1905 <v t="michael.20060929230703.3" a="M"><vh>&lt;&lt; fill base combo &gt;&gt;</vh></v>
1906 </v>
1907 </v>
1908 </v>
1909 <v t="michael.20060930115815"><vh>Import Editors</vh>
1910 <v t="michael.20060930115917"><vh>class ImportRemover</vh>
1911 <v t="michael.20060930115917.1"><vh>apply</vh></v>
1912 <v t="michael.20060930115917.2"><vh>apply_browser_menu</vh></v>
1913 <v t="michael.20060930115917.3" a="M"><vh>activate</vh></v>
1914 </v>
1915 <v t="michael.20060930120528"><vh>class ImportCreator</vh>
1916 <v t="michael.20060930120528.1"><vh>__init__</vh></v>
1917 <v t="michael.20060930120528.2"><vh>apply</vh></v>
1918 <v t="michael.20060930120528.3"><vh>apply_browser_menu</vh></v>
1919 <v t="michael.20060930120528.4"><vh>activate</vh></v>
1920 </v>
1921 </v>
1922 <v t="michael.20060921225322"><vh>NameEditor</vh>
1923 <v t="michael.20060921225442"><vh>class NameEditor</vh>
1924 <v t="michael.20060921225442.1"><vh>apply_browser_menu</vh></v>
1925 <v t="michael.20060921225442.2"><vh>init_attributes</vh></v>
1926 <v t="michael.20060921225442.3"><vh>check_constraints</vh></v>
1927 <v t="michael.20060921225442.4"><vh>realize_code</vh></v>
1928 </v>
1929 <v t="michael.20060921225700" a="M"><vh>class NameEditorView</vh></v>
1930 </v>
1931 <v t="michael.20060921230629"><vh>class RenameEditor</vh>
1932 <v t="michael.20060921230629.1"><vh>apply_browser_menu</vh></v>
1933 <v t="michael.20060921230629.2"><vh>init_attributes</vh></v>
1934 <v t="michael.20060921230629.3"><vh>realize_code</vh></v>
1935 <v t="michael.20061031175127"><vh>correct_code</vh></v>
1936 </v>
1937 <v t="michael.20060727171438" a="M"><vh>class AttributeEditor</vh>
1938 <v t="michael.20060727171438.1"><vh>__init__</vh></v>
1939 <v t="michael.20060727171438.2"><vh>apply</vh></v>
1940 <v t="michael.20060907133950" a="M"><vh>apply_browser_menu</vh></v>
1941 <v t="michael.20060727171438.3" a="M"><vh>activate</vh></v>
1942 </v>
1943 </v>
1944 <v t="michael.20060927174723"><vh>Assign Editors</vh></v>
1945 </v>
1946 <v t="michael.20060622093346" tnodeList="michael.20060622093346,mr7771.20060609151433,michael.20060622093402,michael.20060623163022,michael.20060626130414,michael.20060627153216,michael.20060626130823,michael.20060626130019,michael.20060627153941,michael.20060627153941.1,michael.20060622234836,michael.20060727171523,michael.20060727171523.1,michael.20060727171523.2,michael.20060727174639,michael.20060727171523.5,michael.20060817140817,michael.20060727171523.6,michael.20060727171523.7,michael.20060727171523.8,michael.20060727171523.10,michael.20060727171523.11,michael.20060817145008,michael.20060817142344,michael.20060727171523.12,michael.20060727171523.13,michael.20060817144005,michael.20060817115302,michael.20060817145008.1,michael.20060817145008.2,michael.20060817145008.3,michael.20060817145030,michael.20060817115302.1,michael.20060817115418,michael.20060727171523.14,michael.20060901190834,michael.20060901190851,michael.20060901190952,michael.20060627100623,michael.20060627124836,michael.20060627125439,michael.20060915191847,michael.20060627172634,michael.20060627172805,michael.20060627172805.1,michael.20060628221722,michael.20060627125048,michael.20060627150618,michael.20060627150618.1,michael.20060627150618.2,michael.20060627124836.1,michael.20060628221746,michael.20060628221243,michael.20060627125048.1,michael.20060623001958.7,michael.20060727171038.1,michael.20060727171038.4,michael.20060923161713,michael.20060923162103,michael.20060923162103.1,michael.20060923162103.2,michael.20060923162103.3,michael.20060923140956,michael.20060923140956.1,michael.20060923140956.2,michael.20060923140956.3,michael.20060918124853,michael.20060918124853.1,michael.20060918124853.2,michael.20060918124853.3,michael.20060915234005,michael.20060915234005.1,michael.20060915234005.2,michael.20060915234005.3,michael.20060921012719.1,michael.20060913132734,michael.20060921230035,michael.20060914103351,michael.20060914103204.1,michael.20060913152318.2,michael.20060914103204.2,michael.20060914103403,michael.20060914104037,michael.20060914104037.1,michael.20061026114634,michael.20061026124000,michael.20061026114839,michael.20061026125228,michael.20060929093303,michael.20061026130909,michael.20060622093827,michael.20060727174303,michael.20060622095823"><vh>@file gui/editor/task.py</vh>
1947 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
1948 <v t="michael.20060622093402"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
1949 <v t="michael.20060623163022"><vh>ExpressionEvaluator</vh>
1950 <v t="michael.20060626130414"><vh>class PathWrapper</vh></v>
1951 <v t="michael.20060627153216" a="M"><vh>class AttributeWrapper</vh></v>
1952 <v t="michael.20060626130823"><vh>class ValueWrapper</vh></v>
1953 <v t="michael.20060626130019"><vh>class TaskEvaluator</vh>
1954 <v t="michael.20060627153941"><vh>&lt;&lt; define path variables &gt;&gt;</vh></v>
1955 <v t="michael.20060627153941.1" a="M"><vh>&lt;&lt; define wmax and wmin &gt;&gt;</vh></v>
1956 </v>
1957 </v>
1958 <v t="michael.20060622234836"><vh>Models and Views</vh>
1959 <v t="michael.20060727171523"><vh>ScenarioContainer</vh>
1960 <v t="michael.20060727171523.1"><vh>class ScenarioContainer</vh>
1961 <v t="michael.20060727171523.2"><vh>__init__</vh>
1962 <v t="michael.20060727174639" a="M"><vh>&lt;&lt; calculate attribute value &gt;&gt;</vh></v>
1963 </v>
1964 <v t="michael.20060727171523.5" a="M"><vh>remove_scenario</vh></v>
1965 <v t="michael.20060817140817"><vh>add_scenario</vh></v>
1966 <v t="michael.20060727171523.6" a="M"><vh>show</vh></v>
1967 <v t="michael.20060727171523.7" a="M"><vh>code</vh></v>
1968 <v t="michael.20060727171523.8"><vh>realize</vh></v>
1969 </v>
1970 <v t="michael.20060727171523.10" a="M"><vh>class ScenarioView</vh>
1971 <v t="michael.20060727171523.11" a="M"><vh>create_controls</vh></v>
1972 <v t="michael.20060817145008"><vh>remove_scenario</vh></v>
1973 <v t="michael.20060817142344"><vh>add_scenario</vh></v>
1974 <v t="michael.20060727171523.12" a="M"><vh>prepare</vh></v>
1975 <v t="michael.20060727171523.13"><vh>constitute</vh></v>
1976 <v t="michael.20060817144005" a="M"><vh>modify_subview</vh></v>
1977 </v>
1978 <v t="michael.20060817115302" a="M"><vh>class NewScenario</vh>
1979 <v t="michael.20060817145008.1"><vh>__init__</vh></v>
1980 <v t="michael.20060817145008.2" a="M"><vh>get_scenarios</vh></v>
1981 <v t="michael.20060817145008.3"><vh>show</vh></v>
1982 <v t="michael.20060817145030"><vh>realize</vh></v>
1983 </v>
1984 <v t="michael.20060817115302.1" a="M"><vh>class NewScenarioView</vh>
1985 <v t="michael.20060817115418"><vh>constitute</vh></v>
1986 <v t="michael.20060727171523.14"><vh>update_scenarios</vh></v>
1987 </v>
1988 </v>
1989 <v t="michael.20060901190834"><vh>Balance</vh>
1990 <v t="michael.20060901190851"><vh>__init__</vh></v>
1991 <v t="michael.20060901190952" a="M"><vh>__str__</vh></v>
1992 </v>
1993 <v t="michael.20060627100623"><vh>RefDate</vh>
1994 <v t="michael.20060627124836" a="M"><vh>class RefDate</vh>
1995 <v t="michael.20060627125439"><vh>__init__</vh>
1996 <v t="michael.20060915191847" a="M"><vh>&lt;&lt; define path_argument &gt;&gt;</vh></v>
1997 <v t="michael.20060627172634" a="M"><vh>&lt;&lt; add predecessor with lag &gt;&gt;</vh></v>
1998 <v t="michael.20060627172805"><vh>&lt;&lt; add predecessor without lag &gt;&gt;</vh></v>
1999 <v t="michael.20060627172805.1"><vh>&lt;&lt; set fixed date &gt;&gt;</vh></v>
2000 </v>
2001 <v t="michael.20060628221722" a="M"><vh>__str__</vh></v>
2002 </v>
2003 <v t="michael.20060627125048" a="M"><vh>class RefDateView</vh>
2004 <v t="michael.20060627150618"><vh>create_controls</vh></v>
2005 <v t="michael.20060627150618.1"><vh>prepare</vh></v>
2006 <v t="michael.20060627150618.2"><vh>constitute</vh></v>
2007 </v>
2008 <v t="michael.20060627124836.1" a="M"><vh>class Predecessor</vh>
2009 <v t="michael.20060628221746" a="M"><vh>to_string</vh></v>
2010 <v t="michael.20060628221243" a="M"><vh>check_constraints</vh></v>
2011 </v>
2012 <v t="michael.20060627125048.1"><vh>class PredecessorGrid</vh></v>
2013 </v>
2014 </v>
2015 <v t="michael.20060623001958.7"><vh>Editors</vh>
2016 <v t="michael.20060727171038.1"><vh>class ScenarioAttributeEditor</vh>
2017 <v t="michael.20060727171038.4"><vh>activate</vh></v>
2018 </v>
2019 <v t="michael.20060923161713" a="M"><vh>print_task_references</vh></v>
2020 <v t="michael.20060923162103"><vh>class TaskRemover</vh>
2021 <v t="michael.20060923162103.1"><vh>apply</vh></v>
2022 <v t="michael.20060923162103.2"><vh>apply_browser_menu</vh></v>
2023 <v t="michael.20060923162103.3" a="M"><vh>activate</vh></v>
2024 </v>
2025 <v t="michael.20060923140956"><vh>class TaskReferencePrinter</vh>
2026 <v t="michael.20060923140956.1"><vh>apply</vh></v>
2027 <v t="michael.20060923140956.2"><vh>apply_browser_menu</vh></v>
2028 <v t="michael.20060923140956.3"><vh>activate</vh></v>
2029 </v>
2030 <v t="michael.20060918124853"><vh>class TaskIndenter</vh>
2031 <v t="michael.20060918124853.1"><vh>apply</vh></v>
2032 <v t="michael.20060918124853.2"><vh>apply_browser_menu</vh></v>
2033 <v t="michael.20060918124853.3" a="M"><vh>activate</vh></v>
2034 </v>
2035 <v t="michael.20060915234005"><vh>class TaskUnindenter</vh>
2036 <v t="michael.20060915234005.1"><vh>apply</vh></v>
2037 <v t="michael.20060915234005.2"><vh>apply_browser_menu</vh></v>
2038 <v t="michael.20060915234005.3" a="M"><vh>activate</vh></v>
2039 </v>
2040 <v t="michael.20060921012719.1" a="M"><vh>class TaskRenamer</vh></v>
2041 <v t="michael.20060913132734"><vh>class TaskCreator</vh>
2042 <v t="michael.20060921230035"><vh>apply_browser_menu</vh></v>
2043 <v t="michael.20060914103351"><vh>realize_code</vh></v>
2044 </v>
2045 <v t="michael.20060914103204.1"><vh>class SubTaskCreator</vh>
2046 <v t="michael.20060913152318.2"><vh>insert_code</vh></v>
2047 </v>
2048 <v t="michael.20060914103204.2"><vh>class TaskSiblingCreator</vh>
2049 <v t="michael.20060914103403"><vh>insert_code</vh></v>
2050 </v>
2051 <v t="michael.20060914104037"><vh>class TaskSiblingBeforeCreator</vh>
2052 <v t="michael.20060914104037.1"><vh>insert_code</vh></v>
2053 </v>
2054 <v t="michael.20061026114634" a="M"><vh>class ProjectTaskCreator</vh>
2055 <v t="michael.20061026124000"><vh>realize_code</vh></v>
2056 <v t="michael.20061026114839"><vh>apply_browser_menu</vh></v>
2057 </v>
2058 <v t="michael.20061026125228"><vh>class ProjectTaskRenamer</vh>
2059 <v t="michael.20060929093303"><vh>realize_code</vh></v>
2060 <v t="michael.20061026130909"><vh>__str__</vh></v>
2061 </v>
2062 <v t="michael.20060622093827"><vh>class ScenarioAttributeEditor</vh></v>
2063 <v t="michael.20060727174303"><vh>class AttributeEditor</vh></v>
2064 </v>
2065 <v t="michael.20060622095823"><vh>Assign Editors</vh></v>
2066 </v>
2067 <v t="michael.20060804041654" tnodeList="michael.20060804041654,mr7771.20060609151433,michael.20060804041905,michael.20060918134452,michael.20060923160547,michael.20060923160547.1,michael.20060923160547.2,michael.20060923160547.3,michael.20060923160547.4,michael.20060923134450,michael.20060923134450.1,michael.20060923134450.2,michael.20060923134450.3,michael.20060918135024,michael.20060918135024.5,michael.20060921144552.1,michael.20060804041820"><vh>@file gui/editor/resource.py</vh>
2068 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
2069 <v t="michael.20060804041905"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
2070 <v t="michael.20060918134452"><vh>Editors</vh>
2071 <v t="michael.20060923160547" a="M"><vh>print_resource_references</vh></v>
2072 <v t="michael.20060923160547.1"><vh>class ResourceRemover</vh>
2073 <v t="michael.20060923160547.2"><vh>apply</vh></v>
2074 <v t="michael.20060923160547.3"><vh>apply_browser_menu</vh></v>
2075 <v t="michael.20060923160547.4" a="M"><vh>activate</vh></v>
2076 </v>
2077 <v t="michael.20060923134450" a="M"><vh>class ReferencePrinter</vh>
2078 <v t="michael.20060923134450.1"><vh>apply</vh></v>
2079 <v t="michael.20060923134450.2"><vh>apply_browser_menu</vh></v>
2080 <v t="michael.20060923134450.3"><vh>activate</vh></v>
2081 </v>
2082 <v t="michael.20060918135024"><vh>class ResourceCreator</vh>
2083 <v t="michael.20060918135024.5"><vh>realize_code</vh></v>
2084 </v>
2085 <v t="michael.20060921144552.1"><vh>class ResourceRenamer</vh></v>
2086 </v>
2087 <v t="michael.20060804041820"><vh>Assign Editors</vh></v>
2088 </v>
2089 <v t="michael.20060804044438" tnodeList="michael.20060804044438,michael.20060804044438.1,michael.20060804044438.2,michael.20060804151253,michael.20060804140428,michael.20060804180304.3,michael.20060804183602,michael.20060804183602.1,michael.20060804183602.2,michael.20060804183602.3,michael.20060804183602.4,michael.20060804183602.5,michael.20060804183602.6,michael.20060804183602.7,michael.20060804183602.8,michael.20060804183602.9,michael.20060821122847,michael.20060909120029,michael.20060909120029.1,michael.20060804145158,michael.20060804140428.12,michael.20060804145710,michael.20060804140428.13,michael.20060804145403,michael.20060804140428.15,michael.20060804140428.1,michael.20060804140428.2,michael.20060804140428.3,michael.20060804140428.7,michael.20061002015044,michael.20060804140428.8,michael.20060804140428.9,michael.20060804140428.10,michael.20060902013502,michael.20060906020656,michael.20060906020656.1,michael.20060906020656.2,michael.20060906020907,michael.20060906005234,michael.20060906020338,michael.20060906020338.1,michael.20060906020338.2,michael.20060906182627,michael.20060910220708,michael.20060906020656.3,michael.20060906020656.4,michael.20060804044506,michael.20060804044506.1,michael.20060901201827,michael.20060804172453,michael.20060821191020,michael.20060804172453.3,michael.20060901200906,michael.20060901202023,michael.20060901201020,michael.20060901201924,michael.20060907134327,michael.20060921230339,michael.20061002022123,michael.20061002022123.1,michael.20061002022123.2,michael.20061002022123.3,michael.20061002020357,michael.20060930134539,michael.20061002020357.1,michael.20061002020357.2,michael.20061002020357.3,michael.20061002020357.4,michael.20061002020357.5,michael.20061002020357.6,michael.20061002020357.7,michael.20061002020357.8,michael.20061002020357.9,michael.20061002020357.10,michael.20061002020357.11,michael.20061002020357.12,michael.20061002020357.13,michael.20061002020357.14,michael.20061002020357.15,michael.20061002020357.16,michael.20061002020357.17,michael.20060804120410,michael.20060921225151,michael.20060821115933"><vh>@file gui/editor/observer.py</vh>
2090 <v t="michael.20060804044438.1"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
2091 <v t="michael.20060804044438.2"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
2092 <v t="michael.20060804151253"><vh>class ObserverEvaluator</vh></v>
2093 <v t="michael.20060804140428"><vh>Models and Views</vh>
2094 <v t="michael.20060804180304.3"><vh>Property</vh>
2095 <v t="michael.20060804183602"><vh>Widgets</vh>
2096 <v t="michael.20060804183602.1"><vh>class BoolEnum</vh></v>
2097 <v t="michael.20060804183602.2"><vh>class FamilyCombo</vh></v>
2098 <v t="michael.20060804183602.3"><vh>class WeightCombo</vh></v>
2099 <v t="michael.20060804183602.4"><vh>class SizeCombo</vh></v>
2100 <v t="michael.20060804183602.5"><vh>class VariantEnum</vh></v>
2101 <v t="michael.20060804183602.6"><vh>class LinestyleEnum</vh></v>
2102 <v t="michael.20060804183602.7"><vh>class JoinstyleEnum</vh></v>
2103 <v t="michael.20060804183602.8"><vh>class StyleEnum</vh></v>
2104 </v>
2105 <v t="michael.20060804183602.9"><vh>class Property</vh></v>
2106 <v t="michael.20060821122847"><vh>class PropertySet</vh></v>
2107 <v t="michael.20060909120029"><vh>class PropertySetView</vh></v>
2108 <v t="michael.20060909120029.1"><vh>class PropertyGrid</vh></v>
2109 </v>
2110 <v t="michael.20060804145158"><vh>Evaluation</vh>
2111 <v t="michael.20060804140428.12"><vh>class Evaluation</vh>
2112 <v t="michael.20060804145710"><vh>__init__</vh></v>
2113 <v t="michael.20060804140428.13"><vh>__str__</vh></v>
2114 </v>
2115 <v t="michael.20060804145403"><vh>class EvaluationView</vh></v>
2116 <v t="michael.20060804140428.15"><vh>class EvaluationGrid</vh></v>
2117 </v>
2118 <v t="michael.20060804140428.1"><vh>MultiEvaluation</vh>
2119 <v t="michael.20060804140428.2"><vh>class MultiEvaluation</vh>
2120 <v t="michael.20060804140428.3"><vh>__init__</vh></v>
2121 <v t="michael.20060804140428.7"><vh>__str__</vh></v>
2122 <v t="michael.20061002015044"><vh>check_constraints</vh></v>
2123 </v>
2124 <v t="michael.20060804140428.8"><vh>class MultiEvaluationView</vh>
2125 <v t="michael.20060804140428.9"><vh>create_controls</vh></v>
2126 <v t="michael.20060804140428.10"><vh>prepare</vh></v>
2127 </v>
2128 </v>
2129 <v t="michael.20060902013502"><vh>Column</vh>
2130 <v t="michael.20060906020656"><vh>class Column</vh></v>
2131 <v t="michael.20060906020656.1"><vh>class ColumnSet</vh>
2132 <v t="michael.20060906020656.2"><vh>__init__</vh>
2133 <v t="michael.20060906020907"><vh>&lt;&lt; get the data attribute value &gt;&gt;</vh></v>
2134 <v t="michael.20060906005234"><vh>&lt;&lt; create the choice list for column values &gt;&gt;</vh></v>
2135 <v t="michael.20060906020338"><vh>&lt;&lt; get the code_item, that creates the columns &gt;&gt;</vh></v>
2136 <v t="michael.20060906020338.1"><vh>&lt;&lt; get column values &gt;&gt;</vh></v>
2137 <v t="michael.20060906020338.2"><vh>&lt;&lt; get column headers &gt;&gt;</vh></v>
2138 </v>
2139 <v t="michael.20060906182627"><vh>realize</vh></v>
2140 <v t="michael.20060910220708"><vh>get_object_attribs</vh></v>
2141 </v>
2142 <v t="michael.20060906020656.3"><vh>class ColumnSetView</vh></v>
2143 <v t="michael.20060906020656.4"><vh>class ColumnGrid</vh></v>
2144 </v>
2145 </v>
2146 <v t="michael.20060804044506"><vh>Editors</vh>
2147 <v t="michael.20060804044506.1"><vh>class AttributeEditor</vh>
2148 <v t="michael.20060901201827"><vh>apply</vh></v>
2149 </v>
2150 <v t="michael.20060804172453"><vh>class PropertyEditor</vh>
2151 <v t="michael.20060821191020"><vh>__init__</vh></v>
2152 <v t="michael.20060804172453.3"><vh>activate</vh></v>
2153 </v>
2154 <v t="michael.20060901200906"><vh>class ColumnEditor</vh>
2155 <v t="michael.20060901202023"><vh>__init__</vh></v>
2156 <v t="michael.20060901201020"><vh>apply</vh></v>
2157 <v t="michael.20060901201924"><vh>activate</vh></v>
2158 <v t="michael.20060907134327"><vh>apply_browser_menu</vh></v>
2159 </v>
2160 <v t="michael.20060921230339"><vh>class ObserverRenamer</vh></v>
2161 <v t="michael.20061002022123"><vh>class ObserverRemover</vh>
2162 <v t="michael.20061002022123.1"><vh>apply</vh></v>
2163 <v t="michael.20061002022123.2"><vh>apply_browser_menu</vh></v>
2164 <v t="michael.20061002022123.3"><vh>activate</vh></v>
2165 </v>
2166 <v t="michael.20061002020357"><vh>ObserverCreator</vh>
2167 <v t="michael.20060930134539"><vh>class ObserverCreator</vh>
2168 <v t="michael.20061002020357.1"><vh>apply_browser_menu</vh></v>
2169 <v t="michael.20061002020357.2"><vh>init_attributes</vh></v>
2170 <v t="michael.20061002020357.3"><vh>realize_code</vh></v>
2171 <v t="michael.20061002020357.4"><vh>check_constraints</vh></v>
2172 <v t="michael.20061002020357.5"><vh>set_observer</vh></v>
2173 </v>
2174 <v t="michael.20061002020357.6"><vh>class ObserverCreatorView</vh>
2175 <v t="michael.20061002020357.7"><vh>create_controls</vh></v>
2176 <v t="michael.20061002020357.8"><vh>prepare</vh></v>
2177 <v t="michael.20061002020357.9"><vh>constitute</vh>
2178 <v t="michael.20061002020357.10"><vh>&lt;&lt; fill observer list &gt;&gt;</vh>
2179 <v t="michael.20061002020357.11"><vh>&lt;&lt; find observers &gt;&gt;</vh>
2180 <v t="michael.20061002020357.12"><vh>&lt;&lt; filter out non valid modules &gt;&gt;</vh></v>
2181 <v t="michael.20061002020357.13"><vh>&lt;&lt; get public attribs of module &gt;&gt;</vh></v>
2182 <v t="michael.20061002020357.14"><vh>&lt;&lt; add observer image in img_list &gt;&gt;</vh></v>
2183 </v>
2184 <v t="michael.20061002020357.15"><vh>&lt;&lt; fill list control &gt;&gt;</vh></v>
2185 </v>
2186 </v>
2187 <v t="michael.20061002020357.16"><vh>state_changed</vh></v>
2188 <v t="michael.20061002020357.17"><vh>_on_select_item</vh></v>
2189 </v>
2190 </v>
2191 </v>
2192 <v t="michael.20060804120410"><vh>Editor Assignment</vh>
2193 <v t="michael.20060921225151"><vh>Assign Editors</vh></v>
2194 <v t="michael.20060821115933"><vh>class EditorRegistry</vh></v>
2195 </v>
2196 </v>
2197 </v>
2198 </v>
2199 <v t="michael.20060918141622"><vh>ChartView</vh>
2200 <v t="mr7771.20060609152050" tnodeList="mr7771.20060609152050,mr7771.20060609151433,mr7771.20060609152050.1,mr7771.20060609152050.2,mr7771.20060609152050.3,mr7771.20060609152050.4,mr7771.20060609152050.5,mr7771.20060609152050.6,mr7771.20060609152050.7,mr7771.20060609152050.8,mr7771.20060609152050.9,mr7771.20060609152050.10,mr7771.20060609152050.11,mr7771.20060609152050.12,mr7771.20060609152050.13,mr7771.20060609152050.14,mr7771.20060609152050.15,mr7771.20060609152050.16,mr7771.20060609152050.17,mr7771.20060609152050.18,mr7771.20060609152050.19,michael.20060703173400,mr7771.20060609152050.20,mr7771.20060609152050.27,mr7771.20060609152050.23,mr7771.20060609152050.22,mr7771.20060609152050.26,mr7771.20060609152050.43,michael.20060703173400.1,mr7771.20060609152050.21,mr7771.20060609152050.36,mr7771.20060609152050.40,mr7771.20060609152050.44,mr7771.20060609152050.45,mr7771.20060609152050.47,michael.20060703173400.2,mr7771.20060609152050.24,mr7771.20060609152050.25,mr7771.20060609152050.30,mr7771.20060609152050.31,mr7771.20060609152050.32,mr7771.20060609152050.33,mr7771.20060609152050.46,michael.20060703173400.3,mr7771.20060609152050.37,mr7771.20060609152050.39,michael.20060703173400.4,mr7771.20060609152050.28,mr7771.20060609152050.29,mr7771.20060609152050.34,mr7771.20060609152050.35,mr7771.20060609152050.38,mr7771.20060609152050.41,mr7771.20060609152050.42,mr7771.20060609152050.48,mr7771.20060609152050.49,mr7771.20060609152050.50,mr7771.20060609152050.52,michael.20060703173400.5,mr7771.20060609152050.51,mr7771.20060609152050.53,mr7771.20060609152050.54,mr7771.20060609152050.55,mr7771.20060609152050.56,mr7771.20060609152050.57,mr7771.20060609152050.58,mr7771.20060609152050.59,mr7771.20060609152050.60,mr7771.20060609152050.61,mr7771.20060609152050.62,mr7771.20060609152050.63,mr7771.20060609152050.64,mr7771.20060609152050.65,mr7771.20060609152050.66,mr7771.20060609152050.67,mr7771.20060609152050.68,mr7771.20060609152050.69,mr7771.20060609152050.70,mr7771.20060609152050.71"><vh>@file gui/chartview.py</vh>
2201 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
2202 <v t="mr7771.20060609152050.1"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
2203 <v t="mr7771.20060609152050.2"><vh>_cint</vh></v>
2204 <v t="mr7771.20060609152050.3"><vh>_nop</vh></v>
2205 <v t="mr7771.20060609152050.4"><vh>_chart_factory</vh></v>
2206 <v t="mr7771.20060609152050.5"><vh>_timechart_factory</vh></v>
2207 <v t="mr7771.20060609152050.6"><vh>class _ErrorChart</vh>
2208 <v t="mr7771.20060609152050.7"><vh>&lt;&lt; class _ErrorChart declarations &gt;&gt;</vh></v>
2209 <v t="mr7771.20060609152050.8"><vh>create</vh></v>
2210 </v>
2211 <v t="mr7771.20060609152050.9"><vh>class Toolbar</vh>
2212 <v t="mr7771.20060609152050.10"><vh>_init_toolbar</vh></v>
2213 <v t="mr7771.20060609152050.11"><vh>create_menus</vh></v>
2214 <v t="mr7771.20060609152050.12"><vh>make_menu</vh></v>
2215 <v t="mr7771.20060609152050.13"><vh>refresh_buttons</vh></v>
2216 <v t="mr7771.20060609152050.14"><vh>set_history_buttons</vh></v>
2217 <v t="mr7771.20060609152050.15"><vh>set_cursor</vh></v>
2218 <v t="mr7771.20060609152050.16"><vh>draw_rubberband</vh></v>
2219 <v t="mr7771.20060609152050.17"><vh>release</vh></v>
2220 <v t="mr7771.20060609152050.18"><vh>mouse_move</vh></v>
2221 </v>
2222 <v t="mr7771.20060609152050.19"><vh>class ChartView</vh>
2223 <v t="michael.20060703173400"><vh>Init Methods</vh>
2224 <v t="mr7771.20060609152050.20"><vh>__init__</vh></v>
2225 <v t="mr7771.20060609152050.27"><vh>_setup_events</vh></v>
2226 <v t="mr7771.20060609152050.23"><vh>init_scrolling</vh></v>
2227 <v t="mr7771.20060609152050.22"><vh>replace_data</vh></v>
2228 <v t="mr7771.20060609152050.26"><vh>create_chart</vh></v>
2229 <v t="mr7771.20060609152050.43"><vh>setup_scrolling</vh></v>
2230 </v>
2231 <v t="michael.20060703173400.1"><vh>wxPython Methods</vh>
2232 <v t="mr7771.20060609152050.21"><vh>Destroy</vh></v>
2233 <v t="mr7771.20060609152050.36"><vh>_on_timer</vh></v>
2234 <v t="mr7771.20060609152050.40"><vh>_on_size</vh></v>
2235 <v t="mr7771.20060609152050.44"><vh>_on_set_focus</vh></v>
2236 <v t="mr7771.20060609152050.45"><vh>_on_kill_focus</vh></v>
2237 <v t="mr7771.20060609152050.47"><vh>_on_idle</vh></v>
2238 </v>
2239 <v t="michael.20060703173400.2"><vh>Geometry Methods</vh>
2240 <v t="mr7771.20060609152050.24"><vh>scale_figure</vh></v>
2241 <v t="mr7771.20060609152050.25"><vh>check_limits</vh></v>
2242 <v t="mr7771.20060609152050.30"><vh>zoom_to_fit</vh></v>
2243 <v t="mr7771.20060609152050.31"><vh>horz_zoom</vh></v>
2244 <v t="mr7771.20060609152050.32"><vh>vert_zoom</vh></v>
2245 <v t="mr7771.20060609152050.33"><vh>scroll</vh></v>
2246 <v t="mr7771.20060609152050.46"><vh>update_state</vh></v>
2247 </v>
2248 <v t="michael.20060703173400.3"><vh>Matplotlib Events</vh>
2249 <v t="mr7771.20060609152050.37"><vh>mouse_over</vh></v>
2250 <v t="mr7771.20060609152050.39"><vh>mouse_button</vh></v>
2251 </v>
2252 <v t="michael.20060703173400.4"><vh>Misc Methods</vh>
2253 <v t="mr7771.20060609152050.28"><vh>become_visible</vh></v>
2254 <v t="mr7771.20060609152050.29"><vh>duplicate</vh></v>
2255 <v t="mr7771.20060609152050.34"><vh>change_link</vh></v>
2256 <v t="mr7771.20060609152050.35"><vh>deferred</vh></v>
2257 <v t="mr7771.20060609152050.38"><vh>mark_widget</vh></v>
2258 <v t="mr7771.20060609152050.41"><vh>_show_info</vh></v>
2259 <v t="mr7771.20060609152050.42"><vh>mouse_pos_data</vh></v>
2260 <v t="mr7771.20060609152050.48"><vh>show_object</vh></v>
2261 <v t="mr7771.20060609152050.49"><vh>_show_widget</vh></v>
2262 <v t="mr7771.20060609152050.50"><vh>show_x_coord</vh></v>
2263 <v t="mr7771.20060609152050.52"><vh>draw</vh></v>
2264 </v>
2265 <v t="michael.20060703173400.5"><vh>Metapie Methods</vh>
2266 <v t="mr7771.20060609152050.51"><vh>accept_sibling</vh></v>
2267 </v>
2268 </v>
2269 <v t="mr7771.20060609152050.53"><vh>class TimeViewManager</vh>
2270 <v t="mr7771.20060609152050.54"><vh>&lt;&lt; class TimeViewManager declarations &gt;&gt;</vh></v>
2271 <v t="mr7771.20060609152050.55"><vh>get_manager</vh></v>
2272 <v t="mr7771.20060609152050.56"><vh>__init__</vh></v>
2273 <v t="mr7771.20060609152050.57"><vh>register</vh></v>
2274 <v t="mr7771.20060609152050.58"><vh>unregister</vh></v>
2275 <v t="mr7771.20060609152050.59"><vh>update_siblings</vh></v>
2276 <v t="mr7771.20060609152050.60"><vh>_update_scroll_info</vh></v>
2277 <v t="mr7771.20060609152050.61"><vh>update_xlim</vh></v>
2278 <v t="mr7771.20060609152050.62"><vh>shared</vh></v>
2279 <v t="mr7771.20060609152050.63"><vh>get_sibling_pos</vh></v>
2280 </v>
2281 <v t="mr7771.20060609152050.64"><vh>class TimeChartView</vh>
2282 <v t="mr7771.20060609152050.65"><vh>__init__</vh></v>
2283 <v t="mr7771.20060609152050.66"><vh>create_chart</vh></v>
2284 <v t="mr7771.20060609152050.67"><vh>scale_figure</vh></v>
2285 <v t="mr7771.20060609152050.68"><vh>Destroy</vh></v>
2286 <v t="mr7771.20060609152050.69"><vh>accept_sibling</vh></v>
2287 <v t="mr7771.20060609152050.70"><vh>show_x_coord</vh></v>
2288 <v t="mr7771.20060609152050.71"><vh>init_scrolling</vh></v>
2289 </v>
2290 </v>
2291 <v t="michael.20060918141622.1" tnodeList="michael.20060918141622.1,mr7771.20060609151433,michael.20060918141622.2,michael.20060918141622.3,michael.20060918141622.4,michael.20060918141622.5,michael.20060918141622.6,michael.20060918141622.7,michael.20060918141622.8,michael.20060918141622.9,michael.20060918141622.10,michael.20060918141622.11,michael.20060918141622.12,michael.20060918141622.13,michael.20060918141622.14,michael.20060918141622.15,michael.20060918141622.16,michael.20060918141622.17,michael.20060918141622.18,michael.20060918141622.19,michael.20060918141622.20,michael.20060918141622.21,michael.20060918141622.22,michael.20060918141622.23,michael.20060918141622.24,michael.20060918141622.25,michael.20060918141622.26,michael.20060918141622.27,michael.20060918141622.28,michael.20060918141622.29,michael.20060918141622.30,michael.20060918141622.31,michael.20060918141622.32,michael.20060918141622.33,michael.20060918141622.34,michael.20060918141622.35,michael.20060918141622.36,michael.20060918141622.37,michael.20060918141622.38,michael.20060918141622.39,michael.20060918141622.40,michael.20060918141622.41,michael.20060918141622.42,michael.20060918141622.43,michael.20060918141622.44,michael.20060918141622.45,michael.20060918141622.46,michael.20060918141622.47,michael.20060918141622.48,michael.20060918141622.49,michael.20060918141622.50,michael.20060918141622.51,michael.20060918141622.52,michael.20060918141622.53,michael.20060918141622.54,michael.20060918141622.55,michael.20060918141622.56,michael.20060918141622.57,michael.20060918141622.58,michael.20060918141622.59,michael.20060918141622.60,michael.20060918141622.61,michael.20060918141622.62,michael.20060918141622.63,michael.20060918141622.64,michael.20060918141622.65,michael.20060918141622.66,michael.20060918141622.67,michael.20060918141622.68,michael.20060918141622.69,michael.20060918141622.70,michael.20060918141622.71,michael.20060918141622.73,michael.20060918141622.74,michael.20060918141622.75,michael.20060918141622.77,michael.20060918141622.78,michael.20060918141622.80,michael.20060918141622.82,michael.20060918141622.84,michael.20060918141622.86,michael.20060918141622.87,michael.20060918141622.88"><vh>@file gui/print_chart.py</vh>
2292 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
2293 <v t="michael.20060918141622.2"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
2294 <v t="michael.20060918141622.3"><vh>class ChartPrinter</vh>
2295 <v t="michael.20060918141622.4"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
2296 <v t="michael.20060918141622.5"><vh>__init__</vh></v>
2297 <v t="michael.20060918141622.6"><vh>refresh</vh></v>
2298 <v t="michael.20060918141622.7"><vh>reset_valid</vh></v>
2299 <v t="michael.20060918141622.8"><vh>__call__</vh></v>
2300 <v t="michael.20060918141622.9"><vh>_fire_others</vh></v>
2301 <v t="michael.20060918141622.10"><vh>_get_filename</vh></v>
2302 <v t="michael.20060918141622.11"><vh>_set_filename</vh></v>
2303 <v t="michael.20060918141622.12"><vh>_get_unit</vh></v>
2304 <v t="michael.20060918141622.13"><vh>_set_unit</vh></v>
2305 <v t="michael.20060918141622.14"><vh>_get_width</vh></v>
2306 <v t="michael.20060918141622.15"><vh>_set_width</vh></v>
2307 <v t="michael.20060918141622.16"><vh>_get_height</vh></v>
2308 <v t="michael.20060918141622.17"><vh>_set_height</vh></v>
2309 <v t="michael.20060918141622.18"><vh>_get_dpi</vh></v>
2310 <v t="michael.20060918141622.19"><vh>_set_dpi</vh></v>
2311 <v t="michael.20060918141622.20"><vh>calc_media_size</vh></v>
2312 <v t="michael.20060918141622.21"><vh>calc_command</vh></v>
2313 <v t="michael.20060918141622.22"><vh>add_command_attributes</vh></v>
2314 <v t="michael.20060918141622.23"><vh>check_constraints</vh></v>
2315 <v t="michael.20060918141622.24"><vh>save</vh></v>
2316 <v t="michael.20060918141622.25"><vh>call_ps2pdf</vh></v>
2317 </v>
2318 <v t="michael.20060918141622.26"><vh>class LimitsPrinter</vh>
2319 <v t="michael.20060918141622.27"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
2320 <v t="michael.20060918141622.28"><vh>__init__</vh></v>
2321 <v t="michael.20060918141622.29"><vh>zoom</vh></v>
2322 <v t="michael.20060918141622.30"><vh>_fire_others</vh></v>
2323 <v t="michael.20060918141622.31"><vh>_set_xmin</vh></v>
2324 <v t="michael.20060918141622.32"><vh>_set_xmax</vh></v>
2325 <v t="michael.20060918141622.33"><vh>_set_ymin</vh></v>
2326 <v t="michael.20060918141622.34"><vh>_set_ymax</vh></v>
2327 <v t="michael.20060918141622.35"><vh>_get_xmin</vh></v>
2328 <v t="michael.20060918141622.36"><vh>_get_xmax</vh></v>
2329 <v t="michael.20060918141622.37"><vh>_get_ymin</vh></v>
2330 <v t="michael.20060918141622.38"><vh>_get_ymax</vh></v>
2331 <v t="michael.20060918141622.39"><vh>set_max_limits</vh></v>
2332 <v t="michael.20060918141622.40"><vh>add_command_attributes</vh></v>
2333 </v>
2334 <v t="michael.20060918141622.41"><vh>class WidgetPrinter</vh>
2335 <v t="michael.20060918141622.42"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
2336 <v t="michael.20060918141622.43"><vh>_get_font_size</vh></v>
2337 <v t="michael.20060918141622.44"><vh>_set_font_size</vh></v>
2338 <v t="michael.20060918141622.45"><vh>add_command_attributes</vh></v>
2339 </v>
2340 <v t="michael.20060918141622.46"><vh>class TimePrinter</vh>
2341 <v t="michael.20060918141622.47"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
2342 <v t="michael.20060918141622.48"><vh>__init__</vh></v>
2343 <v t="michael.20060918141622.49"><vh>_set_tmin</vh></v>
2344 <v t="michael.20060918141622.50"><vh>_set_tmax</vh></v>
2345 <v t="michael.20060918141622.51"><vh>_get_tmin</vh></v>
2346 <v t="michael.20060918141622.52"><vh>_get_tmax</vh></v>
2347 <v t="michael.20060918141622.53"><vh>add_command_attributes</vh></v>
2348 </v>
2349 <v t="michael.20060918141622.54"><vh>class TimeWidgetPrinter</vh></v>
2350 <v t="michael.20060918141622.55"><vh>class TimePlotPrinter</vh>
2351 <v t="michael.20060918141622.56"><vh>add_command_attributes</vh></v>
2352 </v>
2353 <v t="michael.20060918141622.57"><vh>class PointPrinter</vh></v>
2354 <v t="michael.20060918141622.58"><vh>class PrinterView</vh>
2355 <v t="michael.20060918141622.59"><vh>&lt;&lt; declarations &gt;&gt;</vh></v>
2356 <v t="michael.20060918141622.60"><vh>__init__</vh></v>
2357 <v t="michael.20060918141622.61"><vh>create_buttons_controls</vh></v>
2358 <v t="michael.20060918141622.62"><vh>prepare</vh></v>
2359 <v t="michael.20060918141622.63"><vh>modify_subview</vh></v>
2360 <v t="michael.20060918141622.64"><vh>_prepare_others</vh></v>
2361 <v t="michael.20060918141622.65"><vh>button_cancel</vh></v>
2362 <v t="michael.20060918141622.66"><vh>button_save</vh></v>
2363 <v t="michael.20060918141622.67"><vh>make_size_int</vh></v>
2364 <v t="michael.20060918141622.68"><vh>make_size_float</vh></v>
2365 <v t="michael.20060918141622.69"><vh>state_changed</vh></v>
2366 <v t="michael.20060918141622.70"><vh>constitute</vh></v>
2367 </v>
2368 <v t="michael.20060918141622.71"><vh>class LimitsPrinterView</vh>
2369 <v t="michael.20060918141622.73"><vh>_prepare_others</vh></v>
2370 <v t="michael.20060918141622.74"><vh>create_controls</vh></v>
2371 </v>
2372 <v t="michael.20060918141622.75"><vh>class WidgetPrinterView</vh>
2373 <v t="michael.20060918141622.77"><vh>_prepare_others</vh></v>
2374 </v>
2375 <v t="michael.20060918141622.78"><vh>class TimePrinterView</vh></v>
2376 <v t="michael.20060918141622.80"><vh>class TimePlotPrinterView</vh></v>
2377 <v t="michael.20060918141622.82"><vh>class TimeWidgetPrinterView</vh></v>
2378 <v t="michael.20060918141622.84"><vh>class PointPrinterView</vh></v>
2379 <v t="michael.20060918141622.86"><vh>class PrintChart</vh>
2380 <v t="michael.20060918141622.87"><vh>__init__</vh></v>
2381 <v t="michael.20060918141622.88"><vh>ShowModal</vh></v>
2382 </v>
2383 </v>
2384 </v>
2385 <v t="michael.20060621114845" tnodeList="michael.20060621114845,mr7771.20060609151433,michael.20060621114845.1,michael.20060621114845.2,michael.20060622085024,michael.20060622085024.1,michael.20060621114845.3,michael.20060621114845.4,michael.20060621114845.5,michael.20060621114845.6,michael.20060621114845.7,michael.20060705004026,michael.20060621114845.8,michael.20060621114845.10,michael.20060621114845.9,michael.20060705003619,michael.20060621114845.14,michael.20060621114845.15,michael.20060621114845.16,michael.20060705003619.1,michael.20060621114845.33,michael.20060621114845.34,michael.20060621114845.31,michael.20060621114845.28,michael.20060705003619.2,michael.20060621114845.19,michael.20060621114845.20,michael.20060621114845.21,michael.20060705004026.1,michael.20060621114845.22,michael.20060621114845.12,michael.20060705004818,michael.20070116023524,michael.20060621114845.17,michael.20060621114845.18,michael.20060621114845.23,michael.20060621114845.24,michael.20060705004026.2,michael.20060621114845.13,michael.20060621114845.25,michael.20060621114845.26,michael.20060621114845.27,michael.20060621114845.35,michael.20060621114845.36,michael.20060621114845.37,michael.20060621114845.38,michael.20060621114845.39,michael.20060621114845.40,michael.20060621114845.41,michael.20060629005237,michael.20060621114845.42,michael.20060621114845.43,michael.20060621114845.44,michael.20060626184639,michael.20060621114845.45,michael.20060703212350.1,michael.20060703212350,michael.20060621114845.46,michael.20060621120211.7,michael.20060621131531,michael.20060622090146.1,michael.20060621120211.1,michael.20060621120211.2,michael.20060621120211.3,michael.20060724204736,michael.20060621120211.4,michael.20060621120211.5,michael.20060621120211.6,michael.20060621114845.47,michael.20060622090146.2,michael.20060703211129.1,michael.20060703191028,michael.20060703191028.1,michael.20060703211129,michael.20060621114845.48,michael.20060621114845.49,michael.20060621114845.50,michael.20060621114845.51,michael.20060621114845.52,michael.20060621114845.53,michael.20060621114845.54,michael.20060621114845.55,michael.20060621114845.56,michael.20060621114845.57,michael.20060621114845.58,michael.20060621114845.59,michael.20060621114845.60,michael.20060621114845.61,michael.20060621114845.62,michael.20060621114845.63,michael.20060621114845.64,michael.20061106013825,michael.20060621114845.65,michael.20060621114845.66,michael.20060621114845.67,michael.20060621114845.68,michael.20060621114845.69,michael.20060621114845.70,michael.20060621114845.71,michael.20060621114845.72,michael.20060621114845.73,michael.20060621114845.74,michael.20060621114845.75,michael.20070421153201,michael.20060621114845.76,michael.20060621114845.77,michael.20060621114845.78,michael.20060621114845.79,michael.20060919144445,michael.20060621114845.80,michael.20060621114845.81,michael.20060621114845.82,michael.20060621114845.83,michael.20060923134450.4,michael.20060621114845.84"><vh>@file gui/plangui.py</vh>
2386 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
2387 <v t="michael.20060621114845.1"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
2388 <v t="michael.20060621114845.2"><vh>&lt;&lt; Setting Globals &gt;&gt;</vh></v>
2389 <v t="michael.20060622085024"><vh>Tools</vh>
2390 <v t="michael.20060622085024.1"><vh>_import_</vh></v>
2391 <v t="michael.20060621114845.3"><vh>title_of_path</vh></v>
2392 <v t="michael.20060621114845.4"><vh>is_project_file</vh></v>
2393 <v t="michael.20060621114845.5"><vh>getsourcefile</vh></v>
2394 <v t="michael.20060621114845.6"><vh>_generate_menu_wrapper</vh></v>
2395 </v>
2396 <v t="michael.20060621114845.7"><vh>class PlanBuffer</vh>
2397 <v t="michael.20060705004026"><vh>Construct and Destroy Methods</vh>
2398 <v t="michael.20060621114845.8"><vh>__init__</vh></v>
2399 <v t="michael.20060621114845.10"><vh>__del__</vh></v>
2400 <v t="michael.20060621114845.9"><vh>close</vh></v>
2401 </v>
2402 <v t="michael.20060705003619"><vh>Metapie Methods</vh>
2403 <v t="michael.20060621114845.14"><vh>_right_click_</vh></v>
2404 <v t="michael.20060621114845.15"><vh>register</vh></v>
2405 <v t="michael.20060621114845.16"><vh>accept_sibling</vh></v>
2406 </v>
2407 <v t="michael.20060705003619.1"><vh>Mediator Methods</vh>
2408 <v t="michael.20060621114845.33"><vh>goto_source</vh></v>
2409 <v t="michael.20060621114845.34"><vh>find_in_source</vh></v>
2410 <v t="michael.20060621114845.31" a="M"><vh>show_object</vh></v>
2411 <v t="michael.20060621114845.28"><vh>get_edit_view</vh></v>
2412 </v>
2413 <v t="michael.20060705003619.2"><vh>Backup Methods</vh>
2414 <v t="michael.20060621114845.19"><vh>get_backup_file</vh></v>
2415 <v t="michael.20060621114845.20"><vh>remove_backup_file</vh></v>
2416 <v t="michael.20060621114845.21"><vh>save_backup</vh></v>
2417 </v>
2418 <v t="michael.20060705004026.1"><vh>Buffer Methods</vh>
2419 <v t="michael.20060621114845.22"><vh>__deferred_save</vh></v>
2420 <v t="michael.20060621114845.12" a="M"><vh>refresh</vh>
2421 <v t="michael.20060705004818"><vh>&lt;&lt; find path and consider backups &gt;&gt;</vh></v>
2422 <v t="michael.20070116023524"><vh>&lt;&lt; fix efficiency misspelling &gt;&gt;</vh></v>
2423 </v>
2424 <v t="michael.20060621114845.17" a="M"><vh>get_encoding</vh></v>
2425 <v t="michael.20060621114845.18"><vh>save</vh></v>
2426 <v t="michael.20060621114845.23"><vh>save_buffer</vh></v>
2427 <v t="michael.20060621114845.24"><vh>modified</vh></v>
2428 </v>
2429 <v t="michael.20060705004026.2"><vh>Misc Methods</vh>
2430 <v t="michael.20060621114845.13"><vh>__str__</vh></v>
2431 <v t="michael.20060621114845.25"><vh>menu_save_as</vh></v>
2432 <v t="michael.20060621114845.26"><vh>set_focus</vh></v>
2433 <v t="michael.20060621114845.27"><vh>set_menus</vh></v>
2434 <v t="michael.20060621114845.35"><vh>set_observer</vh></v>
2435 <v t="michael.20060621114845.36"><vh>__set_views</vh></v>
2436 </v>
2437 </v>
2438 <v t="michael.20060621114845.37"><vh>class _Executer</vh>
2439 <v t="michael.20060621114845.38"><vh>&lt;&lt; class _Executer declarations &gt;&gt;</vh></v>
2440 <v t="michael.20060621114845.39"><vh>__init__</vh></v>
2441 <v t="michael.20060621114845.40"><vh>get_module</vh></v>
2442 <v t="michael.20060621114845.41"><vh>remove_modules</vh>
2443 <v t="michael.20060629005237" a="M"><vh>&lt;&lt; remove module &gt;&gt;</vh></v>
2444 </v>
2445 <v t="michael.20060621114845.42"><vh>clear_cache</vh></v>
2446 <v t="michael.20060621114845.43" a="M"><vh>execute_plan</vh></v>
2447 <v t="michael.20060621114845.44"><vh>save_execute</vh></v>
2448 <v t="michael.20060626184639"><vh>traceback</vh></v>
2449 <v t="michael.20060621114845.45"><vh>__refresh_active_buffer_list</vh>
2450 <v t="michael.20060703212350.1" a="M"><vh>&lt;&lt; get all loaded source files &gt;&gt;</vh></v>
2451 <v t="michael.20060703212350"><vh>&lt;&lt; add new plan buffers &gt;&gt;</vh></v>
2452 </v>
2453 <v t="michael.20060621114845.46"><vh>__refresh_view_list</vh>
2454 <v t="michael.20060621120211.7"><vh>&lt;&lt; init collections &gt;&gt;</vh></v>
2455 <v t="michael.20060621131531" a="M"><vh>&lt;&lt; define is_valid_module &gt;&gt;</vh></v>
2456 <v t="michael.20060622090146.1"><vh>&lt;&lt; import a possible gui part of the module &gt;&gt;</vh></v>
2457 <v t="michael.20060621120211.1"><vh>&lt;&lt; check if k, v is an observer &gt;&gt;</vh></v>
2458 <v t="michael.20060621120211.2"><vh>&lt;&lt; check if k, v is an project evaluation &gt;&gt;</vh></v>
2459 <v t="michael.20060621120211.3"><vh>&lt;&lt; check if k, v is a resource &gt;&gt;</vh></v>
2460 <v t="michael.20060724204736"><vh>&lt;&lt; check if k, v is a calendar &gt;&gt;</vh></v>
2461 <v t="michael.20060621120211.4"><vh>&lt;&lt; check if k, v has menu &gt;&gt;</vh></v>
2462 <v t="michael.20060621120211.5"><vh>&lt;&lt; assign collections to models &gt;&gt;</vh></v>
2463 <v t="michael.20060621120211.6"><vh>&lt;&lt; create Toolmenu &gt;&gt;</vh></v>
2464 </v>
2465 <v t="michael.20060621114845.47"><vh>__execute_module</vh>
2466 <v t="michael.20060622090146.2"><vh>&lt;&lt; check filename &gt;&gt;</vh></v>
2467 <v t="michael.20060703211129.1"><vh>&lt;&lt; remove modules that have to be reloaded &gt;&gt;</vh></v>
2468 <v t="michael.20060703191028"><vh>&lt;&lt; init main_module &gt;&gt;</vh></v>
2469 <v t="michael.20060703191028.1"><vh>&lt;&lt; fetch code and execute it &gt;&gt;</vh></v>
2470 <v t="michael.20060703211129"><vh>&lt;&lt; find imported modules &gt;&gt;</vh></v>
2471 </v>
2472 </v>
2473 <v t="michael.20060621114845.48"><vh>class ShellView</vh>
2474 <v t="michael.20060621114845.49"><vh>__init__</vh></v>
2475 <v t="michael.20060621114845.50"><vh>_on_get_focus</vh></v>
2476 </v>
2477 <v t="michael.20060621114845.51"><vh>class LoggerView</vh>
2478 <v t="michael.20060621114845.52"><vh>__init__</vh></v>
2479 <v t="michael.20060621114845.53"><vh>_on_get_focus</vh></v>
2480 </v>
2481 <v t="michael.20060621114845.54"><vh>class Session</vh>
2482 <v t="michael.20060621114845.55"><vh>&lt;&lt; class Session declarations &gt;&gt;</vh></v>
2483 <v t="michael.20060621114845.56"><vh>__init__</vh></v>
2484 <v t="michael.20060621114845.57"><vh>end_session</vh></v>
2485 <v t="michael.20060621114845.58"><vh>get_help</vh></v>
2486 <v t="michael.20060621114845.59"><vh>jump_to_file</vh></v>
2487 <v t="michael.20060621114845.60"><vh>set_menus</vh></v>
2488 <v t="michael.20060621114845.61"><vh>add_recent_file</vh></v>
2489 <v t="michael.20060621114845.62"><vh>update_recent_menu</vh></v>
2490 <v t="michael.20060621114845.63"><vh>register</vh></v>
2491 <v t="michael.20060621114845.64"><vh>menu_recalc</vh></v>
2492 <v t="michael.20061106013825"><vh>check_for_correction</vh></v>
2493 <v t="michael.20060621114845.65"><vh>menu_help</vh></v>
2494 <v t="michael.20060621114845.66"><vh>menu_send_project</vh></v>
2495 <v t="michael.20060621114845.67"><vh>menu_howtos</vh></v>
2496 <v t="michael.20060621114845.68"><vh>menu_new</vh></v>
2497 <v t="michael.20060621114845.69"><vh>menu_open</vh></v>
2498 <v t="michael.20060621114845.70"><vh>menu_close</vh></v>
2499 <v t="michael.20060621114845.71"><vh>open_file</vh></v>
2500 <v t="michael.20060621114845.72"><vh>check_modified_buffers</vh></v>
2501 </v>
2502 <v t="michael.20060621114845.73"><vh>showwarning</vh></v>
2503 <v t="michael.20060621114845.74"><vh>check_installation</vh></v>
2504 <v t="michael.20060621114845.75"><vh>check_memory</vh></v>
2505 <v t="michael.20070421153201" a="M"><vh>class TaskBarIcon</vh></v>
2506 <v t="michael.20060621114845.76"><vh>class FacesApp</vh>
2507 <v t="michael.20060621114845.77"><vh>OnInit</vh></v>
2508 <v t="michael.20060621114845.78"><vh>show_splash</vh></v>
2509 <v t="michael.20060621114845.79"><vh>_on_frame_close</vh></v>
2510 <v t="michael.20060919144445"><vh>_on_menu_open</vh></v>
2511 <v t="michael.20060621114845.80"><vh>is_processing</vh></v>
2512 <v t="michael.20060621114845.81"><vh>progress_start</vh></v>
2513 <v t="michael.20060621114845.82"><vh>progress_update</vh></v>
2514 <v t="michael.20060621114845.83"><vh>progress_end</vh></v>
2515 <v t="michael.20060923134450.4"><vh>get_planbuffers</vh></v>
2516 </v>
2517 <v t="michael.20060621114845.84"><vh>main</vh></v>
2518 </v>
2519 <v t="michael.20060703233047" tnodeList="michael.20060703233047,mr7771.20060609151433,michael.20060703233047.1,michael.20060703233047.2,michael.20060703233047.3,michael.20060912153307,michael.20060703233047.4,michael.20060703233047.5,michael.20060703233047.6,michael.20060703233047.7,michael.20060703233047.8,michael.20060703233047.9,michael.20060703233047.10,michael.20060703233047.11,michael.20060703233047.12,michael.20060703233047.13,michael.20060703233047.14,michael.20060703233047.15,michael.20060703233047.16,michael.20060703233047.17,michael.20060703233047.18,michael.20060703233047.19,michael.20060703233047.20,michael.20060703233047.21,michael.20060703233047.22,michael.20060703233047.23,michael.20060703233047.24,michael.20060703233047.25,michael.20060703233047.26,michael.20060703233047.27,michael.20060703233047.28,michael.20060703233047.29,michael.20060703233047.30,michael.20060703233047.31,michael.20060703233047.32,michael.20060703233047.33,michael.20060703233047.34,michael.20060703233047.36,michael.20060703233047.37,michael.20060703233047.38,michael.20060703233047.39,michael.20060703233047.40,michael.20060703233047.41,michael.20060703233047.42,michael.20060703233047.43"><vh>@file gui/repview.py</vh>
2520 <v t="mr7771.20060609151433"><vh>&lt;&lt; Copyright &gt;&gt;</vh></v>
2521 <v t="michael.20060703233047.1"><vh>&lt;&lt; Imports &gt;&gt;</vh></v>
2522 <v t="michael.20060703233047.2"><vh>convert_color</vh></v>
2523 <v t="michael.20060703233047.3"><vh>_report_factory</vh></v>
2524 <v t="michael.20060912153307"><vh>encode</vh></v>
2525 <v t="michael.20060703233047.4"><vh>class _ErrorReport</vh>
2526 <v t="michael.20060703233047.5"><vh>&lt;&lt; class _ErrorReport declarations &gt;&gt;</vh></v>
2527 <v t="michael.20060703233047.6"><vh>make_report</vh></v>
2528 </v>
2529 <v t="michael.20060703233047.7"><vh>class CellRenderer</vh>
2530 <v t="michael.20060703233047.8"><vh>__init__</vh></v>
2531 <v t="michael.20060703233047.9"><vh>Draw</vh></v>
2532 <v t="michael.20060703233047.10"><vh>GetBestSize</vh></v>
2533 <v t="michael.20060703233047.11"><vh>Clone</vh></v>
2534 </v>
2535 <v t="michael.20060703233047.12"><vh>class ReportView</vh>
2536 <v t="michael.20060703233047.13"><vh>__init__</vh></v>
2537 <v t="michael.20060703233047.14"><vh>make_menu</vh></v>
2538 <v t="michael.20060703233047.15"><vh>navigate</vh></v>
2539 <v t="michael.20060703233047.16"><vh>set_grid_notifications</vh></v>
2540 <v t="michael.20060703233047.17"><vh>change_link</vh></v>
2541 <v t="michael.20060703233047.18"><vh>OnLeftDown</vh></v>
2542 <v t="michael.20060703233047.19"><vh>OnRightDown</vh></v>
2543 <v t="michael.20060703233047.20"><vh>OnCellSelect</vh></v>
2544 <v t="michael.20060703233047.21"><vh>menu_print_report</vh></v>
2545 <v t="michael.20060703233047.22"><vh>menu_export_csv</vh></v>
2546 <v t="michael.20060703233047.23"><vh>Destroy</vh></v>
2547 <v t="michael.20060703233047.24"><vh>show_object</vh></v>
2548 <v t="michael.20060703233047.25"><vh>set_cursor</vh></v>
2549 <v t="michael.20060703233047.26"><vh>replace_data</vh></v>
2550 <v t="michael.20060703233047.27"><vh>__fill_grid</vh></v>
2551 <v t="michael.20060703233047.28"><vh>calc_font_size</vh></v>
2552 <v t="michael.20060703233047.29"><vh>accept_sibling</vh></v>
2553 </v>
2554 <v t="michael.20060703233047.30"><vh>class ExportCSV_Model</vh>
2555 <v t="michael.20060703233047.31"><vh>&lt;&lt; class ExportCSV_Model declarations &gt;&gt;</vh></v>
2556 <v t="michael.20060703233047.32"><vh>check_constraints</vh></v>
2557 <v t="michael.20060703233047.33"><vh>exporter</vh></v>
2558 </v>
2559 <v t="michael.20060703233047.34"><vh>class ExportCSV_View</vh>
2560 <v t="michael.20060703233047.36"><vh>prepare</vh></v>
2561 <v t="michael.20060703233047.37"><vh>constitute</vh></v>
2562 <v t="michael.20060703233047.38"><vh>state_changed</vh></v>
2563 <v t="michael.20060703233047.39"><vh>button_cancel</vh></v>
2564 <v t="michael.20060703233047.40"><vh>button_ok</vh></v>
2565 </v>
2566 <v t="michael.20060703233047.41"><vh>class ExportCSV_Dialog</vh>
2567 <v t="michael.20060703233047.42"><vh>__init__</vh></v>
2568 <v t="michael.20060703233047.43"><vh>ShowModal</vh></v>
2569 </v>
2570 </v>
2571 </v>
2572 </v>
2573 </vnodes>
2574 <tnodes>
2575 <t tx="michael.20060616141344"> @others</t>
2576 <t tx="michael.20060616141400.1"></t>
2577 <t tx="michael.20060616143205">def get_main_completion_list(self):
2579 returns the completion list of the context
2581 return ()
2584 </t>
2585 <t tx="michael.20060616143205.1"> @others</t>
2586 <t tx="michael.20060616143938">def get_sub_completion_list(self, name):
2588 returns the completions list of a specific attribute
2590 return ()</t>
2591 <t tx="michael.20060616144322"></t>
2592 <t tx="michael.20060616144322.1"></t>
2593 <t tx="michael.20060616144322.2"></t>
2594 <t tx="michael.20060616144838"></t>
2595 <t tx="michael.20060616144838.1"></t>
2596 <t tx="michael.20060616144838.2"></t>
2597 <t tx="michael.20060616144838.3"></t>
2598 <t tx="michael.20060616151822">compl = self.__completion_list = self.get_session_completions()
2599 try:
2600 if self.context.code_item.obj_type == pyeditor.FUNCTION:
2601 args = self.context.code_item.get_args()
2602 compl += map(lambda a: (a, a), args)
2603 except AttributeError: pass</t>
2604 <t tx="michael.20060616153549">def set_menus(self):
2605 self.model.set_menus()
2607 ctrl = controller()
2608 owner = ctrl.find_view_of(self)
2609 top = ctrl.get_top_menu()
2611 edit_menu = top.make_menu(_("&amp;Edit"), pos=100)
2612 fold_menu = edit_menu.make_menu(_("Fold"), pos=1000)
2613 help_menu = top.make_menu(_("&amp;Help"), pos=99999, id=wx.ID_HELP)
2614 file_menu = top.make_menu(_("&amp;File"))
2616 menu = lambda *args, **kw: edit_menu.make_item(owner, *args, **kw)
2617 def nrc(func):
2618 def no_record_call():
2619 self.no_record_call(func)
2620 return no_record_call
2622 &lt;&lt; create help menu &gt;&gt;
2623 &lt;&lt; create snapshot menu &gt;&gt;
2624 &lt;&lt; create basic edit menus &gt;&gt;
2625 &lt;&lt; create comment menus &gt;&gt;
2626 &lt;&lt; create bookmark menus &gt;&gt;
2627 &lt;&lt; create find menus &gt;&gt;
2628 &lt;&lt; create macro menus &gt;&gt;
2629 &lt;&lt; create context menu &gt;&gt;
2630 &lt;&lt; create correct code menu &gt;&gt;
2631 &lt;&lt; create menu separators &gt;&gt;
2632 &lt;&lt; create fold menus &gt;&gt;
2633 &lt;&lt; create Generate HTML menu &gt;&gt;
2635 return True
2636 </t>
2637 <t tx="michael.20060616162635">obj = self.get_dot_object(text)
2638 if obj:
2639 self.__completion_list = self.make_attrib_list(obj)
2640 else:
2641 self.__completion_list = None
2642 </t>
2643 <t tx="michael.20060616163019">def find_object(self, name):
2645 Find an object by name.
2647 return None</t>
2648 <t tx="michael.20060616163651"> @others</t>
2649 <t tx="michael.20060616163651.1">def get_object(self):
2651 retrieve a valid code or pseudo object
2653 try:
2654 obj = self.code_item.obj
2655 except AttributeError:
2656 obj = self.code_item.obj = self.get_default_pseudo()
2658 return obj
2659 </t>
2660 <t tx="michael.20060616170952">def get_dot_object(self, name):
2661 first_dot = name.index(".")
2662 last_dot = name.rindex(".")
2664 root_name = name[:first_dot]
2665 obj = self.context.find_object(root_name)
2667 if obj is None:
2668 obj = self.guess_object(root_name)
2670 if obj is None:
2671 obj = getattr(self.get_module(), root_name, None)
2673 try:
2674 return eval("obj%s" % name[first_dot:last_dot])
2675 except:
2676 return None
2678 </t>
2679 <t tx="michael.20060616171654">attrib = attrib or self.get_word_at(complete=True)
2680 try:
2681 #attrib contains dots
2682 obj = self.get_dot_object(attrib)
2683 attrib = attrib[attrib.rindex(".") + 1:]
2684 except ValueError:
2685 try:
2686 obj = obj or self.context.code_item.obj
2687 except AttributeError: pass
2688 </t>
2689 <t tx="michael.20060616175116">class CBetweenObservers(Context):
2690 editor = None
2691 @others
2693 Context.context_list.append(CBetweenObservers())</t>
2694 <t tx="michael.20060616175207"></t>
2695 <t tx="michael.20060616175207.1">def can_activate(self, editor, line, prev, next, inside):
2696 def check():
2697 if inside: return False
2698 if is_observer(prev) or is_observer_func(prev): return True
2699 if is_evaluation(prev):
2700 return line &gt; prev.get_last_line() + 1
2702 return is_observer(next)
2704 if check():
2705 self.editor = editor
2706 return True
2707 else:
2708 self.editor = None
2709 return False
2710 </t>
2711 <t tx="michael.20060616175302">class CObserverFunc(Context):
2712 @others
2714 Context.context_list.append(CObserverFunc())</t>
2715 <t tx="michael.20060616175302.1"></t>
2716 <t tx="michael.20060616175302.2">def can_activate(self, editor, line, prev, next, inside):
2717 return is_observer_func(inside)
2718 </t>
2719 <t tx="michael.20060616181548"></t>
2720 <t tx="michael.20060616181548.1">def get_main_completion_list(self):
2721 &lt;&lt; get_observers &gt;&gt;
2722 observers = []
2723 return get_observers(self.editor.get_module(), "", observers) \
2724 + self.editor.get_session_completions()
2725 </t>
2726 <t tx="michael.20060616182813">def get_observers(module, prefix, observers):
2727 if len(prefix.split(".")) &gt; 2: return observers
2729 try:
2730 attribs = module.__all__
2731 except AttributeError:
2732 attribs = dir(module)
2734 for a in attribs:
2735 if a.startswith("_"): continue
2737 obj = getattr(module, a, None)
2738 if isinstance(obj, types.ModuleType):
2739 name = prefix and ".".join((prefix, a)) or a
2740 get_observers(obj, name, observers)
2741 continue
2742 try:
2743 if issubclass(obj, fobserver.Observer):
2744 name = prefix and ".".join((prefix, a)) or a
2745 observers.append(("class %s" % name, "class |My%s(%s):\n" % (a, name)))
2746 except: pass
2747 return observers</t>
2748 <t tx="michael.20060616185633">if not self.context.activate(self, line, prev, next, inside):
2749 #oldc = self.context
2750 for c in Context.context_list:
2751 if self.context is c: continue
2752 if c.activate(self, line, prev, next, inside):
2753 self.context = c
2754 break
2755 else:
2756 c = self.context = Context.default
2757 c.activate(self, line, prev, next, inside)</t>
2758 <t tx="michael.20060616185633.1">self.Refresh(False)
2759 if item: self.GetParent().browser.update_selection(item)
2761 </t>
2762 <t tx="michael.20060616185633.2">line = self.GetLine(line)
2763 try:
2764 attrib_name = line[:line.index("=")].strip()
2765 except ValueError:
2766 attrib_name = None</t>
2767 <t tx="michael.20060616185633.3">if wx.Window_FindFocus() is self:
2768 try:
2769 self.model.show_object(self.GetParent().GetParent(),
2770 self.context.code_item.obj,
2771 attrib_name)
2772 except AttributeError:
2773 pass
2775 self.__last_attrib = attrib_name
2776 </t>
2777 <t tx="michael.20060616192508">class CBetweenResource(Context):
2778 @others
2780 Context.context_list.append(CBetweenResource()) </t>
2781 <t tx="michael.20060616192508.1"></t>
2782 <t tx="michael.20060616192508.2">def can_activate(self, editor, line, prev, next, inside):
2783 if inside: return False
2784 return is_resource(next) \
2785 and (is_resource(prev) \
2786 or is_import(prev) \
2787 and line &gt; prev.get_last_line() + 1)
2789 </t>
2790 <t tx="michael.20060616193412">class PTask(object):
2792 A pseudo task object
2794 __doc__ = ftask.Task.__doc__
2795 __attrib_completions__ = ftask.Task.__attrib_completions__.copy()
2796 __attrib_completions__.update({ "up" : "up", "root" : "root"})
2797 @others
2800 </t>
2801 <t tx="michael.20060616193412.1">def __init__(self, code_item=None):
2802 self.code_item = code_item
2803 self.to_string = self.me = weakref.proxy(self)
2805 if code_item:
2806 self.name = code_item.name
2807 self.dict_children = dict(map(lambda c: (c.name, PTask(c)),
2808 self.code_item.get_children()))
2809 try:
2810 self.title = code_item.obj.title
2811 except AttributeError:
2812 self.title = self.name
2813 else:
2814 self.name = self.title = ""</t>
2815 <t tx="michael.20060616193412.2">def _get_root(self):
2816 last_parent = self.code_item
2817 parent = last_parent.get_parent()
2818 while parent:
2819 last_parent = parent
2820 parent = parent.get_parent()
2822 return PTask(last_parent)
2824 root = property(_get_root)
2825 </t>
2826 <t tx="michael.20060616193412.3">def _get_up(self):
2827 parent = self.code_item.get_parent()
2828 return parent and PTask(parent) or None
2830 up = property(_get_up)</t>
2831 <t tx="michael.20060616202740"></t>
2832 <t tx="michael.20060616202740.1">def get_main_completion_list(self):
2833 return [("class (Resource):", "class |NewResource(Resource):\n")]
2834 </t>
2835 <t tx="michael.20060616203047"></t>
2836 <t tx="michael.20060616203047.1">def get_main_completion_list(self):
2837 import editor
2838 return editor._editor_completions \
2839 + self.editor.get_session_completions() \
2840 + [("class (Resource):", "class |NewResource(Resource):\n"),
2841 ("def NewProject():", "def |NewProject():\n" ) ]
2842 </t>
2843 <t tx="michael.20060616204036"></t>
2844 <t tx="michael.20060616204036.1">def get_sub_completion_list(self, name):
2845 compl = super(CTask, self).get_sub_completion_list(name)
2846 if not compl:
2847 compl = self.code_item.editor.get_session_completions()
2849 compl += [("up", "up"), ("root", "root")]
2850 return compl
2852 </t>
2853 <t tx="michael.20060616212150">def get_main_completion_list(self):
2854 import editor
2855 return editor._editor_completions + self.editor.get_session_completions()
2858 </t>
2859 <t tx="michael.20060616213907">_editor_completions = [ ("faces_show_call_tips", "faces_show_call_tips = False" ),
2860 ("faces_dimmer_color", 'faces_dimmer_color = "#A0A0A0"' ),
2861 ("faces_task_completions",
2862 'faces_task_completions = [ (\'notes\', \'notes = """\\n\\n"""\') ]'),
2863 ("alt_week_locator", "alt_week_locator()") ]</t>
2864 <t tx="michael.20060619145551">@language python
2865 &lt;&lt; Copyright &gt;&gt;
2867 This module contains all classes for project plan objects
2869 &lt;&lt; Imports &gt;&gt;
2871 _is_source = True
2873 STRICT = 3
2874 SLOPPY = 2
2875 SMART = 1
2877 @others
2881 Atttribute mit Bedeutung:
2883 calendar
2884 --------
2885 minimum_time_unit |int in minutes|
2886 working_days_per_week |int in days |
2887 working_days_per_month|int in days |
2888 working_days_per_year |int in days |
2889 working_hours_per_day |int in hours |
2890 vacation | [ one_day, (from, to), .. ] |
2891 working_days
2896 Task
2897 -----
2898 load
2899 start
2901 length
2902 effort
2903 duration
2904 resource
2905 booked_resource
2907 milestone
2908 complete
2909 done
2910 todo
2911 priority
2912 efficiency
2913 buffer
2915 children
2916 depth
2917 index
2918 path
2919 dont_inherit
2921 performed_effort
2922 performed_end
2923 performed_start
2925 sum()
2926 min()
2927 max()
2928 costs()
2929 indent_name()
2930 max_load
2932 copy_src (set: copy all attributes of another task
2933 get: reference of copy)
2935 balance
2937 for gantt
2938 -----
2939 line
2940 accumulate
2945 Resource
2946 ----------
2947 efficiency
2948 load
2949 vacation
2950 max_load
2953 </t>
2954 <t tx="michael.20060619145551.1">import pcalendar
2955 import resource
2956 import types
2957 import sys
2958 import datetime
2959 import operator as op
2960 import warnings
2961 import locale
2962 import weakref
2963 import opcode
2964 import new
2965 try:
2967 except NameError:
2968 from sets import Set as set
2969 </t>
2970 <t tx="michael.20060619145551.2">class _NEVER_USED_:
2971 pass
2973 </t>
2974 <t tx="michael.20060619145551.4">class AttributeError(AttributeError):
2975 &lt;&lt; class AttributeError declarations &gt;&gt;
2976 </t>
2977 <t tx="michael.20060619145551.5">is_frozen = False
2980 </t>
2981 <t tx="michael.20060619145551.6">class RecursionError(Exception):
2982 """This exception is raised in cas of cirular dependencies
2983 within an project"""
2984 &lt;&lt; class RecursionError declarations &gt;&gt;
2985 </t>
2986 <t tx="michael.20060619145551.7">pass
2989 </t>
2990 <t tx="michael.20060619145551.8">class _IncompleteError(Exception):
2991 """This exception is raised, when there is not enough
2992 data specified to calculate as task"""
2993 @others
2994 </t>
2995 <t tx="michael.20060619145551.9">def __init__(self, *args):
2996 if isinstance(args[0], (basestring)):
2997 Exception.__init__(self, *args)
2998 else:
2999 Exception.__init__(self,
3000 "not enough data for calculating task, "\
3001 "maybe you have a recursive reference",
3002 *args)
3003 </t>
3004 <t tx="michael.20060619145551.10">class _MeProxy(object):
3006 A Proxy class for the me attribute of tasks in the compile case
3008 &lt;&lt; declarations &gt;&gt;
3009 @others</t>
3010 <t tx="michael.20060619145551.11">__slots__ = "task"
3012 </t>
3013 <t tx="michael.20060619145551.12">def __init__(self, task):
3014 object.__setattr__(self, "task", task)
3015 </t>
3016 <t tx="michael.20060619145551.13">def __getattr__(self, name):
3017 if self.task._is_frozen:
3018 return getattr(self.task, name)
3020 if name in ("name", "up", "root", "path",
3021 "depth", "index", "calendar",
3022 "children", "resource", "balance"):
3023 return getattr(self.task, name)
3025 value = self.task.__dict__.get(name, _NEVER_USED_)
3026 def make_val(default):
3027 if value is _NEVER_USED_: return default
3028 return value
3030 if name in ("start", "end"):
3031 return self.task._to_start(make_val("1.1.2006"))
3033 if name in ("length", "effort", "duration", "todo", "done",
3034 "buffer", "performed", "performed_effort",
3035 "performed_end", "performed_start",
3036 "performed_work_time" ):
3037 return self.task._to_delta(make_val("0d"))
3039 if name in ("complete", "priority", "efficiency"):
3040 return make_val(0)
3042 if value is _NEVER_USED_:
3043 raise AttributeError("'%s' is not a valid attribute." % (name))
3045 return value
3046 </t>
3047 <t tx="michael.20060619145551.14">def __setattr__(self, name, value):
3048 self.task._set_attrib(name, value)
3049 </t>
3050 <t tx="michael.20060619145551.15">def add_attrib(self, name_or_iter, val=None):
3051 if not isinstance(name_or_iter, str):
3052 for n, v in name_or_iter:
3053 setattr(self, n, v)
3054 else:
3055 setattr(self, name_or_iter, val)
3056 </t>
3057 <t tx="michael.20060619145551.16">class _MeProxyRecalc(_MeProxy):
3059 A Proxy class for the me attribute of tasks in the recalc case
3061 @others
3062 </t>
3063 <t tx="michael.20060619145551.17">def __setattr__(self, name, value):
3064 if self.task._properties.has_key(name):
3065 self.task._set_attrib(name, value)
3066 </t>
3067 <t tx="michael.20060619145551.18">class _MeProxyError(_MeProxy):
3068 &lt;&lt; declarations &gt;&gt;
3069 @others
3070 </t>
3071 <t tx="michael.20060619145551.19">__slots__ = ("task", "attrib", "exc")
3073 </t>
3074 <t tx="michael.20060619145551.20">def __init__(self, task, attrib, exc):
3075 _MeProxy.__init__(self, task)
3076 object.__setattr__(self, "attrib", attrib)
3077 object.__setattr__(self, "exc", exc)
3078 </t>
3079 <t tx="michael.20060619145551.21">def __setattr__(self, name, value):
3080 if name == self.attrib or not self.attrib:
3081 raise self.exc
3082 </t>
3083 <t tx="michael.20060619145551.22">class _MeProxyWarn(_MeProxy):
3084 &lt;&lt; declarations &gt;&gt;
3085 @others
3086 </t>
3087 <t tx="michael.20060619145551.23">__slots__ = ("task", "attrib", "message")
3089 </t>
3090 <t tx="michael.20060619145551.24">def __init__(self, task, attrib, message):
3091 _MeProxy.__init__(self, task)
3092 object.__setattr__(self, "attrib", attrib)
3093 object.__setattr__(self, "message", message)
3094 </t>
3095 <t tx="michael.20060619145551.25">def __setattr__(self, name, value):
3096 if name == self.attrib or not self.attrib:
3097 warnings.warn(self.message, RuntimeWarning, 2)
3098 if not self.attrib:
3099 #warn only one time!
3100 object.__setattr__(self, "attrib", 1)
3101 </t>
3102 <t tx="michael.20060619145551.26">class _Path(object):
3104 This class represents an instrumented path, to
3105 a task. If it points to an attribute of a task, it
3106 not only returns the value of the attribute. You can also
3107 find out the source attribute (task and attribute name)
3108 of the value.
3110 @others
3112 </t>
3113 <t tx="michael.20060619145551.27">def __init__(self, task, path_str):
3114 self._task = task
3115 self._path_str = path_str
3116 </t>
3117 <t tx="michael.20060619145551.28">def __getattr__(self, name):
3118 new = getattr(self._task, name)
3119 if isinstance(new, Task):
3120 return _Path(new, self._path_str + "." + name)
3122 return _ValueWrapper(new, [(self._task, name)])
3123 </t>
3124 <t tx="michael.20060619145551.29">def __str__(self):
3125 return self._path_str
3126 </t>
3127 <t tx="michael.20060619145551.30">def _int_to_arg(value):
3128 return value % 256, value / 256
3129 </t>
3130 <t tx="michael.20060619145551.31">def _correct_labels(old_code, new_code):
3131 &lt;&lt; localize dot variables &gt;&gt;
3132 &lt;&lt; loop initialization &gt;&gt;
3133 while i &lt; n:
3134 op = old_code[i]
3135 nop = new_code[j]
3136 old_new_map[i] = j
3137 i = i + 1
3138 j = j + 1
3139 if op &gt;= HAVE_ARGUMENT:
3140 oparg = old_code[i] + old_code[i + 1] * 256
3141 i = i + 2
3142 j = j + 2
3143 if nop != op:
3144 j += 3 # skip the 3 addition opcodes for attrib access
3145 else:
3146 &lt;&lt; add label if necessary &gt;&gt;
3148 for offset, label in labels.iteritems():
3149 new_offset = old_new_map[offset]
3150 new_label = old_new_map[label]
3151 op = new_code[new_offset - 3]
3152 #change jump arguments
3153 if op in hasjrel:
3154 jump = _int_to_arg(new_label - new_offset)
3155 new_code[new_offset - 2:new_offset] = jump
3156 elif op in hasjabs:
3157 new_code[new_offset - 2:new_offset] = _int_to_arg(new_label)</t>
3158 <t tx="michael.20060619145551.32">def _instrument(func):
3159 &lt;&lt; localize dot variables &gt;&gt;
3160 &lt;&lt; define local functions list_to_dict and is_local &gt;&gt;
3162 #convert code
3163 &lt;&lt; loop initialization &gt;&gt;
3164 while i &lt; n:
3165 if i == next_tab_point:
3166 &lt;&lt; calculate new tab point &gt;&gt;
3168 op = code[i]
3169 i += 1
3170 if op &gt;= HAVE_ARGUMENT:
3171 &lt;&lt; calculate argument &gt;&gt;
3172 i += 2
3174 if opname[op] == "LOAD_GLOBAL":
3175 global_names.add(oparg)
3177 elif opname[op] == "STORE_FAST":
3178 &lt;&lt; change "store fast" to "store attribute" &gt;&gt;
3180 elif opname[op] == "LOAD_FAST":
3181 &lt;&lt; change "load fast" to "load attribute" &gt;&gt;
3183 elif op in jumps:
3184 has_labels = True
3186 new_code.extend((op, arg0, arg1))
3187 else:
3188 new_code.append(op)
3190 if has_labels:
3191 _correct_labels(code, new_code)
3193 &lt;&lt; create new code and function objects and return &gt;&gt;</t>
3194 <t tx="michael.20060619145551.33">def _calc_load(task, resource):
3195 #changed at the resource instance
3196 load = resource.__dict__.get("load")
3197 if load is not None: return load
3199 load = task.__dict__.get("load")
3200 if load is not None: return load
3202 #inherited by the task
3203 return min(task.load, task.max_load, resource.max_load or 100.0)
3204 </t>
3205 <t tx="michael.20060619145551.34">def _calc_maxload(task, resource):
3206 #changed at the resource instance
3207 max_load = resource.__dict__.get("max_load")
3208 if max_load: return max_load
3210 #an explicit load can overwrite max_load
3211 load = max(resource.__dict__.get("load", 0),
3212 task.__dict__.get("load"), 0)
3214 #change at the task
3215 max_load = task.__dict__.get("max_load")
3216 if max_load: return max(max_load, load)
3218 #inherited by the resource
3219 max_load = resource.max_load
3220 if max_load: return max(max_load, load)
3222 #inherited by the task
3223 return max(task.max_load, load)
3224 </t>
3225 <t tx="michael.20060619145551.35">#helper functions for _ValueWrapper
3226 #----------------------------------
3228 def _val(val):
3229 if isinstance(val, _ValueWrapper):
3230 return val._value
3232 return val
3233 </t>
3234 <t tx="michael.20060619145551.36">def _ref(val):
3235 if isinstance(val, _ValueWrapper):
3236 return val._ref
3238 return []
3239 </t>
3240 <t tx="michael.20060619145551.37">def _sref(val, ref):
3241 if isinstance(val, _ValueWrapper):
3242 val._ref = ref</t>
3243 <t tx="michael.20060619145551.38">
3245 class _ValueWrapper(object):
3247 This class represents a value, of a task attribute or
3248 a return value of a task method. It contains the value,
3249 and the supplier of that value
3251 @others
3252 </t>
3253 <t tx="michael.20060619145551.39">def __init__(self, value, ref):
3254 self._value = value
3255 self._ref = ref
3256 </t>
3257 <t tx="michael.20060619145551.40">def _vw(self, operand, *args):
3258 refs = _refsum(map(_ref, args))
3259 vals = map(_val, args)
3260 result = operand(*vals)
3261 return self.__class__(result, refs)
3262 </t>
3263 <t tx="michael.20060619145551.41">def _cmp(self, operand, *args):
3264 refs = _refsum(map(_ref, args))
3265 vals = map(_val, args)
3266 result = operand(*vals)
3267 map(lambda a: _sref(a, refs), args)
3268 return result
3269 </t>
3270 <t tx="michael.20060619145551.42">def __getattr__(self, name): return getattr(self._value, name)
3271 </t>
3272 <t tx="michael.20060619145551.43">def __str__(self): return str(self._value)
3273 </t>
3274 <t tx="michael.20060619145551.44">def __repr__(self): return repr(self._value)
3275 </t>
3276 <t tx="michael.20060619145551.45">def __nonzero__(self): return bool(self._value)
3277 </t>
3278 <t tx="michael.20060619145551.46">def __lt__(self, other): return self._cmp(op.lt, self, other)
3279 </t>
3280 <t tx="michael.20060619145551.47">def __le__(self, other): return self._cmp(op.le, self, other)
3281 </t>
3282 <t tx="michael.20060619145551.48">def __eq__(self, other): return self._cmp(op.eq, self, other)
3283 </t>
3284 <t tx="michael.20060619145551.49">def __ne__(self, other): return self._cmp(op.ne, self, other)
3285 </t>
3286 <t tx="michael.20060619145551.50">def __gt__(self, other): return self._cmp(op.gt, self, other)
3287 </t>
3288 <t tx="michael.20060619145551.51">def __ge__(self, other): return self._cmp(op.ge, self, other)
3289 </t>
3290 <t tx="michael.20060619145551.52">def __add__(self, other): return self._vw(op.add, self, other)</t>
3291 <t tx="michael.20060619145551.53">def __sub__(self, other): return self._vw(op.sub, self, other)
3292 </t>
3293 <t tx="michael.20060619145551.54">def __mul__(self, other): return self._vw(op.mul, self, other)
3294 </t>
3295 <t tx="michael.20060619145551.55">def __floordiv__(self, other): return self._vw(op.floordiv, self, other)
3296 </t>
3297 <t tx="michael.20060619145551.56">def __mod__(self, other): return self._vw(op.mod, self, other)
3298 </t>
3299 <t tx="michael.20060619145551.57">def __divmod__(self, other): return self._vw(op.divmod, self, other)
3300 </t>
3301 <t tx="michael.20060619145551.58">def __pow__(self, other): return self._vw(op.pow, self, other)
3302 </t>
3303 <t tx="michael.20060619145551.59">def __lshift__(self, other): return self._vw(op.lshift, self, other)
3304 </t>
3305 <t tx="michael.20060619145551.60">def __rshift__(self, other): return self._vw(op.rshift, self, other)
3306 </t>
3307 <t tx="michael.20060619145551.61">def __and__(self, other): return self._vw(op.and_, self, other)
3308 </t>
3309 <t tx="michael.20060619145551.62">def __xor__(self, other): return self._vw(op.xor, self, other)
3310 </t>
3311 <t tx="michael.20060619145551.63">def __or__(self, other): return self._vw(op.or_, self, other)
3312 </t>
3313 <t tx="michael.20060619145551.64">def __div__(self, other): return self._vw(op.div, self, other)
3314 </t>
3315 <t tx="michael.20060619145551.65">def __radd__(self, other): return self._vw(op.add, other, self)
3316 </t>
3317 <t tx="michael.20060619145551.66">def __rsub__(self, other): return self._vw(op.sub, other, self)
3318 </t>
3319 <t tx="michael.20060619145551.67">def __rmul__(self, other): return self._vw(op.mul, other, self)
3320 </t>
3321 <t tx="michael.20060619145551.68">def __rdiv__(self, other): return self._vw(op.div, other, self)
3322 </t>
3323 <t tx="michael.20060619145551.69">def __rtruediv__(self, other): return self._vw(op.truediv, other, self)
3324 </t>
3325 <t tx="michael.20060619145551.70">def __rfloordiv__(self, other): return self._vw(op.floordiv, other, self)
3326 </t>
3327 <t tx="michael.20060619145551.71">def __rmod__(self, other): return self._vw(op.mod, other, self)
3328 </t>
3329 <t tx="michael.20060619145551.72">def __rdivmod__(self, other): return self._vw(op.divmod, other, self)
3330 </t>
3331 <t tx="michael.20060619145551.73">def __rpow__(self, other): return self._vw(op.pow, other, self)
3332 </t>
3333 <t tx="michael.20060619145551.74">def __rlshift__(self, other): return self._vw(op.lshift, other, self)
3334 </t>
3335 <t tx="michael.20060619145551.75">def __rrshift__(self, other): return self._vw(op.rshift, other, self)
3336 </t>
3337 <t tx="michael.20060619145551.76">def __rand__(self, other): return self._vw(op.and_, other, self)
3338 </t>
3339 <t tx="michael.20060619145551.77">def __rxor__(self, other): return self._vw(op.xor, other, self)
3340 </t>
3341 <t tx="michael.20060619145551.78">def __ror__(self, other): return self._vw(op.or_, other, self)
3342 </t>
3343 <t tx="michael.20060619145551.79">def __int__(self): return int(self._value)
3344 </t>
3345 <t tx="michael.20060619145551.80">def __long__(self): return long(self._value)
3346 </t>
3347 <t tx="michael.20060619145551.81">def __float__(self): return float(self._value)
3348 </t>
3349 <t tx="michael.20060619145551.82">def __len__(self): return len(self._value)
3350 </t>
3351 <t tx="michael.20060619145551.83">def __iter__(self): return iter(self._value)
3352 </t>
3353 <t tx="michael.20060619145551.84">def __hash__(self): return hash(self._value)
3354 </t>
3355 <t tx="michael.20060619145551.85">class _StringConverter(object):
3356 """This class is a helper for the to_string mechanism
3357 of tasks"""
3358 @others
3359 </t>
3360 <t tx="michael.20060619145551.86">def __init__(self, source, format=None):
3361 self.source = source
3362 self.format = format
3363 </t>
3364 <t tx="michael.20060619145551.87">def __getitem__(self, format):
3365 return _StringConverter(self.source, format)
3366 </t>
3367 <t tx="michael.20060619145551.88">def __getattr__(self, name):
3368 class StrWrapper(object):
3369 def __init__(self, value, name, source, format):
3370 self._value = value
3371 self.name = name
3372 self.source = source
3373 self.format = format
3375 def __call__(self, arg):
3376 formatter = self.source.formatter(self.name,
3377 arg,
3378 self.format)
3379 return formatter(self._value(arg))
3381 value = getattr(self.source, name)
3382 if callable(value):
3383 #for methods the wrapper has to
3384 return StrWrapper(value, name, self.source, self.format)
3386 formatter = self.source.formatter(name, format=self.format)
3387 return formatter(value)
3388 </t>
3389 <t tx="michael.20060619145551.89">class AllocationAlgorithm(object):
3390 """This class is a base for resource allocation algorithms"""
3391 @others
3392 </t>
3393 <t tx="michael.20060619145551.90">def test_allocation(self, task, resource):
3394 """This method simulates the allocation of a specific resource.
3395 It returns a list of values representing the state of the allocation.
3396 The task allocator calls test_allocation for every alternative resource.
3397 It compares the first items of all return lists, and allocates the
3398 resource with the minum first item value"""
3399 return (task.end, )
3400 </t>
3401 <t tx="michael.20060619145551.91">def allocate(self, task, state):
3402 """This method eventually allocates a specific resource.
3403 State is the return list of test_allocation"""
3404 pass
3405 </t>
3406 <t tx="michael.20060619145551.92">class StrictAllocator(AllocationAlgorithm):
3407 """This class implements the STRICT resource allocation"""
3408 @others
3409 </t>
3410 <t tx="michael.20060619145551.93">def _distribute_len_loads(self, task, resource, effort, length):
3411 # A special load calculation, if effort and length are given.
3412 # and the resources have a defined maxload, the load must be
3413 # individually calculated for each resource.
3415 # Formulars: r=resources, t=task
3416 # effort = length * efficiency(t) * sum[load(r) * effiency(r)]
3417 # ==&gt; sum_load = sum[load(r) * effiency(r)]
3418 # = effort / (length * efficiency(t))
3421 sum_load = float(effort) / (task.efficiency * length)
3423 # algorithm:
3424 # The goal is to distribute the load (norm_load) equally
3425 # to all resources. If a resource has a max_load(r) &lt; norm_load
3426 # the load of this resource will be max_load(r), and the other
3427 # resources will have another (higher) norm_load
3429 max_loads = map(lambda r: (_calc_maxload(task, r), r), resource)
3430 max_loads.sort()
3432 efficiency_sum = sum(map(lambda r: r.efficiency, resource))
3433 norm_load = sum_load / efficiency_sum
3435 loads = {}
3436 for max_load, r in max_loads[:-1]:
3437 if max_load &lt; norm_load:
3438 loads[r] = max_load
3439 efficiency_sum -= r.efficiency
3440 sum_load -= max_load * r.efficiency
3441 norm_load = sum_load / efficiency_sum
3442 else:
3443 loads[r] = norm_load
3445 max_load, r = max_loads[-1]
3446 loads[r] = norm_load
3447 return loads
3448 </t>
3449 <t tx="michael.20060619145551.94">def test_allocation(self, task, resource):
3450 effort = task.__dict__.get("effort")
3451 to_start = task._to_start
3452 to_end = task._to_end
3453 to_delta = task._to_delta
3455 if task.performed_end:
3456 start = to_start(max(task.performed_end,
3457 task.root.calendar.now,
3458 task.start))
3459 else:
3460 start = task.start
3461 if task.root.has_actual_data and task.complete == 0:
3462 start = max(start, to_start(task.root.calendar.now))
3464 base_start = to_start(task.performed_start or task.start)
3465 calc_load = lambda r: _calc_load(task, r)
3466 loads = map(lambda r: (r, calc_load(r)), resource)
3468 length = task.__dict__.get("length")
3469 duration = task.__dict__.get("duration")
3470 end = task.__dict__.get("end")
3472 &lt;&lt; correct length &gt;&gt;
3473 &lt;&lt; correct duration &gt;&gt;
3474 &lt;&lt; check end &gt;&gt;
3475 &lt;&lt; correct effort and (re)calculate length &gt;&gt;
3476 &lt;&lt; set adjust_date and delta &gt;&gt;
3478 # find the earliest start date
3479 start, book_load\
3480 = self.balance(task, start, delta, adjust_date,
3481 calc_load, resource)
3483 end = to_end(start + delta)
3484 start = to_start(start)
3486 if effort is None:
3487 #length is frozen ==&gt; a new effort will be calculated
3488 factor = sum(map(lambda a: a[1], loads))
3489 length = end - start
3491 effort = to_delta(length * factor\
3492 + task.performed_effort).round()
3494 return (end, book_load), resource, calc_load, start, effort
3495 </t>
3496 <t tx="michael.20060619145551.95">def allocate(self, task, state):
3497 # now really book the resource
3498 end_bl, resource, calc_load, start, effort = state
3499 end = end_bl[0]
3500 cal = task.root.calendar
3501 to_start = task._to_start
3502 to_end = task._to_end
3503 to_delta = task._to_delta
3505 task.start = task.performed_start \
3506 and to_start(task.performed_start) \
3507 or to_start(start)
3509 task.end = end
3510 task._unfreeze("length")
3511 task._unfreeze("duration")
3512 length = end - start
3514 for r in resource:
3515 book_load = calc_load(r)
3516 work_time = to_delta(length * book_load).round()
3517 r.book_task(task, start, end, book_load, work_time, False)
3519 #the following lines are important to be exactly at this
3520 #positions in that order:
3521 # done and todo are dependend on:
3522 # - the existence of effort (if effort was set or not set)
3523 # - book_task (they can only be calculated, if the task is booked)
3524 # - booked_resource (to get the booked tasks)
3525 task.booked_resource = resource
3526 task.done = task.done
3527 task.todo = task.todo
3528 task.length = end - task.start
3529 task.effort = to_delta(effort + task.performed_effort)
3530 </t>
3531 <t tx="michael.20060619145551.96"> #now effort exists always
3534 def balance(self, task, start, delta, adjust_date,
3535 calc_load, resource):
3536 book_load = max(map(lambda r: r.get_load(task.start, task.scenario), resource))
3537 return start, book_load
3538 </t>
3539 <t tx="michael.20060619145551.97">
3541 class SmartAllocator(StrictAllocator):
3542 @others
3543 </t>
3544 <t tx="michael.20060619145551.98">def balance(self, task, start, delta, adjust_date,
3545 calc_load, resource):
3546 #find the earliest start date, at which all
3547 #resources in the team are free
3549 cal = task.root.calendar
3550 to_start = task._to_start
3551 start = adjust_date(start)
3552 scenario = task.scenario
3554 while True:
3555 #we have finished, when all resources have the
3556 #same next free start date
3557 for r in resource:
3558 max_load = _calc_maxload(task, r)
3559 load = calc_load(r)
3561 #find the next free time of the resource
3562 s = r.find_free_time(start, delta, load, max_load, scenario)
3563 if s != start:
3564 s = to_start(s)
3565 start = adjust_date(s)
3566 break
3567 else:
3568 #only one resource
3569 break
3571 return start, 1.0
3572 </t>
3573 <t tx="michael.20060619145551.99">
3575 class SloppyAllocator(AllocationAlgorithm):
3576 @others
3577 </t>
3578 <t tx="michael.20060619145551.100">def test_allocation(self, task, resource):
3579 if task.__dict__.has_key("effort"):
3580 return self.test_allocation_effort(task, resource)
3582 return self.test_allocation_length(task, resource)
3583 </t>
3584 <t tx="michael.20060619145551.101">def test_allocation_length(self, task, resource):
3585 #length is frozen ==&gt; effort will be calculated
3586 to_start = task._to_start
3587 to_end = task._to_end
3588 to_delta = task._to_delta
3590 end = task.end
3591 if task.performed_end:
3592 start = to_start(max(task.performed_end,
3593 task.root.calendar.now,
3594 start))
3595 else:
3596 start = task.start
3598 base_start = to_start(task.performed_start or task.start)
3599 length = to_delta(max(task.length - (start - base_start), 0))
3600 sum_effort = 0
3601 intervals = []
3602 scenario = task.scenario
3603 for r in resource:
3604 date = start
3605 max_load = _calc_maxload(task, r)
3606 book_load = _calc_load(task, r)
3608 while date &lt; end:
3609 #find free time intervals and add them for booking
3610 endi, load = r.end_of_booking_interval(date, task)
3611 endi = min(endi, end)
3612 endi = to_end(endi)
3614 if book_load &lt;= 0:
3615 #variable book_load ==&gt; calc the maxmimal possible book_load &gt;= (the given book_load)
3616 used_book_load = - book_load
3617 diff_load = max_load - load
3618 if diff_load and diff_load &gt;= book_load:
3619 used_book_load = diff_load
3620 else:
3621 used_book_load = max_load
3622 else:
3623 used_book_load = book_load
3625 if max_load - load &gt;= used_book_load:
3626 intervals.append((r, used_book_load, date, endi))
3627 sum_effort = (endi - date) * used_book_load
3629 date = to_start(endi)
3631 return -sum_effort, end, resource, intervals
3632 </t>
3633 <t tx="michael.20060619145551.102">def test_allocation_effort(self, task, resource):
3634 #effort is frozen ==&gt; length will be calculated
3636 to_start = task._to_start
3637 to_end = task._to_end
3638 to_delta = task._to_delta
3640 intervals = []
3641 effort = task.__dict__.get("effort")
3643 if task.performed_end:
3644 next_date = to_start(max(task.performed_end,
3645 task.root.calendar.now,
3646 task.start))
3647 else:
3648 next_date = task.start
3649 if task.root.has_actual_data and task.complete == 0:
3650 next_date = max(next_date, to_start(task.root.calendar.now))
3652 #walks chronologicly through the booking
3653 #intervals of each resource, and reduces
3654 #the effort for each free interval
3655 #until it becomes 0
3657 alloc_effort = effort
3658 effort -= task.performed_effort
3659 while effort &gt; 0:
3660 date = next_date
3662 interval_resource = []
3663 interval_end = to_start(sys.maxint)
3664 factor = 0
3666 for r in resource:
3667 max_load = _calc_maxload(task, r)
3668 book_load = _calc_load(task, r)
3669 end, load = r.end_of_booking_interval(date, task)
3670 interval_end = to_start(min(end, interval_end))
3672 if book_load &lt;= 0:
3673 #variable book_load ==&gt; calc the maxmimal possible book_load &gt;= (the given book_load)
3674 book_load = - book_load
3675 diff_load = max_load - load
3676 if diff_load and diff_load &gt;= book_load:
3677 book_load = diff_load
3678 else:
3679 book_load = max_load
3681 if book_load + load &lt;= max_load:
3682 resource_factor = book_load * r.efficiency
3683 interval_resource.append((r, book_load, resource_factor))
3684 factor += resource_factor
3688 next_date = interval_end
3689 if factor:
3690 factor *= task.efficiency
3691 length = to_delta(effort / factor).round()
3692 end = date + length
3694 if interval_end &gt;= end:
3695 next_date = interval_end = end
3696 effort = 0
3697 book_end = end
3698 else:
3699 book_end = interval_end
3700 length = book_end - date
3701 minus_effort = length * factor
3702 effort -= minus_effort
3704 book_end = to_end(book_end)
3705 intervals.append((date, book_end, length, interval_resource))
3707 return next_date, alloc_effort, resource, intervals
3708 </t>
3709 <t tx="michael.20060619145551.103">def allocate(self, task, state):
3710 if task.__dict__.has_key("effort"): self.allocate_effort(task, state)
3711 else: self.allocate_length(task, state)
3712 </t>
3713 <t tx="michael.20060619145551.104">def allocate_length(self, task, state):
3714 # now really book the resource
3715 neg_sum_effort, end, resource, intervals = state
3717 cal = task.root.calendar
3718 to_start = task._to_start
3719 to_end = task._to_end
3720 to_delta = task._to_delta
3722 task.start = to_start(task.performed_start or task.start)
3723 task.end = to_end(end)
3724 task._unfreeze("length")
3725 task._unfreeze("duration")
3727 effort = 0
3728 for r, load, s, e in intervals:
3729 work_time = to_delta((e - s) * load).round()
3730 effort += work_time
3731 r.book_task(task, s, e, load, work_time, False)
3733 #see comment at StrictAllocator.allocate
3734 task.booked_resource = resource
3735 task.done = task.done
3736 task.todo = task.todo
3737 task.effort = to_delta(effort + task.performed_effort).round()
3738 </t>
3739 <t tx="michael.20060619145551.105">def allocate_effort(self, task, state):
3740 # now really book the resource
3741 end, effort, resource, intervals = state
3742 to_start = task._to_start
3743 to_end = task._to_end
3744 to_delta = task._to_delta
3746 task.start = task.performed_start \
3747 and to_start(task.performed_start) \
3748 or to_start(intervals[0][0])
3749 task.end = to_end(end)
3750 task._unfreeze("length")
3751 task._unfreeze("duration")
3753 for start, end, length, resources in intervals:
3754 for r, load, factor in resources:
3755 work_time = to_delta(length * load)
3756 r.book_task(task, start, end, load, work_time, False)
3758 task.booked_resource = resource
3759 task.done = task.done
3760 task.todo = task.todo
3761 task.effort = to_delta(effort)
3762 task.length = task.end - task.start
3763 </t>
3764 <t tx="michael.20060619145551.106">def _split_path(path):
3765 try:
3766 index = path.rindex(".")
3767 return path[:index], path[index + 1:]
3768 except:
3769 return path
3770 </t>
3771 <t tx="michael.20060619145551.107">def Multi(val, **kwargs):
3772 """returns a directory for mutlivalued attributes"""
3773 return dict(_default=val, **kwargs)</t>
3774 <t tx="michael.20060619145551.108">def _get_tasks_of_sources(task, attrib_filter="end,start,effort,length,duration"):
3775 #return all source tasks, this task is dependend on
3777 dep_tasks = {}
3779 while task:
3780 for dep in task._sources.values():
3781 for d in dep:
3782 path, attrib = _split_path(d)
3783 if attrib and attrib_filter.find(attrib) &gt;= 0:
3784 dep_tasks[path] = True
3786 task = task.up
3788 return dep_tasks.keys()
3789 </t>
3790 <t tx="michael.20060619145551.109">def _build_balancing_list(tasks):
3792 Returns a specialy sorted list of tasks.
3793 If the tasks will allocate resources in the sorting order of that list
3794 correct balancing is ensured
3797 # first sort the list for attributes
3798 index = 0
3799 balancing_list = [(-t.priority, t.balance, index, t) for index, t in enumerate(tasks)]
3800 balancing_list.sort()
3802 #print
3803 #for p, b, i, t in balancing_list:
3804 # print p, b, i, t.path
3806 balancing_list = [ t for p, b, i, t in balancing_list ]
3808 #now correct the presorted list:
3809 #if task a is dependent on task b, b will be moved before a
3811 done_map = { }
3812 count = len(balancing_list)
3813 while len(done_map) &lt; count:
3814 for i in range(count):
3815 to_inspect = balancing_list[i]
3816 if done_map.has_key(to_inspect):
3817 continue
3819 done_map[to_inspect] = True
3820 break
3821 else:
3822 break
3824 &lt;&lt; define inspect_depends_on &gt;&gt;
3825 for j in range(i + 1, count):
3826 check_task = balancing_list[j]
3827 if done_map.has_key(check_task):
3828 continue
3830 if inspect_depends_on(check_task):
3831 del balancing_list[j]
3832 balancing_list.insert(i, check_task)
3833 i += 1 # to_inspect is now at i + 1
3836 return balancing_list
3837 </t>
3838 <t tx="michael.20060619145551.110">def _as_string(val):
3839 if isinstance(val, basestring):
3840 return '"""%s"""' % val.replace("\n", "\\n")
3842 if isinstance(val, pcalendar._WorkingDateBase):
3843 return '"%s"' % val.strftime("%Y-%m-%d %H:%M")
3845 if isinstance(val, datetime.datetime):
3846 return '"%s"' % val.strftime("%Y-%m-%d %H:%M")
3848 if isinstance(val, datetime.timedelta):
3849 return '"%id %iM"' % (val.days, val.seconds / 60)
3851 if isinstance(val, tuple):
3852 result = map(_as_string, val)
3853 return "(%s)" % ", ".join(result)
3855 if isinstance(val, list):
3856 result = map(_as_string, val)
3857 return "[%s]" % ", ".join(result)
3859 if isinstance(val, resource.Resource):
3860 return val._as_string()
3862 if isinstance(val, Task):
3863 return val.path
3865 return str(val)
3866 </t>
3867 <t tx="michael.20060619145551.111">def _step_tasks(task):
3868 if isinstance(task, Task):
3869 yield task
3871 stack = [iter(task.children)]
3872 while stack:
3873 for task in stack[-1]:
3874 yield task
3876 if task.children:
3877 stack.append(iter(task.children))
3878 break
3879 else:
3880 stack.pop()
3881 </t>
3882 <t tx="michael.20060619145551.115">def YearlyMax(value):
3884 Calculates a load parameter with a maximal yearly workload
3886 &lt;&lt; calculate calendar and time_diff &gt;&gt;
3887 return float(time_diff) / \
3888 (cal.working_days_per_year \
3889 * cal.working_hours_per_day \
3890 * 60)</t>
3891 <t tx="michael.20060619145551.117">def WeeklyMax(value):
3893 Calculates a load parameter with a maximal weekly workload
3895 &lt;&lt; calculate calendar and time_diff &gt;&gt;
3896 return float(time_diff) / \
3897 (cal.working_days_per_week \
3898 * cal.working_hours_per_day \
3899 * 60)
3901 </t>
3902 <t tx="michael.20060619145551.119">def MonthlyMax(value):
3904 Calculates a load parameter with a maximal monthly workload
3906 &lt;&lt; calculate calendar and time_diff &gt;&gt;
3907 return float(time_diff) / \
3908 (cal.working_days_per_month \
3909 * cal.working_hours_per_day \
3910 * 60)
3912 </t>
3913 <t tx="michael.20060619145551.121">def DailyMax(value):
3915 Calculates a load parameter with a maximal daily workload
3917 &lt;&lt; calculate calendar and time_diff &gt;&gt;
3918 return float(time_diff) / (cal.working_hours_per_day * 60)
3919 </t>
3920 <t tx="michael.20060619145551.123">class _TaskProperty(object):
3921 @others
3922 </t>
3923 <t tx="michael.20060619145551.124">def __init__(self, method):
3924 self.method = method
3925 </t>
3926 <t tx="michael.20060619145551.125">def __get__(self, instance, owner):
3927 if not instance:
3928 return None
3930 return instance._wrap_attrib(self.method)
3931 </t>
3932 <t tx="michael.20060619145551.126">class _RoundingTaskProperty(object):
3933 @others
3934 </t>
3935 <t tx="michael.20060619145551.127">def __init__(self, method, name):
3936 self.method = method
3937 self.name = name
3938 </t>
3939 <t tx="michael.20060619145551.128">def __get__(self, instance, owner):
3940 if not instance:
3941 return None
3943 result = instance._wrap_attrib(self.method).round()
3944 if instance._is_frozen:
3945 #correct the attrib to the rounded value
3946 setattr(instance, self.name, result)
3948 return result
3949 </t>
3950 <t tx="michael.20060619145551.129">class Task(object):
3951 &lt;&lt; description &gt;&gt;
3952 &lt;&lt; declarations &gt;&gt;
3953 @others</t>
3954 <t tx="michael.20060619145551.130"># Variables for the gui interface
3955 _date_completion = { "Date": 'Date("|")',
3956 "max": "max(|)",
3957 "min": "min(|)",
3958 "Multi" : "Multi(|)" }
3961 _delta_completion = { "Delta" : 'Delta("|")',
3962 "Multi" : "Multi(|)" }
3965 __attrib_completions__ = { \
3966 "def NewTask():" : "def |NewTask():\n",
3967 "milestone": 'milestone = True',
3968 "start": 'start = ',
3969 "end": 'end = ',
3970 "effort": 'effort = "|"',
3971 "duration": 'duration = "|"',
3972 "length": 'length = "|"',
3973 "todo": 'todo = "|"',
3974 "done": 'done = "|"',
3975 "title": 'title = "|"',
3976 "load": 'load = ',
3977 "max_load": 'max_load = ',
3978 "efficiency": 'efficiency = ',
3979 "complete": 'complete = ',
3980 "copy_src": 'copy_src =',
3981 "__constraint__": '__constraint__():\n|"',
3982 "priority": 'priority = ',
3983 "balance" : 'balance = ',
3984 "resource": 'resource = ',
3985 "performed" : 'performed = [(|resource, "2002-02-01", "2002-02-05", "2H"),]',
3986 "add_attrib": "add_attrib(|'name', None)",
3987 "working_days_per_week": 'working_days_per_week = ',
3988 "working_days_per_month": 'working_days_per_month = ',
3989 "working_days_per_year": 'working_days_per_year = ',
3990 "working_hours_per_day": 'working_hours_per_day = ',
3991 "minimum_time_unit": 'minimum_time_unit = ',
3992 "vacation": 'vacation = [("|2002-02-01", "2002-02-05")]',
3993 "extra_work": 'extra_work = [("|2002-02-01", "2002-02-05")]',
3994 "working_days" : 'working_days = ["|mon,tue,wed,thu,fri", "8:00-12:00", "13:00-17:00"]',
3995 "now": 'now = "|"',
3996 "calendar" : 'calendar = ',
3997 "#load": { "YearlyMax": 'YearlyMax("|")',
3998 "WeeklyMax": 'WeeklyMax("|")',
3999 "MonthlyMax": 'MonthlyMax("|")',
4000 "DailyMax": 'DailyMax("|")',
4001 "VariableLoad" : "VariableLoad(|)"},
4002 "#max_load": { "YearlyMax": 'YearlyMax("|")',
4003 "WeeklyMax": 'WeeklyMax("|")',
4004 "MonthlyMax": 'MonthlyMax("|")',
4005 "DailyMax": 'DailyMax("|")' },
4006 "#start": _date_completion,
4007 "#end": _date_completion,
4008 "#effort": _delta_completion,
4009 "#duration": _delta_completion,
4010 "#length": _delta_completion,
4011 "#todo": _delta_completion,
4012 "#done": _delta_completion,
4013 "#resource" : "get_resource_completions",
4014 "#calendar" : "get_calendar_completions",
4015 "#balance": { "STRICT": "STRICT",
4016 "SMART": "SMART",
4017 "SLOPPY": "SLOPPY" } }
4020 formats = { "start" : "%x %H:%M",
4021 "end" : "%x %H:%M",
4022 "performed_start" : "%x %H:%M",
4023 "performed_end" : "%x %H:%M",
4024 "load" : "%.2f",
4025 "length" : "%dd{ %HH}{ %MM}",
4026 "effort" : "%dd{ %HH}{ %MM}",
4027 "estimated_effort" : "%dd{ %HH}{ %MM}",
4028 "performed_effort" : "%dd{ %HH}{ %MM}",
4029 "duration" : "%dd{ %HH}{ %MM}",
4030 "complete" : "%i",
4031 "priority" : "%i",
4032 "todo" : "%dd{ %HH}{ %MM}",
4033 "done" : "%dd{ %HH}{ %MM}",
4034 "efficiency" : "%.2f",
4035 "buffer" : "%dd{ %HH}{ %MM}",
4036 "costs" : "%.2f",
4037 "sum" : "%.2f",
4038 "max" : "%.2f",
4039 "min" : "%.2f",
4040 "milestone" : "%s",
4041 "resource" : "%s",
4042 "booked_resource" : "%s",
4043 "performed_resource" : "%s" }
4045 _constraint = None
4046 _is_frozen = False
4047 _is_compiled = False
4048 _is_parent_referer = False
4050 scenario = None # only for autocompletion
4051 milestone = False
4052 performed = ()
4053 performed_resource = ()
4054 booked_resource = ()
4055 _performed_resource_length = ()
4056 _resource_length = ()
4057 dont_inherit = ()
4058 performed_start = None
4059 performed_end = None
4060 performed_work_time = pcalendar.Minutes(0)
4062 _setting_hooks = {}</t>
4063 <t tx="michael.20060619145551.131">def __init__(self, func, name, parent=None, index=1):
4064 assert(type(func) == types.FunctionType)
4066 func_key = (func.func_code, func.func_closure and id(func.func_closure))
4068 try:
4069 instrumented = instrumentation_cache[func_key]
4070 except KeyError:
4071 instrumented = _instrument(func)
4072 instrumented.org_code = func_key
4073 instrumentation_cache[func_key] = instrumented
4075 func.task_func = instrumented # will be used in the gui
4076 self._function = instrumented
4077 self.name = name
4078 self.up = parent
4079 self.children = []
4080 self._sources = {} # all tasks, I am linked to
4081 self._dependencies = {} # all tasks that link to me
4082 self._original_values = {}
4083 self._properties = {} # a registry of all non standard attributes
4084 self.title = self.name
4085 self.root = parent and parent.root or self
4086 self.scenario = self.root.scenario
4087 self.path = parent and parent.path + "." + name or name
4088 self.depth = len(self.path.split(".")) - 1
4089 self.index = parent and ("%s.%i" % (parent.index, index)) \
4090 or str(index)
4091 if self.formats.has_key(name):
4092 raise AttributeError("Task name '%s' hides attribute of parent." \
4093 % name)
4095 cal = self.calendar
4096 self._to_delta = cal.Minutes
4097 self._to_start = cal.StartDate
4098 self._to_end = cal.EndDate
4100 </t>
4101 <t tx="michael.20060619145551.132">def __iter__(self):
4102 return _step_tasks(self)
4103 </t>
4104 <t tx="michael.20060619145551.133">def __repr__(self):
4105 return "&lt;Task %s&gt;" % self.name
4106 </t>
4107 <t tx="michael.20060619145551.134">def __cmp__(self, other):
4108 try:
4109 return cmp(self.path, other.path)
4110 except Exception:
4111 return cmp(self.path, other)
4112 </t>
4113 <t tx="michael.20060619145551.135">def _idendity_(self): return self.root.id + self.path[4:]
4114 </t>
4115 <t tx="michael.20060619145551.136">def to_string(self): return _StringConverter(self)
4116 to_string = property(to_string)</t>
4117 <t tx="michael.20060619145551.137">def indent_name(self, ident=" "):
4119 returns a indented name, according to its depth in the hierachy.
4122 return ident * self.depth + self.name
4124 indent_name.attrib_method = True
4125 indent_name.__call_completion__ = "indent_name()"
4126 </t>
4127 <t tx="michael.20060619145551.138">def costs(self, cost_name, mode="ep"):
4129 calculates the resource costs for the task.
4130 cost_name is the name of a rate attribute of the reosurce
4131 mode is character combination:
4132 e calculates the estimated costs
4133 p calculates the performed costs
4134 ==&gt; pe calculates all costs
4137 if self.children:
4138 return sum([ c.costs(cost_name, mode) for c in self.children])
4140 costs = 0
4141 if 'e' in mode:
4142 costs += sum(map(lambda rl: getattr(rl[0], cost_name) * rl[1],
4143 self._resource_length))
4145 if 'p' in mode:
4146 costs += sum(map(lambda rl: getattr(rl[0], cost_name) * rl[1],
4147 self._performed_resource_length))
4149 costs /= (60.0 * self.root.calendar.working_hours_per_day)
4150 return round(costs, 2)
4152 costs.attrib_method = True
4153 costs.__call_completion__ = 'costs("|")'
4154 </t>
4155 <t tx="michael.20060619145551.139">def sum(self, attrib_name):
4156 val = 0
4158 if self.children:
4159 val += sum(map(lambda c: c.sum(attrib_name), self.children))
4160 if self.is_inherited(attrib_name):
4161 return val
4163 if attrib_name not in self.dont_inherit:
4164 return val
4166 return val + getattr(self, attrib_name)
4168 sum.attrib_method = True
4169 sum.__call_completion__ = 'sum("|")'
4171 </t>
4172 <t tx="michael.20060619145551.140">def min(self, attrib_name):
4173 if self.children:
4174 return min(map(lambda c: c.min(attrib_name), self.children))
4176 return getattr(self, attrib_name)
4178 min.attrib_method = True
4179 min.__call_completion__ = 'min("|")'
4181 </t>
4182 <t tx="michael.20060619145551.141">def max(self, attrib_name):
4183 if self.children:
4184 return max(map(lambda c: c.max(attrib_name), self.children))
4186 return getattr(self, attrib_name)
4188 max.attrib_method = True
4189 max.__call_completion__ = 'max("|")'
4191 </t>
4192 <t tx="michael.20060619145551.142">def is_inherited(self, attrib_name):
4193 return not self.__dict__.has_key(attrib_name)
4194 </t>
4195 <t tx="michael.20060619145551.143">def formatter(self, attrib_name, arg=None, format=None):
4196 """returns a function which is able
4197 to convert the value of the given attrib_name to a string"""
4199 formats = self.formats
4200 format = format or formats.get(attrib_name)
4202 if attrib_name in ("start", "end", "length", "effort",
4203 "done", "todo", "buffer", "estimated_effort",
4204 "performed_effort", "performed_start", "performed_end"):
4205 def save_strftime(v):
4206 try:
4207 return v.strftime(format)
4208 #except AttributeError: some bug avoid catching this exception
4209 except Exception:
4210 return str(v)
4212 return save_strftime
4214 if attrib_name == "duration":
4215 def save_strftime(v):
4216 try:
4217 return v.strftime(format, True)
4218 except AttributeError:
4219 return str(v)
4221 return save_strftime
4223 if attrib_name in ("booked_resource", "performed_resource"):
4224 def get_resource_name(v):
4225 title = getattr(v, "title", None)
4226 if title: return title
4227 return ", ".join([r.title for r in v])
4228 return get_resource_name
4230 if arg and attrib_name in ("costs", "sum", "max", "min"):
4231 format = formats.get("%s(%s)" % (attrib_name, arg), format)
4233 if format:
4234 return lambda v: locale.format(format, v, True)
4236 return str
4237 </t>
4238 <t tx="michael.20060619145551.144">def all_resources(self):
4239 result = self._all_resources_as_dict()
4240 result = result.keys()
4241 result.sort()
4242 return result
4243 </t>
4244 <t tx="michael.20060619145551.145">def _unfreeze(self, attrib_name):
4245 if self.__dict__.has_key(attrib_name):
4246 del self.__dict__[attrib_name]
4247 </t>
4248 <t tx="michael.20060619145551.146">def _all_resources_as_dict(self):
4249 if self.children:
4250 result = {}
4251 for c in self.children:
4252 result.update(c._all_resources_as_dict())
4254 return result
4256 if self.resource:
4257 return dict(map(lambda r: (r, 1), self.resource.all_members()))
4259 return {}
4260 </t>
4261 <t tx="michael.20060619145551.147">def _iter_booked_resources(self):
4262 result = dict(map(lambda r: (r, 1), self.performed_resource))
4263 result.update(dict(map(lambda r: (r, 1), self.booked_resource)))
4264 return result.iterkeys()
4265 </t>
4266 <t tx="michael.20060619145551.148">def get_task(self, path=None):
4268 Returns a task with the given path.
4271 if not path:
4272 return self
4274 names = path.split(".")
4275 rest = ".".join(names[1:])
4276 result = getattr(self, names[0], None)
4277 return isinstance(result, Task) and result.get_task(rest) or None
4278 </t>
4279 <t tx="michael.20060619145551.149">def check(self):
4280 if self._constraint and self._is_compiled:
4281 globals_ = self._function.func_globals
4282 globals_["me"] = self
4283 globals_["up"] = self.up
4284 globals_["root"] = self.root
4285 globals_["assert_"] = self.__assert
4286 self._constraint()
4287 </t>
4288 <t tx="michael.20060619145551.150">def snapshot(self, indent="", name=None):
4289 text = indent + "def %s():\n" % (name or self.name)
4290 indent += " "
4291 for name in ("priority", "balance", "complete",
4292 "milestone", "end", "start", "effort", "load"):
4293 val = getattr(self, name, None)
4294 if val is None:
4295 continue
4297 if name[0] == "_":
4298 name = name[1:]
4300 text += "%s%s = %s\n" % (indent, name, _as_string(val))
4302 for name in self._properties:
4303 if name.startswith("performed"): continue
4304 val = getattr(self, name, None)
4305 try:
4306 if issubclass(val, resource.Resource): continue
4307 except TypeError:
4308 pass
4309 text += "%s%s = %s\n" % (indent, name, _as_string(val))
4311 resources = tuple(self._iter_booked_resources())
4312 if resources:
4313 text += "%sresource = \\\n" % indent
4314 def make_resource(res):
4315 return "%s %s" \
4316 % (indent, res.snapshot())
4318 text += "&amp;\\\n".join(map(make_resource, resources)) + "\n"
4320 def make_resource_booking(res):
4321 def make_booking(booking):
4322 return '%s (%s, "%s", "%s", "%sM"),' \
4323 % (indent, res.name,
4324 booking.book_start.strftime("%Y%m%d %H:%M"),
4325 booking.book_end.strftime("%Y%m%d %H:%M"),
4326 booking.work_time)
4328 return "\n".join(map(make_booking, res.get_bookings(self)))
4331 text += "%sperformed = [\n" % indent
4332 text += "\n".join(map(make_resource_booking, resources)) + "]"
4335 child_text = map(lambda c: c.snapshot(indent), self.children)
4336 text += "\n\n"
4337 text += "".join(child_text)
4339 return text
4340 </t>
4341 <t tx="michael.20060619145551.151">def _test_allocation(self, resource_state, allocator):
4342 resource = self.resource._get_resources(resource_state)
4343 if not resource:
4344 return False
4346 return allocator.test_allocation(self, resource)
4347 </t>
4348 <t tx="michael.20060619145551.152">def _allocate(self, state, allocator):
4349 allocator.allocate(self, state)
4350 #activate cache for done and todo
4352 if self.start.to_datetime() &gt; self.end.to_datetime():
4353 #this can happen when performed effort are
4354 #during non working time
4355 tmp = self.start
4356 self.start = self.end
4357 self.end = tmp
4359 for r in self.performed_resource:
4360 r.correct_bookings(self)
4362 self._resource_length = map(lambda r: (weakref.proxy(r), \
4363 r.length_of(self)),
4364 self._iter_booked_resources())
4365 </t>
4366 <t tx="michael.20060619145551.153">def _generate(self, deferred=None):
4367 do_raise = False
4368 deferred = deferred or [ self ]
4369 while deferred:
4370 new_deferred = []
4371 for task in deferred:
4372 task._compile(new_deferred, do_raise)
4374 do_raise = deferred == new_deferred
4375 deferred = new_deferred
4376 </t>
4377 <t tx="michael.20060619145551.154">def _recalc_properties(self):
4378 if not self._properties: return
4379 self.__compile_function([], False, _MeProxyRecalc(self))
4380 self._is_compiled = True
4381 </t>
4382 <t tx="michael.20060619145551.155">def _compile(self, deferred, do_raise):
4383 self.dont_inherit = ()
4384 self._constraint = None
4385 self._original_values.clear()
4386 self._properties.clear()
4388 try:
4389 self.__at_compile
4390 &lt;&lt; raise child recursion error &gt;&gt;
4391 except AttributeError:
4392 self.__at_compile = self, ""
4394 try:
4395 self.__compile_function(deferred, do_raise, _MeProxy(self))
4396 finally:
4397 del self.__at_compile
4399 for c in self.children:
4400 if not c._is_compiled:
4401 c._compile(deferred, do_raise)
4403 if self._is_compiled:
4404 self.__check_milestone()
4405 self.__check_task()
4406 self.root.has_actual_data |= self.__dict__.has_key("performed")
4408 </t>
4409 <t tx="michael.20060619145551.156">def __compile_function(self, deferred, do_raise, me_instance):
4410 self._is_compiled = self._is_frozen
4412 restore_globals = []
4413 globals_ = self._function.func_globals
4415 &lt;&lt; set function global values &gt;&gt;
4416 &lt;&lt; set me in global functions &gt;&gt;
4417 try:
4418 &lt;&lt; eval function &gt;&gt;
4419 finally:
4420 for fg in restore_globals:
4421 del fg["me"]
4423 </t>
4424 <t tx="michael.20060619145551.157">def __check_task(self):
4425 if self.children: return
4427 start = self._find_frozen("start")
4428 end = self._find_frozen("end")
4430 if not (start or end):
4431 self._raise(ValueError("You must specify either a"\
4432 " start or an end attribute"))
4434 if start and end: return
4436 length = self.__dict__.get("length")
4437 duration = self.__dict__.get("duration")
4438 effort = self.__dict__.get("effort")
4439 if not (effort or length or duration):
4440 #set a default value
4441 self._set_effort("1d")
4442 #self._raise(ValueError("You must specify either a"\
4443 # " length or a duration or "\
4444 # "an effort attribute"))
4445 </t>
4446 <t tx="michael.20060619145551.158">def __check_milestone(self):
4447 if not self.milestone: return
4449 self.length = self._to_delta(0)
4450 start = self.__dict__.get("start")
4451 if not start:
4452 self._raise(ValueError("Milestone must have start attribute"),
4453 "milstone")
4455 if self.__start_class.__name__ == "edt":
4456 #the milestone is probably dependent on the end date of
4457 #an other task (see edt in pcalendar) ==&gt; start at the end date
4458 self.start = self.end = self._to_end(self.start)
4459 else:
4460 self.start = self.end = self._to_start(self.start)
4462 </t>
4463 <t tx="michael.20060619145551.159">def _set_attrib(self, name, value):
4464 if value is _NEVER_USED_: return
4466 try:
4467 value = self._setting_hooks[name](self, name, value)
4468 except KeyError: pass
4470 if name == "__constraint__":
4471 self._constraint = value
4472 return
4474 if type(value) == types.FunctionType:
4475 if value.func_code.co_argcount == 0:
4476 &lt;&lt; add child task &gt;&gt;
4478 if name[0] == "_":
4479 #private vars will not be set
4480 return
4482 if isinstance(value, _Path):
4483 value = value._task
4485 set_method = getattr(self, "_set_" + name, None)
4486 if set_method:
4487 &lt;&lt; set standard attribute &gt;&gt;
4488 else:
4489 &lt;&lt; set userdefined attribute &gt;&gt;
4490 </t>
4491 <t tx="michael.20060619145551.160">def _set_name(self, value):
4492 raise AttributeError("The attribute 'name' is readonly.")</t>
4493 <t tx="michael.20060619145551.161">def _set_start(self, value):
4494 self.__start_class = value.__class__
4495 self.start = self._to_start(value).round()
4496 </t>
4497 <t tx="michael.20060619145551.162">def _set_end(self, value):
4498 self.end = self._to_end(value)
4499 </t>
4500 <t tx="michael.20060619145551.163">def _set_max_load(self, max_load):
4501 self.max_load = float(max_load)
4502 </t>
4503 <t tx="michael.20060619145551.164">def _set_load(self, load):
4504 self.load = float(load)
4505 </t>
4506 <t tx="michael.20060619145551.165">def _set_length(self, value):
4507 self.length = self._to_delta(value).round()
4508 </t>
4509 <t tx="michael.20060619145551.166">def _set_effort(self, value):
4510 self.effort = self._to_delta(value).round()
4511 </t>
4512 <t tx="michael.20060619145551.167">def _set_duration(self, value):
4513 self.duration = self._to_delta(value, True).round()
4514 </t>
4515 <t tx="michael.20060619145551.168">def _set_complete(self, value):
4516 self.complete = value
4517 </t>
4518 <t tx="michael.20060619145551.169">def _set_done(self, value):
4519 self.done = self._to_delta(value).round()
4520 </t>
4521 <t tx="michael.20060619145551.170">def _set_todo(self, value):
4522 self.todo = self._to_delta(value).round()
4523 </t>
4524 <t tx="michael.20060619145551.171">def _set_milestone(self, value):
4525 self.milestone = value
4526 </t>
4527 <t tx="michael.20060619145551.172">def _set_resource(self, value):
4528 if not value:
4529 self.resource = None
4530 return
4532 if isinstance(value, (tuple, list)):
4533 value = reduce(lambda a, b: a &amp; b, value)
4535 self.resource = value()
4536 </t>
4537 <t tx="michael.20060619145551.173">def _set_copy_src(self, value):
4538 if isinstance(value, _MeProxy):
4539 raise RuntimeError("Cannot copy me.")
4541 if not value._is_compiled:
4542 raise _IncompleteError(value, "copy_src")
4544 if value.resource and not self.resource:
4545 self.resource = value.resource
4547 if value.balance and not self.balance:
4548 self.balance = value.balance
4550 copy_parms = ("priority", "todo", "complete",
4551 "_constraint", "load", "length",
4552 "effort", "duration")
4554 for p in copy_parms:
4555 v = value.__dict__.get(p)
4556 if v: setattr(self, p, v)
4558 self.copy_src = value
4559 self._properties.update(value._properties)
4560 for k in value._properties.iterkeys():
4561 setattr(self, k, getattr(value, k))
4562 </t>
4563 <t tx="michael.20060619145551.174">def _wrap_attrib(self, method):
4564 attrib_name = method.__name__[7:]
4565 recursion_attrib = "_rec" + attrib_name
4567 try:
4568 dest, dattr = self.__at_compile
4569 raise RecursionError("Recursive definition of %s(%s) and %s(%s)" \
4570 % (self.path, attrib_name, dest.path, dattr))
4571 except AttributeError: pass
4573 if not self._is_compiled:
4574 raise _IncompleteError(self, attrib_name)
4576 try:
4577 getattr(self, recursion_attrib)
4578 raise RecursionError(self, attrib_name)
4579 except AttributeError: pass
4581 setattr(self, recursion_attrib, True)
4583 try:
4584 result = method(self)
4586 if self._is_frozen:
4587 setattr(self, attrib_name, result)
4589 return result
4590 finally:
4591 delattr(self, recursion_attrib)
4592 </t>
4593 <t tx="michael.20060619145551.175">def _find_frozen(self, attrib_name, default=None):
4594 value = self.__dict__.get(attrib_name)
4595 if value is not None:
4596 return value
4598 up = self.up
4599 return up and up._find_frozen(attrib_name) or default
4600 </t>
4601 <t tx="michael.20060619145551.177">def __calc_start(self):
4602 to_start = self._to_start
4604 if self.children:
4605 try:
4606 return min([ to_start(t.start) for t in self.children
4607 if not t._is_parent_referer ])
4608 except ValueError:
4609 &lt;&lt; raise child recursion error &gt;&gt;
4611 try:
4612 end = self.end
4613 duration = self.__dict__.get("duration")
4614 if duration is not None:
4615 start = end.to_datetime() - datetime.timedelta(minutes=duration)
4616 else:
4617 start = end - self.length
4619 return to_start(start)
4621 except RecursionError:
4622 start = self._find_frozen("start")
4623 if start: return to_start(start)
4624 &lt;&lt; raise recursion error &gt;&gt;
4626 start = _TaskProperty(__calc_start)
4628 </t>
4629 <t tx="michael.20060619145551.178">def __calc_end(self):
4630 to_end = self._to_end
4632 if self.children:
4633 try:
4634 return max([ to_end(t.end) for t in self.children
4635 if not t._is_parent_referer ])
4636 except ValueError:
4637 &lt;&lt; raise child recursion error &gt;&gt;
4639 try:
4640 start = self.start
4641 duration = self.__dict__.get("duration")
4642 if duration is not None:
4643 end = start.to_datetime() + datetime.timedelta(minutes=duration)
4644 else:
4645 end = start + self.length
4647 return to_end(end)
4649 except RecursionError:
4650 end = self._find_frozen("end")
4651 if end: return to_end(end)
4652 &lt;&lt; raise recursion error &gt;&gt;
4655 end = _TaskProperty(__calc_end)
4656 </t>
4657 <t tx="michael.20060619145551.179">def __calc_load(self):
4658 length = self.__dict__.get("length")
4659 effort = self.__dict__.get("effort")
4661 if length is not None and effort is not None:
4662 return float(effort) / (float(length) or 1.0)
4664 load = self._find_frozen("load")
4665 if load is not None: return load
4666 return 1.0
4668 load = _TaskProperty(__calc_load)
4669 </t>
4670 <t tx="michael.20060619145551.180">def __calc_length(self):
4671 effort = self.__dict__.get("effort")
4672 if effort is None:
4673 return self.end - self.start
4675 return self._to_delta(effort / self.load)
4677 length = _RoundingTaskProperty(__calc_length, "length")
4678 </t>
4679 <t tx="michael.20060619145551.181">def __calc_duration(self):
4680 return self._to_delta(self.end.to_datetime()\
4681 - self.start.to_datetime(), True)
4683 duration = _TaskProperty(__calc_duration)
4684 </t>
4685 <t tx="michael.20060619145551.182">def __calc_effort(self):
4686 if self.children:
4687 return self._to_delta(sum([ t.effort for t in self.children ]))
4689 return self._to_delta(self.length * self.load)
4691 effort = _RoundingTaskProperty(__calc_effort, "effort")
4692 </t>
4693 <t tx="michael.20060619145551.183">def __calc_done(self):
4694 if self.children:
4695 dones = map(lambda t: t.done, self.children)
4696 return self._to_delta(sum(dones))
4698 res = self._iter_booked_resources()
4699 done = sum(map(lambda r: r.done_of(self), res))
4701 complete = self.__dict__.get("complete")
4702 todo = self.__dict__.get("todo")
4704 if not done and complete == 100 or todo == 0:
4705 #if now is not set
4706 done = self.effort
4708 return self._to_delta(done)
4710 done = _TaskProperty(__calc_done)
4711 </t>
4712 <t tx="michael.20060619145551.184">def __calc_buffer(self):
4713 if self.children:
4714 return self._to_delta(min(map(lambda t: t.buffer, self.children)))
4716 scenario = self.scenario
4717 end = self.end
4718 old_end = self.__dict__.get("end")
4720 &lt;&lt; find all tasks, that depend on my end &gt;&gt;
4722 &lt;&lt; define unfreeze_parents &gt;&gt;
4724 buffers = [ ]
4725 for d in deps.keys():
4726 path, attrib = _split_path(d)
4727 if attrib != "start":
4728 continue
4730 &lt;&lt; calculate buffer to descendant 'd' &gt;&gt;
4732 buffers.append(buffer_)
4733 if not buffer_:
4734 break
4736 if buffers:
4737 return self._to_delta(min(buffers))
4739 return not self.milestone \
4740 and self.root.end - end \
4741 or self._to_delta(0)
4743 buffer = _TaskProperty(__calc_buffer)
4744 </t>
4745 <t tx="michael.20060619145551.185">def __calc_complete(self):
4746 done = self.done
4747 todo = self.todo
4748 return int(100.0 * done / ((done + todo) or 1))
4750 complete = _TaskProperty(__calc_complete)
4751 </t>
4752 <t tx="michael.20060619145551.186">def __calc_todo(self):
4753 complete = self.__dict__.get("complete")
4754 if complete:
4755 # effort = done + todo
4756 # done done
4757 # complete = ------ ==&gt; todo = -------- - done
4758 # effort complete
4759 complete = float(complete)
4760 done = self.done
4761 if done:
4762 done = float(done)
4763 return self._to_delta(done * 100.0 / complete - done)
4764 return self._to_delta(self.effort * complete / 100.0)
4766 if self.children:
4767 todos = map(lambda t: t.todo, self.children)
4768 return self._to_delta(sum(todos))
4770 todo = sum(map(lambda r: r.todo_of(self), self.booked_resource))
4771 return self._to_delta(max(todo, self.effort - self.done))
4773 todo = _TaskProperty(__calc_todo)
4774 </t>
4775 <t tx="michael.20060619145551.187">def _convert_performed(self, all_resources):
4776 performed = self.performed
4777 if not performed: return False
4779 if not isinstance(performed, (tuple, list)) \
4780 or not isinstance(performed[0], (tuple, list)) \
4781 or not len(performed[0]) &gt;= 3:
4782 self._raise(TypeError("""The format of the performed attribute must be:
4783 [( res_name, start_literal, end_literal, working_time ), ... ].
4784 """), "performed")
4786 round_down_delta = self.root.calendar.minimum_time_unit / 2
4787 round_down_delta = datetime.timedelta(minutes=round_down_delta)
4789 def convert_item(index):
4790 item = performed[index]
4791 res, start, end = item[:3]
4792 if isinstance(res, str):
4793 found = filter(lambda r: r.name == res, all_resources)
4794 if found: res = found[0]
4796 try:
4797 if not isinstance(res, (resource.Resource,
4798 resource._MetaResource)):
4799 raise ValueError("the resource '%s' is unknown." % res)
4801 start = _to_datetime(start)
4802 end = _to_datetime(end)
4804 if len(item) &gt; 3:
4805 working_time = self._to_delta(item[3]).round()
4806 else:
4807 working_time = self._to_delta(end - start, True)
4809 return ((res, start, end, working_time), index)
4810 except Exception, exc:
4811 self._raise(exc.__class__("Item %i: %s" \
4812 % (index + 1, str(exc))),
4813 "performed")
4815 converted = dict(map(convert_item, range(len(performed))))
4816 converted = converted.items()
4817 converted.sort()
4819 #check for overlapping items
4820 last_res = None
4821 for item, index in converted:
4822 res, start, end, work_time = item
4823 if last_res == res and start &lt; last_end:
4824 self._warn("Items %i, %i: %s and %s are overlapping." \
4825 % (last_index + 1, index + 1,
4826 str(performed[last_index]),
4827 str(performed[index])),
4828 "performed")
4830 last_res = res
4831 last_end = end
4832 last_index = index
4834 self._performed = map(lambda x: x[0], converted)
4835 return True
4836 </t>
4837 <t tx="michael.20060619145551.188">def _allocate_performed(self, performed):
4838 if not performed: return
4840 to_delta = self._to_delta
4841 to_start = self._to_start
4842 to_end = self._to_end
4844 last = datetime.datetime.min
4845 first = datetime.datetime.max
4846 effort = 0
4847 work_time_sum = 0
4848 zero_minutes = to_delta(0)
4849 minimum_time_unit = to_delta(self.calendar.minimum_time_unit)
4850 summary = {}
4852 for item in performed:
4853 res, start, end, work_time = item
4854 effort += work_time * self.efficiency * res.efficiency
4855 work_time_sum += work_time
4857 res = res()
4858 ss, es, wts = summary.get(res, (datetime.datetime.max,
4859 datetime.datetime.min,
4860 zero_minutes))
4861 summary[res] = (min(ss, start), max(es, end), wts + work_time)
4863 for r, v in summary.iteritems():
4864 start, end, work_time = v
4865 assert(start.__class__ is datetime.datetime)
4866 assert(end.__class__ is datetime.datetime)
4868 #the booking limits should be inside the workingtime
4869 #to display them correct in resource charts
4870 cstart = to_start(start).to_datetime()
4871 if cstart &gt; start: cstart = to_end(start).to_datetime()
4873 cend = to_end(end).to_datetime()
4874 if cend &lt; end: cend = to_start(end).to_datetime()
4876 if self.root.is_snapshot:
4877 delta = to_end(cend) - to_start(cstart)
4878 else:
4879 delta = to_delta(cend - cstart).round()
4881 if not delta:
4882 delta = minimum_time_unit
4884 book_load = float(work_time) / delta
4885 r().book_task(self, cstart, cend, book_load, work_time, True)
4886 last = max(end, last)
4887 first = min(start, first)
4889 self._performed_resource_length = tuple([ (r, v[2]) for r, v in summary.iteritems() ])
4890 self.performed_resource = tuple(summary.keys())
4891 self.performed_end = last
4892 self.performed_start = first
4893 self.performed_effort = to_delta(effort)
4894 self.performed_work_time = to_delta(work_time_sum)
4895 self._check_completion()
4896 </t>
4897 <t tx="michael.20060619145551.189">def _check_completion(self):
4898 if not self.performed_effort: return
4899 if self.root.is_snapshot: return
4901 # allocation is not done yet ==&gt; self.todo, self.done,
4902 # self.complete cannot be calculated
4903 if self._find_frozen("complete", 0) &lt; 100 \
4904 and self.__dict__.get("todo", 1) &gt; 0:
4905 return
4907 start = self.performed_start
4908 end = self.performed_end
4909 #ensure that self.start.to_datetime() &lt; self.end.to_datetime()
4910 cstart = self._to_start(start)
4911 if cstart.to_datetime() &gt; start: cstart = self._to_end(start)
4913 cend = self._to_end(end)
4914 if cend.to_datetime() &lt; end: cend = self._to_start(end)
4916 self.start = cstart
4917 self.end = cend
4919 if self.performed_effort != self.effort:
4920 self.estimated_effort = self.effort
4921 self.effort = self.performed_effort
4922 </t>
4923 <t tx="michael.20060619145551.190">def __assert(self, value):
4924 if not value:
4925 warnings.warn('assertion in scenario: "%s"' % self.scenario,
4926 RuntimeWarning, 2)
4927 </t>
4928 <t tx="michael.20060619145551.191">def __set_sources(self, attrib_name, value):
4929 &lt;&lt; find references &gt;&gt;
4930 if not sources: return
4932 #track only dependcies within the same project
4933 root = self.root
4934 sources = [ task.path + "." + attrib
4935 for task, attrib in sources
4936 if task and task.root is root ]
4937 self._sources[attrib_name] = tuple(sources)
4938 attr_path = self.path + "." + attrib_name
4940 #set dependencies of my sources
4941 for d in sources:
4942 path, attrib = _split_path(d)
4943 task = self.get_task(path)
4944 r_d = task._dependencies
4945 d_l = r_d.setdefault(attrib, {})
4946 d_l[attr_path] = True
4947 </t>
4948 <t tx="michael.20060619145551.192">def _warn(self, message, attrib=None, level=2):
4949 self.__compile_function([], True, _MeProxyWarn(self, attrib, message))
4950 </t>
4951 <t tx="michael.20060619145551.193">def _raise(self, exc, attrib=None):
4952 self.__compile_function([], True, _MeProxyError(self, attrib, exc))
4953 raise exc
4954 </t>
4955 <t tx="michael.20060619145551.194">def __getattr__(self, name):
4956 try:
4957 if name[0] != "_":
4958 parent = self.up
4959 while parent:
4960 if name not in parent.dont_inherit:
4961 result = getattr(parent, name)
4962 if not (isinstance(result, Task) and result.up == parent):
4963 return result
4965 parent = parent.up
4966 except AttributeError:
4967 pass
4968 except IndexError:
4969 raise AttributeError()
4971 exception = AttributeError("'%s' is not a valid attribute of '%s'"
4972 % (name, self.path))
4973 exception.is_frozen = self._is_frozen
4974 raise exception
4975 </t>
4976 <t tx="michael.20060619145551.195">class _ProjectBase(Task):
4978 Base class for all projects.
4980 &lt;&lt; class _ProjectBase declarations &gt;&gt;
4981 @others
4982 </t>
4983 <t tx="michael.20060619145551.196">__attrib_completions__ = { }
4984 __attrib_completions__.update(Task.__attrib_completions__)
4985 del __attrib_completions__["milestone"] #project cannot be milestones
4987 priority = 500
4988 efficiency = 1.0
4989 max_load = 1.0
4990 balance = 0
4991 resource = None
4992 copy_src = None
4993 has_actual_data = False
4994 is_snapshot = False
4996 </t>
4997 <t tx="michael.20060619145551.197">def __init__(self, top_task, scenario="_default", id=""):
4998 self.calendar = pcalendar.Calendar()
4999 Task.__init__(self, top_task, top_task.func_name)
5000 self.id = id or self.name
5001 self.scenario = scenario
5002 self.all_scenarios = set(("_default",))
5003 self.path = "root"
5004 self._globals = top_task.func_globals.copy()
5005 self._generate()
5007 </t>
5008 <t tx="michael.20060619145551.198">def _idendity_(self): return self.id
5009 </t>
5010 <t tx="michael.20060619145551.200">def __renew_dates(self):
5011 for attrib in ("effort", "start", "end", "length", "todo"):
5012 try:
5013 self._set_attrib(attrib, self._original_values[attrib])
5014 except KeyError:
5015 pass
5017 </t>
5018 <t tx="michael.20060619145551.201">def free(self):
5019 all_resources = self.all_resources()
5020 for r in all_resources:
5021 r().unbook_tasks_of_project(self.id, self.scenario)
5023 for t in self:
5024 t.booked_resource = ()
5026 return all_resources
5027 </t>
5028 <t tx="michael.20060619145551.202">def _get_balancing_list(self):
5030 try:
5031 cached_list = balancing_cache[self._function.org_code]
5032 if len(cached_list) != len(tuple(self)):
5033 # different scenarios can have different tasks
5034 raise KeyError()
5036 except KeyError:
5037 cached_list = _build_balancing_list(self)
5038 balancing_cache[self._function.org_code] = cached_list
5039 else:
5040 cached_list = [ self.get_task(t.path) for t in cached_list ]
5042 return cached_list
5043 </t>
5044 <t tx="michael.20060619145551.204">def _set_vacation(self, value):
5045 self.__make_calendar()
5046 self.calendar.set_vacation(value)
5047 self._properties["vacation"] = True
5048 self.vacation = value
5049 self.__renew_dates()
5050 </t>
5051 <t tx="michael.20060619145551.205">def _set_extra_work(self, value):
5052 self.__make_calendar()
5053 self.calendar.set_extra_work(value)
5054 self._properties["extra_work"] = True
5055 self.extra_work = value
5056 self.__renew_dates()
5057 </t>
5058 <t tx="michael.20060619145551.206">def _set_working_days(self, value):
5059 if type(value[0]) is str:
5060 value = (value, )
5062 self.working_days = value
5063 self._properties["working_days"] = True
5064 self.__make_calendar()
5066 for v in value:
5067 day_range = v[0]
5068 tranges = tuple(v[1:])
5069 self.calendar.set_working_days(day_range, *tranges)
5071 self.__renew_dates()</t>
5072 <t tx="michael.20060619145551.207">def _set_now(self, value):
5073 proxy = weakref.proxy
5074 self.calendar.now = _to_datetime(value)
5075 </t>
5076 <t tx="michael.20060619145551.208">def _set_minimum_time_unit(self, value):
5077 self.__make_calendar()
5078 self.calendar.minimum_time_unit = value
5079 self._properties["minimum_time_unit"] = True
5080 </t>
5081 <t tx="michael.20060619145551.209">def _get_minimum_time_unit(self):
5082 return self.calendar.minimum_time_unit
5084 minimum_time_unit = property(_get_minimum_time_unit)
5085 </t>
5086 <t tx="michael.20060619145551.210">def _set_working_days_per_week(self, value):
5087 self.__make_calendar()
5088 self.calendar.working_days_per_week = value
5089 self._properties["working_days_per_week"] = True
5090 </t>
5091 <t tx="michael.20060619145551.211">def _get_working_days_per_week(self):
5092 return self.calendar.working_days_per_week
5094 working_days_per_week = property(_get_working_days_per_week)
5095 </t>
5096 <t tx="michael.20060619145551.212">def _set_working_days_per_month(self, value):
5097 self.__make_calendar()
5098 self.calendar.working_days_per_month = value
5099 self._properties["working_days_per_month"] = True
5100 </t>
5101 <t tx="michael.20060619145551.213">def _get_working_days_per_month(self):
5102 return self.calendar.working_days_per_month
5104 working_days_per_month = property(_get_working_days_per_month)
5105 </t>
5106 <t tx="michael.20060619145551.214">def _set_working_days_per_year(self, value):
5107 self.__make_calendar()
5108 self.calendar.working_days_per_year = value
5109 self._properties["working_days_per_year"] = True
5110 </t>
5111 <t tx="michael.20060619145551.215">def _get_working_days_per_year(self):
5112 return self.calendar.working_days_per_year
5114 working_days_per_year = property(_get_working_days_per_year)
5115 </t>
5116 <t tx="michael.20060619145551.216">def _set_working_hours_per_day(self, value):
5117 self.__make_calendar()
5118 self.calendar.working_hours_per_day = value
5119 self._properties["set_working_hours_per_day"] = True
5120 </t>
5121 <t tx="michael.20060619145551.217">def _get_working_hours_per_day(self):
5122 return self.calendar.working_hours_per_day
5124 working_hours_per_day = property(_get_working_hours_per_day)
5125 </t>
5126 <t tx="michael.20060619145551.218">def snapshot(self, indent="", name=None):
5127 text = Task.snapshot(self, indent, name)
5129 lines = text.splitlines(True)
5130 indent += " "
5132 def make_resource(r):
5133 return '%sclass %s(Resource): title = "%s"\n' \
5134 % (indent, r.name, r.title)
5136 now = datetime.datetime.now().strftime("%x %H:%M")
5137 resource_text = map(lambda r: make_resource(r), self.all_resources())
5138 lines.insert(1, "%sfrom faces import Resource\n" % indent)
5139 lines.insert(2, "".join(resource_text) + "\n")
5140 lines.insert(3, '%snow = "%s"\n' % (indent, now))
5141 lines.insert(4, '%sis_snapshot = True\n' % indent)
5142 return "".join(lines)
5143 </t>
5144 <t tx="michael.20060619145551.219">class Project(_ProjectBase):
5146 Generates a Project without allocating resources.
5148 @param top_task: Specifies the highest function of a project definiton.
5150 @param scenario: Specifies the name of the scenario which should be scheduled.
5152 @param id: Specifiess a unique idenfication name to distinguish the project from
5153 other projects in the resource database. The default value for id
5154 is the name of top_task.
5156 &lt;&lt; class Project declarations &gt;&gt;
5157 @others
5159 </t>
5160 <t tx="michael.20060619145551.220">__call_completion__ = 'Project(|top_task, scenario="_default", id=None)'
5162 </t>
5163 <t tx="michael.20060619145551.221">def __init__(self, top_task, scenario="_default", id=None):
5164 _ProjectBase.__init__(self, top_task, scenario, id)
5165 no_snapshot = not self.is_snapshot
5166 for t in self:
5167 t._is_frozen = True
5168 t._recalc_properties()
5169 no_snapshot and t.check()
5171 self._restore_globals()
5173 </t>
5174 <t tx="michael.20060619145551.222">class _AllocationPoject(_ProjectBase):
5175 @others
5176 </t>
5177 <t tx="michael.20060619145551.223">def unfreeze_parents(self):
5178 if self.has_actual_data:
5179 for t in filter(lambda t: t.children, self):
5180 if not t._original_values.has_key("start"): t._unfreeze("start")
5181 if not t._original_values.has_key("end"): t._unfreeze("end")
5182 </t>
5183 <t tx="michael.20060619145551.224">class BalancedProject(_AllocationPoject):
5185 Generates a project with allocated resources. The tasks are balanced
5186 to fit the resources load conditions.
5188 &lt;&lt; class BalancedProject declarations &gt;&gt;
5189 @others
5190 </t>
5191 <t tx="michael.20060619145551.225">__call_completion__ = """BalancedProject(|top_task, scenario="_default",
5192 id=None, balance=SMART, performed=None)"""
5194 </t>
5195 <t tx="michael.20060619145551.226">def __init__(self, top_task, scenario="_default",
5196 id=None, balance=SMART, performed=None):
5197 _AllocationPoject.__init__(self, top_task, scenario, id)
5198 self.balance = balance
5199 if performed:
5200 self._distribute_performed(performed)
5201 self.has_actual_data = True
5203 no_snapshot = not self.is_snapshot
5204 if no_snapshot:
5205 self.allocate()
5206 else:
5207 self.allocate_snapshot()
5209 for t in self:
5210 t._is_frozen = True
5211 t._recalc_properties()
5212 no_snapshot and t.check()
5214 self._restore_globals()</t>
5215 <t tx="michael.20060619145551.227">def allocate_snapshot(self):
5216 all_resources = self.free()
5217 scenario = self.scenario
5218 has_actual_data = True
5219 for t in self:
5220 if not t.resource or t.milestone or t.children:
5221 continue
5223 t._convert_performed(all_resources)
5224 t._allocate_performed(t._performed)
5225 </t>
5226 <t tx="michael.20060619145551.228">def allocate(self):
5227 all_resources = self.free()
5228 balancing_list = self._get_balancing_list()
5229 scenario = self.scenario
5231 #for t in balancing_list:
5232 # print t.path
5234 for t in balancing_list:
5235 t._compile([], True)
5237 if not t.resource or t.milestone or t.children:
5238 continue
5240 if t._convert_performed(all_resources):
5241 has_actual_data = True
5243 try:
5244 t._allocate_performed(t._performed)
5245 except AttributeError:
5246 pass
5248 allocator = _allocators[t.balance]
5249 min_val = None
5250 min_state = None
5251 for p in range(t.resource._permutation_count()):
5252 state = t._test_allocation(p, allocator)
5254 if not state: continue
5256 to_minimize = state[0]
5257 if not min_val or min_val &gt; to_minimize:
5258 min_val = to_minimize
5259 min_state = state
5261 if min_state:
5262 t._allocate(min_state, allocator)
5263 elif t.performed_start:
5264 # t could not be allocated ==&gt;
5265 # performance data holds all information
5266 t.start = t._to_start(t.performed_start)
5267 t.end = t._to_end(t.performed_end)
5269 self.unfreeze_parents()
5270 </t>
5271 <t tx="michael.20060619145551.229">def _distribute_performed(self, performed):
5272 project_id = self._idendity_()
5273 plen = len(project_id)
5275 performed = filter(lambda item: item[0].startswith(project_id),
5276 performed)
5277 performed.sort()
5279 task = None
5280 for item in performed:
5281 path = item[0]
5282 rpath = "root" + path[plen:]
5283 task = self.get_task(rpath)
5285 if not task:
5286 &lt;&lt; extract task in activity path &gt;&gt;
5288 if not task or task.children:
5289 self._warn("The performance data contain "
5290 "a task with id '%s'. But such "
5291 "a task does not exist in your "
5292 "project." % path)
5293 continue
5295 if not isinstance(task.performed, list):
5296 task.performed = list(task.performed)
5298 task.performed.append(item[1:])</t>
5299 <t tx="michael.20060619145551.230">class AdjustedProject(_AllocationPoject):
5301 Generates a project with allocated resources. The tasks are
5302 adjusted to the actual tracking data and balanced to fit the
5303 resources load conditions.
5305 &lt;&lt; class AdjustedProject declarations &gt;&gt;
5306 @others
5307 </t>
5308 <t tx="michael.20060619145551.231">__call_completion__ = 'AdjustedProject(|base_project)'
5310 </t>
5311 <t tx="michael.20060619145551.232">def __init__(self, base_project):
5312 _AllocationPoject.__init__(self, base_project._function,
5313 base_project.scenario,
5314 base_project.id)
5316 self.balance = base_project.balance
5317 self.has_actual_data = base_project.has_actual_data
5318 self.allocate(base_project)
5319 for t in self:
5320 t._is_frozen = True
5321 t._recalc_properties()
5322 t.check()
5324 self._restore_globals()
5327 </t>
5328 <t tx="michael.20060619145551.233">def allocate(self, base):
5329 balancing_list = self._get_balancing_list()
5330 scenario = self.scenario
5331 cal = self.calendar
5332 now = cal.now
5334 #for t in balancing_list:
5335 # print t.path
5337 &lt;&lt; free the resources, we have to rebook &gt;&gt;
5339 for t in balancing_list:
5340 src = base.get_task(t.path)
5342 if src.end &lt;= now and src.complete == 100:
5343 &lt;&lt; copy the attribs of complete tasks &gt;&gt;
5344 continue
5346 t._compile([], True)
5347 if not t.resource or t.milestone or t.children:
5348 continue
5350 # now allocate the uncomplete tasks
5351 &lt;&lt; allocate performed data &gt;&gt;
5352 allocator = _allocators[t.balance]
5354 if src.start &gt;= now:
5355 &lt;&lt; allocate tasks, that have not begun yet &gt;&gt;
5356 else:
5357 &lt;&lt; allocate tasks, that are allready at work &gt;&gt;
5359 self.unfreeze_parents()</t>
5360 <t tx="michael.20060619145930"></t>
5361 <t tx="michael.20060619145930.1"></t>
5362 <t tx="michael.20060619145930.2">@others
5364 _smart_allocator = SmartAllocator()
5365 _sloppy_allocator = SloppyAllocator()
5366 _strict_allocator = StrictAllocator()
5367 _allocators = { SMART: _smart_allocator,
5368 SLOPPY: _sloppy_allocator,
5369 STRICT: _strict_allocator }
5371 _allocator_strings = { SMART: "SMART",
5372 SLOPPY: "SLOPPY",
5373 STRICT: "STRICT" }
5374 </t>
5375 <t tx="michael.20060619145930.3"></t>
5376 <t tx="michael.20060619150055"></t>
5377 <t tx="michael.20060619150413">@doc
5378 This section contains code for byte code instrumenting
5379 the task functions</t>
5380 <t tx="michael.20060619150413.1"></t>
5381 <t tx="michael.20060619150519"></t>
5382 <t tx="michael.20060619150542"></t>
5383 <t tx="michael.20060619151509">for t in balancing_list:
5384 src = base.get_task(t.path)
5385 if src.end &gt; now or src.complete &lt; 100:
5386 for r in src._iter_booked_resources():
5387 r.unbook_task(src)</t>
5388 <t tx="michael.20060619151509.1">t.effort = src.effort
5389 t.load = src.load
5390 t.start = src.start
5391 t.end = src.end
5392 t.done = src.done
5393 t.todo = src.todo
5394 t.booked_resource = src.booked_resource
5395 t.performed_resource = src.performed_resource
5396 t._unfreeze("length")
5397 t._unfreeze("duration")</t>
5398 <t tx="michael.20060619151509.2">try:
5399 t._performed = src._performed
5400 t._allocate_performed(t._performed)
5401 except AttributeError:
5402 pass</t>
5403 <t tx="michael.20060619151509.3">min_val = None
5404 min_state = None
5405 for p in range(t.resource._permutation_count()):
5406 state = t._test_allocation(p, allocator)
5407 if not state: continue
5409 to_minimize = state[0]
5410 if not min_val or min_val &gt; to_minimize:
5411 min_val = to_minimize
5412 min_state = state
5414 if min_state:
5415 t._allocate(min_state, allocator)
5416 elif t.performed_start:
5417 t.start = t._to_start(t.performed_start)
5418 t.end = t._to_end(t.performed_end)
5419 </t>
5420 <t tx="michael.20060619151846">if t.__dict__.has_key("effort"):
5421 t.effort = t._to_delta(src.done + src.todo).round()
5423 resource = src.booked_resource or src.performed_resource
5424 state = allocator.test_allocation(t, resource)
5425 if state:
5426 t._allocate(state, allocator)</t>
5427 <t tx="michael.20060619153005">deps = { }
5428 task = self
5429 while task:
5430 deps.update(task._dependencies.get("end", {}))
5431 task = task.up</t>
5432 <t tx="michael.20060619153005.1">def unfreeze_parents():
5433 task = self.up
5434 while task:
5435 task._unfreeze("end")
5436 task = task.up</t>
5437 <t tx="michael.20060619153005.2">unfreeze_parents()
5439 # the following code considers a expressione like
5440 # start = predecessor.end + Delta("1d") the buffer
5441 # calculation must be aware of the 1d delay.
5442 # (therefore a simple succ_start - end would be
5443 # incorrect)
5444 # Solution: Simluate a later end and calculate the
5445 # real delay
5447 succ_task = self.get_task(path)
5448 simulated_task = Task(succ_task._function,
5449 succ_task.name,
5450 succ_task.up, 1)
5452 current_start = succ_task.start
5453 simulated_end = current_start
5454 self.end = current_start
5456 simulated_task._generate()
5457 simulated_start = simulated_task.start
5459 unfreeze_parents()
5460 if old_end: self.end = old_end
5461 else: self._unfreeze("end")
5462 del simulated_task
5464 current_delay = current_start - end
5465 simulated_delay = simulated_start - simulated_end
5466 real_delay = current_delay - simulated_delay
5467 try:
5468 buffer_ = real_delay + succ_task.buffer
5469 except RecursionError, err:
5470 self._raise(err)</t>
5471 <t tx="michael.20060619163321">def guess_object(self, name, pos=None, context=None):
5473 try to calculate the value of variable "name",
5474 by finding an assignment to name
5476 &lt;&lt; calculate search end &gt;&gt;
5477 &lt;&lt; find context start line &gt;&gt;
5478 &lt;&lt; define find_last &gt;&gt;
5479 pos, is_seq = find_last(self.PositionFromLine(line))
5481 if pos &gt;= 0:
5482 expression = self.get_expression(self.LineFromPosition(pos))
5483 if is_seq:
5484 expression = expression[:expression.index(":")] + ": break"
5486 try:
5487 attribs = self.eval_expression(expression, {name : None},
5488 context=context)
5489 return attribs[name]
5490 except Exception: pass
5492 return None
5494 </t>
5495 <t tx="michael.20060619163321.1">find_str_eq = r"\&lt;%s\&gt;[^=]*=" % name
5496 find_str_in = r"for.*\&lt;%s\&gt;.*\&lt;in\&gt;" % name
5498 def find(start, fstr):
5499 pos = start
5500 while pos &gt;= 0:
5501 last_pos = pos
5502 pos = self.FindText(pos + 1, end, fstr,
5503 wx.stc.STC_FIND_REGEXP\
5504 |wx.stc.STC_FIND_MATCHCASE)
5506 if last_pos &lt;= start: last_pos = sys.maxint
5507 return last_pos
5510 def find_last(pos):
5511 p1 = find(pos, find_str_eq)
5512 p2 = find(pos, find_str_in)
5513 pos = min(p1, p2)
5514 if p1 == p2: return -1, False
5515 return pos, pos == p2
5517 </t>
5518 <t tx="michael.20060619164503"></t>
5519 <t tx="michael.20060619164503.2">def find_object(self, name):
5521 Find an object by name.
5524 &lt;&lt; define get_observer &gt;&gt;
5526 if name == "self":
5527 return get_observer()
5529 args = list(self.code_item.get_args())
5530 try:
5531 no = args.index(name)
5532 except ValueError:
5533 return None
5535 observer = get_observer()
5536 &lt;&lt; get argument description &gt;&gt;
5538 try:
5539 obj = arg_desc[no - 1]
5540 except IndexError:
5541 return None
5543 if isinstance(obj, basestring):
5544 # a string indicates a refrence to an attribute
5545 parent = CObserver(self.code_item.get_parent())
5546 obj = parent.find_object(obj)
5548 return obj</t>
5549 <t tx="michael.20060619164749">context = context or self.context
5550 try:
5551 line = context.code_item.get_line()
5552 except AttributeError:
5553 line = 0
5555 </t>
5556 <t tx="michael.20060619183441"></t>
5557 <t tx="michael.20060619183441.1">def get_main_completion_list(self):
5559 returns the completion list of the context
5561 fimport = lambda n: ("import faces.lib.%s" % n,
5562 "import faces.lib.%s as %s" % (n, n))
5563 ffrom = lambda n: ("from faces.lib.%s" % n,
5564 "from faces.lib.%s import %s" % (n, n))
5566 modules = ("report", "gantt", "resource", "generator", "workbreakdown")
5567 return map(fimport, modules) + map(ffrom, modules)
5572 </t>
5573 <t tx="michael.20060619184051">def get_observer_pseudo(code_item):
5574 module = code_item.editor.get_module()
5575 for base in code_item.get_args():
5576 try:
5577 bo = eval("module.%s" % base)
5578 if issubclass(bo, fobserver.Observer):
5579 return bo
5580 except AttributeError: pass
5581 except TypeError: pass
5582 except SyntaxError: pass
5584 return fobserver.Observer</t>
5585 <t tx="michael.20060619191608">@language python
5586 &lt;&lt; Copyright &gt;&gt;
5588 A report generator
5590 &lt;&lt; declarations &gt;&gt;
5591 @others
5592 </t>
5593 <t tx="michael.20060619191608.1">import task
5594 import observer
5595 import datetime as datetime
5596 import inspect
5597 import pcalendar
5598 import plocale
5599 import utils
5600 from task import _ValueWrapper
5602 _is_source_ = True
5603 _ = plocale.get_gettext()
5606 header_names = { "indent_name": _("Name"),
5607 "name": _("Name"),
5608 "index": _("Index"),
5609 "title" : _("Title"),
5610 "start" : _("Start"),
5611 "end" : _("End"),
5612 "load" : _("Load"),
5613 "estimated_effort" : _("Estimated Effort"),
5614 "performed_effort" : _("Performed Effort"),
5615 "performed_end" : _("Performed End"),
5616 "performed_start" : _("Performed Start"),
5617 "performed_work_time" : _("Worktime"),
5618 "length" : _("Length"),
5619 "effort" : _("Effort"),
5620 "duration" : _("Duration"),
5621 "real_effort" : _("Real Effort"),
5622 "quotient" : _("Quotient"),
5623 "complete" : _("Complete"),
5624 "priority" : _("Priority"),
5625 "todo" : _("Todo"),
5626 "efficiency" : _("Efficiency"),
5627 "buffer" : _("Buffer"),
5628 "costs" : _("Costs"),
5629 "sum" : _("Sum"),
5630 "max" : _("Max"),
5631 "min" : _("Min"),
5632 "milestone" : _("Milestone"),
5633 "resource" : _("Resource"),
5634 "booked_resource" : _("Booked Resource") }
5637 </t>
5638 <t tx="michael.20060619191608.2"></t>
5639 <t tx="michael.20060619191608.3">def _val(val):
5640 if isinstance(val, _ReportValueWrapper):
5641 return val._value
5643 return val
5644 </t>
5645 <t tx="michael.20060619191608.4">def _has_ref(val):
5646 if isinstance(val, _ReportValueWrapper):
5647 return val._ref
5649 return False
5650 </t>
5651 <t tx="michael.20060619191608.5">class _ReportValueWrapper(_ValueWrapper):
5652 @others</t>
5653 <t tx="michael.20060619191608.6">def __init__(self, value, ref=(None, "")):
5654 _ValueWrapper.__init__(self, value, ref)
5655 </t>
5656 <t tx="michael.20060619191608.7">def _vw(self, operand, *args):
5657 refs = map(_has_ref, args)
5658 refs = filter(bool, refs)
5659 vals = map(_val, args)
5660 result = operand(*vals)
5661 return _ReportValueWrapper(result, refs and refs[0] or (None, ""))
5662 </t>
5663 <t tx="michael.20060619191608.8">def _cmp(self, operand, *args):
5664 vals = map(_val, args)
5665 return operand(*vals)
5666 </t>
5667 <t tx="michael.20060619191608.9">def __call__(self, *args):
5668 vals = map(_val, args)
5669 other = _ReportValueWrapper(self._value(*vals),
5670 (self._ref[0], self._ref[1], args))
5671 return other
5672 </t>
5673 <t tx="michael.20060619191608.10">def __repr__(self):
5674 if isinstance(self._value, basestring):
5675 return self._value
5677 formatter = self._ref[0].formatter(self._ref[1])
5678 return formatter(self._value)
5679 </t>
5680 <t tx="michael.20060619191608.11">__str__ = __repr__
5682 def type(self):
5683 return type(self._value)
5684 </t>
5685 <t tx="michael.20060619191608.12">
5687 class _TaskWrapper:
5688 @others
5689 </t>
5690 <t tx="michael.20060619191608.13">def __init__(self, task):
5691 self.task = task
5692 </t>
5693 <t tx="michael.20060619191608.14">def __getattr__(self, name):
5694 if name == "copy_src":
5695 return self.task.copy_src and _TaskWrapper(self.task.copy_src)
5697 if name == "to_string":
5698 return _ToStringWrapper(self.task.to_string)
5700 value = getattr(self.task, name)
5702 if isinstance(value, task.Task):
5703 result = _TaskWrapper(value)
5704 else:
5705 result = _ReportValueWrapper(value, (self.task, name))
5707 setattr(self, name, result)
5708 return result
5709 </t>
5710 <t tx="michael.20060619191608.15">def __iter__(self):
5711 def wrap_iter():
5712 for t in self.task:
5713 yield _TaskWrapper(t)
5715 return wrap_iter()
5716 </t>
5717 <t tx="michael.20060619191608.16">def __str__(self):
5718 return "_TaskWrapper %s" % self.task
5719 </t>
5720 <t tx="michael.20060619191608.17">
5722 class _ToStringWrapper:
5723 @others
5724 </t>
5725 <t tx="michael.20060619191608.18">def __init__(self, converter):
5726 self.converter = converter
5727 </t>
5728 <t tx="michael.20060619191608.19">def __getattr__(self, name):
5729 value = getattr(self.converter, name)
5730 result = _ReportValueWrapper(value, (self.converter.source, name))
5731 setattr(self, name, result)
5732 return result
5733 </t>
5734 <t tx="michael.20060619191608.20">def __getitem__(self, format):
5735 return _ToStringWrapper(self.converter[format])
5736 </t>
5737 <t tx="michael.20060619191608.21">
5740 class _ReportIter(object):
5741 @others
5742 </t>
5743 <t tx="michael.20060619191608.22">def __init__(self, report):
5744 self.report = report
5745 try:
5746 self.stepper = iter(report.make_report(report.data))
5747 except Exception, e:
5748 report._raise(e)
5749 </t>
5750 <t tx="michael.20060619191608.23">def __iter__(self):
5751 return self
5752 </t>
5753 <t tx="michael.20060619191608.24">def next(self):
5754 row = self.stepper.next()
5755 if not isinstance(row, (tuple, list)):
5756 row = (row, )
5758 def to_cell(c):
5759 if isinstance(c, Cell): return c
5760 return Cell(c)
5762 row = map(to_cell, row)
5763 if row[0].left_border is None:
5764 row[0].left_border = True
5766 return self.report.modify_row(row)
5767 </t>
5768 <t tx="michael.20060619191608.25"></t>
5769 <t tx="michael.20060619191608.26">class Cell(object):
5771 The class represents a cell within a report row
5773 @var back_color:
5774 Specifies the background color of the cell. Valid value are any
5775 html hex string like '\#eeefff' or legal html names for colors,
5776 like 'red', 'burlywood' and 'chartreuse'.
5778 @var text_color:
5779 Specifies the text color of the cell. Valid value are any html hex
5780 string like '\#eeefff' or legal html names for colors, like 'red',
5781 'burlywood' and 'chartreuse'.
5783 @var font_bold:
5784 Specifies if the text should be displayed bold. Valid values are
5785 True or False.
5787 @var font_italic:
5788 Specifies if the text should be displayed italic. Valid values
5789 are True or False.
5791 @var font_underline:
5792 Specifies if the text should be displayed underlined. Valid
5793 values are True or False.
5795 @var font_size:
5796 Specifies the font size of the text. Valid values are either an
5797 absolute value of"xx-small", "x-small", "small", "medium", "large",
5798 "x-large", "xx-large"; or a relative value of"smaller" or "larger";
5799 or an absolute font size, e.g. 12.
5801 @var left_border:
5802 Specifies if a left border apperars. Valid values
5803 are True or False.
5805 @var top_border:
5806 Specifies if a top border apperars. Valid values
5807 are True or False.
5809 @var right_border:
5810 Specifies if a right border apperars. Valid values
5811 are True or False.
5813 @var bottom_border:
5814 Specifies if a bottom border apperars. Valid values
5815 are True or False.
5817 @var align:
5818 Specifies the alignment of the cell. Valid values are
5819 LEFT(0), RIGHT(1), CENTER(2)
5821 &lt;&lt; declarations &gt;&gt;
5822 @others
5824 __repr__ = __str__</t>
5825 <t tx="michael.20060619191608.27">LEFT = 0
5826 RIGHT = 1
5827 CENTER = 2
5829 back_color = None
5830 text_color = None
5831 font_bold = False
5832 font_italic = False
5833 font_underline = False
5834 font_size = None
5835 left_border = None
5836 top_border = False
5837 right_border = True
5838 bottom_border = True
5839 align = LEFT
5841 __all__ = ("LEFT", "RIGHT", "CENTER", "back_color",\
5842 "text_color", "font_bold", "font_italic",\
5843 "font_underline", "font_size", "left_border",\
5844 "top_border", "right_border", "bottom_border",\
5845 "align")
5847 </t>
5848 <t tx="michael.20060619191608.28">def __init__(self, value, **kwargs):
5849 for k, v in kwargs.iteritems():
5850 setattr(self, k, v)
5852 self.value = value
5853 if self.get_type() is float:
5854 self.align = self.RIGHT
5855 </t>
5856 <t tx="michael.20060619191608.29">def get_label(self):
5857 if isinstance(self.value, _ReportValueWrapper):
5858 return self.value._ref[1]
5860 return ""
5861 </t>
5862 <t tx="michael.20060619191608.30">def get_type(self):
5863 if isinstance(self.value, _ReportValueWrapper):
5864 return type(self.value._value)
5866 return type(self.value)
5867 </t>
5868 <t tx="michael.20060619191608.31">def get_ref(self):
5869 if isinstance(self.value, _ReportValueWrapper):
5870 return self.value._ref
5872 return (None, "")
5873 </t>
5874 <t tx="michael.20060619191608.32">def __str__(self):
5875 return str(self.value)
5876 </t>
5877 <t tx="michael.20060619191608.33">def __unicode__(self):
5878 return unicode(self.value)
5879 </t>
5880 <t tx="michael.20060619191608.34">def __nonzero__(self):
5881 return bool(self.value)
5882 </t>
5883 <t tx="michael.20060619191608.35">def __cmp__(self, other):
5884 return cmp(self.value, other.value)
5885 </t>
5886 <t tx="michael.20060619191608.36">def native(self):
5888 returns the native value of the cell.
5891 if isinstance(self.value, _ReportValueWrapper):
5892 return self.value._value
5894 return self.value
5895 </t>
5896 <t tx="michael.20060619191608.37">class Report(observer.Observer):
5898 A standart report.
5900 @var headers:
5901 A tuple specifying the report header.
5903 &lt;&lt; declarations &gt;&gt;
5904 @others
5905 </t>
5906 <t tx="michael.20060619191608.38">__type_name__ = "report"
5907 __type_image__ = "report"
5908 data = None
5909 headers = ()
5911 __attrib_completions__ = observer.Observer.__attrib_completions__.copy()
5912 __attrib_completions__.update({\
5913 "#data" : "get_evaluation_completions",
5914 "data" : 'data = ',
5915 "headers" : 'headers = ()',
5916 "def make_report" : "def make_report(self, data):\nfor d0 in data: \nyield (|d0.indent_name(), d0.start)",
5917 "def prepare_data" : "def prepare_data(self, data):\nreturn data",
5918 "def modify_row" : "def modify_row(self, row):\nreturn row" })
5920 __all__ = ("headers", "data")
5921 </t>
5922 <t tx="michael.20060619191608.39">def __init__(self):
5923 if not self.data:
5924 self._raise(RuntimeError('no data attribute specified'))
5926 if not self.headers:
5927 def get_header(c):
5928 result = c.get_label()
5929 return header_names.get(result, result)
5931 first = iter(self).next()
5932 if not self.headers:
5933 self.headers = tuple(map(get_header, first))
5934 </t>
5935 <t tx="michael.20060619191608.40">def _raise(self, exc):
5936 line = inspect.getsourcelines(self.__class__)[1]
5937 fname = inspect.getsourcefile(self.__class__)
5938 raise exc.__class__('%s (File "%s", line %i)' % (str(exc), fname, line))
5939 </t>
5940 <t tx="michael.20060619191608.41">def make_report(self, data):
5941 raise RuntimeError("called base report")
5943 make_report.args = ("data",)</t>
5944 <t tx="michael.20060619191608.42">def prepare_data(self, data):
5945 return data
5946 </t>
5947 <t tx="michael.20060619191608.43">def instrument_data(self, data):
5948 def wrap_obj(obj):
5949 if isinstance(obj, task.Task):
5950 return _TaskWrapper(obj)
5952 if isinstance(obj, _TaskWrapper):
5953 return obj
5955 if isinstance(obj, basestring):
5956 return obj
5958 try:
5959 return map(wrap_obj, iter(obj))
5960 except TypeError:
5961 return obj
5963 return wrap_obj(data)
5964 </t>
5965 <t tx="michael.20060619191608.44">def modify_row(self, row):
5966 return row
5968 modify_row.args = ([Cell]*20,)
5970 </t>
5971 <t tx="michael.20060619191608.45">__is_prepared = False
5972 def __iter__(self):
5973 if not self.__is_prepared:
5974 self.data = self.prepare_data(self.data)
5975 self.data = self.instrument_data(self.data)
5976 self.__is_prepeditared = True
5977 return _ReportIter(self)
5978 </t>
5979 <t tx="michael.20060619192815">def get_observer():
5980 parent = self.code_item.get_parent()
5981 try:
5982 return parent.obj
5983 except AttributeError:
5984 return get_observer_pseudo(parent)</t>
5985 <t tx="michael.20060619193106">@language python
5986 &lt;&lt; Copyright &gt;&gt;
5988 A library of different reports.
5990 &lt;&lt; imports &gt;&gt;
5992 _is_source_ = True
5993 Cell = _report.Cell
5994 _ = faces.plocale.get_gettext()
5996 __all__ = ("Standard", "Titles", "Critical", "Calendar")
5999 @others
6000 </t>
6001 <t tx="michael.20060619193106.1">import faces.report as _report
6002 import faces.pcalendar as _pcalendar
6003 import faces.task as _task
6004 import datetime as _datetime
6005 import bisect as _bisect
6006 import faces.plocale
6007 import locale
6010 </t>
6011 <t tx="michael.20060619193106.2">class Standard(_report.Report):
6013 A standard report
6016 @others
6017 </t>
6018 <t tx="michael.20060619193106.4">def make_report(self, data):
6019 for t in data:
6020 yield (t.indent_name(), t.start, t.end, t.effort, t.length)
6022 </t>
6023 <t tx="michael.20060619193106.5">class Titles(Standard):
6024 &lt;&lt; declarations &gt;&gt;
6025 @others
6026 </t>
6027 <t tx="michael.20060619193106.6">__attrib_completions__ = Standard.__attrib_completions__.copy()
6028 del __attrib_completions__["def modify_row"]
6030 </t>
6031 <t tx="michael.20060619193106.7">def modify_row(self, row):
6032 task = row[0].get_ref()[0]
6033 if not isinstance(task, _task.Task):
6034 return row
6036 if task.children:
6037 ds = {
6038 0 : "xx-large",
6039 1 : "x-large",
6040 2 : "large",
6041 }.get(int(task.depth))
6043 for c in row:
6044 c.font_bold = True
6045 c.font_size = ds
6047 return row
6048 </t>
6049 <t tx="michael.20060619193106.8">class Critical(Standard):
6050 &lt;&lt; declarations &gt;&gt;
6051 @others
6052 </t>
6053 <t tx="michael.20060619193106.9">colors = { 0 : "red" }
6055 __attrib_completions__ = Standard.__attrib_completions__.copy()
6056 __attrib_completions__.update({\
6057 "colors" : 'colors = { |0 : "red" }' })
6058 del __attrib_completions__["def modify_row"]
6061 </t>
6062 <t tx="michael.20060619193106.10">def __init__(self):
6063 self._colors = []
6065 to_minutes = _pcalendar._default_calendar.Minutes
6066 self._colors = map(lambda i: (to_minutes(i[0]), i[1]),
6067 self.colors.items())
6068 self._colors.sort()
6069 self._colors.reverse()
6071 Standard.__init__(self)
6072 </t>
6073 <t tx="michael.20060619193106.11">def modify_row(self, row):
6074 task = row[0].get_ref()[0]
6075 if not isinstance(task, _task.Task):
6076 return row
6078 color = None
6079 for v, c in self._colors:
6080 if task.buffer &lt;= v: color = c
6082 if color:
6083 for c in row:
6084 c.back_color = color
6086 return row
6087 </t>
6088 <t tx="michael.20060619193106.12">class Calendar(Standard):
6089 &lt;&lt; declarations &gt;&gt;
6090 @others
6091 </t>
6092 <t tx="michael.20060619193106.13">__type_image__ = "calendar"
6094 show_start = True
6095 show_end = True
6096 start = None
6097 end = None
6099 __attrib_completions__ = Standard.__attrib_completions__.copy()
6100 __attrib_completions__.update({\
6101 "show_start" : 'show_start = True',
6102 "show_end" : 'show_end = True',
6103 "start" : 'start = None',
6104 "end" : 'end = None',
6105 "def modify_cell" : "def modify_cell(self, cell):\npass" })
6107 del __attrib_completions__["def modify_row"]
6108 del __attrib_completions__["def make_report"]
6111 </t>
6112 <t tx="michael.20060619193106.14">def instrument_data(self, data):
6113 data = tuple(data)
6114 self.dates = dates = {}
6116 mind = _datetime.datetime.max
6117 maxd = _datetime.datetime.min
6119 &lt;&lt; define insert_task &gt;&gt;
6121 for i, t in enumerate(data):
6122 if self.show_start:
6123 mind, maxd = insert_task(i, t.start, 0, mind, maxd)
6125 if self.show_end:
6126 mind, maxd = insert_task(i, t.end, 1, mind, maxd)
6128 if not self.start:
6129 self.start = mind
6130 else:
6131 self.start = _pcalendar.WorkingDate(self.start).to_datetime()
6133 if not self.end:
6134 self.end = maxd
6135 else:
6136 self.end = _pcalendar.WorkingDate(self.end).to_datetime()
6138 self._create_columns(self.start, self.end)
6139 self._create_headers()
6141 return Standard.instrument_data(self, data)
6142 </t>
6143 <t tx="michael.20060619193106.15">def get_dates(self, date):
6144 result = self.dates.get(date, ())
6145 return map(lambda i: (self.data[i[2]], i[1]), result)
6146 </t>
6147 <t tx="michael.20060619193106.16">def make_cell(self, value, **kwargs):
6148 cell = Cell(value, **kwargs)
6149 date = kwargs["date"]
6150 is_header = kwargs.get("header", False)
6152 if date and date.weekday() in (5, 6) and not is_header:
6153 cell.back_color = "gray"
6155 self.modify_cell(cell)
6156 return cell
6157 </t>
6158 <t tx="michael.20060619193106.17">def modify_cell(self, cell):
6159 pass
6161 modify_cell.args = (Cell,)</t>
6162 <t tx="michael.20060619193106.18">def make_report(self, data):
6163 day_header = None
6164 day_rows = None
6166 &lt;&lt; define add_row &gt;&gt;
6167 &lt;&lt; define add_date &gt;&gt;
6169 col_range = range(len(self.columns))
6170 for d in range(1, 32):
6171 #iterate through all days
6172 day_header = []
6173 day_rows = []
6175 &lt;&lt; create day header cells &gt;&gt;
6176 add_row()
6178 &lt;&lt; create day data cells &gt;&gt;
6179 day_rows.insert(0, day_header)
6181 &lt;&lt; adjust borders &gt;&gt;
6183 for r in day_rows:
6184 r[0].left_border = left_frame_border
6185 yield r
6186 </t>
6187 <t tx="michael.20060619193106.21">def get_start_text(self, task):
6188 text = task.to_string["%H:%M"].start + " " + task.title + " (start)"
6189 if task.booked_resource:
6190 text += "\n " + task.to_string.booked_resource
6191 return text
6192 </t>
6193 <t tx="michael.20060619193106.22">def get_end_text(self, task):
6194 text = task.to_string["%H:%M"].end + " " + task.title + " (end)"
6195 if task.booked_resource:
6196 text += "\n " + task.to_string.booked_resource
6197 return text
6198 </t>
6199 <t tx="michael.20060619193106.23">def _create_columns(self, start, end):
6200 start = start.year * 12 + start.month - 1
6201 end = end.year * 12 + end.month
6202 def to_date(month):
6203 return _datetime.datetime(month / 12, 1 + (month % 12), 1)
6204 self.columns = map(to_date, range(start, end))
6205 </t>
6206 <t tx="michael.20060619193106.24">def _create_headers(self):
6207 encoding = locale.getlocale()[1] or "ascii"
6208 self.headers = map(lambda d: d.strftime("%B %y").decode(encoding),
6209 self.columns)
6210 </t>
6211 <t tx="michael.20060619193517">for c in inspect.getmro(observer):
6212 try:
6213 func = getattr(c, self.code_item.name)
6214 arg_desc = func.args
6215 break
6216 except AttributeError:
6217 pass
6218 else:
6219 return None</t>
6220 <t tx="michael.20060619194944">def add_row():
6221 row = map(lambda c: self.make_cell("",
6222 right_border=c.right_border,
6223 font_size="small",
6224 header=False,
6225 bottom_border=False,
6226 date=c.date),\
6227 day_header)
6229 day_rows.append(row)</t>
6230 <t tx="michael.20060619194944.1">def add_date(col, date):
6231 if day_rows[-1][col].value:
6232 add_row()
6233 day_rows[-1][col].value = date
6234 return
6236 for r in day_rows:
6237 if not r[col].value:
6238 r[col].value = date
6239 break</t>
6240 <t tx="michael.20060619200005">for month in self.columns:
6241 try:
6242 date = month.replace(day=d).date()
6243 c = self.make_cell(date.strftime("%d. %A"),
6244 back_color="gold",
6245 bottom_border=False,
6246 header=True,
6247 date=date)
6248 if day_header: day_header[-1].right_border = True
6249 day_header.append(c)
6250 except:
6251 #the day does not exist at tha month
6252 c = self.make_cell("",
6253 right_border=False,
6254 bottom_border=False,
6255 header=False,
6256 date=None)
6257 day_header.append(c)</t>
6258 <t tx="michael.20060619200005.1">for c in col_range:
6259 date = day_header[c].date
6260 if not date: continue
6261 tasks = self.get_dates(date)
6262 for t, soe in tasks:
6263 if soe == 0:
6264 text = self.get_start_text(t)
6265 else:
6266 text = self.get_end_text(t)
6268 if text:
6269 add_date(c, text)</t>
6270 <t tx="michael.20060619200005.2">for c in col_range:
6271 date = day_header[c].date
6272 if date:
6273 day_rows[-1][c].bottom_border = True
6275 left_frame_border = bool(day_header[0].date)</t>
6276 <t tx="michael.20060619200744">def insert_task(index, date, soe, min_date, max_date):
6277 date = date.to_datetime()
6278 day = dates.setdefault(date.date(), [])
6279 _bisect.insort_right(day, (date.time(), soe, index))
6280 return min(date, min_date), max(date, max_date)</t>
6281 <t tx="michael.20060619222451">@language python
6282 &lt;&lt; Copyright &gt;&gt;
6284 Matplotlib-based charts
6286 &lt;&lt; imports &gt;&gt;
6288 _is_source_ = True
6289 _ = faces.plocale.get_gettext()
6291 __all__ = ("TimeWidgetChart", "TableChart", "TimeAxisWidgetChart",
6292 "TimeAxisPlotChart", "TimeAxisMultiChart",
6293 "TimeAxisTabledChart")
6294 @others</t>
6295 <t tx="michael.20060619222451.1">import matplotlib.figure as figure
6296 import matplotlib.backends
6297 import matplotlib.font_manager as font
6298 import matplotlib.backend_bases as bases
6299 import matplotlib.ticker as ticker
6300 import matplotlib.axes as axes
6301 import matplotlib.transforms as mtrans
6302 import matplotlib.pylab as pylab
6303 import faces
6304 import faces.pcalendar as pcal
6305 import faces.utils as utils
6306 import faces.observer
6307 import faces.plocale
6308 import patches
6309 import widgets as widget
6310 import printer
6311 import faxes
6312 import taxis
6313 import timescale
6314 from tools import *
6318 </t>
6319 <t tx="michael.20060619222451.8">class MatplotChart(faces.observer.Observer, widget._PropertyAware):
6321 Base Class for all charts.
6323 @var properties:
6324 Specifies a dictionary of display properties.
6326 @var show_tips:
6327 Specifies a boolean value, wether the charts should display tool tips.
6329 @var scroll_bars:
6330 Specifies a boolean value, wether the charts should display scroll bars.
6333 &lt;&lt; declarations &gt;&gt;
6334 @others
6335 </t>
6336 <t tx="michael.20060619222451.9">__type_name__ = "matplot_chart"
6337 properties = {
6338 "family" : "sans-serif",
6339 #"family": [ "Arial", "Verdana", "Bitstream Vera Sans" ] ,
6340 "background.facecolor" : "w",
6341 "fill" : 1,
6342 "alpha" : 1,
6343 "marker.edgecolor" : "blue",
6344 "marker.linewidth" : 2,
6345 "marker.antialiased" : True,
6346 "marker.facecolor" : "green",
6347 "marker.alpha" : "0.4",
6348 "focused.marker.edgecolor" : "red" }
6350 __attrib_completions__ = faces.observer.Observer.__attrib_completions__.copy()
6351 __attrib_completions__.update({\
6352 "properties" : 'properties = { | }',
6353 "show_tips" : 'show_tips = False',
6354 "scroll_bars" : 'scroll_bars = False',
6355 "def add_decorations" : """def add_decorations(self, axes):
6356 pass
6361 show_tips = True
6362 scroll_bars = True
6364 </t>
6365 <t tx="michael.20060619222451.10">def printer(cls, **kwargs):
6366 return printer.FreePrinter(cls, **kwargs)
6368 printer = classmethod(printer)</t>
6369 <t tx="michael.20060619222451.11">def __init__(self, paint_to=None, rect=None, **kwargs):
6370 faces.observer.Observer.__init__(self)
6371 widget._PropertyAware.__init__(self)
6373 self.figure = None
6374 self.axes = None
6376 back_face = self.get_property("background.facecolor")
6377 if isinstance(paint_to, figure.Figure):
6378 self.figure = paint_to
6379 self.axes = self.create_axes(rect, **kwargs)
6380 self.axes.set_axis_bgcolor(back_face)
6381 self.setup_axes_interface(self.axes)
6383 if isinstance(paint_to, axes.Axes):
6384 self.axes = paint_to
6385 self.figure = self.axes.get_figure()
6386 self.axes.set_axis_bgcolor(back_face)
6387 self.setup_axes_interface(self.axes)
6389 if self.figure:
6390 self.create()
6391 self._add_decorations()
6392 </t>
6393 <t tx="michael.20060619222451.12">def _add_decorations(self):
6394 self.add_decorations(self.axes)
6395 </t>
6396 <t tx="michael.20060619222451.13">def add_decorations(self, axes):
6398 Overwrite this method to add decorations to the chart
6400 pass
6402 add_decorations.args = (faxes.WidgetAxes,)
6403 </t>
6404 <t tx="michael.20060619222451.14">def create_axes(self, rect=None, **kwargs):
6406 creates the default axes for the chart
6408 raise RuntimeError("abstract")
6409 </t>
6410 <t tx="michael.20060619222451.15">def create(self):
6412 create the chart
6415 raise RuntimeError("abstract")
6416 </t>
6417 <t tx="michael.20060619222451.16">def get_tip(self, tipobj):
6418 return None
6419 </t>
6420 <t tx="michael.20060619222451.17">def setup_axes_interface(self, axes):
6422 Setup interface for chartview and printer
6424 def dumy(*args): return None
6425 self._set_frame_on = axes.set_frame_on
6426 self._axes_patch = axes.axesPatch
6427 self._left_margin = getattr(axes, "left_margin", None)
6428 self._right_margin = getattr(axes, "right_margin", None)
6429 self._top_margin = getattr(axes, "top_margin", None)
6430 self._bottom_margin = getattr(axes, "bottom_margin", None)
6431 self._trans_data = axes.transData
6432 self._data_lim = axes.dataLim
6433 self._view_lim = axes.viewLim
6434 self._bbox = getattr(axes, "content_bbox", self.axes.bbox)
6435 self._set_xlim = axes.set_xlim
6436 self._set_ylim = axes.set_ylim
6437 self._get_xlim = axes.get_xlim
6438 self._get_ylim = axes.get_ylim
6439 self._set_autoscale_on = axes.set_autoscale_on
6440 self._autoscale_view = axes.autoscale_view
6441 self._set_auto_scale_y =getattr(axes, "set_auto_scale_y", dumy)
6442 self._zoomx = axes.zoomx
6443 self._zoomy = axes.zoomy
6444 self._widget_at = getattr(axes, "widget_at", dumy)
6445 self._find_widget = getattr(axes, "find_widget", dumy)
6446 self._set_focused_on = getattr(axes, "set_focused_on", dumy)
6447 self._set_focused_off = getattr(axes, "set_focused_off", dumy)
6448 self._speed_up = getattr(axes, "speed_up", dumy)
6449 self._clear_speed_cache = getattr(axes, "clear_speed_cache", dumy)
6450 self._widget_x_visible = getattr(axes, "widget_x_visible", dumy)
6451 self._widget_y_visible = getattr(axes, "widget_y_visible", dumy)
6452 self._share_axes = axes
6453 self._mark_widget = getattr(axes, "mark_widget", dumy)
6454 self._check_limits = getattr(axes, "check_limits", dumy)
6455 self._get_time_lim = getattr(axes, "get_time_lim", dumy)
6456 self._set_time_lim = getattr(axes, "set_time_lim", dumy)
6457 self._widgets = getattr(axes, "widgets", ())
6458 </t>
6459 <t tx="michael.20060619222451.18">class TimeWidgetChart(MatplotChart):
6461 Base class for all charts that have a horizontal time axes.
6463 @var sharex:
6464 Specifies a group of charts that share their time axis. All charts
6465 with the same attribute will be synchronized within the gui.
6467 @var show_rowlines:
6468 Specifies wether the chart should display row lines.
6470 @var auto_scale_y:
6471 Specifies wether the chart should be also autoscaled in the y axis
6472 to fit in a window.
6475 &lt;&lt; declarations &gt;&gt;
6476 @others
6477 </t>
6478 <t tx="michael.20060619222451.19">__type_name__ = "matplot_timechart"
6479 __type_image__ = "gantt"
6480 data = None
6481 sharex = None
6482 show_rowlines = False
6483 auto_scale_y = False
6485 __attrib_completions__ = MatplotChart.__attrib_completions__.copy()
6486 __attrib_completions__.update({\
6487 "data" : 'data = ',
6488 "sharex" : 'sharex = "time_share"',
6489 "show_rowlines" : "show_rowlines = False",
6490 "auto_scale_y" : 'auto_scale_y = False',
6491 "#data" : "get_evaluation_completions" })
6494 </t>
6495 <t tx="michael.20060619222451.20">def __init__(self, *args, **kwargs):
6496 self.calendar = pcal._default_calendar
6497 self.time_scale = timescale._default_scale
6499 if not self.data:
6500 raise RuntimeError("no data attribute specified")
6502 MatplotChart.__init__(self, *args, **kwargs)
6503 </t>
6504 <t tx="michael.20060619222451.21">def to_date(self, date):
6506 converts a date to a x value
6508 return self.time_scale.to_num(date)
6509 </t>
6510 <t tx="michael.20060619222451.22">def create_axes(self, rect=None, **kwargs):
6511 pprop = self.get_patch
6512 rect = rect or [ 0, 0, 1, 1 ]
6514 ax = self.figure.add_axes(faxes.TimeWidgetAxes(self.figure,
6515 rect, **kwargs))
6516 ax.auto_scale_y = self.auto_scale_y
6517 ax.cla()
6518 ax.set_marker(pprop("focused.marker"), pprop("marker"))
6519 return ax
6520 </t>
6521 <t tx="michael.20060619222451.23">def create(self):
6522 if not isinstance(self.axes, faxes.TimeWidgetAxes):
6523 raise RuntimeError("axes has to be an instance "\
6524 "of TimeWidgetAxes but is %s" \
6525 % self.axes.__class__.__name__)
6527 row_widgets = filter(lambda w: hasattr(w, "row"), self.axes.widgets)
6528 if row_widgets:
6529 rows = map(lambda w: (w.row.y.get(), w.row), row_widgets)
6530 row = min(rows)[1]
6531 else:
6532 row = None
6534 push_active(self)
6535 widget.Row.show_rowline = self.show_rowlines
6537 all_widgets = self.create_all_widgets(row)
6539 utils.progress_start(_("create widgets for %s") \
6540 % self.__class__.__name__,
6541 len(all_widgets))
6543 for count, w in enumerate(all_widgets):
6544 self.axes.add_widget(w)
6545 utils.progress_update(count)
6547 utils.progress_end()
6548 self.axes.xaxis_timescale(self.time_scale)
6549 pop_active()
6550 </t>
6551 <t tx="michael.20060619222451.24">def create_all_widgets(self, start_row):
6552 raise RuntimeError("abstract")
6553 </t>
6554 <t tx="michael.20060619222451.25">def _finalize_row_widgets(self, row_widgets, start_row):
6555 rows = enumerate(map(lambda w: w.row, row_widgets)) #get rows
6557 rows = map(lambda r: (r[1], r), rows) # save row order
6558 rows.reverse() # to elimnate duplicates with higher row numbers
6559 rows = dict(rows) #eliminate duplicates
6560 rows = rows.values()
6561 rows.sort() #restore row order
6562 rows = map(lambda r: r[1], rows) # back to sequence
6564 if start_row:
6565 y = start_row.next_y()
6566 else:
6567 y = mtrans.zero()
6569 for r in rows: y = r.set_y(y)
6570 return rows
6571 </t>
6572 <t tx="michael.20060619222451.26">class TimePlotChart(MatplotChart):
6573 &lt;&lt; class TimePlotChart declarations &gt;&gt;
6574 @others
6575 </t>
6576 <t tx="michael.20060619222451.27">__type_name__ = "matplot_timechart"
6577 __type_image__ = "plot"
6578 calendar = None
6579 sharex = None
6581 __attrib_completions__ = MatplotChart.__attrib_completions__.copy()
6582 __attrib_completions__.update({\
6583 "calendar" : 'calendar = ',
6584 "sharex" : 'sharex = "time_share"',
6585 "def create_plot" : """def create_plot(self, to_x):
6586 pass
6587 """})
6589 </t>
6590 <t tx="michael.20060619222451.28">def __init__(self, *args, **kwargs):
6591 if not self.calendar:
6592 raise RuntimeError("no calendar specified")
6594 self.time_scale = timescale.TimeScale(self.calendar)
6595 MatplotChart.__init__(self, *args, **kwargs)
6596 </t>
6597 <t tx="michael.20060619222451.29">def create_axes(self, rect=None, **kwargs):
6598 pprop = self.get_patch
6599 rect = rect or [ 0, 0, 1, 1 ]
6601 ax = self.figure.add_axes(faxes.TimePlotAxes(self.figure,
6602 rect, **kwargs))
6603 ax.cla()
6604 return ax
6605 </t>
6606 <t tx="michael.20060619222451.30">def create(self):
6607 push_active(self)
6608 self.create_plot(self.time_scale.to_num)
6609 self.axes.xaxis_timescale(self.time_scale)
6610 pop_active()
6611 </t>
6612 <t tx="michael.20060619222451.31">def create_plot(self, to_x):
6613 pass
6614 </t>
6615 <t tx="michael.20060619222451.32">class TimeMultiChart(MatplotChart):
6616 &lt;&lt; class TimeMultiChart declarations &gt;&gt;
6617 @others
6618 </t>
6619 <t tx="michael.20060619222451.33">__type_name__ = "matplot_timechart"
6620 __type_image__ = "gantt"
6621 sharex = None
6622 auto_scale_y = False
6624 __attrib_completions__ = MatplotChart.__attrib_completions__.copy()
6625 __attrib_completions__.update({\
6626 "auto_scale_y" : 'auto_scale_y = True',
6627 "sharex" : 'sharex = "time_share"'})
6630 </t>
6631 <t tx="michael.20060619222451.34">def __init__(self, *args, **kwargs):
6632 self.charts = []
6633 self.time_scale = timescale._default_scale
6634 self.main_axes = None
6635 MatplotChart.__init__(self, *args, **kwargs)
6636 </t>
6637 <t tx="michael.20060619222451.35">def create_axes(self, rect=None, **kwargs):
6638 pprop = self.get_patch
6639 rect = rect or [ 0, 0, 1, 1 ]
6641 ax = self.figure.add_axes(faxes.TimeWidgetAxes(self.figure,
6642 rect, **kwargs))
6643 ax.auto_scale_y = self.auto_scale_y
6644 ax.cla()
6645 ax.set_navigate(False)
6646 ax.set_marker(pprop("focused.marker"), pprop("marker"))
6647 ax.set_frame_on(True)
6648 ax.axesPatch.set_fill(True)
6649 return ax
6650 </t>
6651 <t tx="michael.20060619222451.36">def create(self):
6652 push_active(self)
6653 self.create_chart()
6655 #find a better timescale
6656 for ax in self.figure.get_axes():
6657 if ax is not self.axes and isinstance(ax, faxes.TimeAxes):
6658 self.time_scale = ax.time_scale
6659 ax.time_axis.set_visible(False)
6660 ax.update_time_axis()
6662 self.axes.xaxis_timescale(self.time_scale)
6663 self.axes.update_time_axis()
6664 self.setup_axes_interface(self.main_axes)
6666 pop_active()
6667 </t>
6668 <t tx="michael.20060619222451.37">def add_TimeWidgetAxes(self, **kwargs):
6669 pprop = self.get_patch
6670 kwargs["sharex"] = self.axes
6671 if not kwargs.has_key("rect"): kwargs["rect"] = (0, 0, 1, 1)
6672 rect = kwargs["rect"]
6673 if rect[1] + rect[3] &gt;= 1:
6674 kwargs["top_margin"] = self.axes.top_margin
6676 ax = faxes.TimeWidgetAxes(self.figure, **kwargs)
6677 self.figure.add_axes(ax)
6678 ax.auto_scale_y = self.auto_scale_y
6679 ax.cla()
6680 ax.set_frame_on(False)
6681 ax.set_marker(pprop("focused.marker"), pprop("marker"))
6682 ax.set_frame_on(False)
6683 ax.axesPatch.set_fill(False)
6684 self.main_axes = ax
6685 return ax
6686 </t>
6687 <t tx="michael.20060619222451.38">def add_TimePlotAxes(self, **kwargs):
6688 kwargs["sharex"] = self.axes
6689 if not kwargs.has_key("rect"): kwargs["rect"] = (0, 0, 1, 1)
6690 rect = kwargs["rect"]
6691 if rect[1] + rect[3] &gt;= 1:
6692 kwargs["top_margin"] = self.axes.title_height
6694 ax = faxes.TimePlotAxes(self.figure, **kwargs)
6695 self.figure.add_axes(ax)
6696 ax.cla()
6697 ax.set_frame_on(False)
6698 return ax
6699 </t>
6700 <t tx="michael.20060619222451.39">def add_chart(self, chart):
6701 push_active(self)
6702 try:
6703 self.charts.append(chart)
6704 finally:
6705 pop_active()
6706 </t>
6707 <t tx="michael.20060619222451.40">def get_tip(self, tipobj):
6708 if not self.show_tips: return
6709 for c in self.charts:
6710 info = c.get_tip(tipobj)
6711 if info: return info
6713 return None
6714 </t>
6715 <t tx="michael.20060619222451.41">def create_chart(self):
6716 pass
6717 </t>
6718 <t tx="michael.20060619222451.42">class TimeAxisChart(object):
6720 A Mixin for Charts with a Time Axis
6722 @var time_axis_properties:
6723 Specifies a dictionary of display properties for the time axis.
6725 @var show_grid:
6726 A boolean value that specifies wether to display a horizontal grid.
6728 @var show_scale:
6729 A boolean value that specifies wether to display the time scale.
6731 @var show_free_time:
6732 A boolean value that specifies wether to distinguish between free
6733 times and working times.
6735 @var show_now:
6736 A boolean value that specifies wether to display a line at now.
6738 &lt;&lt; declarations &gt;&gt;
6739 @others
6740 </t>
6741 <t tx="michael.20060619222451.43">time_axis_properties = None
6742 show_grid = True
6743 show_scale = True
6744 show_free_time = True
6745 show_now = True
6747 __attrib_completions__ = {\
6748 "time_axis_properties" : 'time_axis_properties = { | }',
6749 "show_grid": "show_grid = False",
6750 "show_scale": "show_scale = False",
6751 "show_free_time": "show_free_time = False",
6752 "show_now": "show_now = False" }
6754 </t>
6755 <t tx="michael.20060619222451.44">def create(self):
6756 super(TimeAxisChart, self).create()
6757 self.set_time_axis()
6758 </t>
6759 <t tx="michael.20060619222451.45">def set_time_axis(self):
6760 self.time_axis = taxis.TimeAxis(self.time_axis_properties)
6761 self.time_axis.show_grid = self.show_grid
6762 self.time_axis.show_scale = self.show_scale
6763 self.time_axis.show_free_time = self.show_free_time
6764 self.time_axis.show_now = self.show_now
6765 self.time_axis.time_scale = self.time_scale
6766 self.axes.set_time_axis(self.time_axis)
6767 </t>
6768 <t tx="michael.20060619222451.46">class TimeAxisWidgetChart(TimeAxisChart, TimeWidgetChart):
6769 &lt;&lt; class TimeAxisWidgetChart declarations &gt;&gt;
6770 @others
6771 </t>
6772 <t tx="michael.20060619222451.47">__attrib_completions__ = TimeAxisChart.__attrib_completions__.copy()
6773 __attrib_completions__.update(TimeWidgetChart.__attrib_completions__)
6775 </t>
6776 <t tx="michael.20060619222451.48">def printer(cls, **kwargs):
6777 return printer.TimeWidgetPrinter(cls, **kwargs)
6779 printer = classmethod(printer)
6780 </t>
6781 <t tx="michael.20060619222451.49">class TimeAxisPlotChart(TimeAxisChart, TimePlotChart):
6782 &lt;&lt; class TimeAxisPlotChart declarations &gt;&gt;
6783 @others
6784 </t>
6785 <t tx="michael.20060619222451.50">__attrib_completions__ = TimeAxisChart.__attrib_completions__.copy()
6786 __attrib_completions__.update(TimePlotChart.__attrib_completions__)
6788 </t>
6789 <t tx="michael.20060619222451.51">def printer(cls, **kwargs):
6790 return printer.TimePlotPrinter(cls, **kwargs)
6792 printer = classmethod(printer)
6793 </t>
6794 <t tx="michael.20060619222451.52">class TimeAxisMultiChart(TimeAxisChart, TimeMultiChart):
6795 &lt;&lt; class TimeAxisMultiChart declarations &gt;&gt;
6796 @others
6797 </t>
6798 <t tx="michael.20060619222451.53">__attrib_completions__ = TimeAxisChart.__attrib_completions__.copy()
6799 __attrib_completions__.update(TimeMultiChart.__attrib_completions__)
6801 </t>
6802 <t tx="michael.20060619222451.54">def printer(cls, **kwargs):
6803 return printer.TimeWidgetPrinter(cls, **kwargs)
6805 printer = classmethod(printer)
6806 </t>
6807 <t tx="michael.20060619222451.55">class TableChart(MatplotChart):
6808 &lt;&lt; class TableChart declarations &gt;&gt;
6809 @others
6810 </t>
6811 <t tx="michael.20060619222451.56">__type_name__ = "matplot_pointchart"
6812 show_rowlines = True
6813 show_collines = True
6815 __attrib_completions__ = MatplotChart.__attrib_completions__.copy()
6816 __attrib_completions__.update({\
6817 "show_collines" : 'show_collines = True',
6818 "show_rowlines" : 'show_rowlines = True' })
6821 </t>
6822 <t tx="michael.20060619222451.57">def printer(cls, **kwargs):
6823 return printer.PointPrinter(cls, **kwargs)
6825 printer = classmethod(printer)
6826 </t>
6827 <t tx="michael.20060619222451.58">def __init__(self, *args, **kwargs):
6828 self.cols = {}
6829 self.rows = {}
6830 self.widgets = []
6831 MatplotChart.__init__(self, *args, **kwargs)
6832 </t>
6833 <t tx="michael.20060619222451.59">def create_axes(self, rect=None, **kwargs):
6834 pprop = self.get_patch
6835 rect = rect or [0, 0, 1, 1]
6836 fig = self.figure
6837 ax = fig.add_axes(faxes.PointAxes(fig, rect, **kwargs))
6838 ax.cla()
6839 ax.set_marker(pprop("focused.marker"), pprop("marker"))
6840 return ax
6841 </t>
6842 <t tx="michael.20060619222451.60">def create(self):
6843 if not isinstance(self.axes, faxes.PointAxes):
6844 raise RuntimeError("axes has to be an instance "\
6845 "of PointAxes but is %s" \
6846 % self.axes.__class__.__name__)
6848 push_active(self)
6850 header_transform = self.axes.build_margin_transform(top=False)
6851 def dumy(*args): pass
6853 try:
6854 self.create_all_widgets()
6855 self._finalize_row_widgets()
6856 self._finalize_col_widgets()
6858 utils.progress_start(_("create widgets for %s") \
6859 % self.__class__.__name__,
6860 len(self.widgets))
6862 count = 0
6863 for w in self.widgets:
6864 self.axes.add_widget(w)
6865 utils.progress_update(count)
6866 count += 1
6868 utils.progress_end()
6870 for r in self.rows.itervalues(): self.axes.add_widget(r)
6871 for c in self.cols.itervalues(): self.axes.add_widget(c)
6872 finally:
6873 pop_active()
6874 </t>
6875 <t tx="michael.20060619222451.61">def get_col(self, col_no):
6876 col = self.cols.get(col_no)
6877 if not col:
6878 widget.Column.show_colline = self.show_collines
6879 col = self.cols[col_no] = widget.Column()
6881 return col
6882 </t>
6883 <t tx="michael.20060619222451.62">def get_row(self, row_no=None):
6884 if row_no is None:
6885 if self.rows:
6886 row_no = max(self.rows.keys()) + 1
6887 else:
6888 row_no = 0
6890 row = self.rows.get(row_no)
6891 if not row:
6892 widget.Row.show_rowline = self.show_rowlines
6893 row = self.rows[row_no] = widget.Row()
6895 return row
6896 </t>
6897 <t tx="michael.20060619222451.63">def add_cell(self, row_no, col_no, fobj, properties=None):
6898 row = self.get_row(row_no)
6899 col = self.get_col(col_no)
6900 cell = widget.CellWidget(row, col, fobj, properties)
6901 self.widgets.append(cell)
6902 return cell
6903 </t>
6904 <t tx="michael.20060619222451.64">def create_all_widgets(self):
6905 pass
6906 </t>
6907 <t tx="michael.20060619222451.65">def _finalize_row_widgets(self):
6908 row_widgets = filter(lambda w: hasattr(w, "row"), self.axes.widgets)
6909 if row_widgets:
6910 rows = map(lambda w: (w.row.y.get(), w.row), row_widgets)
6911 y = min(rows)[1].next_y()
6912 else:
6913 y = mtrans.zero()
6915 rows = self.rows.items()
6916 rows.sort() #restore row order
6917 for rno, row in rows:
6918 y = row.set_y(y)
6919 </t>
6920 <t tx="michael.20060619222451.66">def _finalize_col_widgets(self):
6921 col_widgets = filter(lambda w: hasattr(w, "col"), self.axes.widgets)
6922 if col_widgets:
6923 cols = map(lambda w: (w.col.x.get(), w.col), col_widgets)
6924 x = max(cols)[1].next_x()
6925 else:
6926 x = mtrans.zero()
6928 cols = self.cols.items()
6929 cols.sort()
6930 for cno, col in cols:
6931 x = col.set_x(x)
6933 </t>
6934 <t tx="michael.20060619222451.67">class _DescriptionTable(TableChart):
6935 &lt;&lt; class _DescriptionTable declarations &gt;&gt;
6936 @others
6937 </t>
6938 <t tx="michael.20060619222451.68">properties = { "edgecolor" : "black",
6939 "title.facecolor" : "darkgray",
6940 "title.antialiased" : True,
6941 "title.linewidth" : 1 }
6943 </t>
6944 <t tx="michael.20060619222451.69">def __init__(self, report, src_axes, paint_to=None, rect=None,
6945 property_prefix="", properties=None, **kwargs):
6946 self.src_axes = src_axes
6947 self.report = report
6948 self.property_prefix = property_prefix
6949 self.properties = properties or { }
6950 TableChart.__init__(self, paint_to, rect, **kwargs)
6951 </t>
6952 <t tx="michael.20060619222451.70">def get_col(self, col_no):
6953 col = self.cols.get(col_no)
6954 if not col:
6955 class TitleColumn(widget.Column):
6956 def set_transform(self, transform):
6957 transform = self.axes.build_margin_transform(top=False)
6958 widget.Column.set_transform(self, transform)
6959 widget.Column.set_clip_box(self, transform.get_bbox2())
6961 TitleColumn.show_colline = self.show_collines
6962 col = self.cols[col_no] = TitleColumn()
6964 return col
6965 </t>
6966 <t tx="michael.20060619222451.71">def create_all_widgets(self):
6967 rows = { }
6968 cells = { }
6970 report = self.report()
6971 self.create_header(report)
6972 rows[-1] = self.header_row
6974 for r in report:
6975 for c in r:
6976 task, attrib = c.get_ref()[:2]
6977 if task: break
6978 else:
6979 continue
6981 src_widget = self.src_axes.find_widget(task)
6982 if not src_widget: continue
6984 for i, c in enumerate(r):
6985 col = self.get_col(i)
6986 row = rows.get(src_widget.row)
6987 if not row:
6988 row = rows[src_widget.row] = widget.Row()
6989 row.show_rowline = self.show_rowlines
6990 row.height = src_widget.row.height
6991 row.top_sep = src_widget.row.top_sep
6992 row.bottom_sep = src_widget.row.bottom_sep
6993 row.set_y(src_widget.row.y)
6995 task, attrib = c.get_ref()[:2]
6996 cell = cells.get((row, col))
6997 if not cell:
6998 cell = cells[(row, col)] = widget.CellWidget(row, col, task)
6999 cell.fattrib = attrib
7000 self.widgets.append(cell)
7002 #cell.vert_sep = row.top_sep + row.bottom_sep
7003 #row.top_sep = row.bottom_sep = 0
7004 self.modify_widget(cell, task, c)
7006 self.rows = rows
7007 </t>
7008 <t tx="michael.20060619222451.72">def create_header(self, report):
7009 class TitleWidget(object):
7010 def set_transform(self, transform):
7011 Point = mtrans.Point
7012 Bbox = mtrans.Bbox
7013 zero = mtrans.zero()
7015 point_to_pixel = self.axes.fig_point_to_pixel
7016 bbox = self.axes.bbox
7017 dbox = transform.get_bbox1()
7018 top_margin = self.axes.top_margin
7019 left = self.axes.left_margin * point_to_pixel
7020 right = self.axes.right_margin * point_to_pixel
7021 mheight = point_to_pixel * top_margin
7022 bheight = bbox.ur().y() - bbox.ll().y()
7023 offset = bheight - mheight
7025 view_box = Bbox(Point(bbox.ll().x() + left,
7026 bbox.ll().y() + offset),
7027 Point(bbox.ur().x() - right,
7028 bbox.ur().y()))
7030 data_box = Bbox(Point(dbox.ll().x() , zero - top_margin),
7031 Point(dbox.ur().x(), zero))
7033 transform = mtrans.get_bbox_transform(data_box, view_box)
7034 super(TitleWidget, self).set_transform(transform)
7035 super(TitleWidget, self).set_clip_box(bbox)
7038 def contains(self, x, y):
7039 return False
7042 class TitleRow(TitleWidget, widget.Row):
7043 def update_height(self, height): pass
7045 class TitleCell(TitleWidget, widget.CellWidget): pass
7047 self.header_row = TitleRow()
7048 self.header_row.axes = self.axes
7049 self.header_row.show_rowline = True
7050 self.header_row.top_sep = self.header_row.bottom_sep = 0
7051 self.header_row.height = Lazy(self.axes.top_margin)
7052 self.header_row.set_y(0)
7053 self.header_row._is_header = True
7054 kwargs = make_properties(self.get_property,
7055 self.property_prefix+"title")
7056 back = patches.Polygon(((LEFT, TOP), (LEFT, BOTTOM),
7057 (RIGHT, BOTTOM), (RIGHT, TOP)), **kwargs)
7058 self.header_row.add_artist(back)
7059 for i, header in enumerate(report.headers):
7060 col = self.get_col(i)
7061 col._is_header = True
7062 cell = TitleCell(self.header_row, col, None)
7063 cell._is_header = True
7064 self.modify_header_widget(cell, header)
7065 self.widgets.append(cell)
7066 </t>
7067 <t tx="michael.20060619222451.73">def _finalize_row_widgets(self):
7068 pass
7069 </t>
7070 <t tx="michael.20060619222451.74">def modify_header_widget(self, cell, title):
7071 cell.horz_sep = 6
7072 cell.text(title,
7073 HCENTER, VCENTER,
7074 horizontalalignment ="center",
7075 verticalalignment="center",
7076 fontproperties=self.property_prefix+"title")
7077 </t>
7078 <t tx="michael.20060619222451.75">def modify_widget(self, widget, obj, cell):
7079 if widget.artists: return
7081 if cell.back_color:
7082 back = patches.Polygon(((LEFT, TOP), (LEFT, BOTTOM),
7083 (RIGHT, BOTTOM), (RIGHT, TOP)),
7084 facecolor=cell.back_color,
7085 linewidth=0)
7086 widget.add_artist(back)
7089 halign = { cell.LEFT : "left",
7090 cell.RIGHT : "right",
7091 cell.CENTER : "center" }[cell.align]
7093 t = widget.text(str(cell),
7094 LEFT + 2 * HSEP, VCENTER,
7095 horizontalalignment=halign,
7096 verticalalignment="center",
7097 fontproperties=self.property_prefix+"row")
7099 if cell.back_color: t.set_backgroundcolor(cell.back_color)
7100 if cell.text_color: t.set_color(cell.text_color)
7101 if cell.font_bold: t.set_weight("bold")
7102 if cell.font_italic: t.set_style("italic")
7103 if cell.font_size: t.set_size(cell.font_size)
7104 #if cell.left_border = None
7105 #if cell.top_border = False
7106 #if cell.right_border = True
7107 #if cell.bottom_border = True
7108 widget.horz_sep = 6
7109 </t>
7110 <t tx="michael.20060619222451.76">class TimeTabledChart(MatplotChart):
7111 &lt;&lt; class TimeTabledChart declarations &gt;&gt;
7112 @others
7113 </t>
7114 <t tx="michael.20060619222451.77">__type_name__ = "matplot_timechart"
7115 __type_image__ = "gantt"
7117 properties = { "background.facecolor" : "white" }
7119 sharex = None
7120 auto_scale_y = False
7121 content_charts = ()
7122 plot_chart = None
7123 left_report = None
7124 right_report = None
7126 __attrib_completions__ = MatplotChart.__attrib_completions__.copy()
7127 __attrib_completions__.update({\
7128 "sharex" : 'sharex = "time_shared"',
7129 "auto_scale_y" : 'auto_scale_y = True',
7130 "content_charts" : 'content_charts = ()',
7131 "plot_chart" : 'plot_chart = None',
7132 "left_report" : 'left_report = None',
7133 "right_report" : 'right_report = None'})
7136 </t>
7137 <t tx="michael.20060619222451.78">def printer(cls, **kwargs):
7138 return printer.TimeWidgetPrinter(cls, **kwargs)
7139 </t>
7140 <t tx="michael.20060619222451.79">printer = classmethod(printer)
7143 def __init__(self, *args, **kwargs):
7144 self.charts = []
7145 self.time_scale = timescale._default_scale
7146 MatplotChart.__init__(self, *args, **kwargs)
7147 </t>
7148 <t tx="michael.20060619222451.80">def setup_axes_interface(self, axes):
7149 super(TimeTabledChart, self).setup_axes_interface(self.content_axes)
7150 self._share_axes = axes
7151 del self._check_limits
7152 del self._widget_at
7153 del self._mark_widget
7154 </t>
7155 <t tx="michael.20060619222451.81">def _check_limits(self, cut=True):
7156 self.left_axes.check_limits(cut)
7157 self.axes.check_limits(cut)
7158 self.right_report and self.right_axes.check_limits(cut)
7159 </t>
7160 <t tx="michael.20060619222451.82">def _widget_at(self, x, y):
7161 try:
7162 return self.content_axes.widget_at(x, y) \
7163 or self.left_axes.widget_at(x, y) \
7164 or self.right_axes.widget_at(x, y)
7165 except AttributeError:
7166 return None
7167 </t>
7168 <t tx="michael.20060619222451.83">def _mark_widget(self, widget):
7169 changed = 0
7170 changed += self.content_axes.mark_widget(widget)
7171 changed += self.left_axes.mark_widget(widget)
7172 try:
7173 changed += self.right_axes.mark_widget(widget)
7174 except AttributeError:
7175 pass
7177 return bool(changed)
7178 </t>
7179 <t tx="michael.20060619222451.84">def create_axes(self, rect=None, **kwargs):
7180 rect = ( 0, 0, 1, 1 )
7182 #be carefully the order of the following
7183 #is very important (and unfortunatly quite complicated)
7184 #A fine tuned use of lazy values...
7186 top_margin = kwargs["top_margin"] = mtrans.Value(0)
7187 self.left_axes = faxes.PointAxes(self.figure, ( 0, 0, 1, 1 ), **kwargs)
7188 self.figure.add_axes(self.left_axes).cla()
7190 #self.left_axes.point_to_pixel and self.left_axes.fig_point_to_pixel
7191 #have new lazy values after add_axes
7193 font_factor = self.left_axes.point_to_pixel \
7194 / self.left_axes.fig_point_to_pixel
7196 right_data_lim = mtrans.unit_bbox()
7197 right_offset = self.figure.figwidth * mtrans.Value(72 / 2)\
7198 - right_data_lim.ur().x() * font_factor
7200 self.right_axes = faxes.PointAxes(self.figure, ( 0.5, 0, 0.5, 1 ),
7201 left_margin=right_offset,
7202 sharey=self.left_axes,
7203 **kwargs)
7205 self.figure.add_axes(self.right_axes).cla()
7206 self.right_axes.dataLim = right_data_lim
7208 kwargs["left_margin"] = self.left_axes.dataLim.ur().x() * font_factor
7209 kwargs["right_margin"] = self.right_axes.dataLim.ur().x() * font_factor
7211 class MainAxes(faxes.TimeWidgetAxes):
7212 def update_time_axis(self):
7213 self.time_axis.show_scale = True #this axes must always have a scale
7214 faxes.TimeWidgetAxes.update_time_axis(self)
7216 main_axes = MainAxes(self.figure, rect, **kwargs)
7217 main_axes.auto_scale_y = self.auto_scale_y
7218 main_axes.set_navigate(False)
7220 kwargs["sharex"] = main_axes
7221 kwargs["sharey"] = self.left_axes
7222 self.content_axes = faxes.TimeWidgetAxes(self.figure, rect, **kwargs)
7223 self.content_axes.set_frame_on(False)
7225 self.figure.add_axes(main_axes).cla()
7226 self.figure.add_axes(self.content_axes).cla()
7228 #correct the axespatch of mainaxes
7229 dtrans = main_axes.build_margin_transform(top=False)
7230 atrans = mtrans.get_bbox_transform(mtrans.unit_bbox(),
7231 dtrans.get_bbox2())
7232 main_axes.axesPatch.set_transform(atrans)
7233 return main_axes
7234 </t>
7235 <t tx="michael.20060619222451.85">def create(self):
7236 push_active(self)
7237 self.charts = map(lambda c: c(self.content_axes), self.content_charts)
7239 if self.left_report:
7240 _DescriptionTable(self.left_report,
7241 self.content_axes,
7242 self.left_axes,
7243 property_prefix="left.",
7244 properties=self.properties)
7247 if self.right_report:
7248 _DescriptionTable(self.right_report,
7249 self.content_axes,
7250 self.right_axes,
7251 property_prefix="right.",
7252 properties=self.properties)
7254 prop = self.get_property
7255 pprop = self.get_patch
7256 self.figure.set_facecolor(prop("background.facecolor"))
7258 if self.left_axes.widgets:
7259 self.left_axes.set_axis_bgcolor(prop("left.background.facecolor"))
7260 self.left_axes.set_marker(pprop("left.focused.marker"),
7261 pprop("left.marker"))
7263 if not self.right_axes.widgets:
7264 self.figure.delaxes(self.right_axes)
7265 del self.right_axes
7266 else:
7267 self.right_axes.set_axis_bgcolor(prop("right.background.facecolor"))
7268 self.right_axes.set_marker(pprop("right.focused.marker"),
7269 pprop("right.marker"))
7271 self.time_scale = self.content_axes.time_scale
7272 self.axes.xaxis_timescale(self.time_scale)
7273 self.content_axes.time_axis.set_visible(False)
7274 self.content_axes.update_time_axis()
7275 self.content_axes.set_axis_bgcolor(prop("content.background.facecolor"))
7276 self.content_axes.set_marker(pprop("focused.marker"), pprop("marker"))
7277 pop_active()
7278 </t>
7279 <t tx="michael.20060619222451.86">def get_tip(self, tipobj):
7280 if not self.show_tips: return
7281 for c in self.charts:
7282 info = c.get_tip(tipobj)
7283 if info: return info
7285 return None
7286 </t>
7287 <t tx="michael.20060619222451.87">def create_chart(self):
7288 pass
7289 </t>
7290 <t tx="michael.20060619222451.88">class TimeAxisTabledChart(TimeAxisChart, TimeTabledChart):
7291 &lt;&lt; class TimeAxisTabledChart declarations &gt;&gt;
7292 </t>
7293 <t tx="michael.20060619222451.89">__attrib_completions__ = TimeAxisChart.__attrib_completions__.copy()
7294 __attrib_completions__.update(TimeTabledChart.__attrib_completions__)
7298 </t>
7299 <t tx="michael.20060619223120">def _dumy(): return None, None, None
7301 matplotlib.backends.pylab_setup = _dumy
7303 def _wrong_pylab_function(*args, **kwargs):
7304 raise RuntimeError("this function may not be called inside faces")
7306 def _new_figure_manager(*args, **kwargs):
7307 return _figure_manager
7309 pylab.switch_backend = _wrong_pylab_function
7310 pylab.subplot_tool = _wrong_pylab_function
7311 pylab.close = _wrong_pylab_function
7312 pylab.show = _wrong_pylab_function
7313 pylab.draw_if_interactive = _dumy
7314 pylab.new_figure_manager = _new_figure_manager
7316 class _DumyFigureManager(bases.FigureManagerBase):
7317 def __init__(self):
7318 self.canvas = None
7319 self.num = -1
7321 def key_press(self, event):
7322 pass
7324 _figure_manager = _DumyFigureManager()
7325 </t>
7326 <t tx="michael.20060619225419">@language python
7327 &lt;&lt; Copyright &gt;&gt;
7328 &lt;&lt; Imports &gt;&gt;
7329 &lt;&lt; Declarations &gt;&gt;
7331 @others</t>
7332 <t tx="michael.20060619225419.1">import faces
7333 import faces.pcalendar as pcal
7334 import faces.charting.charts as charts
7335 import faces.charting.widgets as widget
7336 import faces.charting.shapes as shapes
7337 import faces.charting.timescale as timescale
7338 import faces.charting.connector as connector
7339 import faces.task as task
7340 import faces.plocale
7341 from faces.charting.tools import *
7342 from faces.charting.shapes import *
7343 </t>
7344 <t tx="michael.20060619225419.2">_is_source_ = True
7345 _ = faces.plocale.get_gettext()
7347 _color_index = ( "navy",
7348 "seagreen",
7349 "indianred",
7350 "violet",
7351 "skyblue",
7352 "purple",
7353 "limegreen",
7354 "darkgray" )
7357 GanttWidget = widget.GanttWidget
7359 __all__ = ("Standard", "Compare", "Critical") + shapes.__all__</t>
7360 <t tx="michael.20060619225419.3">class Gantt(charts.TimeAxisWidgetChart):
7362 A standard gantt chart
7364 @var show_connectors:
7365 A boolean value that specifies wether to display connectors between tasks.
7367 @var show_complete:
7368 A boolean value that specifies wether to display a completion bar
7369 inside the gantt bars.
7371 @var row_attrib:
7372 A string value specifying the name of the row attribute inside the
7373 project definitions. With this attribute you can control in which
7374 row a task will be displayed.
7376 @var accumulate_attrib:
7377 A string value specifying the name of the accumulate attribute
7378 inside the project definitions. If a parent task defines the
7379 accumulate attribute as True it will be displayed as
7380 leaf, and all child tasks will not be displayed.
7382 @var shape_attrib:
7383 A string value specifying the name of the shape attribute inside
7384 the project definitions. The shape attribute controls the
7385 displayed shape of the gantt object.
7387 @var shape_properties_attrib:
7388 A string value specifying the name of the shape properties
7389 attribute inside the project definitions. The shape properties
7390 attribute controls the style properties of the gantt object.
7392 @var parent_shape:
7393 A string value specifying the name of the general shape for parent tasks.
7395 @var milestone_shape:
7396 A string value specifying the name of the general shape for milestone tasks.
7398 @var leaf_shape:
7399 A string value specifying the name of the general shape for leaf tasks.
7401 @var title_attrib:
7402 A string value specifying the name of the task attribute that
7403 should be displayed at the gantt object, to identify the task.
7405 @var show_resource:
7406 A boolean value that specifies wether to display the allocated
7407 resources after the title.
7409 &lt;&lt; declarations &gt;&gt;
7410 @others
7412 &lt;&lt; set __all__ attribute &gt;&gt;
7414 </t>
7415 <t tx="michael.20060619225419.4">__editor__ = ("faces.gui.edit_gantt", "Standard")
7417 show_connectors = True
7418 show_complete = True
7419 row_attrib = "gantt_same_row"
7420 accumulate_attrib = "gantt_accumulate"
7421 shape_attrib = "gantt_shape"
7422 shape_properties_attrib = "gantt_properties"
7423 parent_shape = "brace"
7424 milestone_shape = "diamond"
7425 leaf_shape = "bar"
7426 title_attrib = "title"
7427 show_resource = True
7428 properties = { "parent.facecolor": "black",
7429 "complete.facecolor" : "black",
7430 "connector.end.facecolor" : "darkslategray",
7431 "connector.end.edgecolor" : "darkslategray",
7432 "connector.edgecolor" : "darkslategray",
7433 "facecolor" : "blue",
7434 "milestone.facecolor" : "black",
7435 "background.facecolor" : "w",
7436 "height" : 4, "complete.height" : 2 }
7438 __attrib_completions__ = charts.TimeAxisWidgetChart\
7439 .__attrib_completions__.copy()
7440 __attrib_completions__.update({\
7441 "show_resource" : 'show_resource = False',
7442 "show_connectors" : 'show_connectors = True',
7443 "show_complete" : 'show_complete = True',
7444 "row_attrib" : 'row_attrib = "gantt_same_row"',
7445 "accumulate_attrib" : 'accumulate_attrib = "gantt_accumulate"',
7446 "shape_attrib" : 'shape_attrib = "gantt_shape"',
7447 "shape_properties_attrib" : 'shape_properties_attrib = "gantt_properties"',
7448 "parent_shape" : 'parent_shape = "brace"',
7449 "milestone_shape" : 'milestone_shape = "diamond"',
7450 "leaf_shape" : 'leaf_shape = "bar"',
7451 "title_attrib" : 'title_attrib = "title"',
7452 "def create_objects" : """def create_objects(self, data):
7453 for t in data:
7454 yield t
7455 """,
7456 "def modify_widget" : """def modify_widget(self, gantt_widget, task):
7457 gantt_widget.text(task.to_string["%x"].start,
7458 LEFT, BOTTOM - 1.5 * VSEP,
7459 verticalalignment = "top",
7460 horizontalalignment = "center")
7461 """,
7462 "def modify_connector" : """def modify_connector(self, src, dest, connector):
7463 return True
7469 </t>
7470 <t tx="michael.20060619225419.5">def create_all_widgets(self, start_row):
7471 widgets = map(self.create_widget, self.create_objects(self.data))
7472 task_map = dict(map(lambda w: (w.fobj, w), widgets))
7474 if self.calendar is pcal._default_calendar:
7475 self.calendar = task_map.keys()[0].root.calendar
7477 self.time_scale = timescale.TimeScale(self.calendar)
7478 to_num = self.time_scale.to_num
7480 for w in widgets:
7481 w.start = to_num(w.start)
7482 w.end = to_num(w.end)
7484 row_task = getattr(w.fobj, self.row_attrib, None)
7485 if row_task and not w.fobj.is_inherited(self.row_attrib):
7486 row_widget = task_map.get(row_task)
7487 if row_widget: w.row = row_widget.row
7489 rows = self._finalize_row_widgets(widgets, start_row)
7490 if not self.show_rowlines:
7491 rows = filter(lambda t: t.all_artists(), rows)
7493 widgets.extend(rows)
7494 if not self.show_connectors: return widgets
7496 # make connectors
7497 connectors = []
7498 for w in widgets:
7499 if not w.fobj: continue
7501 try:
7502 sources = w.fobj._sources.iteritems()
7503 except AttributeError:
7504 sources = {}
7506 for dattrib, sources in sources:
7507 for s in sources:
7508 path, sattrib = faces.task._split_path(s)
7509 src_task = w.fobj.get_task(path)
7510 src_widget = task_map.get(src_task)
7511 if not src_widget: continue
7513 connectors.append((src_widget, sattrib, w, dattrib))
7515 widgets.extend(self.create_connectors(connectors))
7516 return widgets
7517 </t>
7518 <t tx="michael.20060619225419.6">def create_objects(self, data):
7519 for t in data:
7520 if getattr(t, self.accumulate_attrib, False) \
7521 and t.is_inherited(self.accumulate_attrib):
7522 continue
7524 yield t
7525 </t>
7526 <t tx="michael.20060619225419.7">def get_shape_name(self, task):
7527 if task.children and not getattr(task, self.accumulate_attrib, False):
7528 shape_name = self.parent_shape
7529 else:
7530 if task.milestone:
7531 shape_name = self.milestone_shape
7532 else:
7533 shape_name = self.leaf_shape
7535 return task.__dict__.get(self.shape_attrib, shape_name)
7536 </t>
7537 <t tx="michael.20060619225419.8">def get_property_group(self, task):
7538 if task.children and not getattr(task, self.accumulate_attrib, False):
7539 return "parent"
7541 if task.milestone:
7542 return "milestone"
7544 return "leaf"
7545 </t>
7546 <t tx="michael.20060619225419.9">def calc_title(self, task):
7548 Calculate the task title.
7550 if self.title_attrib:
7551 title = getattr(task, self.title_attrib)
7552 else:
7553 title = ""
7555 if self.show_resource:
7556 if task.booked_resource:
7557 title += " ("+ task.to_string.booked_resource + ")"
7558 elif task.performed_resource:
7559 title += " ("+ task.to_string.performed_resource + ")"
7561 return title
7562 </t>
7563 <t tx="michael.20060619225419.10">def make_shape(self, shape_name, gantt_widget, title, propname=None):
7565 Assigns a shape to gantt_widget.
7567 try:
7568 shape_func = getattr(self, "make_%s_shape" % shape_name)
7569 except AttributeError:
7570 if shape_name in shapes.symbols:
7571 self.make_symbol_shape(shape_name, gantt_widget,
7572 title, propname)
7573 else:
7574 self.make_combined_shape(shape_name, gantt_widget,
7575 title, propname)
7576 else:
7577 try:
7578 shape_func(gantt_widget, title, propname)
7579 except TypeError:
7580 shape_func(gantt_widget, title)
7581 </t>
7582 <t tx="michael.20060619225419.11">def create_widget(self, task):
7584 Create a gantt widget for a task.
7586 if isinstance(task, widget.Widget): return task
7588 title = self.calc_title(task)
7589 shape_name = self.get_shape_name(task)
7590 props = task.__dict__.get(self.shape_properties_attrib, None)
7591 gantt_widget = widget.GanttWidget(task.start, task.end,
7592 task, properties=props)
7593 gantt_widget.row.top_sep = gantt_widget.row.bottom_sep = 3
7594 self.make_shape(shape_name, gantt_widget, title)
7595 self.modify_widget(gantt_widget, task)
7596 return gantt_widget
7597 </t>
7598 <t tx="michael.20060619225419.12">def modify_widget(self, widget, task):
7600 Overwrite this method to decorate a widget.
7603 modify_widget.args = (widget.GanttWidget, task.Task)</t>
7604 <t tx="michael.20060619225419.13">def make_combined_shape(self, shape_name, widget, title, propname=None):
7605 end_shapes = shape_name.split("_bar_")
7606 if len(end_shapes) != 2:
7607 raise ValueError("Cannot find a shape %s" % shape_name)
7609 left, right = end_shapes
7610 left = getattr(shapes, left)
7611 right = getattr(shapes, right)
7613 try:
7614 complete = self.show_complete and widget.fobj.complete or 0
7615 except AttributeError:
7616 complete = 0
7618 propname = propname or self.get_property_group(widget.fobj)
7619 widget.set_shape(shapes.combibar, propname, left, right, complete)
7620 widget.text(title, HCENTER, TOP + VSEP,
7621 horizontalalignment ="center",
7622 verticalalignment="bottom",
7623 fontproperties=propname)
7624 </t>
7625 <t tx="michael.20060619225419.14">def make_symbol_shape(self, shape_name, widget, title, propname=None):
7626 propname = propname or self.get_property_group(widget.fobj)
7627 widget.set_shape(getattr(shapes, shape_name), propname)
7628 widget.text(title, RIGHT + HSEP, VCENTER,
7629 horizontalalignment ="left",
7630 verticalalignment="center",
7631 fontproperties=propname)
7632 </t>
7633 <t tx="michael.20060619225419.15">def make_bar_shape(self, widget, title, propname=None):
7634 try:
7635 complete = self.show_complete and widget.fobj.complete or 0
7636 except AttributeError:
7637 complete = 0
7639 propname = propname or self.get_property_group(widget.fobj)
7640 widget.set_shape(shapes.bar, propname, complete)
7641 widget.inside_text(title, RIGHT + HSEP, VCENTER,
7642 verticalalignment="center",
7643 inside_properties=propname+".inside",
7644 fontproperties=propname)
7645 </t>
7646 <t tx="michael.20060619225419.16">def make_brace_shape(self, widget, title, propname=None):
7647 propname = propname or self.get_property_group(widget.fobj)
7648 widget.set_shape(shapes.brace, propname)
7649 widget.text(title, HCENTER, TOP + VSEP,
7650 horizontalalignment ="center",
7651 verticalalignment="bottom",
7652 fontproperties=propname)
7653 </t>
7654 <t tx="michael.20060619225419.17">def find_path(self, sa, da):
7655 aamap = {
7656 ("start", "start") : connector.StartStartPath,
7657 ("end", "start") : connector.EndStartPath,
7658 ("start", "end") : connector.StartEndPath,
7659 ("end", "end") : connector.EndEndPath }
7661 return aamap.get((sa, da)) #connector.ShortestPath
7662 </t>
7663 <t tx="michael.20060619225419.18">def create_connectors(self, connectors):
7664 cws = []
7665 for src, sa, dest, da in connectors:
7666 path = self.find_path(sa, da)
7667 if path:
7668 cw = connector.GanttConnector(src, dest, path)
7669 if self.modify_connector(src, dest, cw):
7670 cws.append(cw)
7672 return cws
7673 </t>
7674 <t tx="michael.20060619225419.19">def modify_connector(self, src, dest, connector):
7675 return True
7677 modify_connector.args = (task.Task, task.Task, connector.GanttConnector)</t>
7678 <t tx="michael.20060619225419.20">def get_tip(self, tipobj):
7679 if not self.show_tips: return
7680 try:
7681 if isinstance(tipobj.fobj, task.Task):
7682 return self.get_task_tip(tipobj.fobj)
7683 except AttributeError:
7684 pass
7686 return None
7687 </t>
7688 <t tx="michael.20060619225419.21">def get_task_tip(self, tsk):
7689 lines = [
7690 (_("Name"), tsk.title),
7691 (_("Timeframe"), "%s - %s" % (tsk.to_string.start,\
7692 tsk.to_string.end)),
7693 (_("Effort"), tsk.to_string.effort),
7694 (_("Length"), tsk.to_string.length),
7695 (_("Load"), tsk.to_string.load),
7696 (_("Complete"), tsk.to_string.complete),
7697 (_("Done"), tsk.to_string.done),
7698 (_("Todo"), tsk.to_string.todo) ]
7700 append = lines.append
7701 if tsk.booked_resource:
7702 append((_("Resources"), tsk.to_string.booked_resource))
7703 elif tsk.performed_resource:
7704 append((_("Resources"), tsk.to_string.performed_resource))
7706 try:
7707 append((_("Buffer"), tsk.to_string.buffer))
7708 except task.RecursionError:
7709 pass
7711 return lines
7712 </t>
7713 <t tx="michael.20060619225419.22">class Critical(Standard):
7715 A Gantt to visualize the critical chain.
7717 @var colors:
7718 Specify a dictionary, that defines colours for different
7719 buffer values.
7721 &lt;&lt; declarations &gt;&gt;
7722 @others
7723 </t>
7724 <t tx="michael.20060619225419.23">__type_image__ = "critical_gantt"
7725 show_rowlines = False
7726 show_connectors = True
7727 colors = { "0d" : "red" }
7729 __editor__ = ("faces.gui.edit_gantt", "Critical")
7730 __attrib_completions__ = Standard.__attrib_completions__.copy()
7731 __attrib_completions__.update({\
7732 "colors" : 'colors = { |"0d" : "red" }' })
7733 del __attrib_completions__["def modify_widget"]
7736 </t>
7737 <t tx="michael.20060619225419.24">def __init__(self, *args, **kwargs):
7738 to_minutes = pcal._default_calendar.Minutes
7740 self._colors = map(lambda i: (to_minutes(i[0]), i[1]),
7741 self.colors.items())
7742 self._colors.sort()
7743 self._colors.reverse()
7745 Standard.__init__(self, *args, **kwargs)
7746 </t>
7747 <t tx="michael.20060619225419.25">def modify_widget(self, widget, task):
7748 for v, c in self._colors:
7749 if task.buffer &lt;= v:
7750 shape_name = self.get_shape_name(task)
7751 group = self.get_property_group(task)
7752 widget.set_property("%s.facecolor" % group, c)
7753 widget.set_property("%s.bar.facecolor" % group, c)
7755 return widget
7756 </t>
7757 <t tx="michael.20060619225419.26">class Compare(Gantt):
7759 A Gantt chart for comparing different projects.
7761 @var colors:
7762 Specifies a list of different colors for each project.
7764 &lt;&lt; declarations &gt;&gt;
7765 @others
7766 </t>
7767 <t tx="michael.20060619225419.27">__type_image__ = "compare_gantt"
7768 colors = _color_index
7769 show_rowlines = True
7770 show_connectors = False
7772 __editor__ = ("faces.gui.edit_gantt", "Compare")
7773 __attrib_completions__ = Gantt.__attrib_completions__.copy()
7774 __attrib_completions__.update({\
7775 "colors" : 'colors = ( "navy", "seagreen", "indianred")' })
7776 del __attrib_completions__["def create_objects"]
7779 </t>
7780 <t tx="michael.20060619225419.28">def create_objects(self, data):
7781 colors = self.colors
7783 for task_list in data:
7784 if not isinstance(task_list, (tuple, list)):
7785 task_list = (task_list, )
7787 last = len(task_list) - 1
7788 sum_widget = None
7789 sum_start = 0
7790 sum_end = -0
7791 last_widget = None
7793 for i, task in enumerate(task_list):
7794 if not task: continue
7796 if getattr(task, self.accumulate_attrib, False) \
7797 and task.is_inherited(self.accumulate_attrib):
7798 break
7800 if task.children:
7801 if not sum_widget:
7802 sum_widget = self.create_widget(task)
7803 sum_start = task.start
7804 sum_end = task.end
7805 else:
7806 sum_start = min(sum_start, task.start)
7807 sum_end = max(sum_end, task.end)
7808 else:
7809 last_widget = widget = self.create_widget(task)
7810 shape_name = self.get_shape_name(task)
7811 widget.set_property("facecolor", colors[i % len(colors)])
7812 widget.row.show_rowline = False
7813 yield widget
7815 if last_widget:
7816 last_widget.row.show_rowline = self.show_rowlines
7818 if sum_widget:
7819 sum_widget.start = sum_start
7820 sum_widget.end = sum_end
7821 yield sum_widget
7822 </t>
7823 <t tx="michael.20060619230125">Gantt.__all__ = filter(lambda n: getattr(getattr(Gantt, n), "im_func", None) is None, dir(Gantt))
7824 Gantt.__all__ += [ "calc_title", "make_shape", "create_widget" ]
7825 Gantt.__all__ = tuple(Gantt.__all__)</t>
7826 <t tx="michael.20060619230818">@
7827 Mathplot widgets
7828 @code
7829 @language python
7830 &lt;&lt; Copyright &gt;&gt;
7831 &lt;&lt; Imports &gt;&gt;
7833 _is_source_ = True
7834 _ = faces.plocale.get_gettext()
7836 @others
7837 </t>
7838 <t tx="michael.20060619230818.1">import matplotlib.text as dtext
7839 import patches
7840 import sys
7841 import faces.plocale
7842 import matplotlib.artist as artist
7843 import matplotlib.transforms as mtrans
7844 import matplotlib.font_manager as font
7845 from matplotlib.colors import colorConverter
7846 import locale
7847 import tools
7848 from tools import *
7850 </t>
7851 <t tx="michael.20060619230818.2">class LazyText(dtext.Text):
7852 &lt;&lt; declarations &gt;&gt;
7853 @others
7854 </t>
7855 <t tx="michael.20060619230818.3">height_cache = {}
7857 </t>
7858 <t tx="michael.20060619230818.4">def __init__(self, x, y, text, *args, **kwargs):
7859 if isinstance(text, str):
7860 text = unicode(text, tools.chart_encoding)
7861 dtext.Text.__init__(self, x, y, text, *args, **kwargs)
7863 def set_x(self, x):
7864 self._x = x
7866 def set_y(self, y):
7867 self._y = y
7869 </t>
7870 <t tx="michael.20060619230818.5">def get_prop_tup(self):
7871 x, y = self._transform.xy_tup((self._x, self._y))
7872 return (float(self._x), float(self._y), x, y, self._text, self._color,
7873 self._verticalalignment, self._horizontalalignment,
7874 hash(self._fontproperties), self._rotation)
7875 </t>
7876 <t tx="michael.20060619230818.6">def draw(self, renderer):
7877 if self.get_size() &lt; 3: return False
7878 dtext.Text.draw(self, renderer)
7879 return True
7880 </t>
7881 <t tx="michael.20060619230818.7">def get_bottom_top(self, renderer):
7882 height = self.height_cache.get(hash(self._fontproperties))
7883 if height is None:
7884 w, height = renderer.get_text_width_height("Xg",
7885 self._fontproperties,
7886 False)
7887 self.height_cache[hash(self._fontproperties)] = height
7889 if self._verticalalignment=='center': yo = -height/2.
7890 elif self._verticalalignment=='top': yo = -height
7891 else: yo = 0
7892 xb, yb = self._transform.xy_tup((self._x, self._y))
7893 yt = yb + height
7894 return yb, yt
7895 </t>
7896 <t tx="michael.20060619230818.8">def get_window_extent(self, renderer=None):
7897 text = self._text
7898 self._text = self._text.replace(" ", "_")
7899 result = dtext.Text.get_window_extent(self, renderer)
7900 self._text = text
7901 return result
7902 </t>
7903 <t tx="michael.20060619230818.9">
7905 class _PropertyType(type):
7906 @others
7907 </t>
7908 <t tx="michael.20060619230818.10">def __init__(cls, name, bases, dict_):
7909 super(_PropertyType, cls).__init__(name, bases, dict_)
7911 bchain = [ cls ]
7912 for b in (cls, ) + cls.__bases__:
7913 bchain.extend(getattr(b, "_base_chain", []))
7915 #remove duplicates and preserve order
7917 bchain = filter(lambda b: hasattr(b, "properties"), bchain)
7918 bchain = dict(zip(bchain, enumerate(bchain))).values()
7919 bchain.sort()
7920 bchain = map(lambda c: c[1], bchain)
7921 cls._base_chain = tuple(bchain)
7923 prop_vars = filter(lambda kv: kv[0].endswith("properties")\
7924 and isinstance(kv[1], dict),
7925 dict_.items())
7926 for pk, dv in prop_vars:
7927 for k, v in dv.iteritems():
7928 check_property(k, v)
7929 </t>
7930 <t tx="michael.20060619230818.11">def check_property(name, value):
7931 def do_raise(choices=None):
7932 if choices:
7933 raise ValueError(_('Invalid value "%(value)s" '\
7934 'for property "%(name)s. Possible Values are: %(choices)s"') %
7935 { "name" : name, "value" : str(value), 'choices' : choices } )
7936 else:
7937 raise ValueError(_('Invalid value "%(value)s" '\
7938 'for property "%(name)s"') %
7939 { "name" : name, "value" : str(value) } )
7941 def name_mends(*args):
7942 for n in args:
7943 if name.endswith(n): return True
7944 return False
7946 name_ends = name.endswith
7948 if name_ends("color"):
7949 try:
7950 colorConverter.to_rgb(value)
7951 except ValueError:
7952 do_raise()
7954 elif name_mends("width", "alpha", "magnification", "height"):
7955 try:
7956 float(value)
7957 except ValueError:
7958 do_raise()
7960 elif name_ends("family"):
7961 try:
7962 font.fontManager.ttfdict[value]
7963 except KeyError:
7964 default_names = ['serif', 'sans-serif', 'cursive',
7965 'fantasy', 'monospace', 'sans']
7966 if value not in default_names:
7967 do_raise(", ".join(font.fontManager.ttfdict.keys()\
7968 + default_names))
7970 elif name.endswith("weight"):
7971 try:
7972 if not (isinstance(value, basestring) and font.weight_dict[value]):
7973 int(value)
7974 except Exception:
7975 do_raise()
7977 elif name.endswith("size"):
7978 try:
7979 if not (isinstance(value, basestring) and font.font_scalings[value]):
7980 int(value)
7981 except Exception:
7982 do_raise()
7984 elif name.endswith("variant"):
7985 if value not in ('normal', 'capitals', 'small-caps'):
7986 do_raise()
7988 elif name.endswith("linestyle"):
7989 if value not in ("solid", "dashed", "dashdot", "dotted"):
7990 do_raise()
7992 elif name.endswith("joinstyle"):
7993 if value not in ('miter', 'round', 'bevel'):
7994 do_raise()
7996 elif name.endswith("style"):
7997 if value not in ("italics", "oblique", "normal"):
7998 do_raise()
8000 elif name == "tickers":
8001 if not isinstance(value, (tuple, list, int)):
8002 do_raise()
8003 </t>
8004 <t tx="michael.20060619230818.12">
8009 class _PropertyAware(object):
8010 &lt;&lt; class _PropertyAware declarations &gt;&gt;
8011 @others
8012 </t>
8013 <t tx="michael.20060619230818.13">__metaclass__ = _PropertyType
8015 search_chain = ()
8016 font_attribs = ("family", "style", "weight", "size", "variant")
8017 patch_attribs = ("edgecolor", "linewidth", "antialiased", \
8018 "fill", "facecolor", "alpha" )
8021 </t>
8022 <t tx="michael.20060619230818.14">def __init__(self, properties=None):
8023 self.properties = {}
8024 if properties:
8025 self.properties.update(properties)
8026 </t>
8027 <t tx="michael.20060619230818.15">def set_property(self, name, value):
8029 Sets a specific property
8031 check_property(name, value)
8032 self.properties[name] = value
8033 </t>
8034 <t tx="michael.20060619230818.16">def remove_property(self, name):
8036 Removes a property, and restores a default value.
8039 try:
8040 del self.properties[name]
8041 except:
8042 pass
8043 </t>
8044 <t tx="michael.20060619230818.17">def _find_property_in_chain(self, name):
8045 try:
8046 return self.properties[name]
8047 except KeyError:
8048 pass
8050 for s in getattr(self, "search_chain", ()):
8051 try:
8052 return s._find_property_in_chain(name)
8053 except KeyError: pass
8056 for s in self._base_chain:
8057 try:
8058 return s.properties[name]
8059 except KeyError: pass
8061 raise KeyError(name)
8062 </t>
8063 <t tx="michael.20060619230818.18">def _find_property(self, name):
8064 index = 0
8065 while True:
8066 try:
8067 value = self._find_property_in_chain(name[index:])
8068 self.properties[name] = value
8069 return value
8070 except KeyError: pass
8071 index = name.find(".", index) + 1
8072 if index &lt;= 0: break
8074 raise KeyError("Key error: %s" % name)
8075 </t>
8076 <t tx="michael.20060619230818.19">def get_font(self, name):
8077 kwargs = {}
8078 for a in self.font_attribs:
8079 kwargs[a] = self.get_property(name + "." + a)
8081 return font.FontProperties(**kwargs)
8082 </t>
8083 <t tx="michael.20060619230818.20">def get_property(self, name, default=None):
8084 try:
8085 return self._find_property(name)
8086 except KeyError:
8087 if default is not None:
8088 return default
8089 raise
8090 </t>
8091 <t tx="michael.20060619230818.21">def set_gc(self, gc, name=""):
8092 prop = self.get_property
8093 if gc:
8094 gc.set_foreground(prop(name + ".edgecolor"))
8095 gc.set_linewidth(prop(name + ".linewidth"))
8096 gc.set_linestyle(prop(name + ".linestyle"))
8097 gc.set_antialiased(prop(name + ".antialiased"))
8098 gc.set_alpha(prop(name + ".alpha"))
8099 else:
8100 prop(name + ".edgecolor")
8101 prop(name + ".linewidth")
8102 prop(name + ".linestyle")
8103 prop(name + ".antialiased")
8104 prop(name + ".alpha")
8105 </t>
8106 <t tx="michael.20060619230818.22">def get_patch(self, name=""):
8107 kwargs = {}
8108 for a in self.patch_attribs:
8109 kwargs[a] = self.get_property(name + "." + a)
8111 return kwargs
8112 </t>
8113 <t tx="michael.20060619230818.23">class Widget(artist.Artist, _PropertyAware):
8114 &lt;&lt; declarations &gt;&gt;
8115 @others
8116 </t>
8117 <t tx="michael.20060619230818.24">properties = {
8118 "weight" : "normal",
8119 "size" : "medium",
8120 "style" : "normal",
8121 "variant" : "normal",
8122 "color": 'black',
8123 "facecolor" : 'black',
8124 "edgecolor" : 'black',
8125 "linewidth" : 1,
8126 "joinstyle" : 'miter',
8127 "linestyle" : 'solid',
8128 "fill" : 1,
8129 "antialiased" : True,
8130 "alpha" : 1.0 }
8132 search_chain = (chart_properties,)
8134 bbox = mtrans.unit_bbox()
8135 fobj = None
8137 </t>
8138 <t tx="michael.20060619230818.25">def __init__(self, properties=None):
8139 _PropertyAware.__init__(self, properties)
8140 artist.Artist.__init__(self)
8141 self.artists = []
8142 </t>
8143 <t tx="michael.20060619230818.26">def _extend_text_properties(self, kwargs):
8144 fp = kwargs.get("fontproperties", "")
8145 if not isinstance(fp, font.FontProperties):
8146 kwargs["fontproperties"] = self.get_font(fp)
8148 if not kwargs.has_key("color") and isinstance(fp, basestring):
8149 kwargs["color"] = self.get_property(fp + ".color")
8151 return kwargs
8152 </t>
8153 <t tx="michael.20060619230818.27">def clear(self):
8155 Clears all decorations of the widget.
8157 self.artists = []
8159 clear.__call_completion__ = "clear()"
8160 </t>
8161 <t tx="michael.20060619230818.28">def text(self, txt, x, y, **kwargs):
8163 Adds a text decoration to the widget.
8165 kwargs = self._extend_text_properties(kwargs)
8166 artist = LazyText(x, y, txt, **kwargs)
8167 self.artists.append(artist)
8168 return artist
8170 text.__call_completion__ = """text("|",
8171 HCENTER, TOP + VSEP,
8172 horizontalalignment="center",
8173 verticalalignment="bottom",
8174 fontproperties="center")
8175 """
8176 </t>
8177 <t tx="michael.20060619230818.29">def set_figure(self, figure):
8178 artist.Artist.set_figure(self, figure)
8179 for t in self.all_artists():
8180 t.set_figure(figure)
8181 </t>
8182 <t tx="michael.20060619230818.30">def set_transform(self, transform):
8183 artist.Artist.set_transform(self, transform)
8184 for t in self.all_artists():
8185 t.set_transform(transform)
8186 </t>
8187 <t tx="michael.20060619230818.31">def set_clip_box(self, clipbox):
8188 artist.Artist.set_clip_box(self, clipbox)
8189 for t in self.all_artists():
8190 t.set_clip_box(clipbox)
8191 </t>
8192 <t tx="michael.20060619230818.32">def all_artists(self):
8193 return self.artists
8194 </t>
8195 <t tx="michael.20060619230818.33">def add_artist(self, artist):
8196 self.artists.insert(0, artist)
8198 add_artist.__call_completion__ = "add_artist(|)"
8199 </t>
8200 <t tx="michael.20060619230818.34">def set_font_factor(self, point_to_pixel, fig_point_to_pixel):
8202 Change the fontsize, if the canvas is zoomed
8204 font_factor = Lazy(point_to_pixel / fig_point_to_pixel)
8205 for t in filter(lambda t: isinstance(t, dtext.Text), self.artists):
8206 size = t.get_size()
8207 t.set_size(font_factor * t.get_size())
8208 </t>
8209 <t tx="michael.20060619230818.35">def prepare_draw(self, renderer, point_to_pixel, fig_point_to_pixel):
8211 returns a pair of boolean values:
8212 The first value means horizontal data_limits should be updated)
8213 The second value means vertical data_limits should be updated
8215 raise NotImplementedError()
8216 </t>
8217 <t tx="michael.20060619230818.36">def overlaps(self, bbox):
8218 return bbox.overlaps(self.bbox)
8219 </t>
8220 <t tx="michael.20060619230818.37">def contains(self, x, y):
8221 return self.bbox.contains(x, y)
8222 </t>
8223 <t tx="michael.20060619230818.38">def get_bounds(self, renderer):
8224 raise NotImplementedError()
8225 </t>
8226 <t tx="michael.20060619230818.39">class Row(Widget):
8228 This class represents a row within a chart
8230 @var top_sep:
8231 Top space between row content and the row's
8232 top edge in VSEP units.
8234 @var bottom_sep:
8235 Bottom space between row content and the row's
8236 bottom edge in VSEP units.
8238 &lt;&lt; class Row declarations &gt;&gt;
8239 @others
8240 </t>
8241 <t tx="michael.20060619230818.40">properties = { "edgecolor" : 'gray',
8242 "linewidth" : 1,
8243 "linestyle" : 'solid',
8244 "alpha" : 1.0,
8245 "antialiased" : True }
8247 top_sep = 2
8248 bottom_sep = 2
8249 show_rowline = False
8250 zorder = -100
8252 </t>
8253 <t tx="michael.20060619230818.41">def __init__(self, properties=None):
8254 Widget.__init__(self, properties)
8255 self.y = Lazy(0)
8256 self.height = Lazy(0)
8257 self.show_rowline = self.__class__.show_rowline
8259 #fetch line properties
8260 if self.show_rowline: self.set_gc(None, "row")
8261 </t>
8262 <t tx="michael.20060619230818.42">def update_height(self, height):
8263 self.height.set(max(self.height.get(), height))
8264 </t>
8265 <t tx="michael.20060619230818.43">def draw(self, renderer, data_box):
8266 data_box = self.get_transform().get_bbox1()
8267 if not self.get_visible() or not self.overlaps(data_box): return False
8269 all_artists = self.all_artists()
8270 if all_artists:
8271 set_helpers(self.bbox, self.bbox)
8272 for a in self.all_artists(): a.draw(renderer)
8274 if not self.show_rowline: return False
8275 def prop(name): return self.get_property(name)
8276 transform = self.get_transform()
8278 gc = renderer.new_gc()
8279 if self.get_clip_on():
8280 gc.set_clip_rectangle(self.clipbox.get_bounds())
8282 left, right = self.bbox.intervalx().get_bounds()
8283 self.set_gc(gc, "row")
8284 y = self.bottom - self.bottom_sep * VSEP
8285 y = y.get()
8286 draw_line(renderer, gc, left, y, right, y, transform)
8287 return bool(self.fobj)
8288 </t>
8289 <t tx="michael.20060619230818.44">def set_y(self, y):
8290 self.y = Lazy(y)
8291 self.bottom = self.y - self.height - self.top_sep * VSEP
8292 return self.next_y()
8293 </t>
8294 <t tx="michael.20060619230818.45">def full_height(self):
8295 return self.height + (self.top_sep + self.bottom_sep) * VSEP
8296 </t>
8297 <t tx="michael.20060619230818.46">def next_y(self):
8298 return self.y - self.full_height()
8299 </t>
8300 <t tx="michael.20060619230818.47">def reset_height(self):
8301 self.height.set(0)
8302 </t>
8303 <t tx="michael.20060619230818.48">def contains(self, x, y):
8304 return bool(self.fobj) and self.bbox.contains(x, y)
8305 </t>
8306 <t tx="michael.20060619230818.49">def prepare_draw(self, renderer, point_to_pixel, fig_point_to_pixel):
8307 self.set_font_factor(point_to_pixel, fig_point_to_pixel)
8309 data_box = self.get_transform().get_bbox1()
8310 all_artists = self.all_artists()
8311 if all_artists:
8312 bbox = mtrans.unit_bbox()
8313 set_helpers(bbox, bbox)
8314 extent = lambda t: t.get_window_extent(renderer)
8315 bb_all = mtrans.bbox_all(map(extent, all_artists))
8316 bbox = mtrans.transform_bbox(self.get_transform(), bbox)
8317 height = (bb_all.ymax() - bbox.ymin()) / fig_point_to_pixel.get()
8318 self.update_height(height)
8320 Point = mtrans.Point
8321 Value = mtrans.Value
8323 t = self.y.val
8324 b = self.bottom - self.bottom_sep * VSEP
8325 b = b.val
8326 self.bbox = mtrans.Bbox(Point(data_box.ll().x(), b),
8327 Point(data_box.ur().x(), t))
8329 return False, True
8330 </t>
8331 <t tx="michael.20060619230818.50">def get_bounds(self, renderer):
8332 return self.bbox
8333 </t>
8334 <t tx="michael.20060619230818.51">class Column(Widget):
8335 &lt;&lt; class Column declarations &gt;&gt;
8336 @others
8337 </t>
8338 <t tx="michael.20060619230818.52">properties = { "edgecolor" : 'gray',
8339 "linewidth" : 1,
8340 "linestyle" : 'solid',
8341 "alpha" : 1.0,
8342 "antialiased" : True }
8344 left_sep = 1
8345 right_sep = 1
8346 show_colline = False
8347 zorder = -100
8349 </t>
8350 <t tx="michael.20060619230818.53">def __init__(self, properties=None):
8351 Widget.__init__(self, properties)
8352 self.x = Lazy(0)
8353 self.width = Lazy(0)
8354 self.show_colline = self.__class__.show_colline
8356 #fetch line properties
8357 if self.show_colline: self.set_gc(None, "col")
8358 </t>
8359 <t tx="michael.20060619230818.54">def update_width(self, width):
8360 self.width.set(max(self.width.get(), width))
8361 </t>
8362 <t tx="michael.20060619230818.55">def draw(self, renderer, data_box):
8363 data_box = self.get_transform().get_bbox1()
8364 if not self.get_visible() or not self.overlaps(data_box): return False
8366 all_artists = self.all_artists()
8367 if all_artists:
8368 set_helpers(self.bbox, self.bbox)
8369 for a in self.all_artists(): a.draw(renderer)
8371 if not self.show_colline: return
8372 def prop(name): return self.get_property(name)
8373 transform = self.get_transform()
8375 gc = renderer.new_gc()
8376 if self.get_clip_on():
8377 gc.set_clip_rectangle(self.clipbox.get_bounds())
8379 bottom, top = self.bbox.intervaly().get_bounds()
8380 self.set_gc(gc, "col")
8381 x = self.x + self.width + (self.left_sep + self.right_sep) * HSEP
8382 x = x.get()
8383 draw_line(renderer, gc, x, bottom, x, top, transform)
8384 return False
8385 </t>
8386 <t tx="michael.20060619230818.56">def set_x(self, x):
8387 self.x = Lazy(x)
8388 return self.next_x()
8389 </t>
8390 <t tx="michael.20060619230818.57">def full_width(self):
8391 return self.width + (self.left_sep + self.right_sep) * HSEP
8392 </t>
8393 <t tx="michael.20060619230818.58">def next_x(self):
8394 return self.x + self.full_width()
8395 </t>
8396 <t tx="michael.20060619230818.59">def reset_width(self):
8397 self.width.set(0)
8398 </t>
8399 <t tx="michael.20060619230818.60">def contains(self, x, y):
8400 return False
8401 </t>
8402 <t tx="michael.20060619230818.61">def prepare_draw(self, renderer, point_to_pixel, fig_point_to_pixel):
8403 self.set_font_factor(point_to_pixel, fig_point_to_pixel)
8405 Point = mtrans.Point
8406 Value = mtrans.Value
8407 data_box = self.get_transform().get_bbox1()
8408 HSEP.set(VSEP.get())
8410 l = self.x.val
8411 r = self.x + self.width + (self.left_sep + self.right_sep) * HSEP
8412 r = r.val
8413 self.bbox = mtrans.Bbox(Point(l, data_box.ll().y()),
8414 Point(r, data_box.ur().y()))
8415 return True, False
8416 </t>
8417 <t tx="michael.20060619230818.62">def get_bounds(self, renderer):
8418 return self.bbox
8419 </t>
8420 <t tx="michael.20060619230818.63">_two = Lazy(2)
8422 class CellWidget(Widget):
8423 &lt;&lt; declarations &gt;&gt;
8424 @others
8425 </t>
8426 <t tx="michael.20060619230818.64">min_height = 0
8427 min_width = 0
8428 vert_sep = 2
8429 horz_sep = 2
8431 </t>
8432 <t tx="michael.20060619230818.65">def __init__(self, row, col, fobj, properties=None):
8433 Widget.__init__(self, properties)
8434 self.row = row
8435 self.col = col
8436 self.fobj = fobj
8437 </t>
8438 <t tx="michael.20060619230818.66">def get_bounds(self, renderer):
8439 return self.bbox
8440 </t>
8441 <t tx="michael.20060619230818.67">def prepare_draw(self, renderer, point_to_pixel, fig_point_to_pixel):
8442 self.set_font_factor(point_to_pixel, fig_point_to_pixel)
8444 #calculate cell bounding box
8445 Point = mtrans.Point
8446 Bbox = mtrans.Bbox
8447 HSEP.set(VSEP.get())
8448 left = self.col.x + self.col.left_sep * HSEP
8449 right = left + self.col.width
8450 top = self.row.y - self.row.top_sep * VSEP
8451 bottom = self.row.bottom
8452 self.bbox = Bbox(Point(left.val, bottom.val), Point(right.val, top.val))
8453 self.row.update_height(self.min_height)
8454 self.col.update_width(self.min_width)
8456 #get height and width
8457 set_helpers(self.bbox, self.bbox)
8458 extent = lambda t: t.get_window_extent(renderer)
8459 text_artists = filter(lambda t: isinstance(t, dtext.Text), self.artists)
8460 bb_all = mtrans.bbox_all(map(extent, text_artists))
8462 self.row.update_height(bb_all.height() / fig_point_to_pixel.get()\
8463 + self.vert_sep * VSEP.get())
8464 self.col.update_width(bb_all.width() / fig_point_to_pixel.get() \
8465 + self.horz_sep * HSEP.get())
8467 return True, True
8468 </t>
8469 <t tx="michael.20060619230818.68">def draw(self, renderer, data_box):
8470 data_box = self.get_transform().get_bbox1()
8471 if not self.get_visible() or not self.overlaps(data_box): return False
8472 set_helpers(self.bbox, self.bbox)
8473 #print "draw cell", self.artists[0].get_text(), self.bbox.get_bounds()
8474 for a in self.all_artists(): a.draw(renderer)
8475 return True
8476 </t>
8477 <t tx="michael.20060619230818.69">class TableWidget(Widget):
8479 A table widget, that can have other widgets in its cells
8482 @others
8484 </t>
8485 <t tx="michael.20060619230818.70">def __init__(self, rows, cols, properties=None):
8486 super(TableWidget, self).__init__(properties)
8487 self.cells = [ [ None ] * cols for r in range(rows) ]
8488 </t>
8489 <t tx="michael.20060619230818.71">def get_bounds(self, renderer):
8490 self.check_font_factor(renderer)
8491 return self.bbox
8492 </t>
8493 <t tx="michael.20060619230818.72">def prepare_draw(self, renderer, point_to_pixel, fig_point_to_pixel):
8494 self.set_font_factor(point_to_pixel, fig_point_to_pixel)
8496 zero = mtrans.zero
8497 Point = mtrans.Point
8498 BBox = mtrans.Bbox
8500 widest_cells = self.widest_cells = [ None ] * len(self.cells[0])
8501 max_widths = [ 0 ] * len(widest_cells)
8503 highest_cells = self.highest_cells = [ ]
8505 zorder = sys.maxint
8506 for row in self.cells:
8507 max_height = 0
8508 highest_cell = None
8509 for c, cell in enumerate(row):
8510 cell.prepare_draw(renderer, point_to_pixel, fig_point_to_pixel)
8512 w = cell.bbox.width()
8513 h = cell.bbox.height
8514 if w &gt; max_widths[c]:
8515 widest_cells[c] = cell
8516 max_widths[c] = w
8518 if h &gt; max_height:
8519 highest_cell = cell
8520 max_height = h
8522 zorder = min(zorder, cell.zorder)
8524 highest_cells.append(highest_cell)
8526 self.zorder = zorder - 1
8528 self.width = w = sum([c.width for c in self.widest_cells])
8529 self.height = h = sum([c.height for c in self.highest_cells])
8531 x = y = Lazy(0)
8532 self.bbox = BBox(Point(x.val, y.val),
8533 Point(x.val + w.val, y.val + h.val))
8535 self.prepare_draw = self.prepare_draw_stage2
8536 return True, True
8537 </t>
8538 <t tx="michael.20060619230818.73">def draw(self, renderer, data_box):
8539 data_box = self.get_transform().get_bbox1()
8540 if not self.get_visible() or not self.overlaps(data_box): return False
8542 self.check_font_factor(renderer)
8543 set_helpers(self.bbox, self.bbox)
8544 for a in self.all_artists(): a.draw(renderer)
8546 transform = self.get_transform()
8548 l = self.bbox.ll().x()
8549 r = self.bbox.ur().x()
8550 b = self.bbox.ll().y()
8551 t = self.bbox.ur().y()
8553 lf = l.get()
8554 rf = r.get()
8555 tf = t.get()
8556 bf = b.get()
8558 gc = renderer.new_gc()
8559 self.set_gc(gc, "rowlines")
8560 ry = t
8562 for c in self.highest_cells:
8563 ry -= c.height
8564 ryf = ry.get()
8565 draw_lines(renderer, gc, (lf, rf), (ryf, ryf), transform)
8567 rx = l
8568 for c in self.widest_cells:
8569 rxf = rx.get()
8570 draw_lines(renderer, gc, (rxf, rxf), (bf, tf), transform)
8571 rx += c.width
8573 return True
8575 </t>
8576 <t tx="michael.20060619230818.74">class TimeWidget(Widget):
8577 &lt;&lt; declarations &gt;&gt;
8578 @others
8579 </t>
8580 <t tx="michael.20060619230818.75">properties = {
8581 "inside.color" : "white",
8582 "valign" : 'center',
8583 "magnification" : 1.0 }
8585 shape_height = 8
8586 start = sys.maxint
8587 end = 0
8588 row = Row
8589 </t>
8590 <t tx="michael.20060619230818.76">def __init__(self, start, end, fobj, row=None, properties=None):
8591 Widget.__init__(self, properties)
8592 self.start = start
8593 self.end = end
8594 self.row = row or Row()
8595 self.fobj = fobj
8596 self.text_inside = ()
8597 self.shape = ()
8598 </t>
8599 <t tx="michael.20060619230818.77">def set_shape(self, shape, *args, **kwargs):
8601 Sets the widgetes shape.
8603 @args: (shape, shape_arg1, ...)
8605 self.shape_func = (shape, args, kwargs)
8607 set_shape.__call_completion__ = "set_shape(|)"
8608 </t>
8609 <t tx="michael.20060619230818.78">def all_artists(self):
8610 return tuple(self.artists) + self.shape
8611 </t>
8612 <t tx="michael.20060619230818.79">def finalized_row(self):
8613 #now the row is fixed: it is time to get the shape
8614 factor = Lazy(self.shape_height)
8615 self.height = mtrans.Value(0)
8616 self.depth = mtrans.Value(0)
8618 bb_bottom = self.row.bottom
8619 dh = self.row.height - self.height
8621 valign = self.get_property("valign")
8622 if valign == "center":
8623 bb_bottom += dh / _two
8624 elif valign == "top":
8625 bb_bottom += dh
8627 bottom = bb_bottom + self.depth
8628 top = bottom + factor * VSEP
8629 vcenter = (top + bottom) / _two
8631 left = Lazy(self.start)
8632 right = Lazy(self.end)
8633 hcenter = (left + right) / _two
8635 globs = self.shape_func[0].func_globals
8636 old_globs = {}
8637 def set_glob(name, value):
8638 old_globs[name] = globs.get(name)
8639 globs[name] = value
8641 set_glob("LEFT", left)
8642 set_glob("RIGHT", right)
8643 set_glob("TOP", top)
8644 set_glob("BOTTOM", bottom)
8645 set_glob("HCENTER", hcenter)
8646 set_glob("VCENTER", vcenter)
8647 set_glob("FACTOR", factor)
8648 self.shape = self.shape_func[0](self.get_property,
8649 *self.shape_func[1],
8650 **self.shape_func[2])
8651 globs.update(old_globs)
8653 bb_top = bottom + self.height
8654 self.shape_bbox = mtrans.Bbox(mtrans.Point(left.val, bb_bottom.val),
8655 mtrans.Point(right.val, bb_top.val))
8657 for s in self.shape:
8658 s.set_figure(self.get_figure())
8659 s.set_clip_box(self.get_clip_box())
8660 s.set_transform(self.get_transform())
8662 del self.shape_func
8663 </t>
8664 <t tx="michael.20060619230818.80">def inside_text(self, txt, x=None, y=None,
8665 inside_properties="inside",
8666 **kwargs):
8668 Adds a text decoration inside the widget.
8669 If x and y are not None, the text will be
8670 placed at that position, if the text is larger
8671 than the widget's width.
8674 if not txt: return
8676 def prop(name): return self.get_property(name)
8677 inside = LazyText(HCENTER, VCENTER,
8678 txt, prop(inside_properties + ".color"),
8679 "center", "center",
8680 fontproperties=self.get_font(inside_properties))
8682 if x is None:
8683 self.text_inside = ( inside, )
8684 else:
8685 kwargs = self._extend_text_properties(kwargs)
8686 self.text_inside = ( LazyText(x, y, txt, **kwargs), inside )
8688 self.artists.extend(self.text_inside)
8689 return self.text_inside
8691 inside_text.__call_completion__ = """inside_text("|",
8692 RIGHT + HSEP, VCENTER,
8693 horizontalalignment="left",
8694 verticalalignment="center",
8695 fontproperties="right")"""
8696 </t>
8697 <t tx="michael.20060619230818.81">def get_bounds(self, renderer):
8698 show = self.fobj.name in ("Outer", "inner")
8700 transform = self.get_transform()
8701 extent = lambda t: t.get_window_extent(renderer)
8703 # calc shape bounding (in data coords)
8704 bb_shape = mtrans.bound_vertices(self.shape[0].get_verts())
8705 bb_shape_view = mtrans.transform_bbox(transform, bb_shape) # in view coords
8707 set_helpers(bb_shape, bb_shape)
8709 if self.text_inside:
8710 &lt;&lt; check if inside text fits into the shape &gt;&gt;
8712 bb_text = map(extent, filter(lambda t: t.get_visible(), self.artists))
8713 bb_text.append(bb_shape_view)
8715 #complete bounding box
8716 bb_all = mtrans.bbox_all(bb_text)
8718 inverse = mtrans.inverse_transform_bbox
8719 self.bbox = inverse(self.get_transform(), bb_all)
8721 return self.bbox
8722 </t>
8723 <t tx="michael.20060619230818.82">def overlaps(self, bbox):
8724 return bbox.overlaps(self.shape_bbox)
8725 </t>
8726 <t tx="michael.20060619230818.83">def prepare_draw(self, renderer, point_to_pixel, fig_point_to_pixel):
8727 self.finalized_row()
8729 if not isinstance(self.artists, tuple):
8730 self.artists = tuple(self.artists)
8732 #calc bounding box
8733 trans = self.get_transform()
8734 bb_shape = mtrans.bound_vertices(self.shape[0].get_verts())
8735 bb_shape_view = mtrans.transform_bbox(trans, bb_shape)
8737 set_helpers(bb_shape, bb_shape)
8739 bottom = sys.maxint
8740 top = -sys.maxint
8742 for te in [ t for t in self.artists if isinstance(t, dtext.Text) ]:
8743 b, t = te.get_bottom_top(renderer)
8744 bottom = min(b, bottom)
8745 top = max(t, top)
8747 bb_all = bb_shape_view
8748 bb_all.intervaly().set_bounds(min(bb_all.ymin(), bottom),
8749 max(bb_all.ymax(), top))
8751 #calc height and depth
8752 pxl_height = bb_all.height()
8753 pxl_depth = bb_shape_view.ymin() - bb_all.ymin()
8755 self.depth.set(pxl_depth / fig_point_to_pixel.get())
8756 self.height.set(pxl_height / fig_point_to_pixel.get())
8757 self.row.update_height(self.height.get())
8758 self.set_font_factor(point_to_pixel, fig_point_to_pixel)
8759 self.bbox = self.shape_bbox
8760 return True, True
8761 </t>
8762 <t tx="michael.20060619230818.84">def draw(self, renderer, data_box):
8763 if not self.get_visible() or not self.overlaps(data_box): return False
8765 transform = self.get_transform()
8766 bb_shape = mtrans.bound_vertices(self.shape[0].get_verts())
8767 bb_data = transform.get_bbox1()
8768 set_helpers(bb_shape, bb_data)
8770 bbox = mtrans.transform_bbox(transform, bb_shape.deepcopy())
8771 if not self.prepare_inside_text(renderer, bbox): return False
8773 for s in self.shape:
8774 s.draw(renderer)
8776 for t in self.artists:
8777 if t.get_visible() and t.draw(renderer):
8778 bb = t.get_window_extent()
8779 bbox.update(((bb.xmin(), bb.ymin()),
8780 (bb.xmax(), bb.ymax())), False)
8782 self.bbox = mtrans.inverse_transform_bbox(transform, bbox)
8783 return True
8784 </t>
8785 <t tx="michael.20060619230818.85">def prepare_inside_text(self, renderer, bb_shape):
8786 if not self.text_inside: return True
8788 contains = bb_shape.contains
8790 al_text = self.text_inside[0]
8791 in_text = self.text_inside[-1]
8792 in_text.set_visible(True)
8794 inside = in_text.get_window_extent(renderer)
8795 mid = (inside.ymin() + inside.ymax()) / 2
8797 if contains(inside.xmin(), mid) and contains(inside.xmax(), mid):
8798 al_text.set_visible(False)
8799 in_text.set_visible(True)
8800 else:
8801 al_text.set_visible(True)
8802 in_text.set_visible(False)
8804 return True
8805 </t>
8806 <t tx="michael.20060619230818.86">class GanttWidget(TimeWidget):
8808 A Widget for gantt charts
8810 @var shape_height:
8811 Specifies the height of the widget in VSEPS
8813 @var row:
8814 Specifies the row of the widget within the chart.
8816 </t>
8817 <t tx="michael.20060619230818.87">class ResourceBarWidget(TimeWidget):
8819 A widget for resource charts
8821 @var row:
8822 Specifies the row of the widget within the chart.
8824 &lt;&lt; class ResourceBarWidget declarations &gt;&gt;
8825 @others
8826 </t>
8827 <t tx="michael.20060619230818.88">load_factor = 12
8828 zorder = -10
8830 </t>
8831 <t tx="michael.20060619230818.89">def __init__(self, task, row, start, end, load, offset, properties=None):
8832 props = { "valign" : "bottom" }
8833 if properties: props.update(properties)
8834 TimeWidget.__init__(self, start, end, task, row, props)
8836 self.zorder = -offset
8837 self.offset = offset
8838 self.load = load
8840 def shape(props):
8841 import shapes
8842 kwargs = make_properties(props, "bar")
8843 l = self.load_factor * font.fontManager.get_default_size()
8844 return (patches.Rectangle((LEFT, BOTTOM),
8845 RIGHT - LEFT, round(l * load, 3),
8846 **kwargs),)
8848 self.set_shape(shape)
8849 </t>
8850 <t tx="michael.20060619230818.90">def prepare_draw(self, renderer, point_to_pixel, fig_point_to_pixel):
8851 result = TimeWidget.prepare_draw(self, renderer, point_to_pixel,
8852 fig_point_to_pixel)
8854 l = self.load_factor * font.fontManager.get_default_size()
8855 self.row.update_height(l * (self.offset + self.load))
8856 self.row.update_height(l)
8857 self.depth.set(round(l * self.offset, 3))
8858 for t in self.text_inside:
8859 t.max_size = t._fontproperties.get_size()
8861 return result
8862 </t>
8863 <t tx="michael.20060619230818.91">__last_size = (0, 0)
8864 def prepare_inside_text(self, renderer, bb_shape):
8865 if not self.text_inside: return True
8867 if bb_shape.width() / self.get_figure().get_dpi() &lt;= 0.08:
8868 for s in self.shape:
8869 s.draw(renderer)
8871 self.bbox = mtrans.inverse_transform_bbox(self.get_transform(),
8872 bb_shape)
8873 return False
8875 view_box = self.get_transform().get_bbox2()
8877 width = min(view_box.xmax(), bb_shape.xmax())\
8878 - max(view_box.xmin(), bb_shape.xmin())
8880 height = min(view_box.ymax(), bb_shape.ymax())\
8881 - max(view_box.ymin(), bb_shape.ymin())
8884 if self.__last_size == (width, height): return True
8886 self.__last_size = (width, height)
8887 in_text = self.text_inside[-1]
8888 in_text.set_visible(True)
8889 in_text.set_size(in_text.max_size)
8890 in_text.set_rotation(0)
8891 tbbox = in_text.get_window_extent(renderer)
8893 sep = 0.07 * self.get_figure().get_dpi() # 0.1 inch
8894 width -= sep
8895 height -= sep
8897 wfactor = min(width / tbbox.width(), height / tbbox.height())
8899 if wfactor &lt; 1:
8900 hfactor = min(width / tbbox.height(), height / tbbox.width(), 1.0)
8901 if hfactor &gt; wfactor:
8902 wfactor = hfactor
8903 in_text.set_rotation(90)
8904 else:
8905 in_text.set_rotation(0)
8907 size = wfactor * float(in_text.max_size)
8908 in_text.set_visible(size &gt; 1)
8909 in_text.set_size(wfactor * float(in_text.max_size))
8911 return True
8912 </t>
8913 <t tx="michael.20060619230818.92">def get_bounds(self, renderer):
8914 self.bbox = mtrans.bound_vertices(self.shape[0].get_verts())
8915 return self.bbox
8916 </t>
8917 <t tx="michael.20060619232254">def get_object(self):
8918 return self.pseudo
8919 </t>
8920 <t tx="michael.20060619234514">def _get__all__(self):
8921 return dir(ftask.Task) \
8922 + ["up", "root", "me", "to_string", "calendar"] \
8923 + self.dict_children.keys()
8925 __all__ = property(_get__all__)</t>
8926 <t tx="michael.20060619235739">def __getattr__(self, name):
8927 if name in self.dict_children:
8928 return self.dict_children[name]
8930 return getattr(ftask.Task, name)
8931 </t>
8932 <t tx="michael.20060621114845">@first #! /usr/bin/python
8933 @language python
8934 &lt;&lt; Copyright &gt;&gt;
8935 &lt;&lt; Imports &gt;&gt;
8936 &lt;&lt; Setting Globals &gt;&gt;
8938 @others
8940 if __name__ == "__main__":
8941 if _faces._PROFILING:
8942 import profile
8943 import pstats
8945 profile.run("main()", "profile_out")
8946 p = pstats.Stats('profile_out')
8947 p.strip_dirs().sort_stats('cumulative').print_stats(40)
8948 else:
8949 sys.exit(main())
8950 </t>
8951 <t tx="michael.20060621114845.1">import sys
8953 try:
8954 if sys.frozen:
8955 import encodings
8956 except AttributeError:
8957 import wxversion
8958 wxversion.select(['2.6', '2.8'])
8959 #wxPython 2.4 is not support since version 0.7.0
8961 import wx.html
8962 import os
8963 import time
8964 import locale
8966 try:
8967 #threading can cause problems when reloaded,
8968 #causing nasty error messages at exit if generator module is used
8969 #importing it here will avoid a reload when refreshing a project
8970 import threading
8971 except:
8972 pass
8975 try:
8976 import gc
8977 collect_garbage = gc.collect
8978 #gc.set_debug(gc.DEBUG_LEAK)
8979 except:
8980 def collect_garbage(): pass
8982 from metapie.gui import controller, MetaApp, ResourceManager
8983 import faces.plocale
8984 import os.path
8985 import re
8986 import faces as _faces
8988 _faces.set_default_chart_font_size(8)
8989 _faces.gui_controller = controller
8991 import faces.observer as _observer
8992 import faces.generator # see threading
8993 from faces.gui.editor import PlanEditor, PlanEditorProxy
8994 import faces.gui.repview
8995 import faces.gui.chartview
8996 import faces.gui.graphview
8997 import faces.gui.utils as gutils
8998 import metapie.navigator as navigator
8999 import metapie.gui.session as session
9000 import inspect
9001 import linecache
9002 import stat
9003 import new
9004 import types
9005 import traceback
9006 import warnings
9007 import faces.utils
9008 import ConfigParser
9009 from wx.lib.fancytext import RenderToBitmap
9010 </t>
9011 <t tx="michael.20060621114845.2">_is_source_ = True
9013 if not wx.USE_UNICODE:
9014 def null_gettext(): return lambda x: x
9015 faces.plocale.get_gettext = null_gettext
9017 _ = faces.plocale.get_gettext()
9019 current_directory = ""
9020 _warning_registry = { }
9021 _installation_path = faces.utils.get_installation_path()
9022 _resource_path = faces.utils.get_resource_path()
9023 _template_path = os.path.join(_resource_path, "templates")</t>
9024 <t tx="michael.20060621114845.3">def title_of_path(path):
9025 return os.path.split(path)[1]
9026 </t>
9027 <t tx="michael.20060621114845.4">def is_project_file(path, main_path=None):
9028 path = os.path.abspath(path)
9029 path = os.path.normcase(path)
9031 if path == main_path: return True
9032 if not os.access(path, os.W_OK): return False
9034 if current_directory and path.startswith(current_directory):
9035 return True
9037 return False
9038 </t>
9039 <t tx="michael.20060621114845.5">def getsourcefile(obj):
9040 try:
9041 if isinstance(obj, str):
9042 obj = sys.modules.get(obj)
9044 return inspect.getabsfile(obj)
9045 except:
9046 pass
9048 return ""
9049 </t>
9050 <t tx="michael.20060621114845.6">def _generate_menu_wrapper(executer, obj):
9051 msg = wx.MessageBox
9052 frame = controller().GetTopWindow()
9054 to_execute = getattr(obj, "faces_execute", obj)
9056 if hasattr(obj, "faces_openfile"):
9057 fname = obj.faces_openfile
9058 def wrapper():
9059 dlg = wx.FileDialog(frame, _("Choose a file"),
9060 os.path.split(fname)[0],
9061 os.path.split(fname)[1],
9062 _("All Files|*"), wx.OPEN)
9063 if dlg.ShowModal() == wx.ID_OK:
9064 path = dlg.GetPath()
9065 if executer.save_execute(to_execute, path):
9066 obj.faces_openfile = path
9067 msg(_("%s('%s') was executed successfully")\
9068 % (obj.__name__, path),
9069 _("Success"), style=wx.ICON_INFORMATION|wx.OK)
9070 collect_garbage()
9071 dlg.Destroy()
9073 elif hasattr(obj, "faces_savefile"):
9074 fname = obj.faces_savefile
9075 def wrapper():
9076 dlg = wx.FileDialog(frame, _("Choose a filename"),
9077 os.path.split(fname)[0],
9078 os.path.split(fname)[1],
9079 _("All Files|*"), wx.SAVE)
9080 if dlg.ShowModal() == wx.ID_OK:
9081 path = dlg.GetPath()
9082 if executer.save_execute(to_execute, path):
9083 obj.faces_savefile = path
9084 msg(_("%s('%s') was executed successfully")\
9085 % (obj.__name__, path),
9086 _("Success"), style=wx.ICON_INFORMATION|wx.OK)
9087 collect_garbage()
9088 dlg.Destroy()
9090 elif hasattr(obj, "faces_savedir"):
9091 dname = obj.faces_savedir
9093 def wrapper():
9094 dlg = wx.DirDialog(frame, _("Select Directory to save to"), dname)
9095 if dlg.ShowModal() == wx.ID_OK:
9096 path = dlg.GetPath()
9097 if executer.save_execute(to_execute, path):
9098 obj.faces_savedir = path
9099 msg(_("%s('%s') was executed successfully")\
9100 % (obj.__name__, path),
9101 _("Success"), style=wx.ICON_INFORMATION|wx.OK)
9102 collect_garbage()
9103 dlg.Destroy()
9104 else:
9105 def wrapper():
9106 if executer.save_execute(to_execute):
9107 msg(_("%s() was executed successfully") % obj.__name__,
9108 _("Success"), style=wx.ICON_INFORMATION|wx.OK)
9110 return wrapper
9111 </t>
9112 <t tx="michael.20060621114845.7">class PlanBuffer(navigator.Model):
9113 @others
9114 </t>
9115 <t tx="michael.20060621114845.8">def __init__(self, path, is_main_buffer=False):
9116 self.text = ""
9117 path = os.path.abspath(path)
9118 path = os.path.normcase(path)
9119 self.path = path
9120 self.editor_id = None
9121 self.mod_time = 0
9122 self.is_modified = None
9123 self.resources = {}
9124 self.calendars = {}
9125 self.editor = PlanEditor(self)
9126 self.is_main_buffer = is_main_buffer
9127 self.active_views = {}
9128 self.consider_backup = True
9130 </t>
9131 <t tx="michael.20060621114845.9">def close(self):
9132 #try:
9133 # self.editor.Destroy()
9134 # self.editor = None
9135 #except AttributeError: pass
9136 self.remove_backup_file()
9137 </t>
9138 <t tx="michael.20060621114845.10">def __del__(self):
9139 self.close()
9140 </t>
9141 <t tx="michael.20060621114845.12">def refresh(self):
9142 &lt;&lt; find path and consider backups &gt;&gt;
9144 mod_time = os.stat(path)[stat.ST_MTIME]
9145 if self.mod_time &lt; mod_time:
9146 f = file(path, "r")
9147 self.text = f.read()\
9148 .replace("\r\n", "\n")\
9149 .replace("\r", "\n")\
9150 .replace("\t", " " * 8)
9151 f.close()
9152 &lt;&lt; fix efficiency misspelling &gt;&gt;
9154 self.mod_time = mod_time
9155 if self.is_main_buffer:
9156 _faces.set_chart_encoding(self.get_encoding())
9158 refresh_text = True
9159 else:
9160 refresh_text = False
9162 self.editor.refresh(refresh_text)
9163 if self.consider_backup and self.remove_backup_file(): self.save_buffer()
9164 self.consider_backup = False</t>
9165 <t tx="michael.20060621114845.13">def __str__(self):
9166 return title_of_path(self.path)
9167 </t>
9168 <t tx="michael.20060621114845.14">def _right_click_(self, event, view):
9169 if not view: return
9171 module = controller().session.get_module(self.path)
9172 obj = getattr(module, view, None)
9173 if not obj: return
9175 def find_in_source(): self.find_in_source(obj)
9176 ctrl = controller()
9177 menu = ctrl.make_menu()
9178 menu.make_item(self, _("Find in Source"), find_in_source, "findsource16")
9180 button = event.GetButtonObj()
9181 pos = button.ScreenToClient(wx.GetMousePosition())
9182 button.PopupMenu(menu.wxobj, pos)
9183 </t>
9184 <t tx="michael.20060621114845.15">def register(self):
9185 ctrl = controller()
9186 ctrl.freeze()
9188 factory = lambda parent: PlanEditorProxy(self, parent)
9189 title = title_of_path(self.path)
9190 self.editor_id = ctrl.register_view(self, title, factory, "edit")
9191 ctrl.thaw()
9192 </t>
9193 <t tx="michael.20060621114845.16">def accept_sibling(self, sibling):
9194 if isinstance(sibling, PlanBuffer):
9195 if str(sibling) &lt; str(sibling):
9196 return navigator.SIBLING_ABOVE
9197 else:
9198 return navigator.SIBLING_BELOW
9200 return False
9201 </t>
9202 <t tx="michael.20060621114845.17">def get_encoding(self):
9203 line_end = 0
9204 for i in range(2):
9205 line_end = self.text.find("\n", line_end + 1)
9207 mo = re.search(r"coding[:=]\s*([-\w.]+)", self.text[:line_end])
9208 if mo: return mo.group(1)
9209 return "ascii"
9210 </t>
9211 <t tx="michael.20060621114845.18">def save(self):
9212 if self.path.startswith(_template_path): return self.menu_save_as()
9214 self.set_menus()
9215 ctrl = controller()
9216 ctrl.session.check_for_correction()
9217 ctrl.frame.SetCursor(wx.HOURGLASS_CURSOR)
9218 ctrl.status_bar.SetStatusText(_("Saving..."), 0)
9219 wx.CallAfter(self.__deferred_save)
9220 wx.CallAfter(ctrl.frame.SetCursor, wx.NullCursor)
9221 wx.CallAfter(ctrl.status_bar.SetStatusText, "", 0)
9222 wx.CallAfter(self.set_focus, True)
9223 </t>
9224 <t tx="michael.20060621114845.19">def get_backup_file(self):
9225 if self.path.startswith(_template_path): return ""
9226 ndir, nbase = os.path.split(self.path)
9227 return os.path.join(ndir, "#%s#" % nbase)
9228 </t>
9229 <t tx="michael.20060621114845.20">def remove_backup_file(self):
9230 try:
9231 os.unlink(self.get_backup_file())
9232 return True
9233 except OSError:
9234 pass
9235 return False
9236 </t>
9237 <t tx="michael.20060621114845.21">def save_backup(self):
9238 view = self.get_edit_view(False)
9239 if not view: return
9240 path = self.get_backup_file()
9241 if not path: return
9242 view.sync_text()
9243 f = file(path, "wb")
9244 f.write(self.text)
9245 f.close()
9246 </t>
9247 <t tx="michael.20060621114845.22">def __deferred_save(self):
9248 self.save_buffer()
9249 linecache.checkcache()
9250 controller().session.execute_plan()
9251 </t>
9252 <t tx="michael.20060621114845.23">def save_buffer(self):
9253 self.editor.sync_text(True)
9254 f = file(self.path, "wb")
9255 f.write(self.text)
9256 f.close()
9257 self.remove_backup_file()
9258 mod_time = os.stat(self.path)[stat.ST_MTIME]
9259 self.mod_time = mod_time
9261 </t>
9262 <t tx="michael.20060621114845.24">def modified(self, is_modified=True):
9263 if self.is_modified != is_modified:
9264 self.is_modified = is_modified
9265 self.set_menus()
9266 </t>
9267 <t tx="michael.20060621114845.25">def menu_save_as(self):
9268 directory = current_directory
9269 if not directory or directory.startswith(_template_path):
9270 directory = os.getcwd()
9272 dlg = wx.FileDialog(controller().GetTopWindow(),
9273 _("Choose a filename"),
9274 directory,
9276 _("Faces Files (*.py)|*.py"),
9277 wx.SAVE|wx.OVERWRITE_PROMPT)
9278 if dlg.ShowModal() == wx.ID_OK:
9279 try:
9280 str(dlg.GetPath())
9281 except UnicodeEncodeError:
9282 wx.MessageBox(_("Filenames may only contain ascii characters."),
9283 _("Error"), style=wx.ICON_ERROR|wx.OK)
9284 else:
9285 root, ext = os.path.splitext(dlg.GetPath())
9286 if not root: return
9287 self.path = root + ".py"
9288 self.path = os.path.abspath(self.path)
9289 self.path = os.path.normcase(self.path)
9291 view = self.get_edit_view(False)
9292 if view: view.sync_text()
9294 ctrl = controller()
9295 ctrl.remove_model(self)
9296 ctrl.add_model(self)
9297 ctrl.session.add_recent_file(self.path)
9298 self.set_menus()
9299 self.save()
9301 dlg.Destroy()
9302 </t>
9303 <t tx="michael.20060621114845.26">def set_focus(self, create_view=False):
9304 view = self.get_edit_view(create_view)
9305 if view: view.SetFocus()
9306 </t>
9307 <t tx="michael.20060621114845.27">def set_menus(self):
9308 ctrl = controller()
9310 top = ctrl.get_top_menu()
9311 file_menu = top.make_menu(_("&amp;File"))
9313 menu = lambda *args, **kw: \
9314 file_menu.make_item(self, *args, **kw)
9316 toolbar = ctrl.get_toolbar()
9317 toolbar.make_tool(self, "save", self.save,
9318 "filesave22").enable(bool(self.is_modified))
9319 toolbar.make_tool(self, "saveas", self.menu_save_as,
9320 "filesaveas22").enable(True)
9322 menu(_("&amp;Save\tCTRL-S"), self.save, "filesave16",
9323 pos=30).enable(bool(self.is_modified))
9324 menu(_("&amp;Save as..."), self.menu_save_as, "filesaveas16",
9325 pos=40).enable(True)
9326 </t>
9327 <t tx="michael.20060621114845.28">def get_edit_view(self, create_view=True):
9328 ctrl = controller()
9329 if create_view:
9330 view = ctrl.create_view(self.editor_id)
9331 else:
9332 view = ctrl.get_active_view_by_id(self.editor_id)
9334 return view
9335 </t>
9336 <t tx="michael.20060621114845.31">def show_object(self, caller, fobj, attrib=None):
9337 model = self._find_model(fobj)
9338 model._show_object(caller, fobj, attrib)
9340 __show_object_called = False
9341 def _show_object(self, caller, fobj, attrib=None):
9342 if self.__show_object_called: return
9343 self.__show_object_called = True
9345 try:
9346 edit_view = None
9347 views = controller().get_all_views()
9348 for v in views:
9349 if v is caller: continue
9351 if isinstance(v, PlanEditorProxy):
9352 edit_view = v
9353 continue
9355 try:
9356 v.show_object(fobj, attrib, caller)
9357 except AttributeError:
9358 pass
9360 if edit_view:
9361 if edit_view.model() is not self:
9362 edit_view = self.get_edit_view(True)
9364 edit_view.show_object(fobj, attrib, caller)
9366 finally:
9367 self.__show_object_called = False
9369 def _find_model(self, fobj):
9371 find the model of a task object
9373 try:
9374 path = inspect.getabsfile(getattr(fobj, "_function", None))
9375 except TypeError:
9376 try:
9377 path = inspect.getabsfile(fobj)
9378 except TypeError:
9379 return self
9381 path = os.path.normcase(path)
9382 if path != self.path:
9383 for m in controller().get_planbuffers():
9384 if m.path == path:
9385 return m
9387 return self </t>
9388 <t tx="michael.20060621114845.33">def goto_source(self, line):
9389 self.get_edit_view(True).goto_line(line)
9390 </t>
9391 <t tx="michael.20060621114845.34">def find_in_source(self, obj):
9392 self.get_edit_view(True).find_in_source(obj)
9393 </t>
9394 <t tx="michael.20060621114845.35">def set_observer(self, observer):
9395 #observer is a directory of all observers of the model
9396 #the keys consist of a tuple of
9397 #(observer.__type_name__, observer.__type_image__)
9398 #the values are a list of tuples of (observer_title, observe_class)
9400 active_views = self.active_views
9401 all_observers = reduce(lambda x, y: x + y, observer.values(), [])
9402 new_views = dict(map(lambda v: (v[0], -1), all_observers))
9404 # unregister all observers which are not
9405 # in the plan file anymore
9406 ctrl = controller()
9407 for view, id_ in active_views.iteritems():
9408 if not new_views.has_key(view):
9409 ctrl.unregister_view(id_)
9411 self.active_views = new_views
9412 keys = observer.keys()
9413 keys.sort()
9414 pos = 1
9415 for k in keys:
9416 v = observer[k]
9417 factory = _observer.factories.get(k[0])
9418 if factory:
9419 pos = self.__set_views(k[0], factory, v, pos)
9420 </t>
9421 <t tx="michael.20060621114845.36">def __set_views(self, name, create_factory, new_views, pos):
9422 ctrl = controller()
9423 active_views = self.active_views
9425 new_views.sort()
9426 for t, v in new_views:
9427 factory = create_factory(t, v, self)
9428 id_ = ctrl.register_view(self, t, factory, v.__type_image__, pos=pos)
9429 active_views[t] = id_
9430 view = ctrl.get_active_view_by_id(id_)
9431 if view: view.replace_data(v)
9432 pos += 1
9434 return pos
9435 </t>
9436 <t tx="michael.20060621114845.37">class _Executer:
9437 &lt;&lt; class _Executer declarations &gt;&gt;
9438 @others
9439 </t>
9440 <t tx="michael.20060621114845.38">menus_owner = "mown"
9442 </t>
9443 <t tx="michael.20060621114845.39">def __init__(self):
9444 self.main_buffer = None
9445 self.evaluations = {}
9446 self.loaded_modules = {}
9447 self.tmp_files_to_remove = []
9448 </t>
9449 <t tx="michael.20060621114845.40">def get_module(self, path):
9450 for module in self.loaded_modules.values():
9451 try:
9452 if module._faces_source_file == path:
9453 return module
9454 except AttributeError: pass
9455 except KeyError: pass
9457 return None
9459 </t>
9460 <t tx="michael.20060621114845.41">def remove_modules(self):
9461 for m in self.loaded_modules.keys():
9462 &lt;&lt; remove module &gt;&gt;
9464 self.evaluations.clear()
9465 self.loaded_modules.clear()
9467 </t>
9468 <t tx="michael.20060621114845.42">def clear_cache(self):
9469 _faces.task.clear_cache()
9470 for v in _observer.clear_cache_funcs.itervalues(): v()
9471 for p in self.tmp_files_to_remove:
9472 try:
9473 os.unlink(p)
9474 except OSError:
9475 pass
9477 self.tmp_files_to_remove = []
9478 </t>
9479 <t tx="michael.20060621114845.43">def execute_plan(self):
9480 ctrl = controller()
9481 ctrl.progress_start(_("calculate project"), 8)
9483 _warning_registry.clear()
9484 self.clear_logs()
9485 self.clear_cache()
9487 ctrl.progress_update(1)
9488 collect_garbage()
9490 self.save_execute(self.__execute_module)
9491 ctrl.freeze()
9492 try:
9493 ctrl.progress_update(6)
9494 self.__refresh_active_buffer_list()
9495 self.__refresh_view_list()
9496 finally:
9497 ctrl.thaw()
9499 ctrl.progress_update(7)
9500 self.remove_empty_logview()
9502 ctrl.progress_update(8)
9503 ctrl.progress_end()
9505 logger = ctrl.get_active_view_by_id(ctrl.session.logger_id)
9506 if logger:
9507 focus = logger
9508 else:
9509 focus = self.main_buffer.get_edit_view(True)
9511 focus.SetFocus()</t>
9512 <t tx="michael.20060621114845.44">def save_execute(self, func, *args, **kwargs):
9513 try:
9514 return func(*args, **kwargs)
9515 except SyntaxError, e:
9516 sys.stderr.write('%s %s File "%s", line %i\n'
9517 % (e.__class__.__name__,
9518 e.msg, e.filename, e.lineno))
9519 except Exception, e:
9520 self.traceback(e, sys.exc_info()[2])
9522 return None</t>
9523 <t tx="michael.20060621114845.45">def __refresh_active_buffer_list(self):
9524 ctrl = controller()
9526 &lt;&lt; get all loaded source files &gt;&gt;
9527 for m in ctrl.get_planbuffers():
9528 if m.path in files:
9529 del files[m.path]
9530 else:
9531 #remove obsolete PlanBuffer
9532 ctrl.remove_model(m)
9534 &lt;&lt; add new plan buffers &gt;&gt;
9535 </t>
9536 <t tx="michael.20060621114845.46">def __refresh_view_list(self):
9537 ctrl = controller()
9538 &lt;&lt; init collections &gt;&gt;
9539 &lt;&lt; define is_valid_module &gt;&gt;
9541 public_attribs = lambda obj: filter(lambda n: n[0] != "_", dir(obj))
9542 getabsfile = inspect.getabsfile
9544 for module in filter(is_valid_module, self.loaded_modules.values()):
9545 &lt;&lt; import a possible gui part of the module &gt;&gt;
9546 path = module._faces_source_file
9548 for k in public_attribs(module):
9549 v = getattr(module, k)
9550 &lt;&lt; check if k, v is an observer &gt;&gt;
9551 &lt;&lt; check if k, v is an project evaluation &gt;&gt;
9552 &lt;&lt; check if k, v is a resource &gt;&gt;
9553 &lt;&lt; check if k, v is a calendar &gt;&gt;
9554 &lt;&lt; check if k, v has menu &gt;&gt;
9556 self.evaluations.clear()
9557 for v in evaluations.itervalues():
9558 self.evaluations.update(v)
9560 &lt;&lt; assign collections to models &gt;&gt;
9561 &lt;&lt; create Toolmenu &gt;&gt;
9562 </t>
9563 <t tx="michael.20060621114845.47">def __execute_module(self):
9564 global current_directory
9566 path = self.main_buffer.path
9567 (current_directory, filename) = os.path.split(path)
9569 &lt;&lt; check filename &gt;&gt;
9570 &lt;&lt; remove modules that have to be reloaded &gt;&gt;
9572 actual_modules = {}
9573 actual_modules.update(sys.modules)
9575 &lt;&lt; init main_module &gt;&gt;
9577 tmp_path = sys.path[0]
9578 sys.path[0] = current_directory
9579 try:
9580 &lt;&lt; fetch code and execute it &gt;&gt;
9581 &lt;&lt; find imported modules &gt;&gt;
9583 self.loaded_modules["__faces_main__"] =\
9584 sys.modules["__faces_main__"] = main_module
9585 finally:
9586 sys.path[0] = tmp_path
9587 controller().progress_update(5)
9588 if not "__faces_main__" in self.loaded_modules:
9589 self.loaded_modules["__faces_main__"] =\
9590 sys.modules["__faces_main__"] = main_module
9592 return True
9593 </t>
9594 <t tx="michael.20060621114845.48">class ShellView(session.ShellView):
9595 @others
9596 </t>
9597 <t tx="michael.20060621114845.49">def __init__(self, parent, locals=None):
9598 session.ShellView.__init__(self, parent, locals)
9599 wx.EVT_SET_FOCUS(self, self._on_get_focus)
9600 </t>
9601 <t tx="michael.20060621114845.50">def _on_get_focus(self, event):
9602 top = controller().get_top_menu()
9603 edit_menu = top.make_menu(_("&amp;Edit"), pos=100)
9604 menu = lambda *args, **kw: edit_menu.make_item(self, *args, **kw)
9605 menu(_("&amp;Undo\tCTRL-Z"), self.Undo, "undo16", pos=100)
9606 menu(_("&amp;Redo\tCTRL-R"), self.Redo, "redo16", pos=200)
9607 menu(_("Cut\tCTRL-X"), self.Cut, "editcut16", pos=300)
9608 menu(_("&amp;Copy\tCTRL-C"), self.Copy, "editcopy16", pos=400)
9609 menu(_("&amp;Paste\tCTRL-V"), self.Paste, "editpaste16", pos=500)
9610 event.Skip()
9611 </t>
9612 <t tx="michael.20060621114845.51">class LoggerView(session.MessageLogger):
9613 @others
9614 </t>
9615 <t tx="michael.20060621114845.52">def __init__(self, parent):
9616 session.MessageLogger.__init__(self, parent)
9617 wx.EVT_SET_FOCUS(self, self._on_get_focus)
9618 </t>
9619 <t tx="michael.20060621114845.53">def _on_get_focus(self, event):
9620 top = controller().get_top_menu()
9621 edit_menu = top.make_menu(_("&amp;Edit"), pos=100)
9622 menu = lambda *args, **kw: edit_menu.make_item(self, *args, **kw)
9623 menu(_("&amp;Copy\tCTRL-C"), self.Copy, "editcopy16", pos=400)
9624 event.Skip()
9625 </t>
9626 <t tx="michael.20060621114845.54">class Session(session.Session, _Executer):
9627 &lt;&lt; class Session declarations &gt;&gt;
9628 @others
9629 </t>
9630 <t tx="michael.20060621114845.55">LOGGER = LoggerView
9632 </t>
9633 <t tx="michael.20060621114845.56">def __init__(self):
9634 session.Session.__init__(self)
9635 _Executer.__init__(self)
9637 def open_shell(parent):
9638 try:
9639 dict = sys.modules["__faces_main__"].__dict__
9640 except KeyError:
9641 dict = globals()
9643 return ShellView(parent, dict)
9645 self.SHELL_FACTORY = open_shell
9646 self.help = None
9648 config = controller().config
9649 try:
9650 self.recent_files = config.get("DEFAULT", "recent_files").split(",")
9651 self.recent_files = map(str.strip, self.recent_files)
9652 self.recent_files = filter(bool, self.recent_files)
9653 except ConfigParser.NoOptionError:
9654 self.recent_files = []
9655 </t>
9656 <t tx="michael.20060621114845.57">def end_session(self):
9657 self.clear_cache()
9658 controller().config.set("DEFAULT", "recent_files",
9659 ",".join(self.recent_files))
9660 </t>
9661 <t tx="michael.20060621114845.58">def get_help(self):
9662 if not self.help:
9663 wx.FileSystem.AddHandler(wx.ZipFSHandler())
9664 self.help = wx.html.HtmlHelpController()
9665 self.help.AddBook(os.path.join(_resource_path,
9666 "help", "faces.zip"), True)
9667 return self.help
9668 </t>
9669 <t tx="michael.20060621114845.59">def jump_to_file(self, path, line):
9670 path = os.path.normcase(path)
9671 for m in controller().get_planbuffers():
9672 if m.path == path:
9673 m.goto_source(line)
9674 </t>
9675 <t tx="michael.20060621114845.60">def set_menus(self):
9676 top = controller().get_top_menu()
9678 wx.App.SetMacHelpMenuTitleName(_("&amp;Help"))
9679 help_menu = top.make_menu(_("&amp;Help"), pos=sys.maxint, id=wx.ID_HELP)
9680 menu = lambda *args, **kw: help_menu.make_item(self, *args, **kw)
9681 menu(_("&amp;Content and Index"), self.menu_help)
9682 menu(_("&amp;Send Project..."), self.menu_send_project)
9684 menu(_("&amp;Howtos..."), self.menu_howtos)
9685 item = menu(_("&amp;About"), controller().show_splash, id=wx.ID_ABOUT)
9686 wx.App.SetMacAboutMenuItemId(item.id)
9688 if check_memory: menu(_("Check Memory"), check_memory)
9690 file_menu = top.make_menu(_("&amp;File"))
9692 menu = lambda *args, **kw: file_menu.make_item(self, *args, **kw)
9693 menu(_("&amp;New..."), self.menu_new, "filenew16",
9694 help=_("New faces file"), pos=0)
9695 menu(_("&amp;Open..."), self.menu_open, "fileopen16",
9696 help=_("Open faces file"), pos=10)
9698 self.recent_menu = file_menu.make_menu(\
9699 _("&amp;Recent Files"), help=_("Open recently used files"), pos=15)
9701 self.update_recent_menu()
9702 self.close_menu = menu(_("&amp;Close"), self.menu_close,
9703 "fileclose16",
9704 pos=20)
9706 menu(_("&amp;Save\tCTRL-S"), 1, "filesave16", pos=30).enable(False)
9707 menu(_("&amp;Save as..."), 2, "filesaveas16", pos=40).enable(False)
9708 menu(_("Recalculate\tF5"), self.menu_recalc, "rebuild16", pos=50,
9709 help=_("Recalculate Project"))
9710 self.close_menu.enable(False)
9712 toolbar = controller().get_toolbar()
9714 toolbar.make_tool(self, "new", self.menu_new, "filenew22",
9715 short=_("New Project"))
9717 toolbar.make_tool(self, "open", self.menu_open, "fileopen22",
9718 short=_("Open Project"),
9719 long="open file")
9721 toolbar.make_tool(self, "close", self.menu_close,
9722 "fileclose22",
9723 short=_("Close Project"),
9724 long="close file")
9726 toolbar.make_tool(self, "save", 1, "filesave22",
9727 short=_("save"), long="save file").enable(False)
9729 toolbar.make_tool(self, "saveas", 2, "filesaveas22",
9730 short=_("save as")).enable(False)
9732 toolbar.make_tool(self, "recalculate", self.menu_recalc, "rebuild22",
9733 short=("Recalculate"),
9734 long=_("Recalculate Project"))
9736 toolbar.realize()
9737 </t>
9738 <t tx="michael.20060621114845.61">def add_recent_file(self, path):
9739 path = os.path.abspath(path)
9740 path = os.path.normcase(path)
9742 try:
9743 self.recent_files.remove(path)
9744 except ValueError:
9745 pass
9747 self.recent_files.insert(0, path)
9748 del self.recent_files[8:]
9749 self.update_recent_menu()
9750 </t>
9751 <t tx="michael.20060621114845.62">__recent_owner = object()
9752 def update_recent_menu(self):
9753 file_menu = controller().get_top_menu().make_menu(_("&amp;File"))
9754 self.recent_menu = file_menu.make_menu(\
9755 _("&amp;Recent Files"), help=_("Open recently used files"), pos=15)
9757 self.recent_menu.make_item(None, "dumy", None) #dummy to avoid the deletion of the menu
9758 self.recent_menu.remove_by_owner(self.__recent_owner)
9759 def make_open_file(f):
9760 def open_file(): self.open_file(f)
9761 return open_file
9763 for f in self.recent_files:
9764 self.recent_menu.make_item(self.__recent_owner, f,
9765 make_open_file(f))
9767 self.recent_menu.remove_by_owner(None)
9768 </t>
9769 <t tx="michael.20060621114845.63">def register(self):
9770 session.Session.register(self)
9771 self.set_menus()
9772 </t>
9773 <t tx="michael.20060621114845.64">def menu_recalc(self):
9774 if not self.main_buffer: return
9775 view = self.main_buffer.get_edit_view(False)
9776 if view: view.sync_text()
9778 self.check_for_correction()
9779 self.execute_plan()</t>
9780 <t tx="michael.20060621114845.65">def menu_help(self):
9781 #import webbrowser
9782 #webbrowser.open("http://faces.homeip.net/book/index.html")
9783 self.get_help().DisplayContents()
9784 </t>
9785 <t tx="michael.20060621114845.66">def menu_send_project(self):
9786 def get_text(module):
9787 if not isinstance(module, PlanBuffer): return None
9788 view = module.get_edit_view(False)
9789 if view: view.sync_text()
9790 return (module.path, module.text)
9792 models = controller().id_to_model.values()
9793 projects = filter(bool, map(get_text, models))
9794 if not projects: return
9795 sender = gutils.ProjectSender()
9796 sender.add_recipient("mreithinger@web.de",
9797 "Faces Project Files",
9798 projects)
9799 sender.send()
9800 controller().session.tmp_files_to_remove.append(sender.path)
9801 </t>
9802 <t tx="michael.20060621114845.67">def menu_howtos(self):
9803 dlg = wx.FileDialog(controller().GetTopWindow(),
9804 _("Choose a howto file"),
9805 faces.utils.get_howtos_path(),
9807 _("Faces Files (*.py)|*.py"),
9808 wx.OPEN)
9809 if dlg.ShowModal() == wx.ID_OK:
9810 self.open_file(dlg.GetPath())
9811 dlg.Destroy()
9812 </t>
9813 <t tx="michael.20060621114845.68">def menu_new(self):
9814 templates = filter(lambda f: f.endswith(".py"),
9815 os.listdir(_template_path))
9816 dlg = wx.SingleChoiceDialog(controller().GetTopWindow(),
9817 _("The following templates are available:"),
9818 _("Choose Template"),
9819 templates)
9820 if dlg.ShowModal() == wx.ID_OK:
9821 template = dlg.GetStringSelection()
9822 self.open_file(os.path.join(_template_path, template), False)
9823 dlg.Destroy()
9824 </t>
9825 <t tx="michael.20060621114845.69">def menu_open(self):
9826 dlg = wx.FileDialog(controller().GetTopWindow(),
9827 _("Choose a file"),
9828 current_directory or os.getcwd(),
9830 _("Faces Files (*.py)|*.py"),
9831 wx.OPEN)
9832 if dlg.ShowModal() == wx.ID_OK:
9833 self.open_file(dlg.GetPath())
9834 dlg.Destroy()
9835 </t>
9836 <t tx="michael.20060621114845.70">def menu_close(self):
9837 if not self.check_modified_buffers(): return False
9838 self.close_menu.enable(False)
9839 self.main_buffer = None
9840 for m in controller().get_planbuffers():
9841 m.close()
9842 controller().remove_model(m)
9844 self.remove_modules()
9845 self.clear_logs()
9846 return True
9847 </t>
9848 <t tx="michael.20060621114845.71">def open_file(self, path, add_recent=True):
9849 if not self.menu_close(): return
9850 self.close_menu.enable(True)
9851 self.main_buffer = PlanBuffer(path, True)
9852 self.main_buffer.refresh()
9854 dirname = os.path.dirname(path)
9855 if dirname:
9856 os.chdir(dirname)
9858 controller().add_model(self.main_buffer)
9859 self.execute_plan()
9860 self.main_buffer.set_focus(True)
9861 if add_recent: self.add_recent_file(self.main_buffer.path)
9862 </t>
9863 <t tx="michael.20060621114845.72">def check_modified_buffers(self):
9864 for m in controller().get_planbuffers():
9865 if m.is_modified:
9866 answer = wx.MessageBox(_("The file %s was modified."
9867 " Should it be saved?") % m.path,
9868 _("Close Buffer"),
9869 wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION)
9870 if answer == wx.YES:
9871 m.save_buffer()
9872 elif answer == wx.CANCEL:
9873 return False
9874 else:
9875 m.close()
9877 return True
9878 </t>
9879 <t tx="michael.20060621114845.73">def showwarning(message, category, filename, lineno, file=None):
9880 if _warning_registry.has_key((filename, lineno)):
9881 return
9883 _warning_registry[(filename, lineno)] = True
9884 print &gt;&gt; sys.stderr, warnings.formatwarning(message, category, filename, lineno)
9885 </t>
9886 <t tx="michael.20060621114845.74">def check_installation():
9887 import time
9888 try:
9889 time.strptime("1.1.2005 10:30", "%d.%m.%Y %H:%M")
9890 except Exception, e:
9891 print &gt;&gt; sys.stderr, "Error in installation(time.strptime):"
9892 print &gt;&gt; sys.stderr, e
9893 </t>
9894 <t tx="michael.20060621114845.75">if _faces._DEBUGGING:
9895 def check_memory():
9896 collect_garbage()
9897 objs = gc.get_objects()
9898 print
9899 print "--------------------------------------------------------------"
9900 print "views"
9901 print "--------------------------------------------------------------"
9902 for v in filter(lambda o: isinstance(o, navigator.View), objs):
9903 print v._nav_title, v.__class__.__name__
9904 print "--------------------------------------------------------------"
9906 print
9907 print "--------------------------------------------------------------"
9908 print "observers"
9909 print "--------------------------------------------------------------"
9910 for v in filter(lambda o: isinstance(o, _observer.Observer), objs):
9911 print v.__type_name__, v.__class__.__name__
9912 print "--------------------------------------------------------------"
9914 import matplotlib.axes as axes
9915 print
9916 print "--------------------------------------------------------------"
9917 print "axes"
9918 print "--------------------------------------------------------------"
9919 for v in filter(lambda o: isinstance(o, axes.Axes), objs):
9920 refs = gc.get_referrers(v)
9921 print v.__class__.__name__, len(refs)
9923 print "--------------------------------------------------------------"
9925 import faces.charting.widgets as widgets
9926 print
9927 print "--------------------------------------------------------------"
9928 print "widgets"
9929 print "--------------------------------------------------------------"
9930 for v in filter(lambda o: isinstance(o, widgets.Widget), objs):
9931 refs = gc.get_referrers(v)
9932 print v.__class__.__name__, len(refs)
9933 print "--------------------------------------------------------------"
9934 else:
9935 check_memory = None
9936 </t>
9937 <t tx="michael.20060621114845.76">splash_text = """&lt;font family="swiss" size="9"&gt;
9938 Support &lt;font style="slant"&gt;faces&lt;/font&gt; and send your
9939 project files to mreithinger@web.de.
9941 To improve the quality of &lt;font style="slant"&gt;faces&lt;/font&gt;, we need more
9942 real-world test data. Support the &lt;font style="slant"&gt;faces&lt;/font&gt; development
9943 team and provide your project for use as test data.
9945 You can use the Menu &lt;font family="modern" weight="bold"&gt;Help-&gt;Send Project&lt;/font&gt;
9946 for your convenience.&lt;/font&gt;
9949 version_text = '&lt;font family="swiss" size="7"&gt;'\
9950 'faces version %s. Copyright (c) '\
9951 '2005,2006,2007 by Reithinger GmbH&lt;/font&gt;' % str(_faces.__version__)
9954 class FacesApp(MetaApp):
9955 @others</t>
9956 <t tx="michael.20060621114845.77">def OnInit(self):
9957 if MetaApp.OnInit(self):
9958 self.frame.Bind(wx.EVT_CLOSE, self._on_frame_close)
9959 self.frame.Bind(wx.EVT_MENU_OPEN, self._on_menu_open)
9960 self.status_bar.SetFieldsCount(3)
9961 self.status_bar.SetStatusWidths([-1, 20, 200])
9962 self.gauge = wx.Gauge(self.status_bar, -1, 10)
9963 self.gauge.Hide()
9964 self.show_splash(True)
9965 return True
9967 return False
9969 </t>
9970 <t tx="michael.20060621114845.78">def show_splash(self, timeout=False):
9971 splash = ResourceManager.load_bitmap("splash1")
9973 text = RenderToBitmap(splash_text)
9974 dc = wx.MemoryDC()
9975 dc.SelectObject(splash)
9976 dc.DrawBitmap(text, 14, 100, True)
9978 version = RenderToBitmap(version_text)
9979 y = splash.GetHeight() - version.GetHeight() - 10
9980 dc.DrawBitmap(version, 14, y, True)
9982 dc.SelectObject(wx.NullBitmap)
9984 flags = wx.SPLASH_CENTRE_ON_SCREEN
9985 if timeout:
9986 flags |= wx.SPLASH_TIMEOUT
9987 else:
9988 flags |= wx.SPLASH_NO_TIMEOUT
9990 splash = wx.SplashScreen(splash, flags, 8000, self.frame,
9991 style=wx.STAY_ON_TOP|wx.FRAME_NO_TASKBAR)
9993 self.Yield(True)
9994 </t>
9995 <t tx="michael.20060621114845.79">def _on_frame_close(self, event):
9996 if event.CanVeto() and not self.session.check_modified_buffers():
9997 event.Veto()
9998 else:
9999 event.Skip()
10000 self.frame.Hide() #avoid flickering in Windows
10001 self.frame.Destroy()
10002 </t>
10003 <t tx="michael.20060621114845.80">def is_processing(self):
10004 try:
10005 self.gauge_title
10006 return True
10007 except AttributeError:
10008 return False
10009 </t>
10010 <t tx="michael.20060621114845.81">def progress_start(self, title, maximum, message=""):
10011 self.gauge_title = title
10012 self.frame.SetStatusText(title, 0)
10013 w, h = self.status_bar.GetTextExtent(title + "X")
10014 rect = self.status_bar.GetFieldRect(0)
10015 self.gauge.SetDimensions(rect.x + w, rect.y,
10016 rect.width - w, rect.height)
10017 self.gauge.SetRange(maximum)
10018 self.gauge.Show()
10019 #self.frame.Enable(False)
10020 self.Yield(True)
10022 </t>
10023 <t tx="michael.20060621114845.82">def progress_update(self, value, message=""):
10024 try:
10025 self.frame.SetStatusText(self.gauge_title, 0)
10026 self.gauge.SetValue(value)
10027 self.Yield(True)
10028 except AttributeError:
10029 pass
10030 </t>
10031 <t tx="michael.20060621114845.83">def progress_end(self):
10032 try:
10033 self.frame.SetStatusText("", 0)
10034 self.gauge.Hide()
10035 self.Yield(True)
10036 del self.gauge_title
10037 except AttributeError:
10038 pass
10040 #self.frame.Enable()
10041 self.WakeUpIdle()
10042 </t>
10043 <t tx="michael.20060621114845.84">def main():
10044 sys.setcheckinterval(10000)
10045 lang = os.environ.get("LANG", "")
10046 try:
10047 locale.setlocale(locale.LC_ALL, lang)
10048 except locale.Error, err:
10049 print &gt;&gt; sys.stderr, err
10050 if wx.Platform == '__WXMSW__':
10051 locale.setlocale(locale.LC_ALL, "")
10052 else:
10053 locale.setlocale(locale.LC_ALL, "C")
10055 if not _faces._PROFILING:
10056 try:
10057 import psyco
10058 except ImportError:
10059 pass
10060 else:
10061 psyco.profile()
10062 #psyco.log()
10063 psyco.cannotcompile(re.compile)
10065 ResourceManager.resource_path.append(_resource_path)
10067 app = FacesApp(False)
10068 app.config = ConfigParser.SafeConfigParser()
10069 app.config.read(os.path.expanduser("~/.faces-cfg"))
10071 app.freeze()
10072 faces.utils.do_yield = app.Yield
10073 faces.utils.progress_start = app.progress_start
10074 faces.utils.progress_update = app.progress_update
10075 faces.utils.progress_end = app.progress_end
10077 app.get_toolbar().wxobj.SetToolBitmapSize((24, 24))
10078 app.set_title("faces")
10080 icon = wx.IconFromBitmap(ResourceManager.load_bitmap("gantt"))
10081 app.frame.SetIcon(icon)
10083 app.session = Session()
10084 app.add_model(app.session)
10085 app.session.install_logger()
10087 if _faces._DEBUGGING:
10088 sys.stdout = sys.__stdout__
10090 warnings.showwarning = showwarning
10091 warnings.filterwarnings("always")
10092 try:
10093 # used in python &lt;= 2.3
10094 warnings.filterwarnings("ignore", category=OverflowWarning)
10095 except NameError: pass
10096 warnings.filterwarnings("ignore", category=DeprecationWarning)
10098 check_installation()
10099 app.thaw()
10101 if len(sys.argv) &gt; 1:
10102 try:
10103 app.session.open_file(sys.argv[1])
10104 except:
10105 pass
10107 app.MainLoop()
10108 app.session.end_session()
10110 try:
10111 outf = file(os.path.expanduser("~/.faces-cfg"), "w")
10112 app.config.write(outf)
10113 except IOError:
10114 pass
10116 return 0
10118 </t>
10119 <t tx="michael.20060621120211.1">try:
10120 if issubclass(v, _observer.Observer) and v.visible:
10121 observer.setdefault(path, {})\
10122 .setdefault((v.__type_name__,
10123 v.__type_image__), [])\
10124 .append((k, v))
10125 except TypeError: pass</t>
10126 <t tx="michael.20060621120211.2">if isinstance(v, _faces.task._ProjectBase):
10127 evaluations.setdefault(path, {})[k] = v
10128 continue
10130 try:
10131 #by convention evaluations are attributes of the top task function
10132 if not v.task_func: continue # if v is a task function it has the task_func attribute
10133 for n in public_attribs(v):
10134 p = getattr(v, n)
10135 if isinstance(p, _faces.task._ProjectBase):
10136 evaluations.setdefault(path, {})["%s.%s" % (k, n)] = p
10137 continue
10138 except AttributeError: pass
10141 </t>
10142 <t tx="michael.20060621120211.3">if isinstance(v, (_faces.Resource,
10143 _faces.resource._MetaResource)):
10144 resources.setdefault(path, {})[k] = v
10145 continue</t>
10146 <t tx="michael.20060621120211.4">if hasattr(v, "faces_menu"):
10147 functions.append(v)</t>
10148 <t tx="michael.20060621120211.5">for m in ctrl.get_planbuffers():
10149 m.evaluations = evaluations.get(m.path, {})
10150 m.resources = resources.get(m.path, {})
10151 m.calendars = calendars.get(m.path, {})
10152 m.set_observer(observer.get(m.path, {}))
10153 m.refresh() # refresh edit view</t>
10154 <t tx="michael.20060621120211.6">top = ctrl.get_top_menu()
10155 top.remove_by_owner(self.menus_owner)
10157 for f in functions:
10158 menu_path = f.faces_menu
10159 menu_path = menu_path.split("/")
10161 menu = top.make_menu(_("&amp;Tools"), pos=9980)
10162 for m in menu_path[:-1]:
10163 menu = menu.make_menu(m)
10165 menu.make_item(self.menus_owner, menu_path[-1],
10166 _generate_menu_wrapper(self, f),
10167 bitmap=getattr(f, "faces_menu_icon", None))</t>
10168 <t tx="michael.20060621120211.7">resources = {}
10169 calendars = {}
10170 observer = {}
10171 evaluations = {}
10172 functions = []</t>
10173 <t tx="michael.20060621123928">def _restore_globals(self):
10174 self._function.func_globals.clear()
10175 self._function.func_globals.update(self._globals)
10176 del self._globals
10177 </t>
10178 <t tx="michael.20060621125711">@language python
10179 &lt;&lt; Copyright &gt;&gt;
10182 In this package you find will the library to all report and chart objects
10185 _is_source_ = True</t>
10186 <t tx="michael.20060621125853">@language python
10188 Line connectors between two widgets.
10190 &lt;&lt; Copyright &gt;&gt;
10191 &lt;&lt; Imports &gt;&gt;
10193 _is_source_ = True
10194 _colorConverter = colors.colorConverter
10196 @others
10197 </t>
10198 <t tx="michael.20060621125853.1">import widgets
10199 import matplotlib.transforms as mtrans
10200 import matplotlib.colors as colors
10201 import math
10202 from tools import *
10206 </t>
10207 <t tx="michael.20060621125853.2">def get_arrow(cos, sin, tx, ty, width, height):
10208 h = Lazy(height)
10209 wm = Lazy(-width * 0.5)
10210 wp = Lazy(width * 0.5)
10212 arrow = [ (h, wm), (0, 0), (h, wp) ]
10214 m11 = HSEP * cos
10215 m12 = -HSEP * sin
10216 m21 = VSEP * sin
10217 m22 = VSEP * cos
10219 def multplus(vector):
10220 return (m11 * vector[0] + m12 * vector[1] + tx,
10221 m21 * vector[0] + m22 * vector[1] + ty)
10223 return map(multplus, arrow)
10224 </t>
10225 <t tx="michael.20060621125853.3">class ConnectorPath(object):
10227 Base class for path calculation.
10229 @others
10231 </t>
10232 <t tx="michael.20060621125853.4">def calc_start_end(cls, src, dest):
10233 x_ends = cls.calc_x_ends(src, dest)
10234 return min(x_ends), max(x_ends)
10236 calc_start_end = classmethod(calc_start_end)</t>
10237 <t tx="michael.20060621125853.5">def get_lines(cls, src, dest, transform):
10238 src_end, dest_end = cls.calc_x_ends(src, dest)
10240 def nearest_x(to_find, verts):
10241 return float(min(map(lambda v: (abs(float(v[0]) - to_find), v[0]),
10242 verts))[1])
10243 so = src_end
10244 do = dest_end
10245 src_end = nearest_x(src_end, src.shape[0].get_verts())
10246 dest_end = nearest_x(dest_end, dest.shape[0].get_verts())
10248 return cls.get_edges((src_end, src.row.y.get(), src),
10249 (dest_end, dest.row.y.get(), dest))
10251 get_lines = classmethod(get_lines)</t>
10252 <t tx="michael.20060621125853.6">def point_near(cls, point_widget, wanted_y):
10253 """find all possible connector ends for a given x, y"""
10254 x, y, widget = point_widget
10256 bb_shape = mtrans.bound_vertices(widget.shape[0].get_verts())
10257 set_helpers(bb_shape, bb_shape)
10258 verts = widget.shape[0].get_verts()
10259 wy = wanted_y.get()
10261 def dist_point(point):
10262 #freeze points
10263 px = float(point[0])
10264 py = float(point[1])
10265 dx = abs(px - x) / HSEP.get()
10266 dy = abs(py - wy) / VSEP.get()
10267 return (dx + dy, (point[0], point[1]))
10269 return min([ dist_point(p) for p in verts ])[1]
10271 point_near = classmethod(point_near)</t>
10272 <t tx="michael.20060621125853.7">def find_y_pos(cls, src, dest):
10273 if src[1] &lt; dest[1]: return TOP, BOTTOM
10274 if src[1] &gt; dest[1]: return BOTTOM, TOP
10275 return VCENTER, VCENTER
10277 find_y_pos = classmethod(find_y_pos)</t>
10278 <t tx="michael.20060621125853.8">def get_edges(cls, src, dest):
10279 src_y, dest_y = cls.find_y_pos(src, dest)
10280 return (cls.point_near(src, src_y), cls.point_near(dest, dest_y))
10282 get_edges = classmethod(get_edges)</t>
10283 <t tx="michael.20060621125853.9">class StartEndPath(ConnectorPath):
10284 @others
10286 </t>
10287 <t tx="michael.20060621125853.10">def calc_x_ends(src, dest):
10288 return src.start, dest.end
10290 calc_x_ends = staticmethod(calc_x_ends)</t>
10291 <t tx="michael.20060621125853.11">def get_edges(cls, src, dest):
10292 src_y, dest_y = cls.find_y_pos(src, dest)
10294 if src[0] == dest[0]:
10295 return (cls.point_near(src, src_y),
10296 cls.point_near(dest, dest_y))
10298 if dest[0] &lt; src[0]:
10299 s = cls.point_near(src, VCENTER)
10300 d = cls.point_near(dest, dest_y)
10301 return (s, (d[0], s[1]), d)
10303 sp = cls.point_near(src, src_y)
10304 dp = cls.point_near(dest, dest_y)
10306 # src[0] &gt; dest[0]
10307 row = src[2].row
10308 if src[1] &lt; dest[1]:
10309 next_floor = row.y + VSEP * row.top_sep / 2
10310 else:
10311 next_floor = row.y - row.height - row.bottom_sep / 2 * VSEP
10313 return (sp, (sp[0], next_floor), (dp[0], next_floor), (dp))
10315 get_edges = classmethod(get_edges)</t>
10316 <t tx="michael.20060621125853.12">class StartStartPath(ConnectorPath):
10317 @others
10319 </t>
10320 <t tx="michael.20060621125853.13">def calc_x_ends(src, dest):
10321 return src.start, dest.start
10323 calc_x_ends = staticmethod(calc_x_ends)</t>
10324 <t tx="michael.20060621125853.14">def get_edges(cls, src, dest):
10325 src_y, dest_y = cls.find_y_pos(src, dest)
10327 if src[0] == dest[0]:
10328 src = cls.point_near(src, src_y)
10329 dest = cls.point_near(dest, dest_y)
10330 return (src, dest)
10332 if dest[0] &lt; src[0]:
10333 src = cls.point_near(src, VCENTER)
10334 dest = cls.point_near(dest, dest_y)
10335 return (src, (dest[0], src[1]), dest)
10337 src = cls.point_near(src, src_y)
10338 dest = cls.point_near(dest, VCENTER)
10340 # src[0] &gt; dest[0]
10341 return (src, (src[0], dest[1]), dest)
10343 get_edges = classmethod(get_edges)</t>
10344 <t tx="michael.20060621125853.15">class EndStartPath(ConnectorPath):
10345 @others
10346 </t>
10347 <t tx="michael.20060621125853.16">def calc_x_ends(src, dest):
10348 return src.end, dest.start
10350 calc_x_ends = staticmethod(calc_x_ends)
10351 </t>
10352 <t tx="michael.20060621125853.17">def get_edges(cls, src, dest):
10353 src_y, dest_y = cls.find_y_pos(src, dest)
10355 if src[0] == dest[0]:
10356 return (cls.point_near(src, src_y),
10357 cls.point_near(dest, dest_y))
10359 if src[0] &lt; dest[0]:
10360 s = cls.point_near(src, VCENTER)
10361 d = cls.point_near(dest, dest_y)
10362 return (s, (d[0], s[1]), d)
10364 s = cls.point_near(src, src_y)
10365 d = cls.point_near(dest, dest_y)
10367 # src[0] &gt; dest[0]
10368 row = src[2].row
10369 if src[1] &lt; dest[1]:
10370 next_floor = row.y + VSEP * row.top_sep / 2
10371 else:
10372 next_floor = row.y - row.height - row.bottom_sep / 2 * VSEP
10374 return (s, (s[0], next_floor), (d[0], next_floor), d)
10376 get_edges = classmethod(get_edges)</t>
10377 <t tx="michael.20060621125853.18">class EndEndPath(ConnectorPath):
10378 @others
10379 </t>
10380 <t tx="michael.20060621125853.19">def calc_x_ends(src, dest):
10381 return src.end, dest.end
10383 calc_x_ends = staticmethod(calc_x_ends)
10384 </t>
10385 <t tx="michael.20060621125853.20">def get_edges(cls, src, dest):
10386 src_y, dest_y = cls.find_y_pos(src, dest)
10388 if src[0] == dest[0]:
10389 src = cls.point_near(src, src_y)
10390 dest = cls.point_near(dest, dest_y)
10391 return (src, dest)
10393 if src[0] &lt; dest[0]:
10394 src = cls.point_near(src, VCENTER)
10395 dest = cls.point_near(dest, dest_y)
10396 return (src, (dest[0], src[1]), dest)
10398 src = cls.point_near(src, src_y)
10399 dest = cls.point_near(dest, VCENTER)
10401 # src[0] &gt; dest[0]
10402 return (src, (src[0], dest[1]), dest)
10404 get_edges = classmethod(get_edges)</t>
10405 <t tx="michael.20060621125853.21">class ShortestPath(ConnectorPath):
10406 @others
10407 </t>
10408 <t tx="michael.20060621125853.22">def calc_x_ends(src, dest):
10409 if src.start &lt;= dest.end and dest.start &lt;= src.end:
10410 start = (min(src.end, dest.end) + max(src.start, dest.start)) / 2
10411 return start, start
10413 if src.start &gt; dest.end: return src.start, dest.end
10414 return src.end, dest.start
10416 calc_x_ends = staticmethod(calc_x_ends)</t>
10417 <t tx="michael.20060621125853.23">class GanttConnector(widgets.Widget):
10419 A connecor path between two gantt widgets.
10422 &lt;&lt; declarations &gt;&gt;
10423 @others
10424 </t>
10425 <t tx="michael.20060621125853.24">properties = {
10426 "width" : 3,
10427 "height" : 3,
10428 "edgecolor" : "darkslategray",
10429 "facecolor" : "darkslategray",
10430 "open" : False
10433 zorder = -2
10435 </t>
10436 <t tx="michael.20060621125853.25">def __init__(self, src, dest, path, properties=None):
10437 widgets.Widget.__init__(self, properties)
10438 self.src = src
10439 self.dest = dest
10440 self.set_path(path)
10441 </t>
10442 <t tx="michael.20060621125853.26">def set_path(self, path):
10443 self.path = path
10444 self.start, self.end = path.calc_start_end(self.src, self.dest)
10445 </t>
10446 <t tx="michael.20060621125853.27">def set_property(self, name, value):
10447 if name.find("connector") &lt; 0:
10448 # a convinience hack
10449 name = "connector." + name
10451 widgets.Widget.set_property(self, name, value)
10452 </t>
10453 <t tx="michael.20060621125853.28">def get_bounds(self, renderer):
10454 return self.bbox
10455 </t>
10456 <t tx="michael.20060621125853.29">def contains(self, x, y):
10457 return False
10458 </t>
10459 <t tx="michael.20060621125853.30">def prepare_draw(self, renderer, point_to_pixel, fig_point_to_pixel):
10460 #fetch all properties
10461 self.get_patch("connector")
10462 self.get_patch("connector.end")
10463 self.get_property("connector.end.open")
10464 self.get_property("connector.end.width")
10465 self.get_property("connector.end.height")
10466 self.get_property("connector.end.facecolor")
10468 self.set_font_factor(point_to_pixel, fig_point_to_pixel)
10470 transform = self.get_transform()
10471 lines = self.path.get_lines(self.src, self.dest, transform)
10473 self.xs = map(lambda e: e[0], lines)
10474 self.ys = map(lambda e: e[1], lines)
10476 self.edx = (self.xs[-2] - self.xs[-1]) / HSEP
10477 self.edy = (self.ys[-2] - self.ys[-1]) / VSEP
10478 self.LL = self.edx * self.edx + self.edy * self.edy
10479 self.cos = Lazy(1)
10480 self.sin = Lazy(0)
10482 prop = self.get_property
10484 awidth = prop("connector.end.width")
10485 aheight = prop("connector.end.height")
10487 self.arrow = get_arrow(self.cos, self.sin,
10488 self.xs[-1], self.ys[-1],
10489 awidth, aheight)
10491 Point = mtrans.Point
10492 Value = mtrans.Value
10493 Bbox = mtrans.Bbox
10495 to_float = lambda v: (float(v), v)
10496 xs = map(to_float, self.xs)
10497 ys = map(to_float, self.ys)
10499 left = min(xs)[1] - (awidth * 0.5) * HSEP
10500 right = max(xs)[1] + (awidth * 0.5) * HSEP
10501 bottom = min(ys)[1]
10502 top = max(ys)[1]
10503 self.bbox = Bbox(Point(left.val, bottom.val),
10504 Point(right.val, top.val))
10505 return True, True
10506 </t>
10507 <t tx="michael.20060621125853.31">def draw(self, renderer, data_box):
10508 if not self.get_visible() or not self.overlaps(data_box): return False
10509 transform = self.get_transform()
10511 gc = renderer.new_gc()
10512 if self.get_clip_on():
10513 gc.set_clip_rectangle(self.clipbox.get_bounds())
10515 self.set_gc(gc, "connector")
10516 draw_lines(renderer, gc, self.xs, self.ys, transform)
10518 l = math.sqrt(float(self.LL)) or 1.0
10519 self.cos.set(float(self.edx) / l)
10520 self.sin.set(float(self.edy) / l)
10522 self.set_gc(gc, "connector.end")
10523 if self.get_property("connector.end.open"):
10524 draw_lines(renderer, gc,
10525 map(lambda a: a[0], self.arrow),
10526 map(lambda a: a[1], self.arrow),
10527 transform)
10528 else:
10529 face = self.get_property("connector.end.facecolor")
10530 face = _colorConverter.to_rgb(face)
10531 renderer.draw_polygon(gc, face, transform.seq_xy_tups(self.arrow))
10533 return False
10534 </t>
10535 <t tx="michael.20060621125853.32">class WBKConnector(widgets.Widget):
10537 A connector of widgets inside a workbreakdown chart
10539 &lt;&lt; declarations &gt;&gt;
10540 @others
10541 </t>
10542 <t tx="michael.20060621125853.33">properties = {
10543 "connector.linewidth" : 1,
10544 "connector.edgecolor" : "black",
10547 zorder = -2
10549 </t>
10550 <t tx="michael.20060621125853.34">def __init__(self, src, dest, properties=None):
10551 widgets.Widget.__init__(self, properties)
10552 self.src = src
10553 self.dest = dest
10555 #fetch all properties
10556 self.get_patch("connector")
10557 </t>
10558 <t tx="michael.20060621125853.35">def get_bounds(self, renderer):
10559 return self.bbox
10560 </t>
10561 <t tx="michael.20060621125853.36">def contains(self, x, y):
10562 return False
10563 </t>
10564 <t tx="michael.20060621125853.37">def prepare_draw(self, renderer, point_to_pixel, fig_point_to_pixel):
10565 self.set_font_factor(point_to_pixel, fig_point_to_pixel)
10567 HSEP.set(VSEP.get())
10568 Point = mtrans.Point
10569 BBox = mtrans.Bbox
10571 src_box = self.src.bbox
10572 dst_box = self.dest.bbox
10574 if self.src.row.y.get() &gt; self.dest.row.y.get():
10575 self.bbox = BBox(Point(src_box.ur().x(), dst_box.ll().y()),
10576 Point(dst_box.ll().x(), src_box.ur().y()))
10577 else:
10578 self.bbox = BBox(Point(src_box.ur().x(), src_box.ll().y()),
10579 Point(dst_box.ll().x(), dst_box.ur().y()))
10581 hor_middle = float(self.src.col.x + self.src.col.full_width()\
10582 - self.src.col.right_sep * HSEP.get() / 2)
10583 src_middle = (src_box.ymin() + src_box.ymax()) / 2
10584 dst_middle = (dst_box.ymin() + dst_box.ymax()) / 2
10586 self.xs = (src_box.xmax(), hor_middle, hor_middle, dst_box.xmin())
10587 self.ys = (src_middle, src_middle, dst_middle, dst_middle)
10588 return True, True
10589 </t>
10590 <t tx="michael.20060621125853.38">def draw(self, renderer, data_box):
10591 if not self.get_visible() or not self.overlaps(data_box): return False
10592 transform = self.get_transform()
10594 gc = renderer.new_gc()
10595 if self.get_clip_on():
10596 gc.set_clip_rectangle(self.clipbox.get_bounds())
10598 self.set_gc(gc, "connector")
10599 draw_lines(renderer, gc, self.xs, self.ys, transform)
10600 return False
10601 </t>
10602 <t tx="michael.20060621130232">@
10603 gantt widgets can have the different shapes in this modules.
10605 For all shapes:
10606 the first item of the returned shape list, has to be a patch, that defines, the connection points
10609 @code
10610 @language python
10611 &lt;&lt; Copyright &gt;&gt;
10612 &lt;&lt; Imports &gt;&gt;
10614 __all__ = ("bar", "brace", "combibar", "diamond", "circle", "wedge", "house")
10615 _is_source_ = True
10617 @others
10619 symbols = ("diamond", "circle", "wedge", "house")
10621 </t>
10622 <t tx="michael.20060621130232.1">from patches import *
10623 from tools import *
10624 import widgets
10627 </t>
10628 <t tx="michael.20060621130232.2">def bar(props, name, complete=0):
10629 kwargs = make_properties(props, name)
10630 bar = Polygon(((LEFT, BOTTOM),
10631 (LEFT, VCENTER),
10632 (LEFT, TOP),
10633 (HCENTER, TOP),
10634 (RIGHT, TOP),
10635 (RIGHT, VCENTER),
10636 (RIGHT, BOTTOM),
10637 (HCENTER, BOTTOM)), **kwargs)
10638 if complete:
10639 kwargs = make_properties(props, "%s.complete" % name)
10640 complete /= 100.0
10641 complete = Rectangle((LEFT, BOTTOM + VSEP * FACTOR / 4),
10642 (RIGHT - LEFT) * complete,
10643 VSEP * FACTOR / 2,
10644 **kwargs)
10645 return (bar, complete)
10647 return (bar,)
10648 </t>
10649 <t tx="michael.20060621130232.3">def brace(props, name):
10650 kwargs = make_properties(props, name)
10651 HALF = FACTOR / 2
10652 return (Polygon([(LEFT, TOP),
10653 (RIGHT, TOP),
10654 (RIGHT, BOTTOM),
10655 (RIGHT - HALF * HSEP, BOTTOM + HALF * VSEP),
10656 (LEFT + HALF * HSEP, BOTTOM + HALF * VSEP),
10657 (LEFT, BOTTOM)], **kwargs),)
10658 </t>
10659 <t tx="michael.20060621130232.4">def combibar(props, name, left, right, complete):
10660 left = left(props, name + ".start", VCENTER, LEFT)
10661 right = right(props, name + ".end", VCENTER, RIGHT)
10663 half_height = props(name + ".bar.height") * VSEP / 2
10664 top = VCENTER + half_height
10665 bottom = VCENTER - half_height
10667 def left_vert(vert):
10668 x, y = float(vert[0]), float(vert[1])
10669 return x &lt; LEFT.get() or y &gt; top.get() or y &lt; bottom.get()
10671 def right_vert(vert):
10672 x, y = float(vert[0]), float(vert[1])
10673 return x &gt; RIGHT.get() or y &gt; top.get() or y &lt; bottom.get()
10675 outline_verts = filter(left_vert, left[0].get_verts())\
10676 + [(HCENTER, top), (HCENTER, bottom)] \
10677 + filter(right_vert, right[0].get_verts())
10679 outline = Polygon(outline_verts)
10680 outline.set_visible(False)
10682 kwargs = make_properties(props, name + ".bar")
10683 bar = Polygon([(LEFT, top), (RIGHT, top),
10684 (RIGHT, bottom), (LEFT, bottom)], **kwargs)
10686 #only take the visible part of the symbols
10687 sleft = left[int(len(left) &gt; 1)]
10688 sright = right[int(len(right) &gt; 1)]
10690 if complete:
10691 kwargs = make_properties(props, name + ".complete")
10692 half_height = props(name + ".complete.height") * VSEP / 2
10693 top = VCENTER + half_height
10694 bottom = VCENTER - half_height
10695 right = LEFT + (RIGHT - LEFT) * complete / 100
10696 complete = Polygon([(LEFT, top), (right, top),
10697 (right, bottom), (LEFT, bottom)], **kwargs)
10699 return (outline, bar, complete, sleft, sright)
10701 return (outline, bar, sleft, sright)
10702 </t>
10703 <t tx="michael.20060621130232.5">def diamond(props, name="", vc=None, hc=None):
10705 A diamond symbol, that can be be used as an argument,
10706 for a widgets set_shape method or for a combined shape
10707 like combibar.
10709 @args:
10711 if name: name = ".%s" % name
10712 vc = vc or VCENTER
10713 hc = hc or HCENTER
10714 kwargs = make_properties(props, "diamond" + name)
10715 mag = props("diamond" + name + ".magnification")
10716 HALF = mag * FACTOR / 2
10717 return (Polygon([(hc - HALF * HSEP, vc),
10718 (hc, vc - HALF * VSEP),
10719 (hc + HALF * HSEP, vc),
10720 (hc, vc + HALF * VSEP)], **kwargs),)
10721 </t>
10722 <t tx="michael.20060621130232.6">def circle(props, name="", vc=None, hc=None):
10723 if name: name = ".%s" % name
10724 vc = vc or VCENTER
10725 hc = hc or HCENTER
10726 kwargs = make_properties(props, "circle" + name)
10727 mag = props("circle" + name + ".magnification")
10729 HALF = mag * FACTOR / 2
10731 shape = (Polygon([(hc - HALF * HSEP, vc),
10732 (hc, vc - HALF * VSEP),
10733 (hc + HALF * HSEP, vc),
10734 (hc, vc + HALF * VSEP)]),
10735 Circle((hc, vc), HALF*VSEP, **kwargs))
10736 shape[0].set_visible(False)
10737 return shape
10738 </t>
10739 <t tx="michael.20060621130232.7">def wedge(props, name="", vc=None, hc=None):
10740 if name: name = ".%s" % name
10741 vc = vc or VCENTER
10742 hc = hc or HCENTER
10743 kwargs = make_properties(props, "wedge" + name)
10744 mag = props("wedge" + name + ".magnification")
10746 HALF = mag * FACTOR / 2
10748 if props("wedge" + name + ".up", True):
10749 base = VCENTER - HALF * VSEP
10750 head = VCENTER + HALF * VSEP
10751 else:
10752 base = VCENTER + HALF * VSEP
10753 head = VCENTER - HALF * VSEP
10755 return (Polygon([(hc - HALF * HSEP, base),
10756 (hc, base),
10757 (hc + HALF * HSEP, base),
10758 (hc + HALF * HSEP / 2, vc),
10759 (hc, head),
10760 (hc - HALF * HSEP / 2, vc)], **kwargs),)
10761 </t>
10762 <t tx="michael.20060621130232.8">def house(props, name="", vc=None, hc=None):
10763 if name: name = ".%s" % name
10764 vc = vc or VCENTER
10765 hc = hc or HCENTER
10766 kwargs = make_properties(props, "house" + name)
10767 mag = props("house" + name + ".magnification")
10769 HALF = mag * FACTOR / 2
10771 if props("house" + name + ".up", True):
10772 base = VCENTER - HALF * VSEP
10773 head = VCENTER + HALF * VSEP
10774 else:
10775 base = VCENTER + HALF * VSEP
10776 head = VCENTER - HALF * VSEP
10778 return (Polygon([(hc - HALF * HSEP, base),
10779 (hc, base),
10780 (hc + HALF * HSEP, base),
10781 (hc + HALF * HSEP, vc),
10782 (hc, head),
10783 (hc - HALF * HSEP, vc)], **kwargs),)
10784 </t>
10785 <t tx="michael.20060621131531">@ filters out modules which are definitly not faces modules
10786 @code
10787 buffer_paths = [ m.path for m in ctrl.get_planbuffers() ]
10789 def is_valid_module(module):
10790 try:
10791 if not module._faces_source_file: return False
10792 except AttributeError:
10793 return False
10795 try:
10796 return not module._is_source_
10797 except AttributeError:
10798 return module._faces_source_file in buffer_paths</t>
10799 <t tx="michael.20060621134201">@language python
10800 &lt;&lt; Copyright &gt;&gt;
10801 &lt;&lt; Imports &gt;&gt;
10804 _is_source = True
10805 _FIELD_BULLET = re.compile('^\s*@(\w+)( [^{}:\n]+)?:( +|$)', re.MULTILINE)
10806 _ESCAPE = re.compile('[A-Z]+{([^}]+)}')
10808 @others
10809 </t>
10810 <t tx="michael.20060621134201.1">import re
10811 import inspect
10812 import textwrap
10816 </t>
10817 <t tx="michael.20060621134201.2">def _get_indentdation(line):
10818 return len(line) - len(line.lstrip())
10819 </t>
10820 <t tx="michael.20060621134201.3">def unescape(txt):
10821 return _ESCAPE.sub(r"\1", txt)
10822 </t>
10823 <t tx="michael.20060621134201.4">class DocParser(object):
10824 @others
10825 </t>
10826 <t tx="michael.20060621134201.5">def __init__(self, text):
10827 self.clear()
10828 self.description = self.parse_description(text)
10829 self.parse_fields(text)
10830 </t>
10831 <t tx="michael.20060621134201.6">def clear(self):
10832 self.description = ""
10833 self.order = {}
10834 self.attribs = {}
10835 self.types = {}
10836 self.params = {}
10837 self.args = None
10838 </t>
10839 <t tx="michael.20060621134201.7">def parse_fields(self, txt):
10840 field = { "var" : self.attribs,
10841 "param": self.params,
10842 "type" : self.types }
10844 docs = txt.split("\n")
10846 for i in range(len(docs)):
10847 line = docs[i]
10848 mo = _FIELD_BULLET.search(line)
10849 if mo:
10850 type_ = mo.group(1)
10851 name = mo.group(2)
10852 indent = _get_indentdation(line)
10853 for j in range(i + 1, len(docs)):
10854 if _get_indentdation(docs[j]) &lt; indent \
10855 or _FIELD_BULLET.search(docs[j]):
10856 break
10858 dlines = map(lambda l: l[indent:], docs[i + 1:j])
10859 dlines.insert(0, line[mo.end():].strip())
10861 desc = unescape("\n".join(dlines))
10862 try:
10863 if name:
10864 name = name.strip()
10865 field[type_].setdefault(name.strip(),
10866 textwrap.dedent(desc).strip())
10867 self.order.setdefault(name, i)
10868 else:
10869 field[type_] = textwrap.dedent(desc).strip()
10870 except KeyError: pass
10872 i = j
10874 self.args = field.get("args", None)
10875 </t>
10876 <t tx="michael.20060621134201.8">def parse_methods(self, instance):
10877 ismf = lambda o: inspect.isfunction(o) or inspect.ismethod(0)
10878 for name, val in inspect.getmembers(instance, ismf):
10879 self.methods[name] = self.parse_description(val.__doc__ or "")
10880 </t>
10881 <t tx="michael.20060621134201.9">def parse_description(self, desc):
10882 mo = _FIELD_BULLET.search(desc)
10883 desc = bool(mo) and desc[:mo.start()] or desc
10884 return textwrap.dedent(desc).strip()
10885 </t>
10886 <t tx="michael.20060621134201.10">class DocBase(object):
10887 &lt;&lt; declarations &gt;&gt;
10888 @others
10889 </t>
10890 <t tx="michael.20060621134201.11">min_width = 40
10892 </t>
10893 <t tx="michael.20060621134201.12">def argspec(self, obj):
10894 args = inspect.getargspec(obj)
10895 try:
10896 if args[0][0] == "self": del args[0][0]
10897 except IndexError:
10898 pass
10900 return inspect.formatargspec(*args)
10901 </t>
10902 <t tx="michael.20060621134201.13">class ClassDoc(DocBase):
10903 @others
10904 </t>
10905 <t tx="michael.20060621134201.14">def __init__(self, instance):
10906 try:
10907 doc = str(instance.__doc__ or "")
10908 except AttributeError:
10909 doc = ""
10911 parser = DocParser(doc)
10913 self.description = parser.description
10914 self.order = parser.order
10915 self.attribs = parser.attribs
10916 self.params = parser.params
10917 self.init_args = "()"
10919 args = parser.args
10921 parser.params = {}
10922 if inspect.isclass(instance):
10923 cls = instance
10924 else:
10925 cls = instance.__class__
10927 for c in inspect.getmro(cls):
10928 try:
10929 doc = str(c.__doc__ or "")
10930 except AttributeError:
10931 doc = ""
10933 parser.parse_fields(doc)
10935 self.parse_methods(instance)
10936 self.init_args = args is None and self.init_args or args
10937 </t>
10938 <t tx="michael.20060621134201.15">def get_doc(self, field):
10939 desc = self.attribs.get(field)
10940 if desc:
10941 desc = textwrap.fill(desc, self.min_width)
10942 return len(field) + 1, "%s:\n%s" % (field, desc)
10944 desc = self.methods.get(field)
10945 if desc:
10946 header = field + self.args[field]
10947 desc = textwrap.fill(desc, max(self.min_width, len(header) + 1))
10948 return len(header) + 1, "%s:\n%s" % (header, desc)
10950 return ()
10951 </t>
10952 <t tx="michael.20060621134201.16">def constructor(self, name):
10953 header = name + self.init_args
10954 desc = textwrap.fill(self.description,
10955 max(self.min_width, len(header) + 1))
10956 return len(header) + 1, "%s:\n%s" % (header, desc)
10957 </t>
10958 <t tx="michael.20060621134201.17">def parse_methods(self, instance):
10959 self.methods = {}
10960 self.args = {}
10961 for name, val in inspect.getmembers(instance, inspect.ismethod):
10962 if val.__doc__:
10963 parser = DocParser(str(val.__doc__))
10964 self.methods[name] = parser.description
10965 if parser.args:
10966 self.args[name] = parser.args
10967 continue
10969 self.args[name] = self.argspec(val)
10971 if name == "__init__":
10972 self.init_args = self.argspec(val)
10973 </t>
10974 <t tx="michael.20060621134201.18">class FunctionDoc(DocBase):
10975 @others
10976 </t>
10977 <t tx="michael.20060621134201.19">def __init__(self, func):
10978 doc = str(func.__doc__ or "")
10980 if inspect.ismethod(func) and not doc:
10981 for c in inspect.getmro(func.im_class):
10982 attr = getattr(c, func.__name__, func)
10983 if attr.__doc__:
10984 doc = attr.__doc__
10985 break
10987 parser = DocParser(doc)
10988 self.description = parser.description
10989 self.args = parser.args is None and self.argspec(func) or parser.args
10990 </t>
10991 <t tx="michael.20060621134201.20">def constructor(self, name):
10992 header = name + self.args
10993 desc = textwrap.fill(self.description,
10994 max(self.min_width, len(header) + 1))
10995 return len(header) + 1, "%s:\n%s" % (header, desc)
10996 </t>
10997 <t tx="michael.20060621134220">def get_doc(self, field):
10998 return ()
10999 </t>
11000 <t tx="michael.20060621173535">__last_expression = None
11001 def make_button(self, button, expression):
11002 if expression == self.__last_expression: return
11003 self.__last_expression = expression
11004 if not button: return
11006 editors = self.get_editors()
11007 if not editors:
11008 button.hide()
11009 return
11011 try:
11012 attribs = self.code_item.editor.get_attribs(self.code_item)
11013 except AttributeError:
11014 attribs = ()
11016 if expression:
11017 applies = lambda ne: ne[1].apply(expression, self.code_item)
11018 else:
11019 applies = lambda ne: ne[1].apply(expression, self.code_item) \
11020 and ne[1].attrib_name not in attribs
11021 editors = filter(applies, editors.iteritems())
11023 if not editors:
11024 button.hide()
11025 return
11027 button.set_bitmap(expression and "edit16" or "new16")
11029 if expression:
11030 item_editor = editors[0][1]
11031 def show_popup(editor):
11032 item_editor.activate(self)
11033 else:
11034 def show_popup(editor):
11035 menu = controller().make_menu()
11036 create_editor_menu(menu, self, editors)
11037 button.PopupMenu(menu.wxobj, (0, button.GetSize().height))
11038 editor.SetFocus()
11040 button.action = show_popup
11041 button.Show()</t>
11042 <t tx="michael.20060621180747">if 'wxMac' in wx.PlatformInfo:
11043 #a dummy context button to disable
11044 class ContextButton(wx.PyPanel):
11045 def __init__(self, editor):
11046 wx.PyPanel.__init__(self, editor)
11047 self.Hide()
11049 def set_bitmap(self, bmp_name): pass
11050 def hide(self): pass
11051 def move(self, x, y): pass
11052 def IsShown(self): return False
11053 def Show(self): pass
11055 else:
11056 class ContextButton(wx.PyPanel):
11057 action = None
11058 @others
11062 </t>
11063 <t tx="michael.20060621182829">def move_context_button(self):
11064 if self.context_button.IsShown():
11065 line = self.GetCurrentLine()
11066 pos = self.GetLineEndPosition(line)
11067 pos = self.PointFromPosition(pos)
11068 w, h = self.context_button.GetSize()
11069 th = self.TextHeight(line)
11070 self.context_button.move(pos.x + 10, pos.y + (th - h) / 2)</t>
11071 <t tx="michael.20060621183003">def set_bitmap(self, bmp_name):
11072 bmp = ResourceManager.load_bitmap(bmp_name)
11073 self.button.SetBitmapLabel(bmp)
11074 self.button.SetSize(self.button.GetBestSize())
11075 self.SetClientSize(self.button.GetSize())
11076 self.Refresh(False)</t>
11077 <t tx="michael.20060621183054">def __init__(self, editor):
11078 wx.PyPanel.__init__(self, editor)
11079 self.button = buttons.GenBitmapButton(self, -1, None)
11080 def on_enter(evt): self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
11081 def on_action(evt): self.action and self.action(editor) or editor.SetFocus()
11082 self.button.Bind(wx.EVT_ENTER_WINDOW, on_enter)
11083 self.button.Bind(wx.EVT_BUTTON, on_action)
11086 </t>
11087 <t tx="michael.20060621203738">def hide(self):
11088 self.Hide()
11089 self.action = None</t>
11090 <t tx="michael.20060622082846">@language python
11091 &lt;&lt; Copyright &gt;&gt;
11093 This module contains the base class for all observer objects
11095 &lt;&lt; Imports &gt;&gt;
11096 _is_source_ = True
11097 @others
11098 factories = { }
11099 clear_cache_funcs = {}
11100 </t>
11101 <t tx="michael.20060622082846.1"></t>
11102 <t tx="michael.20060622082846.2">class Observer(object):
11104 Base Class for all charts and reports.
11106 @var visible: Specifies if the observer is visible
11107 at the navigation bar inside the gui.
11109 @var link_view: syncronizes the marked objects in all views.
11112 &lt;&lt; declarations &gt;&gt;
11114 @others
11116 </t>
11117 <t tx="michael.20060622082846.3">__type_name__ = None
11118 __type_image__ = None
11119 visible = True
11120 link_view = True
11122 __attrib_completions__ = { "visible" : 'visible = False',
11123 "link_view" : "link_view = False" }
11126 </t>
11127 <t tx="michael.20060622085024"></t>
11128 <t tx="michael.20060622085024.1">def _import_(name):
11129 mod = __import__(name)
11130 components = name.split('.')
11131 for comp in components[1:]:
11132 mod = getattr(mod, comp)
11133 return mod
11134 </t>
11135 <t tx="michael.20060622090146.1">try:
11136 gui_module = _import_(module.faces_gui_module)
11137 self.loaded_modules[module.faces_gui_module] = gui_module
11138 except AttributeError: pass
11139 </t>
11140 <t tx="michael.20060622090146.2">try:
11141 module_name = str(os.path.splitext(filename)[0])
11142 except UnicodeEncodeError:
11143 print &gt;&gt; sys.stderr, \
11144 u'filename "%s" contains non ascii chars' % unicode(filename)
11145 return True</t>
11146 <t tx="michael.20060622092032"></t>
11147 <t tx="michael.20060622092054">def get_expression_range(self, line=None, with_end=False):
11149 returns the start and end pos of the expression at line
11150 Note: the expression can go over several lines
11152 line = line or self.GetCurrentLine()
11153 indent = self.GetLineIndentation
11154 length = self.LineLength
11155 text = self.GetLine
11156 takewhile = itertools.takewhile
11158 &lt;&lt; find start of expression &gt;&gt;
11159 &lt;&lt; find end of expression &gt;&gt;
11161 return self.GetLineIndentPosition(start_line), \
11162 self.GetLineEndPosition(end_line) + bool(with_end)
11164 </t>
11165 <t tx="michael.20060622093346">@language python
11166 &lt;&lt; Copyright &gt;&gt;
11168 A collection of functions for editing tasks and their attributes
11170 &lt;&lt; Imports &gt;&gt;
11172 _is_source_ = True
11173 _ = faces.plocale.get_gettext()
11175 @others</t>
11176 <t tx="michael.20060622093402">import context
11177 import faces.plocale
11178 import datetime
11179 import faces.pcalendar as pcalendar
11180 import faces.task as ftask
11181 import metapie.dbtransient as db
11182 import metapie.gui.views as views
11183 import classifiers
11184 import editor
11185 from attribedit import *
11186 </t>
11187 <t tx="michael.20060622093608">class ItemEditor(object):
11189 Define the Interface for Editor to
11190 manipulate code_items.
11192 attrib_name = ""
11194 def apply(self, expression):
11196 returns true if the editor applies for the expression
11198 return False
11201 def activate(self, code_item, context):
11203 activates the editor.
11206 </t>
11207 <t tx="michael.20060622093827">class ScenarioAttributeEditor(ScenarioAttributeEditor):
11208 evaluator = TaskEvaluator
11210 </t>
11211 <t tx="michael.20060622095823">tregistry = context.CTask.editors
11212 pregistry = context.CProjectDeclaration.editors
11214 std_attributes = _("Standard/%s")
11215 cal_attributes = _("Calendar/%s")
11217 tregistry[std_attributes % "title..."] = AttributeEditor("title", String, _("Title"))
11218 tregistry[std_attributes % "start..."] = ScenarioAttributeEditor("start", RefDate, datetime.datetime.now())
11219 tregistry[std_attributes % "end..."] = ScenarioAttributeEditor("end", RefDate, datetime.datetime.now())
11220 tregistry[std_attributes % "duration..."] = ScenarioAttributeEditor("duration", Duration, "1d")
11221 tregistry[std_attributes % "effort..."] = ScenarioAttributeEditor("effort", Delta, "1d")
11222 tregistry[std_attributes % "todo..."] = AttributeEditor("todo", Delta, "1d")
11223 tregistry[std_attributes % "done..."] = AttributeEditor("done", Delta, "1d")
11225 tregistry[std_attributes % "length..."] = ScenarioAttributeEditor("length", Delta, "1d")
11226 tregistry[std_attributes % "balance..."] = AttributeEditor("balance", Balance)
11227 tregistry[std_attributes % "notes..."] = AttributeEditor("notes", MultiText)
11228 tregistry[std_attributes % "load..."] = ScenarioAttributeEditor("load", Float, 1.0)
11229 tregistry[std_attributes % "efficiency..."] = ScenarioAttributeEditor("efficiency", Float, 1.0)
11230 tregistry[std_attributes % "max_load..."] = ScenarioAttributeEditor("max_load", Float, 1.0)
11231 tregistry[std_attributes % "priority..."] = AttributeEditor("priority", Int, 500)
11232 tregistry[std_attributes % "complete..."] = AttributeEditor("complete", Int, 100)
11233 tregistry[std_attributes % "milestone..."] = AttributeEditor("milestone", Boolean, True)
11234 tregistry[std_attributes % "resource..."] = AttributeEditor("resource", ResourceSet)
11236 tregistry[cal_attributes % "vacation..."] = AttributeEditor("vacation", DateTimeRanges)
11237 tregistry[cal_attributes % "extra_work..."] = AttributeEditor("extra_work", DateTimeRanges)
11238 tregistry[cal_attributes % "now..."] = AttributeEditor("now", Date, datetime.datetime.now())
11239 tregistry[cal_attributes % "working_days..."] = AttributeEditor("working_days", WorkingTimes,
11240 [("mon,tue,wed,thu,fri", "08:00-12:00", "13:00-17:00")])
11241 tregistry[cal_attributes % "minimum_time_unit..."] = AttributeEditor("minimum_time_unit", Int,
11242 pcalendar.DEFAULT_MINIMUM_TIME_UNIT)
11243 tregistry[cal_attributes % "working_days_per_week..."] = AttributeEditor("working_days_per_week", Int,
11244 pcalendar.DEFAULT_WORKING_DAYS_PER_WEEK)
11245 tregistry[cal_attributes % "working_days_per_month..."] = AttributeEditor("working_days_per_month", Int,
11246 pcalendar.DEFAULT_WORKING_DAYS_PER_MONTH)
11247 tregistry[cal_attributes % "working_days_per_year..."] = AttributeEditor("working_days_per_year", Int,
11248 pcalendar.DEFAULT_WORKING_DAYS_PER_YEAR)
11249 tregistry[cal_attributes % "working_hours_per_day..."] = AttributeEditor("working_hours_per_day", Int,
11250 pcalendar.DEFAULT_WORKING_HOURS_PER_DAY)
11252 pregistry.update(tregistry)
11254 tregistry[_("Task/Create Subtask...(1000)")] = SubTaskCreator()
11255 tregistry[_("Task/Rename...(1010)")] = TaskRenamer()
11256 tregistry[_("Task/Remove...(1012)")] = TaskRemover()
11257 tregistry[_("Task/Insert Sibling After...(1020)")] = TaskSiblingCreator()
11258 tregistry[_("Task/Insert Sibling Before...(1030)")] = TaskSiblingBeforeCreator()
11259 tregistry[_("Task/Indent(1040)")] = TaskIndenter()
11260 tregistry[_("Task/Unindent(1050)")] = TaskUnindenter()
11261 tregistry[_("Task/Show References...(1100)")] = TaskReferencePrinter()
11264 pregistry[_("Project/Create Project...(1000)")] = ProjectTaskCreator()
11265 pregistry[_("Project/Create Task...(1001)")] = SubTaskCreator()
11266 pregistry[_("Project/Rename...(1010)")] = ProjectTaskRenamer()
11267 pregistry[_("Project/Remove...(1012)")] = EvaluationRemover()
11268 pregistry[_("Project/Show References...(1100)")] = EvaluationReferencePrinter()
11270 del pregistry
11271 del tregistry
11272 del std_attributes
11273 del cal_attributes
11275 </t>
11276 <t tx="michael.20060622103212">def find_parent_line(self, line_no):
11278 returns the parent line of line
11281 find = self.FindText
11282 line = self.LineFromPosition
11283 end = self.GetLineEndPosition
11284 text = self.GetTextRange
11285 indent = self.GetLineIndentation
11287 child_indent = indent(line_no)
11288 pos = self.PositionFromLine(line_no)
11289 pos = find(pos, 0, ":")
11290 while pos &gt;= 0:
11291 &lt;&lt; check if pos ident is smaller &gt;&gt;
11292 &lt;&lt; check if pos is not in a string or comment &gt;&gt;
11293 &lt;&lt; check if pos is at the end of an expression &gt;&gt;
11294 else:
11295 raise ValueError("no parent line")
11297 return line(pos)
11298 </t>
11299 <t tx="michael.20060622105356">try:
11300 min_line = self.find_parent_line(line)
11301 except ValueError:
11302 block_indent = 0
11303 min_line = -1
11304 else:
11305 block_indent = indent(min_line + 1)
11307 is_sub_block = lambda l: indent(l) &gt; block_indent
11308 lines = tuple(takewhile(is_sub_block, xrange(line, min_line, -1)))
11309 start_line = lines and lines[-1] - 1 or line
11311 </t>
11312 <t tx="michael.20060622105356.1">def is_child(l):
11313 cindent = indent(l)
11314 return cindent &gt; block_indent or cindent == length(l) - 1
11316 def has_content(l):
11317 return indent(l) &lt; length(l) - 1
11319 lines = filter(has_content,
11320 takewhile(is_child, xrange(line + 1, self.GetLineCount())))
11322 end_line = lines and lines[-1] or line
11323 </t>
11324 <t tx="michael.20060622105715">def get_expression(self, line=None):
11325 start, end = self.get_expression_range(line)
11326 return self.GetTextRangeUTF8(start, end).strip()
11328 </t>
11329 <t tx="michael.20060622112139">style = self.GetStyleAt(pos)
11330 if style in (wx.stc.STC_P_TRIPLEDOUBLE,
11331 wx.stc.STC_P_TRIPLE,
11332 wx.stc.STC_P_STRING,
11333 wx.stc.STC_P_COMMENTLINE,
11334 wx.stc.STC_P_COMMENTBLOCK):
11335 pos = find(pos - 1, 0, ":")
11336 continue</t>
11337 <t tx="michael.20060622112139.1">rest_text = text(pos, end(line(pos))).split()
11338 try:
11339 if not rest_text[1].startswith("#"):
11340 pos = find(pos - 1, 0, ":")
11341 continue
11342 except IndexError: pass
11343 break</t>
11344 <t tx="michael.20060622234836"></t>
11345 <t tx="michael.20060623001958">@language python
11346 &lt;&lt; Copyright &gt;&gt;
11348 A library of classes that, can be used for edit dialogs
11350 &lt;&lt; Imports &gt;&gt;
11352 _is_source_ = True
11354 @others</t>
11355 <t tx="michael.20060623001958.1">import wx
11356 import metapie.gui.views as views
11357 from metapie.gui import controller
11358 from faces.gui.patches import PatchedDialog</t>
11359 <t tx="michael.20060623001958.2">if wx.Platform == '__WXGTK__':
11360 &lt;&lt; gtk patched dialog &gt;&gt;
11361 else:
11362 &lt;&lt; original dialog &gt;&gt;</t>
11363 <t tx="michael.20060623001958.3">class PatchedDialog(wx.Dialog):
11364 def __init__(self, *args, **kwargs):
11365 kwargs["style"] = kwargs.get("style", wx.DEFAULT_DIALOG_STYLE)\
11366 &amp; ~wx.CLOSE_BOX
11367 wx.Dialog.__init__(self, *args, **kwargs)
11368 self.SetSizer(wx.BoxSizer(wx.HORIZONTAL))
11370 #a real ShowModal will break the popup controls under gtk
11371 def simulate_modal(self, focused, call_after=None):
11372 self.focused = focused
11373 self.call_after = call_after
11374 controller().frame.Enable(False)
11375 self.Bind(wx.EVT_CLOSE, self._on_close)
11376 self.Show()
11377 self.SetFocus()
11380 def _on_close(self, event=None):
11381 if event: event.Skip()
11383 focused = self.focused
11384 def after_close():
11385 controller().frame.Enable()
11386 if focused: focused.SetFocus()
11388 wx.CallAfter(after_close)
11391 def EndModal(self, id):
11392 if self.call_after: self.call_after()
11393 self._on_close()
11394 self.Destroy()
11397 </t>
11398 <t tx="michael.20060623001958.4">class PatchedDialog(wx.Dialog):
11399 def __init__(self, *args, **kwargs):
11400 wx.Dialog.__init__(self, *args, **kwargs)
11401 self.SetSizer(wx.BoxSizer(wx.HORIZONTAL))
11404 def simulate_modal(self, focused, call_after=None):
11405 self.ShowModal()
11406 if call_after: call_after()
11407 if focused: focused.SetFocus()
11408 self.Destroy()
11410 </t>
11411 <t tx="michael.20060623001958.7"></t>
11412 <t tx="michael.20060623002701">class MainView(views.FormView):
11413 border = 5
11415 format_buttons = """
11416 btn_ok{r}|btn_refresh{r}|btn_cancel{r}
11419 @others
11420 </t>
11421 <t tx="michael.20060623152229">def __init__(self, parent, style=0):
11422 views.FormView.__init__(self, parent, style)
11423 parent.keep_alive = self # ensure that the view lives as long as the parent
11424 sizer = parent.GetSizer()
11425 sizer.Add(self, border=self.border, flag=wx.ALL|wx.EXPAND, proportion=1)</t>
11426 <t tx="michael.20060623152229.1">def button_cancel(self):
11427 self.GetParent().EndModal(wx.ID_CANCEL)
11428 self.rollback()
11429 try:
11430 self.imodel.cancel()
11431 except AttributeError:
11432 pass
11433 </t>
11434 <t tx="michael.20060623152229.2">def button_ok(self):
11435 if self.save():
11436 self.GetParent().EndModal(wx.ID_OK)
11437 self.imodel.realize()</t>
11438 <t tx="michael.20060623152229.3">def layout(self):
11439 views.FormView.layout(self)
11440 parent = self.GetParent()
11441 w, h = parent.GetClientSize()
11442 wm, hm = self.GetSizer().CalcMin()
11443 wm += 2 * self.border
11444 hm += 2 * self.border
11445 parent.SetClientSize((max(w, wm, 360), max(h, hm)))
11446 parent.SetMinSize((wm, hm))</t>
11447 <t tx="michael.20060623154040"></t>
11448 <t tx="michael.20060623154040.1"></t>
11449 <t tx="michael.20060623154040.2">raise RecursionError("you have to specify a "\
11450 "start or an end at %s" % self.path)</t>
11451 <t tx="michael.20060623154957"></t>
11452 <t tx="michael.20060623154957.1"></t>
11453 <t tx="michael.20060623154957.2"></t>
11454 <t tx="michael.20060623154957.3"></t>
11455 <t tx="michael.20060623154957.4"></t>
11456 <t tx="michael.20060623154957.5"></t>
11457 <t tx="michael.20060623160939">opname = opcode.opname
11458 opmap = opcode.opmap
11459 jumps = opcode.hasjrel + opcode.hasjabs
11460 HAVE_ARGUMENT = opcode.HAVE_ARGUMENT
11461 co = func.func_code
11462 local_names = co.co_varnames
11463 all_names = list(co.co_names)
11464 global_names = set()
11465 </t>
11466 <t tx="michael.20060623160939.1">def list_to_dict(l):
11467 return dict([(t[1], t[0]) for t in enumerate(l)])
11469 def is_local(name):
11470 return name[0] == "_" and name != "__constraint__"</t>
11471 <t tx="michael.20060623160939.3"># all_name_map maps names to the all_names index
11472 # (same like all_names.index())
11473 all_name_map = list_to_dict(all_names)
11474 if not all_name_map.has_key("me"):
11475 all_name_map["me"] = len(all_names)
11476 all_names.append("me")
11478 #&lt;python 2.5&gt;
11479 for ln in local_names:
11480 if not all_name_map.has_key(ln):
11481 all_name_map[ln] = len(all_names)
11482 all_names.append(ln)
11483 #&lt;/python 2.5&gt;
11485 new_local_names = filter(is_local, local_names)
11486 new_local_name_map = list_to_dict(new_local_names)
11488 me_arg = _int_to_arg(all_name_map["me"])
11489 old_lnotab = map(ord, co.co_lnotab)
11490 new_lnotab = []
11491 tab_pos = 0
11492 try:
11493 next_tab_point = old_lnotab[0]
11494 except IndexError:
11495 next_tab_point = None
11497 last_tab_point = 0
11498 code = map(ord, co.co_code)
11499 new_code = []
11500 has_labels = False
11501 n = len(code)
11502 i = 0</t>
11503 <t tx="michael.20060623160939.4">increment = len(new_code) - last_tab_point
11504 new_lnotab.extend((increment, old_lnotab[tab_pos + 1]))
11505 tab_pos += 2
11506 try:
11507 next_tab_point = i + old_lnotab[tab_pos]
11508 last_tab_point = len(new_code)
11509 except IndexError:
11510 next_tab_point = -1</t>
11511 <t tx="michael.20060623160939.5">arg0 = code[i]
11512 arg1 = code[i+1]
11513 oparg = arg0 + arg1 * 256</t>
11514 <t tx="michael.20060623160939.6">name = local_names[oparg]
11515 if not is_local(name):
11516 new_code.append(opmap["LOAD_GLOBAL"])
11517 new_code.extend(me_arg)
11518 op = opmap["STORE_ATTR"]
11519 arg0, arg1 = _int_to_arg(all_name_map[name])
11520 else:
11521 arg0, arg1 = _int_to_arg(new_local_name_map[name])</t>
11522 <t tx="michael.20060623160939.7">name = local_names[oparg]
11523 if not is_local(name):
11524 new_code.append(opmap["LOAD_GLOBAL"])
11525 new_code.extend(me_arg)
11526 op = opmap["LOAD_ATTR"]
11527 arg0, arg1 = _int_to_arg(all_name_map[name])
11528 else:
11529 arg0, arg1 = _int_to_arg(new_local_name_map[name])</t>
11530 <t tx="michael.20060623160939.8">new_code = "".join(map(chr, new_code))
11531 new_lnotab = "".join(map(chr, new_lnotab))
11532 new_co = new.code(co.co_argcount,
11533 len(new_local_names),
11534 max(co.co_stacksize, 2),
11535 co.co_flags,
11536 new_code,
11537 co.co_consts,
11538 tuple(all_names),
11539 tuple(new_local_names),
11540 co.co_filename,
11541 co.co_name,
11542 co.co_firstlineno,
11543 new_lnotab,
11544 co.co_freevars,
11545 co.co_cellvars)
11548 func = new.function(new_co,
11549 func.func_globals,
11550 func.func_name,
11551 func.func_defaults,
11552 func.func_closure)
11553 func.global_names = tuple([all_names[index] for index in global_names])
11554 return func</t>
11555 <t tx="michael.20060623161820">hasjrel = opcode.hasjrel
11556 hasjabs = opcode.hasjabs
11557 HAVE_ARGUMENT = opcode.HAVE_ARGUMENT</t>
11558 <t tx="michael.20060623161820.1">labels = {}
11559 old_new_map = {} # map old code offset to new code offset
11560 n = len(old_code)
11561 i = 0
11562 j = 0</t>
11563 <t tx="michael.20060623161820.2">label = -1
11564 if op in hasjrel:
11565 label = i + oparg
11566 elif op in hasjabs:
11567 label = oparg
11568 if label &gt;= 0:
11569 labels[i] = label</t>
11570 <t tx="michael.20060623163022"></t>
11571 <t tx="michael.20060626130019">class TaskEvaluator(object):
11572 def __init__(self, expression, context):
11573 &lt;&lt; define path variables &gt;&gt;
11574 &lt;&lt; define wmax and wmin &gt;&gt;
11576 vars = { "up" : up,
11577 "root" : root,
11578 "me" : me,
11579 "max" : wmax,
11580 "min" : wmin }
11582 try:
11583 editor = context.code_item.editor
11584 self.attributes = editor.eval_expression(expression, vars, context)
11585 except Exception, e:
11586 self.error = e
11587 </t>
11588 <t tx="michael.20060626130414">class PathWrapper(object):
11589 def __init__(self, code_item, path_str):
11590 self._path_str = path_str
11591 self._code_item = code_item
11594 def _get_up(self):
11595 new_item = self._code_item.get_parent()
11596 new_path = "%s.up" % (self._path_str)
11597 return PathWrapper(new_item, new_path)
11599 up = property(_get_up)
11601 def _get_root(self):
11602 return PathWrapper(get_code_root(self._code_item), "root")
11604 root = property(_get_root)
11607 def __getattr__(self, name):
11608 child = filter(lambda c: c.name == name, self._code_item.get_children())
11609 if child:
11610 return PathWrapper(child[0], "%s.%s" % (self._path_str, name))
11612 return ValueWrapper(AttributeWrapper(self._path_str, name),
11613 ["%s.%s" % (self._path_str, name)])
11616 def __str__(self):
11617 return self._path_str
11618 </t>
11619 <t tx="michael.20060626130823">class ValueWrapper(ftask._ValueWrapper):
11620 def _vw(self, operand, *args):
11621 refs = reduce(lambda a, b: a + b, map(ftask._ref, args), [])
11622 vals = map(ftask._val, args)
11623 vals.insert(0, operand)
11624 return ValueWrapper(tuple(vals), refs)
11627 def _cmp(self, operand, *args):
11628 refs = reduce(lambda a, b: a + b, map(ftask._ref, args), [])
11629 vals = map(str, args)
11630 result = operand(*vals)
11631 map(lambda a: _sref(a, refs), args)
11632 return result
11635 </t>
11636 <t tx="michael.20060626133545">@language python
11637 &lt;&lt; Copyright &gt;&gt;
11639 This module contains all classes and functions for the project plan calendar
11641 &lt;&lt; Imports &gt;&gt;
11642 @others
11644 if __name__ == '__main__':
11645 cal = Calendar()
11647 start = EndDate("10.1.2005")
11648 print "start", start.strftime(), type(start)
11650 delay = Minutes("4H")
11651 print "delay", delay, delay.strftime()
11653 print "Start", cal.StartDate is StartDate
11654 print "base", cal.StartDate.__bases__[0] == StartDate.__bases__[0]
11655 print "type", type(start)
11657 print "convert start"
11658 start2 = cal.StartDate(start)
11659 print "convert end"
11661 start3 = cal.StartDate("10.1.2005")
11662 print "start2", start2.strftime(), type(start2)
11663 </t>
11664 <t tx="michael.20060626133545.1">from string import *
11665 import datetime
11666 import time
11667 import re
11668 import locale
11669 import bisect
11670 import sys
11672 TIME_RANGE_PATTERN = re.compile("(\\d+):(\\d+)\\s*-\\s*(\\d+):(\\d+)")
11673 TIME_DELTA_PATTERN = re.compile("([-+]?\\d+(\\.\\d+)?)([dwmyMH])")
11675 DEFAULT_MINIMUM_TIME_UNIT = 15
11676 DEFAULT_WORKING_DAYS_PER_WEEK = 5
11677 DEFAULT_WORKING_DAYS_PER_MONTH = 20
11678 DEFAULT_WORKING_DAYS_PER_YEAR = 200
11679 DEFAULT_WORKING_HOURS_PER_DAY = 8
11681 DEFAULT_WORKING_TIMES = ( (8 * 60, 12 * 60 ),
11682 (13 * 60, 17 * 60 ) )
11683 DEFAULT_WORKING_DAYS = { 0 : DEFAULT_WORKING_TIMES,
11684 1 : DEFAULT_WORKING_TIMES,
11685 2 : DEFAULT_WORKING_TIMES,
11686 3 : DEFAULT_WORKING_TIMES,
11687 4 : DEFAULT_WORKING_TIMES,
11688 5 : (),
11689 6 : () }
11691 </t>
11692 <t tx="michael.20060626133545.2">def to_time_range(src):
11694 converts a string to a timerange, i.e
11695 (from, to)
11696 from, to are ints, specifing the minutes since midnight
11699 if not src: return ()
11701 mo = TIME_RANGE_PATTERN.match(src)
11702 if not mo:
11703 raise ValueError("%s is no time range" % src)
11705 from_time = int(mo.group(1)) * 60 + int(mo.group(2))
11706 to_time = int(mo.group(3)) * 60 + int(mo.group(4))
11707 return from_time, to_time
11708 </t>
11709 <t tx="michael.20060626133545.3">def to_datetime(src):
11711 a tolerant conversion function to convert different strings
11712 to a datetime.dateime
11715 #to get the original value for wrappers
11716 new = getattr(src, "_value", src)
11717 while new is not src:
11718 src = new
11719 new = getattr(src, "_value", src)
11721 if isinstance(src, _WorkingDateBase):
11722 src = src.to_datetime()
11724 if isinstance(src, datetime.datetime):
11725 return src
11727 src = str(src)
11729 formats = [ "%x %H:%M",
11730 "%x",
11731 "%Y-%m-%d %H:%M",
11732 "%y-%m-%d %H:%M",
11733 "%d.%m.%Y %H:%M",
11734 "%d.%m.%y %H:%M",
11735 "%Y%m%d %H:%M",
11736 "%d/%m/%y %H:%M",
11737 "%d/%m/%Y %H:%M",
11738 "%d/%m/%Y",
11739 "%d/%m/%y",
11740 "%Y-%m-%d",
11741 "%y-%m-%d",
11742 "%d.%m.%Y",
11743 "%d.%m.%y",
11744 "%Y%m%d" ]
11745 for f in formats:
11746 try:
11747 conv = time.strptime(src, f)
11748 return datetime.datetime(*conv[0:-3])
11749 except Exception, e:
11750 pass
11752 raise TypeError("'%s' (%s) is not a datetime" % (src, str(type(src))))
11753 </t>
11754 <t tx="michael.20060626133545.4">def _to_days(src):
11756 converts a string of the day abreviations mon, tue, wed,
11757 thu, fri, sat, sun to a dir with correct weekday indices.
11758 For Example
11759 convert_to_days('mon, tue, thu') results in
11760 { 0:1, 1:1, 3:1 }
11763 tokens = src.split(",")
11764 result = { }
11765 for t in tokens:
11766 try:
11767 index = { "mon" : 0,
11768 "tue" : 1,
11769 "wed" : 2,
11770 "thu" : 3,
11771 "fri" : 4,
11772 "sat" : 5,
11773 "sun" : 6 } [ lower(t.strip()) ]
11774 result[index] = 1
11775 except:
11776 raise ValueError("%s is not a day" % (t))
11778 return result
11779 </t>
11780 <t tx="michael.20060626133545.5">def _add_to_time_spans(src, to_add, is_free):
11781 if not isinstance(to_add, (tuple, list)):
11782 to_add = (to_add,)
11784 tmp = []
11785 for start, end, f in src:
11786 tmp.append((start, True, f))
11787 tmp.append((end, False, f))
11789 for v in to_add:
11790 if isinstance(v, (tuple, list)):
11791 start = to_datetime(v[0])
11792 end = to_datetime(v[1])
11793 else:
11794 start = to_datetime(v)
11795 end = start.replace(hour=0, minute=0) + datetime.timedelta(1)
11797 tmp.append((start, start &lt;= end, is_free))
11798 tmp.append((end, start &gt; end, is_free))
11800 tmp.sort()
11802 # 0: date
11803 # 1: is_start
11804 # 2: is_free
11805 sequence = []
11806 free_count = 0
11807 work_count = 0
11808 last = None
11809 for date, is_start, is_free in tmp:
11810 if is_start:
11811 if is_free:
11812 if not free_count and not work_count:
11813 last = date
11815 free_count += 1
11816 else:
11817 if not work_count:
11818 if free_count: sequence.append((last, date, True))
11819 last = date
11820 work_count += 1
11821 else:
11822 if is_free:
11823 assert(free_count &gt; 0)
11824 free_count -= 1
11825 if not free_count and not work_count:
11826 sequence.append((last, date, True))
11827 else:
11828 assert(work_count &gt; 0)
11829 work_count -= 1
11830 if not work_count: sequence.append((last, date, False))
11831 if free_count: last = date
11833 return tuple(sequence)
11834 </t>
11835 <t tx="michael.20060626133545.6">def to_timedelta(src, cal=None, is_duration=False):
11837 converts a string to a datetime.timedelta. If cal is specified
11838 it will be used for getting the working times. if is_duration=True
11839 working times will not be considered. Valid units are
11840 d for Days
11841 w for Weeks
11842 m for Months
11843 y for Years
11844 H for Hours
11845 M for Minutes
11848 cal = cal or _default_calendar
11849 if isinstance(src, datetime.timedelta):
11850 return datetime.timedelta(src.days, seconds=src.seconds, calendar=cal)
11852 if isinstance(src, (long, int, float)):
11853 src = "%sM" % str(src)
11855 if not isinstance(src, basestring):
11856 raise ValueError("%s is not a duration" % (repr(src)))
11858 src = src.strip()
11860 if is_duration:
11861 d_p_w = 7
11862 d_p_m = 30
11863 d_p_y = 360
11864 d_w_h = 24
11865 else:
11866 d_p_w = cal.working_days_per_week
11867 d_p_m = cal.working_days_per_month
11868 d_p_y = cal.working_days_per_year
11869 d_w_h = cal.working_hours_per_day
11871 def convert_minutes(minutes):
11872 minutes = int(minutes)
11873 hours = minutes / 60
11874 minutes = minutes % 60
11875 days = hours / d_w_h
11876 hours = hours % d_w_h
11877 return [ days, 0, 0, 0, minutes, hours ]
11879 def convert_days(value):
11880 days = int(value)
11881 value -= days
11882 value *= d_w_h
11883 hours = int(value)
11884 value -= hours
11885 value *= 60
11886 minutes = round(value)
11887 return [ days, 0, 0, 0, minutes, hours ]
11889 sum_args = [ 0, 0, 0, 0, 0, 0 ]
11891 split = src.split(" ")
11892 for s in split:
11893 mo = TIME_DELTA_PATTERN.match(s)
11894 if not mo:
11895 raise ValueError(src +
11896 " is not a valid duration: valid"
11897 " units are: d w m y M H")
11899 unit = mo.group(3)
11900 val = float(mo.group(1))
11902 if unit == 'd':
11903 args = convert_days(val)
11904 elif unit == 'w':
11905 args = convert_days(val * d_p_w)
11906 elif unit == 'm':
11907 args = convert_days(val * d_p_m)
11908 elif unit == 'y':
11909 args = convert_days(val * d_p_y)
11910 elif unit == 'M':
11911 args = convert_minutes(val)
11912 elif unit == 'H':
11913 args = convert_minutes(val * 60)
11915 sum_args = [ a + b for a, b in zip(sum_args, args) ]
11917 sum_args = tuple(sum_args)
11918 return datetime.timedelta(*sum_args)
11919 </t>
11920 <t tx="michael.20060626133545.7">def timedelta_to_str(delta, format, cal=None, is_duration=False):
11921 cal = cal or _default_calendar
11922 if is_duration:
11923 d_p_w = 7
11924 d_p_m = 30
11925 d_p_y = 365
11926 d_w_h = 24
11927 else:
11928 d_p_w = cal.working_days_per_week
11929 d_p_m = cal.working_days_per_month
11930 d_p_y = cal.working_days_per_year
11931 d_w_h = cal.working_hours_per_day
11933 has_years = format.find("%y") &gt; -1
11934 has_minutes = format.find("%M") &gt; -1
11935 has_hours = format.find("%H") &gt; -1 or has_minutes
11936 has_days = format.find("%d") &gt; -1
11937 has_weeks = format.find("%w") &gt; -1
11938 has_months = format.find("%m") &gt; -1
11940 result = format
11941 days = delta.days
11943 d_r = (days, format)
11944 minutes = delta.seconds / 60
11946 def rebase(d_r, cond1, cond2, letter, divisor):
11947 #rebase the days
11948 if not cond1: return d_r
11950 days, result = d_r
11952 if cond2:
11953 val = days / divisor
11954 if not val:
11955 result = re.sub("{[^{]*?%" + letter + "[^}]*?}", "", result)
11957 result = result.replace("%" + letter, str(val))
11958 days %= divisor
11959 else:
11960 result = result.replace("%" + letter,
11961 locale.format("%.2f",
11962 (float(days) / divisor)))
11964 return (days, result)
11966 d_r = rebase(d_r, has_years, has_months or has_weeks or has_days, "y", d_p_y)
11967 d_r = rebase(d_r, has_months, has_weeks or has_days, "m", d_p_m)
11968 d_r = rebase(d_r, has_weeks, has_days, "w", d_p_w)
11969 days, result = d_r
11971 if not has_days:
11972 minutes += days * d_w_h * 60
11973 days = 0
11975 if has_hours:
11976 if not days:
11977 result = re.sub("{[^{]*?%d[^}]*?}", "", result)
11979 result = result.replace("%d", str(days))
11980 else:
11981 result = result.replace("%d",
11982 "%.2f" % (days + float(minutes)
11983 / (d_w_h * 60)))
11985 if has_hours:
11986 if has_minutes:
11987 val = minutes / 60
11988 if not val:
11989 result = re.sub("{[^{]*?%H[^}]*?}", "", result)
11991 result = result.replace("%H", str(val))
11992 minutes %= 60
11993 else:
11994 result = result.replace("%H", "%.2f" % (float(minutes) / 60))
11996 if not minutes:
11997 result = re.sub("{[^{]*?%M[^}]*?}", "", result)
11999 result = result.replace("%M", str(minutes))
12001 result = result.replace("{", "")
12002 result = result.replace("}", "")
12003 return result.strip()
12004 </t>
12005 <t tx="michael.20060626133545.8">class _CalendarItem(int):
12006 &lt;&lt; class _CalendarItem declarations &gt;&gt;
12007 @others
12008 </t>
12009 <t tx="michael.20060626133545.9">__slots__ = ()
12010 calender = None
12013 </t>
12014 <t tx="michael.20060626133545.10">def __new__(cls, val):
12015 try:
12016 return int.__new__(cls, val)
12017 except OverflowError:
12018 return int.__new__(cls, sys.maxint)
12019 </t>
12020 <t tx="michael.20060626133545.11">def round(self, round_up=True):
12021 m_t_u = self.calendar.minimum_time_unit
12023 minutes = int(self)
12024 base = (minutes / m_t_u) * m_t_u
12025 minutes %= m_t_u
12027 round_up = round_up and minutes &gt; 0 or minutes &gt; m_t_u / 2
12028 if round_up: base += m_t_u
12029 return self.__class__(base)
12030 </t>
12031 <t tx="michael.20060626133545.12">class _Minutes(_CalendarItem):
12032 &lt;&lt; class _Minutes declarations &gt;&gt;
12033 @others
12034 </t>
12035 <t tx="michael.20060626133545.13">__slots__ = ()
12036 STR_FORMAT = "{%dd}{ %HH}{ %MM}"
12039 </t>
12040 <t tx="michael.20060626133545.14">def __new__(cls, src=0, is_duration=False):
12042 converts a timedelta in working minutes.
12044 if isinstance(src, cls) or type(src) is int:
12045 return _CalendarItem.__new__(cls, src)
12047 cal = cls.calendar
12048 if not isinstance(src, datetime.timedelta):
12049 src = to_timedelta(src, cal, is_duration)
12051 d_w_h = is_duration and 24 or cal.working_hours_per_day
12052 src = src.days * d_w_h * 60 + src.seconds / 60
12053 return _CalendarItem.__new__(cls, src)
12054 </t>
12055 <t tx="michael.20060626133545.15">def __cmp__(self, other):
12056 return cmp(int(self), int(self.__class__(other)))
12057 </t>
12058 <t tx="michael.20060626133545.16">def __add__(self, other):
12059 try:
12060 return self.__class__(int(self) + int(self.__class__(other)))
12061 except:
12062 return NotImplemented
12063 </t>
12064 <t tx="michael.20060626133545.17">def __sub__(self, other):
12065 try:
12066 return self.__class__(int(self) - int(self.__class__(other)))
12067 except:
12068 return NotImplemented
12069 </t>
12070 <t tx="michael.20060626133545.18">def strftime(self, format=None, is_duration=False):
12071 td = self.to_timedelta(is_duration)
12072 return timedelta_to_str(td, format or self.STR_FORMAT,
12073 self.calendar, is_duration)</t>
12074 <t tx="michael.20060626133545.19">class _WorkingDateBase(_CalendarItem):
12076 A daytetime which has only valid values within the
12077 workingtimes of a specific calendar
12079 &lt;&lt; class _WorkingDateBase declarations &gt;&gt;
12080 @others
12081 </t>
12082 <t tx="michael.20060626133545.20">timetuple = True
12083 STR_FORMAT = "%x %H:%M"
12084 _minutes = _Minutes
12085 __slots__ = ()
12088 </t>
12089 <t tx="michael.20060626133545.21">def __new__(cls, src):
12090 #cls.__bases__[0] is the base of
12091 #the calendar specific StartDate and EndDate
12093 if isinstance(src, cls.__bases__[0]) or type(src) in (int, float):
12094 return _CalendarItem.__new__(cls, src)
12096 src = cls.calendar.from_datetime(to_datetime(src))
12097 return _CalendarItem.__new__(cls, src)
12098 </t>
12099 <t tx="michael.20060626133545.22">def __repr__(self):
12100 return self.strftime()
12101 </t>
12102 <t tx="michael.20060626133545.23">def to_datetime(self):
12103 return self.to_starttime()
12104 </t>
12105 <t tx="michael.20060626133545.24">def to_starttime(self):
12106 return self.calendar.to_starttime(self)
12107 </t>
12108 <t tx="michael.20060626133545.25">def to_endtime(self):
12109 return self.calendar.to_endtime(self)
12110 </t>
12111 <t tx="michael.20060626133545.26">def __cmp__(self, other):
12112 return cmp(int(self), int(self.__class__(other)))
12113 </t>
12114 <t tx="michael.20060626133545.27">def __add__(self, other):
12115 try:
12116 return self.__class__(int(self) + int(self._minutes(other)))
12117 except ValueError, e:
12118 raise e
12119 except:
12120 return NotImplemented
12121 </t>
12122 <t tx="michael.20060626133545.28">def __sub__(self, other):
12123 if isinstance(other, (datetime.timedelta, str, _Minutes)):
12124 try:
12125 other = self._minutes(other)
12126 except:
12127 pass
12129 if isinstance(other, self._minutes):
12130 return self.__class__(int(self) - int(other))
12132 try:
12133 return self._minutes(int(self) - int(self.__class__(other)))
12134 except:
12135 return NotImplemented
12136 </t>
12137 <t tx="michael.20060626133545.29">def strftime(self, format=None):
12138 return strftime(self.to_datetime(), format or self.STR_FORMAT)
12139 </t>
12140 <t tx="michael.20060626133545.30">class Calendar(object):
12142 A calendar to specify working times and vacations.
12143 The calendars epoch start at 1.1.1979
12145 &lt;&lt; declarations &gt;&gt;
12146 @others
12149 _default_calendar = Calendar()
12151 WorkingDate = _default_calendar.WorkingDate
12152 StartDate = _default_calendar.StartDate
12153 EndDate = _default_calendar.EndDate
12154 Minutes = _default_calendar.Minutes
12155 </t>
12156 <t tx="michael.20060626133545.31"># january the first must be a monday
12157 EPOCH = datetime.datetime(1979, 1, 1)
12158 minimum_time_unit = DEFAULT_MINIMUM_TIME_UNIT
12159 working_days_per_week = DEFAULT_WORKING_DAYS_PER_WEEK
12160 working_days_per_month = DEFAULT_WORKING_DAYS_PER_MONTH
12161 working_days_per_year = DEFAULT_WORKING_DAYS_PER_YEAR
12162 working_hours_per_day = DEFAULT_WORKING_HOURS_PER_DAY
12163 now = EPOCH
12166 </t>
12167 <t tx="michael.20060626133545.32">def __init__(self):
12168 self.time_spans = ()
12169 self._dt_num_can = ()
12170 self._num_dt_can = ()
12171 self.working_times = { }
12172 self._recalc_working_time()
12173 self._make_classes()
12174 </t>
12175 <t tx="michael.20060626133545.33">def set_working_days(self, day_range, trange, *further_tranges):
12177 Sets the working days of an calendar
12178 day_range is a string of day abbreviations like 'mon, tue'
12179 trange and further_tranges is a time range string like
12180 '8:00-10:00'
12182 time_ranges = [ trange ] + list(further_tranges)
12183 time_ranges = filter(bool, map(to_time_range, time_ranges))
12184 days = _to_days(day_range)
12186 for k in days.keys():
12187 self.working_times[k] = time_ranges
12189 self._recalc_working_time()
12190 self._build_mapping()
12191 </t>
12192 <t tx="michael.20060626133545.34">def set_vacation(self, value):
12194 Sets vacation time.
12195 value is either a datetime literal or
12196 a sequence of items that can be
12197 a datetime literals and or pair of datetime literals
12199 self.time_spans = _add_to_time_spans(self.time_spans, value, True)
12200 self._build_mapping()
12201 </t>
12202 <t tx="michael.20060626133545.35">def set_extra_work(self, value):
12204 Sets extra working time
12205 value is either a datetime literal or
12206 a sequence of items that can be
12207 a datetime literals and or pair of datetime literals
12209 self.time_spans = _add_to_time_spans(self.time_spans, value, False)
12210 self._build_mapping()
12211 </t>
12212 <t tx="michael.20060626133545.36">def _build_mapping(self):
12213 self._dt_num_can = self._num_dt_can = ()
12214 dt_num_can = []
12215 num_dt_can = []
12217 delta = self.Minutes()
12218 for start, end, is_free in self.time_spans:
12219 cstart = self.StartDate(start)
12220 cend = self.EndDate(end)
12221 nstart = cstart + delta
12223 if not is_free:
12224 d = end - start
12225 d = d.days * 24 * 60 + d.seconds / 60
12226 nend = nstart + d
12227 else:
12228 nend = nstart
12230 delta += (nend - nstart) - (cend - cstart)
12231 dt_num_can.append((start, end, nstart, nend, cend))
12232 num_dt_can.append((nstart, nend, start, end, cend))
12234 self._dt_num_can = tuple(dt_num_can)
12235 self._num_dt_can = tuple(num_dt_can)
12236 </t>
12237 <t tx="michael.20060626133545.37">def from_datetime(self, value):
12238 assert(isinstance(value, datetime.datetime))
12240 delta = value - self.EPOCH
12241 days = delta.days
12242 minutes = delta.seconds / 60
12244 #calculate the weektime
12245 weeks = days / 7
12246 wtime = self.week_time * weeks
12248 #calculate the daytime
12249 days %= 7
12250 dtime = sum(self.day_times[:days])
12252 #calculate the minute time
12253 slots = self.working_times.get(days, DEFAULT_WORKING_DAYS[days])
12254 mtime = 0
12255 for start, end in slots:
12256 if minutes &gt; end:
12257 mtime += end - start
12258 else:
12259 if minutes &gt; start:
12260 mtime += minutes - start
12261 break
12263 result = wtime + dtime + mtime
12265 #map exceptional timespans
12266 dt_num_can = self._dt_num_can
12267 pos = bisect.bisect(dt_num_can, (value,)) - 1
12268 if pos &gt;= 0:
12269 start, end, nstart, nend, cend = dt_num_can[pos]
12270 if value &lt; end:
12271 if nstart &lt; nend:
12272 delta = value - start
12273 delta = delta.days * 24 * 60 + delta.seconds / 60
12274 result = nstart + delta
12275 else:
12276 result = nstart
12277 else:
12278 result += (nend - cend) # == (result - cend) + nend
12280 return result
12281 </t>
12282 <t tx="michael.20060626133545.38">def split_time(self, value):
12283 #map exceptional timespans
12284 num_dt_can = self._num_dt_can
12285 pos = bisect.bisect(num_dt_can, (value, sys.maxint)) - 1
12286 if pos &gt;= 0:
12287 nstart, nend, start, end, cend = num_dt_can[pos]
12288 if value &lt; nend:
12289 value = start + datetime.timedelta(minutes=value - nstart)
12290 delta = value - self.EPOCH
12291 return delta.days / 7, delta.days % 7, delta.seconds / 60, -1
12292 else:
12293 value += (cend - nend) # (value - nend + cend)
12295 #calculate the weeks since the epoch
12296 weeks = value / self.week_time
12297 value %= self.week_time
12299 #calculate the remaining days
12300 days = 0
12301 for day_time in self.day_times:
12302 if value &lt; day_time: break
12303 value -= day_time
12304 days += 1
12306 #calculate the remaining minutes
12307 minutes = 0
12308 slots = self.working_times.get(days, DEFAULT_WORKING_DAYS[days])
12309 index = 0
12310 for start, end in slots:
12311 delta = end - start
12312 if delta &gt; value:
12313 minutes = start + value
12314 break
12315 else:
12316 value -= delta
12318 index += 1
12320 return weeks, days, minutes, index
12321 </t>
12322 <t tx="michael.20060626133545.39">def to_starttime(self, value):
12323 weeks, days, minutes, index = self.split_time(value)
12324 return self.EPOCH + datetime.timedelta(weeks=weeks,
12325 days=days,
12326 minutes=minutes)
12327 </t>
12328 <t tx="michael.20060626133545.40">def to_endtime(self, value):
12329 return self.to_starttime(value - 1) + datetime.timedelta(minutes=1)
12330 </t>
12331 <t tx="michael.20060626133545.41">def get_working_times(self, day):
12332 return self.working_times.get(day, DEFAULT_WORKING_DAYS[day])
12333 </t>
12334 <t tx="michael.20060626133545.42">def _recalc_working_time(self):
12335 def slot_sum_time(day):
12336 slots = self.working_times.get(day, DEFAULT_WORKING_DAYS[day])
12337 return sum(map(lambda slot: slot[1] - slot[0], slots))
12339 self.day_times = map(slot_sum_time, range(0, 7))
12340 self.week_time = sum(self.day_times)
12341 </t>
12342 <t tx="michael.20060626133545.43">def _make_classes(self):
12343 #ensure that the clases are instance specific
12344 class minutes(_Minutes):
12345 calendar = self
12346 __slots__ = ()
12348 class db(_WorkingDateBase):
12349 calendar = self
12350 _minutes = minutes
12351 __slots__ = ()
12353 class wdt(db): __slots__ = ()
12354 class edt(db):
12355 __slots__ = ()
12357 def to_datetime(self):
12358 return self.to_endtime()
12360 self.Minutes, self.StartDate, self.EndDate = minutes, wdt, edt
12361 self.WorkingDate = self.StartDate
12362 </t>
12363 <t tx="michael.20060626133839">def to_timedelta(self, is_duration=False):
12364 d_w_h = is_duration and 24 or self.calendar.working_hours_per_day
12365 minutes = int(self)
12366 hours = minutes / 60
12367 minutes = minutes % 60
12368 days = hours / d_w_h
12369 hours = hours % d_w_h
12370 return datetime.timedelta(days, hours=hours, minutes=minutes)</t>
12371 <t tx="michael.20060626184639">def traceback(self, exc, tb, string_replacement=("&lt;string&gt;", 1)):
12372 tb = traceback.extract_tb(tb)
12373 tb.reverse()
12375 print &gt;&gt; sys.stderr, "%s: %s" % (exc.__class__.__name__, str(exc))
12376 for t in tb:
12377 filename, line = t[:2]
12378 if filename == "&lt;string&gt;":
12379 filename, line = string_replacement
12381 if is_project_file(filename, self.main_buffer.path)\
12382 or _faces._DEBUGGING:
12383 print &gt;&gt; sys.stderr, '\tFile "%s", line %i' % (filename, line)
12384 </t>
12385 <t tx="michael.20060627100623"></t>
12386 <t tx="michael.20060627124836">class RefDate(db.Model):
12388 A date that can refer to other tasks
12390 fixed = db.DateTime(none=True)
12392 @others</t>
12393 <t tx="michael.20060627124836.1">class Predecessor(db.Model):
12394 path = db.Text()
12395 relative = db.Boolean(default=False)
12396 lag = db.Text()
12397 ptype = db.Enumerate({ "end" : "end" , "start" : "start" },
12398 default="end")
12399 all_paths = []
12401 @others
12403 db.Relation("refdate_predecessor",
12404 db.End(Predecessor, "preds", multi='*'),
12405 db.End(RefDate))</t>
12406 <t tx="michael.20060627125048">class RefDateView(views.FormView):
12407 __model__ = RefDate
12408 __view_name__ = "default"
12409 vgap = 0
12410 format = _("""
12411 fixed
12412 (0,3)
12413 [Predecessors:]
12414 predecessors&gt;
12415 (0,3)
12416 delete
12417 """)
12419 @others
12420 </t>
12421 <t tx="michael.20060627125048.1">class PredecessorGrid(grid.EditGrid, views.GridView):
12422 __model__ = Predecessor
12423 columns = (("path(auto_tree)", _("Path")),
12424 (Predecessor.relative, _("Relative")),
12425 (Predecessor.lag, _("Lag")),
12426 (Predecessor.ptype, _("Type")))
12427 resize_col = 0
12430 def create_paths(self, code_item):
12431 root = get_code_root(code_item)
12432 self.all_paths = all_paths = [ "root" ]
12434 def add_path(item, prefix):
12435 if item.name[0] == "_": return
12436 prefix = "%s.%s" % (prefix, item.name)
12437 all_paths.append(prefix)
12438 map(lambda c: add_path(c, prefix), item.get_children())
12440 map(lambda c: add_path(c, "root"), root.get_children())
12442 length = all_paths and max(map(len, all_paths)) or 1
12443 self.set_width(0, "N" * length + "XXX")
12447 def prepare(self, attribute):
12448 if attribute == "path":
12449 self.path.fill_tree(self.all_paths)
12455 </t>
12456 <t tx="michael.20060627125439">def __init__(self, code_item, attrib, value):
12457 super(RefDate, self).__init__()
12458 self.code_item = code_item
12459 self.item_path = editor.get_code_item_path(code_item)
12461 &lt;&lt; define path_argument &gt;&gt;
12463 def is_predecessor(obj):
12464 return isinstance(obj, AttributeWrapper) and obj.attrib in ("start", "end")
12466 def parse_value(value):
12467 if isinstance(value, tuple):
12468 operand = value[0]
12469 if operand == max:
12470 map(parse_value, value[1:])
12471 return
12472 &lt;&lt; add predecessor with lag &gt;&gt;
12474 if is_predecessor(value):
12475 &lt;&lt; add predecessor without lag &gt;&gt;
12477 if isinstance(value, (basestring, datetime.datetime)):
12478 &lt;&lt; set fixed date &gt;&gt;
12480 self.fixed = None
12481 parse_value(ftask._val(value))
12484 </t>
12485 <t tx="michael.20060627150618">def create_controls(self):
12486 self.predecessors = self.get_control("preds(PredecessorGrid)")
12487 self.delete = self.predecessors.get_delete_button(self)</t>
12488 <t tx="michael.20060627150618.1">def prepare(self):
12489 self.grow_col(0)
12490 self.grow_row(3)</t>
12491 <t tx="michael.20060627150618.2">def constitute(self, imodel):
12492 super(RefDateView, self).constitute(imodel)
12493 self.predecessors.create_paths(imodel.code_item)
12494 self.layout()
12495 </t>
12496 <t tx="michael.20060627153216">class AttributeWrapper(object):
12497 def __init__(self, path, attrib):
12498 self.path = path
12499 self.attrib = attrib
12501 def __str__(self):
12502 return "%s.%s" % (str(self.path), self.attrib)</t>
12503 <t tx="michael.20060627153941">me = PathWrapper(context.code_item, "me")
12504 up = me.up
12505 root = me.root
12506 up._path_str = "up"
12507 root._path_str = "root"</t>
12508 <t tx="michael.20060627153941.1">def to_value_wrapper(a):
12509 if isinstance(a, ValueWrapper):
12510 return a
12512 return ValueWrapper(a, [])
12514 def wmax(*args):
12515 args = map(to_value_wrapper, args)
12516 first = args[0]
12517 return first._vw(max, *args)
12519 def wmin(*args):
12520 args = map(to_value_wrapper, args)
12521 first = args[0]
12522 return first._vw(min, *args)</t>
12523 <t tx="michael.20060627172634">sign = { operator.add : "+", operator.sub : "-" }.get(value[0])
12524 if not sign: return
12526 pred = None
12527 lag = None
12528 for v in value[1:]:
12529 if is_predecessor(v):
12530 pred = v
12531 elif isinstance(v, basestring):
12532 lag = v
12534 if pred:
12535 self.preds.insert(Predecessor(lag=sign+lag,
12536 ptype=pred.attrib,
12537 **path_argument(pred.path)))
12539 return</t>
12540 <t tx="michael.20060627172805">self.preds.insert(Predecessor(value=value.attrib,
12541 **path_argument(value.path)))
12542 return</t>
12543 <t tx="michael.20060627172805.1">try:
12544 self.fixed = pcalendar.to_datetime(value)
12545 except ValueError:
12546 pass
12547 return</t>
12548 <t tx="michael.20060628145509">def button_refresh(self):
12549 if self.save():
12550 self.GetParent().EndModal(wx.ID_OK)
12551 self.imodel.realize()
12552 controller().session.menu_recalc()</t>
12553 <t tx="michael.20060628145509.1">def get_stock_control(self, parent, name):
12554 if name == "btn_refresh":
12555 parent.btn_refresh = wx.Button(parent, wx.ID_REFRESH)
12556 parent.btn_refresh.Bind(wx.EVT_BUTTON, lambda ev: self.button_refresh())
12557 parent.btn_refresh.SetDefault()
12558 self.set_default_item(parent.btn_refresh)
12559 return parent.btn_refresh
12561 ctrl = super(MainView, self).get_stock_control(parent, name)
12562 if name == "btn_ok" and not hasattr(parent, "btn_refresh"):
12563 ctrl.SetDefault()
12564 self.set_default_item(ctrl)
12566 return ctrl</t>
12567 <t tx="michael.20060628221243">def check_constraints(self):
12568 error = db.ConstraintError()
12569 if not self.path:
12570 error.message["path"] = _("you have to sperciy a path")
12572 if self.lag:
12573 lag = self.lag.replace("+", "").replace("-", "")
12575 try:
12576 val = pcalendar.to_timedelta(self.lag)
12577 except Exception:
12578 error.message["lag"] = _("not a valid time delta")
12580 if error.message:
12581 raise error</t>
12582 <t tx="michael.20060628221722">def __str__(self):
12583 preds = [ p.to_string(self.item_path) for p in self.preds ]
12584 if self.fixed:
12585 preds.append(self.fixed.strftime('"%x %H:%M"'))
12587 if len(preds) &gt; 1:
12588 return "max(%s)" % ", ".join(preds)
12589 else:
12590 return "".join(preds)</t>
12591 <t tx="michael.20060628221746">def to_string(self, item_path):
12592 path = self.path
12593 if self.relative:
12594 path = ftask.create_relative_path(item_path, path)
12596 result = "%s.%s" % (path, self.ptype)
12597 if self.lag:
12598 if self.lag[0] in ("+", "-"):
12599 result += ' %s "%s"' % (self.lag[0], self.lag[1:])
12600 else:
12601 result += ' + "%s"' % self.lag
12603 return result</t>
12604 <t tx="michael.20060628231054">def replace_expression(self, text, start_line=None, with_end=False, move_cursor=True):
12605 self.BeginUndoAction()
12607 start, end = self.get_expression_range(start_line, with_end)
12608 start_line = self.LineFromPosition(start)
12609 start_indent = self.GetLineIndentation(start_line)
12611 if start &lt; end:
12612 self.SetTargetStart(start)
12613 self.SetTargetEnd(end)
12614 self.ReplaceTarget(text)
12615 else:
12616 self.InsertText(start, text)
12618 if move_cursor: self.GotoPos(start + len(text))
12620 lines = text.split("\n")
12621 &lt;&lt; auto indent text &gt;&gt;
12622 self.EndUndoAction()
12623 self.check_code_updates(start_line, line)
12624 </t>
12625 <t tx="michael.20060629005237">try:
12626 module = sys.modules[m]
12627 except KeyError: continue
12629 try:
12630 module.faces_clean_up()
12631 except AttributeError: pass
12633 del sys.modules[m]</t>
12634 <t tx="michael.20060703170652">self.__change_count += 1
12635 if self.__change_count &gt;= 50:
12636 self.model.save_backup()
12637 self.__change_count = 0</t>
12638 <t tx="michael.20060703173400"></t>
12639 <t tx="michael.20060703173400.1"></t>
12640 <t tx="michael.20060703173400.2"></t>
12641 <t tx="michael.20060703173400.3"></t>
12642 <t tx="michael.20060703173400.4"></t>
12643 <t tx="michael.20060703173400.5"></t>
12644 <t tx="michael.20060703173916">@language python
12645 &lt;&lt; Copyright &gt;&gt;
12647 A special axes for faces charts
12649 &lt;&lt; Imports &gt;&gt;
12650 @others
12651 </t>
12652 <t tx="michael.20060703173916.1">import matplotlib.axes as axes
12653 import matplotlib.artist as artist
12654 import matplotlib.transforms as mtrans
12655 import matplotlib.ticker as ticker
12656 import matplotlib._image as mimage
12657 import matplotlib.font_manager as font
12658 import widgets
12659 import sys
12660 import tools
12661 import patches
12662 import renderer as prend
12663 import math
12666 </t>
12667 <t tx="michael.20060703173916.3">def _cint(val): return int(math.ceil(val))
12668 </t>
12669 <t tx="michael.20060703173916.4">def cut_canvas(axes, reset=False):
12670 try:
12671 bbox = axes.content_bbox
12672 except AttributeError:
12673 bbox = axes.bbox
12675 try:
12676 if not reset and axes._last_viewbounds != bbox.get_bounds():
12677 #when the size has changed, don't scale
12678 old_bbox = mtrans.lbwh_to_bbox(*axes._last_viewbounds)
12679 trans = mtrans.get_bbox_transform(axes.viewLim, old_bbox)
12680 data_box = mtrans.inverse_transform_bbox(trans, bbox)
12681 xmin = axes.viewLim.xmin()
12682 ymax = axes.viewLim.ymax()
12684 if not axes._sharey:
12685 axes.set_ylim(ymax - data_box.height(), ymax, emit=True)
12687 if not axes._sharex:
12688 axes.set_xlim(xmin, xmin + data_box.width(), emit=True)
12689 except AttributeError:
12690 pass
12692 axes._last_viewbounds = bbox.get_bounds()
12693 </t>
12694 <t tx="michael.20060703173916.5">
12697 class _WidgetCollection(artist.Artist):
12698 &lt;&lt; class _WidgetCollection declarations &gt;&gt;
12699 @others
12700 </t>
12701 <t tx="michael.20060703173916.6"># a dummy to avoid a complete rewrite of axes draw
12702 zorder = -1
12704 </t>
12705 <t tx="michael.20060703173916.7">def __init__(self, draw_forward):
12706 artist.Artist.__init__(self)
12707 self.draw_forward = draw_forward
12708 </t>
12709 <t tx="michael.20060703173916.8">def draw(self, renderer):
12710 if self.get_visible():
12711 self.draw_forward(renderer)
12712 </t>
12713 <t tx="michael.20060703173916.9"> #time_it(self.draw_forward, renderer)
12717 def _get_margin(name, kwargs):
12718 margin = kwargs.get(name + "_margin")
12719 if margin is not None:
12720 del kwargs[name + "_margin"]
12721 else:
12722 margin = mtrans.Value(0)
12724 return margin
12725 </t>
12726 <t tx="michael.20060703173916.10">class MarginAxes(axes.Axes):
12728 An axes with a title bar inside the axes
12730 @others
12731 </t>
12732 <t tx="michael.20060703173916.11">def __init__(self, *args, **kwargs):
12733 self.top_margin = _get_margin("top", kwargs)
12734 self.bottom_margin = _get_margin("bottom", kwargs)
12735 self.left_margin = _get_margin("left", kwargs)
12736 self.right_margin = _get_margin("right", kwargs)
12737 axes.Axes.__init__(self, *args, **kwargs)
12738 </t>
12739 <t tx="michael.20060703173916.12">def build_margin_transform(self, left=True, bottom=True,
12740 right=True, top=True):
12741 Bbox = mtrans.Bbox
12742 Point = mtrans.Point
12743 get_bbox_transform = mtrans.get_bbox_transform
12745 if left:
12746 left_margin = self.left_margin * self.fig_point_to_pixel
12747 left = self.bbox.ll().x() + left_margin
12748 else:
12749 left = self.bbox.ll().x()
12751 if right:
12752 right_margin = self.right_margin * self.fig_point_to_pixel
12753 right = self.bbox.ur().x() - right_margin
12754 else:
12755 right = self.bbox.ur().x()
12757 if top:
12758 top_margin = self.top_margin * self.fig_point_to_pixel
12759 top = self.bbox.ur().y() - top_margin
12760 else:
12761 top = self.bbox.ur().y()
12763 if bottom:
12764 bottom_margin = self.bottom_margin * self.fig_point_to_pixel
12765 bottom = self.bbox.ll().y() + bottom_margin
12766 else:
12767 bottom = self.bbox.ll().y()
12769 bbox = Bbox(Point(left, bottom), Point(right, top))
12771 transform = get_bbox_transform(self.viewLim, bbox)
12772 transform.set_funcx(self.transData.get_funcx())
12773 transform.set_funcy(self.transData.get_funcy())
12774 return transform
12775 </t>
12776 <t tx="michael.20060703173916.13">def _set_lim_and_transforms(self):
12777 axes.Axes._set_lim_and_transforms(self)
12778 self.fig_point_to_pixel = self.get_figure().dpi / mtrans.Value(72)
12780 self.org_transData = self.transData
12781 self.org_transAxes = self.transAxes
12783 self.transData = self.build_margin_transform()
12784 self.content_bbox = self.transData.get_bbox2()
12785 #self.content_bbox is self.bbox reduced by the margins
12787 self.transAxes = mtrans.get_bbox_transform(mtrans.unit_bbox(),
12788 self.content_bbox)
12789 </t>
12790 <t tx="michael.20060703173916.14">def in_axes(self, xwin, ywin):
12791 return self.content_bbox.contains(xwin, ywin)
12792 </t>
12793 <t tx="michael.20060703173916.15">def cla(self):
12794 axes.Axes.cla(self)
12795 self.axesPatch.set_transform(self.org_transAxes)
12796 </t>
12797 <t tx="michael.20060703173916.16">def draw(self, renderer, inframe=False):
12798 axes.Axes.draw(self, renderer, inframe)
12799 if self.axison and self._frameon:
12800 fill = self.axesPatch.get_fill()
12801 self.axesPatch.set_fill(False)
12802 self.axesPatch.draw(renderer)
12803 self.axesPatch.set_fill(fill)
12804 </t>
12805 <t tx="michael.20060703173916.17">class WidgetAxes(MarginAxes):
12807 An axes which is optimized to display widgets.
12808 If widgets are not inside the current view they will not
12809 be drawn.
12811 @others
12812 </t>
12813 <t tx="michael.20060703173916.18">def __init__(self, *args, **kwargs):
12814 self._first_draw = True
12815 self._fobj_map = {}
12816 self.widgets = []
12817 self._visible_widgets = []
12818 self.widget_artist = _WidgetCollection(self._draw_widgets)
12819 MarginAxes.__init__(self, *args, **kwargs)
12820 </t>
12821 <t tx="michael.20060703173916.19">def cla(self):
12822 MarginAxes.cla(self)
12824 self.dataLim.intervalx().set_bounds(sys.maxint, -sys.maxint)
12825 self.dataLim.intervaly().set_bounds(sys.maxint, -sys.maxint)
12826 self._fobj_map.clear()
12827 self.widgets = []
12828 self.marker = patches.Rectangle((0,0), 0, 0)
12829 self.marker.widget = None
12830 self.marker.set_visible(False)
12831 self.add_artist(self.marker)
12832 self.marker.set_clip_box(self.content_bbox)
12833 self.xaxis.set_major_locator(ticker.NullLocator())
12834 self.xaxis.set_minor_locator(ticker.NullLocator())
12835 self.yaxis.set_major_locator(ticker.NullLocator())
12836 self.yaxis.set_minor_locator(ticker.NullLocator())
12837 self.reset_limits()
12838 self.add_collection(self.widget_artist)
12839 </t>
12840 <t tx="michael.20060703173916.20">def check_limits(self, cut=True):
12842 Changes the viewLimits to reasonable values
12844 if cut: cut_canvas(self)
12845 </t>
12846 <t tx="michael.20060703173916.21">def reset_limits(self, cut=True):
12848 Sets the data width and data size to the default values.
12849 e.g. reset the y axis to display the fonts in the original size
12851 self.check_limits(cut)
12852 vmin, vmax = self.get_ylim()
12853 height = self.content_bbox.height() / self.fig_point_to_pixel.get()
12854 self.set_ylim(vmax - height, vmax, emit=True)
12855 </t>
12856 <t tx="michael.20060703173916.22">def _get_renderer(self):
12857 if not self._cachedRenderer:
12858 Renderer = prend.PatchedRendererAgg
12859 self._cachedRenderer = Renderer(10, 10, self.get_figure().dpi)
12861 return self._cachedRenderer
12862 </t>
12863 <t tx="michael.20060703173916.23">def add_widget(self, widget):
12864 if widget.fobj:
12865 idendity = widget.fobj._idendity_()
12866 self._fobj_map.setdefault(idendity, []).append(widget)
12868 self.widgets.append(widget)
12869 widget.axes = self
12870 widget.set_figure(self.figure)
12871 widget.set_clip_box(self.content_bbox)
12872 widget.set_transform(self.transData)
12874 tools.HSEP.set(5)
12875 horz, vert = widget.prepare_draw(self._get_renderer(),
12876 self.point_to_pixel,
12877 self.fig_point_to_pixel)
12878 #update data lim
12879 if horz:
12880 set_bounds = self.dataLim.intervalx().set_bounds
12881 set_bounds(min(widget.bbox.xmin(), self.dataLim.xmin()),
12882 max(widget.bbox.xmax(), self.dataLim.xmax()))
12885 if vert:
12886 set_bounds = self.dataLim.intervaly().set_bounds
12887 extra = tools.VSEP.get() * 4
12888 set_bounds(min(widget.bbox.ymin() - extra, self.dataLim.ymin()), 0)
12890 </t>
12891 <t tx="michael.20060703173916.24">def mark_widget(self, widget=None):
12892 ow = self.marker.widget
12893 self.marker.widget = widget
12894 if not widget: self.marker.set_visible(False)
12895 return ow != widget
12896 </t>
12897 <t tx="michael.20060703173916.25">def find_widget(self, fobj):
12898 if fobj is str:
12899 return self._fobj_map.get(fobj)
12901 idendity = fobj._idendity_()
12902 widgets = self._fobj_map.get(idendity, ())
12904 #first try to find visible widgets
12905 identicals = filter(lambda w: w.fobj is fobj, widgets)
12906 for w in identicals:
12907 if w in self._visible_widgets: return w
12909 if identicals: return identicals[0]
12911 for w in widgets:
12912 if w in self._visible_widgets: return w
12914 return widgets and widgets[0] or None
12915 </t>
12916 <t tx="michael.20060703173916.26">def widget_at(self, x, y):
12917 self._calc_hsep()
12918 found = filter(lambda w: w.contains(x, y), self._visible_widgets)
12919 if found: return found[-1]
12920 return None
12921 </t>
12922 <t tx="michael.20060703173916.27">def set_focused_on(self):
12923 self.marker.update(self.focused_props)
12924 </t>
12925 <t tx="michael.20060703173916.28">def set_focused_off(self):
12926 self.marker.update(self.marker_props)
12927 </t>
12928 <t tx="michael.20060703173916.29">def set_marker(self, focused_props, normal_props):
12929 self.focused_props = focused_props
12930 self.marker_props = normal_props
12931 self.marker.update(normal_props)
12932 </t>
12933 <t tx="michael.20060703173916.30">def widget_x_visible(self, widget):
12934 self._calc_hsep()
12935 bbox = widget.get_bounds(self._get_renderer())
12936 xmin, xmax = self.get_xlim()
12937 width = xmax - xmin
12938 wxmin, wxmax = bbox.intervalx().get_bounds()
12939 wwidth = wxmax - wxmin
12941 vwidth = min(wwidth, width)
12943 if wxmax &lt;= xmin + vwidth:
12944 xmin = wxmax - vwidth
12945 xmax = xmin + width
12947 if wxmin &gt;= xmax - vwidth:
12948 xmax = wxmin + vwidth
12949 xmin = xmax - width
12951 self.set_xlim(xmin, xmax)
12952 </t>
12953 <t tx="michael.20060703173916.31">def widget_y_visible(self, widget):
12954 ymin, ymax = self.get_ylim()
12955 height = ymax - ymin
12956 wymin, wymax = widget.bbox.intervaly().get_bounds()
12957 if wymax &lt;= ymin + height / 2:
12958 ymin = wymax - height / 2
12959 ymax = ymin + height
12961 if wymin &gt;= ymax - height / 2:
12962 ymax = wymin + height / 2
12963 ymin = ymax - height
12965 self.set_ylim(ymin, ymax)
12966 </t>
12967 <t tx="michael.20060703173916.32">def zoomx(self, numsteps):
12968 MarginAxes.zoomx(self, numsteps)
12969 if self.marker.get_visible():
12970 self.widget_x_visible(self.marker.widget)
12971 self.widget_y_visible(self.marker.widget)
12972 </t>
12973 <t tx="michael.20060703173916.33">def zoomy(self, numsteps):
12974 MarginAxes.zoomy(self, numsteps)
12976 if self.marker.get_visible():
12977 self.widget_x_visible(self.marker.widget)
12978 self.widget_y_visible(self.marker.widget)
12980 </t>
12981 <t tx="michael.20060703173916.34">def _calc_hsep(self):
12982 trans = self.transData
12983 vsep = tools.VSEP.get() * self.point_to_pixel.get()
12984 origin = trans.inverse_xy_tup((0, 0))
12985 seps = trans.inverse_xy_tup((vsep, vsep))
12986 tools.HSEP.set(seps[0] - origin[0])
12987 </t>
12988 <t tx="michael.20060703173916.35">def _draw_widgets(self, renderer):
12989 trans = self.transData
12990 data_box = mtrans.inverse_transform_bbox(trans, self.content_bbox)
12991 self._calc_hsep()
12993 if self._speed_cache:
12994 l, b, w, h = self._speed_bbox.get_bounds()
12995 l, b = self.transData.xy_tup((l, b))
12996 renderer.draw_image(l, b, self._speed_cache, self.content_bbox)
12998 for w in self.widgets:
12999 if isinstance(w, (widgets.Row, widgets.Column)):
13000 w.draw(renderer, data_box)
13002 self._visible_widgets = self.widgets
13003 else:
13004 self._visible_widgets = [ w for w in self.widgets
13005 if w.draw(renderer, data_box) ]
13007 #print "widgets drawn", len(self._visible_widgets)
13008 if self.marker.widget:
13009 if self.marker.widget.overlaps(data_box):
13010 bbox = self.marker.widget.bbox
13011 self.marker.set_bounds(*bbox.get_bounds())
13012 self.marker.set_visible(True)
13013 else:
13014 self.marker.set_visible(False)
13015 </t>
13016 <t tx="michael.20060703173916.36">def clear_speed_cache(self):
13017 self._speed_cache = None
13018 </t>
13019 <t tx="michael.20060703173916.37">_speed_cache = None
13020 def speed_up(self, max_size):
13021 self._speed_cache = None
13023 if not self.widgets: return
13025 self._calc_hsep()
13026 renderer = self._get_renderer()
13027 all_data = self.dataLim.deepcopy()
13029 xmin = ymin = sys.maxint
13030 xmax = ymax = -sys.maxint
13032 for w in self.widgets:
13033 bounds = w.get_bounds(renderer)
13034 xmin = min(xmin, bounds.xmin())
13035 xmax = max(xmax, bounds.xmax())
13036 ymin = min(ymin, bounds.ymin())
13037 ymax = max(ymax, bounds.ymax())
13039 all_data.intervalx().set_bounds(xmin, xmax)
13040 all_data.intervaly().set_bounds(ymin, ymax)
13042 all_view = mtrans.transform_bbox(self.transData, all_data)
13044 # increase view because of rounding mistakes
13045 xmin, xmax = all_view.intervalx().get_bounds()
13046 ymin, ymax = all_view.intervaly().get_bounds()
13047 all_view.intervalx().set_bounds(xmin - 1, xmax + 1)
13048 all_view.intervaly().set_bounds(ymin - 1, ymax + 1)
13050 if all_view.width() * all_view.height() * 4 &gt; max_size:
13051 return
13053 #adjust all_data to increased all_view
13054 all_data = mtrans.inverse_transform_bbox(self.transData, all_view)
13056 Renderer = prend.SpeedupRenderer
13057 cache = Renderer(_cint(all_view.width()), _cint(all_view.height()),
13058 self.get_figure().dpi)
13061 render_bbox = mtrans.lbwh_to_bbox(0, 0, all_view.width(), all_view.height())
13062 all_trans = mtrans.get_bbox_transform(all_data, render_bbox)
13064 for w in self.widgets:
13065 if isinstance(w, (widgets.Row, widgets.Column)): continue
13066 w.set_transform(all_trans)
13067 w.set_clip_box(render_bbox)
13068 w.draw(cache, all_data)
13069 w.set_transform(self.transData)
13070 w.set_clip_box(self.content_bbox)
13072 self._speed_cache = mimage.frombuffer(cache.buffer_rgba(0, 0),
13073 cache.width, cache.height, 1)
13074 if self._speed_cache:
13075 self._speed_cache.flipud_out()
13076 self._speed_bbox = all_data
13077 </t>
13078 <t tx="michael.20060703173916.38">def draw(self, renderer, inframe=False):
13079 if self._first_draw:
13080 self._first_draw = False
13081 widgets = map(lambda w: (w[1].zorder, w[0], w[1]),
13082 enumerate(self.widgets))
13083 widgets.sort()
13084 self.widgets = map(lambda ziw: ziw[2], widgets)
13086 MarginAxes.draw(self, renderer, inframe)
13087 </t>
13088 <t tx="michael.20060703173916.39">def _set_lim_and_transforms(self):
13089 Bbox = mtrans.Bbox
13090 Point = mtrans.Point
13092 MarginAxes._set_lim_and_transforms(self)
13093 dtop = self.viewLim.ur().y()
13094 dbottom = self.viewLim.ll().y()
13096 vtop = self.content_bbox.ur().y()
13097 vbottom = self.content_bbox.ll().y()
13098 self.point_to_pixel = (vtop - vbottom) / (dtop - dbottom)
13099 cut_canvas(self, True)
13100 </t>
13101 <t tx="michael.20060703173916.40">class PointAxes(WidgetAxes):
13103 An axes which scales x, y proportional to points
13105 @others
13106 </t>
13107 <t tx="michael.20060703173916.41">def __init__(self, *args, **kwargs):
13108 WidgetAxes.__init__(self, *args, **kwargs)
13109 self.zoomx = self.zoomy
13110 </t>
13111 <t tx="michael.20060703173916.42">def cla(self):
13112 WidgetAxes.cla(self)
13113 self.dataLim.intervalx().set_bounds(0, 0)
13114 self.dataLim.intervaly().set_bounds(0, 0)
13115 </t>
13116 <t tx="michael.20060703173916.43">__last_size = (0, 0)
13117 def check_limits(self, cut=True):
13118 WidgetAxes.check_limits(self, cut)
13119 size = (self.viewLim.width(), self.viewLim.height())
13120 if size != self.__last_size:
13121 prop = self.content_bbox.width() / self.content_bbox.height()
13122 pwidth = size[1] * prop
13123 if pwidth != size[0]:
13124 #we have to correct x
13125 size = (pwidth, size[1])
13126 xmin = self.viewLim.xmin()
13127 self.set_xlim(xmin, xmin + pwidth)
13129 self.__last_size = size
13130 </t>
13131 <t tx="michael.20060703173916.44">def autoscale_view(self, cut=True):
13132 if not self._autoscaleon: return
13133 self.check_limits(cut)
13135 width = self.dataLim.width()
13136 height = self.dataLim.height()
13138 prop = self.content_bbox.width() / self.content_bbox.height()
13139 pwidth = height * prop
13141 xmin = self.dataLim.xmin()
13142 ymax = self.dataLim.ymax()
13144 if pwidth &gt; width:
13145 self.set_xlim(xmin, xmin + pwidth)
13146 self.set_ylim(ymax - height, ymax)
13147 else:
13148 self.set_xlim(xmin, xmin + width)
13149 self.set_ylim(ymax - width / prop, ymax)
13151 self.__last_size = (self.viewLim.width(), self.viewLim.height())
13152 </t>
13153 <t tx="michael.20060703173916.45">class TimeAxes(object):
13154 &lt;&lt; class TimeAxes declarations &gt;&gt;
13155 @others
13156 </t>
13157 <t tx="michael.20060703173916.46">time_axis = None
13158 time_scale = None
13161 </t>
13162 <t tx="michael.20060703173916.47">def set_time_axis(self, time_axis):
13163 try:
13164 self.collections.remove(self.time_axis)
13165 except ValueError:
13166 pass
13168 self.time_axis = time_axis
13169 self.add_collection(self.time_axis)
13170 axis_transform = self.build_margin_transform(top=False)
13171 self.time_axis.set_transform(axis_transform)
13172 self.time_axis.set_clip_box(axis_transform.get_bbox2())
13173 self.update_time_axis()
13174 </t>
13175 <t tx="michael.20060703173916.48">def xaxis_timescale(self, time_scale):
13176 self.time_scale = time_scale
13177 self.xaxis.set_major_locator(ticker.NullLocator())
13178 self.xaxis.set_minor_locator(ticker.NullLocator())
13179 </t>
13180 <t tx="michael.20060703173916.49">def set_time_lim(self, xmin=None, xmax=None, emit=False):
13181 xmin = xmin and self.time_scale.to_num(xmin)
13182 xmax = xmax and self.time_scale.to_num(xmax)
13183 self.set_xlim(xmin=xmin, xmax=xmax, emit=emit)
13184 </t>
13185 <t tx="michael.20060703173916.50">def get_time_lim(self):
13186 xmin, xmax = self.get_xlim()
13187 xmin = self.time_scale.to_num(int(xmin))
13188 xmax = self.time_scale.to_num(int(xmax))
13189 return xmin.to_datetime(), xmax.to_datetime()
13190 </t>
13191 <t tx="michael.20060703173916.51">def format_coord(self, x, y):
13192 'return a format string formatting the x, y coord'
13194 if self.time_scale:
13195 xs = self.time_scale.to_num(int(x)).strftime()
13196 else:
13197 xs = self.format_xdata(x)
13199 ys = self.format_ydata(y)
13200 return 'x=%s, y=%s'%(xs,ys)
13201 </t>
13202 <t tx="michael.20060703173916.52">def update_time_axis(self):
13203 ah = self.time_axis \
13204 and self.time_axis.get_visible() \
13205 and self.time_axis.calc_height() or 0
13207 self.top_margin.set(ah)
13208 </t>
13209 <t tx="michael.20060703173916.53">def unshare(self):
13210 self._sharex = None
13211 self._sharey = None
13212 </t>
13213 <t tx="michael.20060703173916.54">class TimePlotAxes(TimeAxes, MarginAxes):
13214 &lt;&lt; class TimePlotAxes declarations &gt;&gt;
13215 @others
13216 </t>
13217 <t tx="michael.20060703173916.55">first_draw = True
13219 </t>
13220 <t tx="michael.20060703173916.56">def __init__(self, *args, **kwargs):
13221 MarginAxes.__init__(self, *args, **kwargs)
13222 </t>
13223 <t tx="michael.20060703173916.57">def draw(self, renderer, inframe=False):
13224 if self.first_draw:
13225 self.first_draw = False
13226 for a in self.lines: a.set_clip_box(self.content_bbox)
13227 for a in self.texts: a.set_clip_box(self.content_bbox)
13228 for a in self.patches: a.set_clip_box(self.content_bbox)
13229 for a in self.artists: a.set_clip_box(self.content_bbox)
13231 MarginAxes.draw(self, renderer, inframe)
13232 cut_canvas(self, True)
13233 </t>
13234 <t tx="michael.20060703173916.58">class TimeWidgetAxes(TimeAxes, WidgetAxes):
13236 An axes wich displays widgets horizontal in time. (e.g. GanttCharts)
13238 &lt;&lt; class TimeWidgetAxes declarations &gt;&gt;
13239 @others
13240 </t>
13241 <t tx="michael.20060703173916.59">auto_scale_y = False
13243 </t>
13244 <t tx="michael.20060703173916.60">def __init__(self, *args, **kwargs):
13245 WidgetAxes.__init__(self, *args, **kwargs)
13246 </t>
13247 <t tx="michael.20060703173916.61">def set_auto_scale_y(self, do_scale=True):
13248 self.auto_scale_y = do_scale
13249 </t>
13250 <t tx="michael.20060703173916.62">def check_limits(self, cut=True):
13251 WidgetAxes.check_limits(self, cut)
13253 vmin, vmax = self.viewLim.intervaly().get_bounds()
13254 if vmax &gt; 0:
13255 self.viewLim.intervaly().set_bounds((vmin - vmax), 0)
13256 </t>
13257 <t tx="michael.20060703173916.63">def autoscale_view(self, cut=True):
13258 if not self._autoscaleon: return
13259 self.check_limits(cut)
13261 all_data = self.dataLim.deepcopy()
13262 reduced = self.content_bbox.deepcopy()
13263 renderer = self._get_renderer()
13265 if self.auto_scale_y:
13266 ymin, ymax = self.dataLim.intervaly().get_bounds()
13267 self.set_ylim(ymin, ymax)
13268 else:
13269 self.reset_limits()
13271 xmin, xmax = self.dataLim.intervalx().get_bounds()
13272 self.set_xlim(xmin, xmax, emit=False)
13273 self._calc_hsep()
13275 #Notice: it is not correct to just get the bounds
13276 #in the actual data coords an set the view limits
13277 #This is because text on the left or right bound
13278 #has always the same pixel width. This means the text witdh
13279 #in data coord changes when the data coord scale changes.
13281 #find out the bounds in actual data coords
13282 for w in self.widgets:
13283 bounds = w.get_bounds(renderer)
13284 xmin = min(xmin, bounds.xmin())
13285 xmax = max(xmax, bounds.xmax())
13287 all_data.intervalx().set_bounds(xmin, xmax)
13289 #the complete bound in pixel coords
13290 all_view = mtrans.transform_bbox(self.transData, all_data)
13291 add_space = 0.08 * self.get_figure().get_dpi() #2mm margin left an right
13293 left_offset = self.content_bbox.xmin() - all_view.xmin() + add_space
13294 right_offset = all_view.xmax() - self.content_bbox.xmax() + add_space
13295 width = self.content_bbox.width()
13297 if left_offset &gt; width / 4: left_offset = width / 4
13298 if right_offset &gt; width / 4: right_offset = width / 4
13300 # scale down the pixel bounds
13301 xmin1 = self.content_bbox.xmin() + left_offset
13302 xmax1 = self.content_bbox.xmax() - right_offset
13303 reduced.intervalx().set_bounds(xmin1, xmax1)
13305 # create a new transformation from scaled down pixel coords to limits
13306 trans = mtrans.get_bbox_transform(reduced, self.viewLim)
13307 data_box = mtrans.transform_bbox(trans, self.content_bbox)
13308 self.set_xlim(data_box.xmin(), data_box.xmax(), emit=True)
13309 cut_canvas(self, True)
13310 </t>
13311 <t tx="michael.20060703173916.64">def widget_at(self, x, y):
13312 return WidgetAxes.widget_at(self, x, y)
13313 </t>
13314 <t tx="michael.20060703181442">
13315 inside_ext = map(extent, self.text_inside)
13316 contains = bb_shape_view.contains
13318 inside = inside_ext[-1]
13319 inside_text = self.text_inside[-1]
13320 outside_text = self.text_inside[0]
13322 mid = (inside.ymin() + inside.ymax()) / 2
13323 if contains(inside.xmin(), mid) and contains(inside.xmax(), mid):
13324 outside_text.set_visible(False)
13325 inside_text.set_visible(True)
13326 else:
13327 outside_text.set_visible(True)
13328 inside_text.set_visible(False)</t>
13329 <t tx="michael.20060703191028">main_module = new.module(module_name)
13330 main_module.__file__ = path
13331 main_module._faces_source_file = path
13332 main_module.__name__ = "__faces_main__"
13333 </t>
13334 <t tx="michael.20060703191028.1">text = self.main_buffer.text
13335 controller().progress_update(2)
13336 code = compile(text, path, "exec")
13337 controller().progress_update(3)
13338 exec code in main_module.__dict__
13339 controller().progress_update(4)</t>
13340 <t tx="michael.20060703211129">new_modules = filter(lambda m: m[0] not in actual_modules and m[1],\
13341 sys.modules.iteritems())
13342 new_modules = dict(new_modules)
13344 def set_module_data(module):
13345 source_file = getsourcefile(module)
13346 if source_file:
13347 module._faces_source_file = source_file
13348 try:
13349 module._faces_modtime = os.stat(source_file)[stat.ST_MTIME]
13350 except OSError:
13351 module._faces_modtime = 0
13353 map(set_module_data, new_modules.values())
13354 self.loaded_modules.update(new_modules)
13356 </t>
13357 <t tx="michael.20060703211129.1">for name, module in self.loaded_modules.iteritems():
13358 try:
13359 mod_time = os.stat(module._faces_source_file)[stat.ST_MTIME]
13360 if mod_time &lt;= module._faces_modtime: continue
13361 except AttributeError: continue
13362 except OSError: continue
13364 try:
13365 module.faces_gui_cleanup()
13366 except AttributeError: pass
13368 try:
13369 del sys.modules[name]
13370 except KeyError: pass</t>
13371 <t tx="michael.20060703212350">for f in files.keys():
13372 try:
13373 ctrl.add_model(PlanBuffer(f), False)
13374 except OSError:
13375 pass</t>
13376 <t tx="michael.20060703212350.1">def get_source_file(module):
13377 try:
13378 path = module._faces_source_file
13379 except AttributeError:
13380 return ""
13382 try:
13383 module._is_source_
13384 return ""
13385 except AttributeError:
13386 pass
13388 if is_project_file(path, self.main_buffer.path):
13389 return path
13391 return ""
13393 files = filter(bool, map(get_source_file, self.loaded_modules.values()))
13394 files = dict(map(lambda f: (f, False), files))</t>
13395 <t tx="michael.20060703233047">@language python
13396 &lt;&lt; Copyright &gt;&gt;
13397 &lt;&lt; Imports &gt;&gt;
13398 _is_source_ = True
13399 @others
13400 </t>
13401 <t tx="michael.20060703233047.1">import wx
13402 import wx.grid
13403 import metapie.navigator as navigator
13404 from metapie.gui import controller
13405 import taskfuncs
13406 import faces.observer
13407 import faces.plocale
13408 import faces.report
13409 import faces.gui.editor.context as context
13410 import matplotlib.colors as colors
13411 import matplotlib.font_manager as font
13412 import weakref
13413 import faces.charting.tools as chart_tools
13414 import metapie.dbtransient as db
13415 import metapie.gui.views as views
13416 import csv
13417 try:
13418 import Cheetah.Template as CHTemplate
13419 import webbrowser
13420 import os.path
13421 import tempfile
13422 import faces.utils as utils
13423 _cheetah_is_installed = True
13424 except ImportError:
13425 _cheetah_is_installed = False
13428 </t>
13429 <t tx="michael.20060703233047.2">def convert_color(color):
13430 color = colors.colorConverter.to_rgb(color)
13431 return map(lambda i: int(i * 255), color)
13432 </t>
13433 <t tx="michael.20060703233047.3">def _report_factory(title, data, model):
13434 return lambda parent: ReportView(parent, data, model, title)</t>
13435 <t tx="michael.20060703233047.4">
13436 faces.observer.factories["report"] = _report_factory
13439 _ = faces.plocale.get_gettext()
13442 _LEFT = 1
13443 _RIGHT = 2
13444 _TOP = 4
13445 _BOTTOM = 8
13446 _DEFAULT = _RIGHT + _BOTTOM
13448 _align_map = { faces.report.Cell.LEFT : wx.ALIGN_LEFT,
13449 faces.report.Cell.RIGHT : wx.ALIGN_RIGHT,
13450 faces.report.Cell.CENTER : wx.ALIGN_CENTER }
13453 class _ErrorReport(faces.report.Report):
13454 &lt;&lt; class _ErrorReport declarations &gt;&gt;
13455 @others
13456 </t>
13457 <t tx="michael.20060703233047.5">data = ("Error in Report",)
13459 </t>
13460 <t tx="michael.20060703233047.6">def make_report(self, data):
13461 for s in data:
13462 yield faces.report.Cell(s)
13463 </t>
13464 <t tx="michael.20060703233047.7">
13466 class CellRenderer(wx.grid.PyGridCellRenderer):
13467 @others
13468 </t>
13469 <t tx="michael.20060703233047.8">def __init__(self, report_view):
13470 wx.grid.PyGridCellRenderer.__init__(self)
13471 self.default = wx.grid.GridCellStringRenderer()
13472 self.report_view = report_view
13473 </t>
13474 <t tx="michael.20060703233047.9">def Draw(self, grid, attr, dc, rect, row, col, isSelected):
13475 self.default.Draw(grid, attr, dc, rect, row, col, isSelected)
13476 dc.SetPen(wx.BLACK_PEN)
13478 border_val = getattr(attr, "border_val", _DEFAULT)
13479 if border_val &amp; _LEFT:
13480 dc.DrawLine(rect.left, rect.top, rect.left, rect.bottom + 1)
13482 if border_val &amp; _TOP:
13483 dc.DrawLine(rect.left, rect.top, rect.right + 1, rect.top)
13485 if border_val &amp; _RIGHT:
13486 dc.DrawLine(rect.right, rect.top, rect.right, rect.bottom + 1)
13488 if border_val &amp; _BOTTOM:
13489 dc.DrawLine(rect.left, rect.bottom, rect.right + 1, rect.bottom)
13490 </t>
13491 <t tx="michael.20060703233047.10">def GetBestSize(self, grid, attr, dc, row, col):
13492 return self.default.GetBestSize(grid, attr, dc, row, col)
13493 </t>
13494 <t tx="michael.20060703233047.11">def Clone(self):
13495 return CellRenderer(self.report_view)
13496 </t>
13497 <t tx="michael.20060703233047.12">
13500 class ReportView(wx.Panel, navigator.View):
13501 @others
13502 </t>
13503 <t tx="michael.20060703233047.13">def __init__(self, parent, report, model, title):
13504 wx.Panel.__init__(self, parent, -1, style=wx.SUNKEN_BORDER)
13505 self.grid = None
13506 self.code_info = {}
13507 self.task_info = {}
13508 self.model = model
13509 self.link_view = True
13510 self.replace_data(report)
13511 self.make_menu()
13512 </t>
13513 <t tx="michael.20060703233047.14">def make_menu(self, popup=False, task=None):
13514 def find_in_source():
13515 self.model.find_in_source(self.report.__class__)
13517 ctrl = controller()
13518 if popup:
13519 report_menu = ctrl.make_menu()
13520 else:
13521 top = ctrl.get_top_menu()
13522 report_menu = top.make_menu(_("&amp;Report"), pos=300)
13524 menu = lambda *args, **kw: report_menu.make_item(self, *args, **kw)
13526 if _cheetah_is_installed:
13527 menu(_("Print Report..."), self.menu_print_report, "print16", pos=100)
13529 menu(_("Export to CSV..."), self.menu_export_csv, "export16", pos=101)
13530 if not popup:
13531 def nav(func):
13532 def function(): self.navigate(func)
13533 return function
13535 menu(_("Move Left\tCTRL-ALT-LEFT"), nav("MoveCursorLeft"), "left16", pos=10)
13536 menu(_("Move Right\tCTRL-ALT-RIGHT"), nav("MoveCursorRight"),
13537 "right16", pos=20)
13538 menu(_("Move Up\tCTRL-ALT-UP"), nav("MoveCursorUp"), "up16", pos=30)
13539 menu(_("Move Down\tCTRL-ALT-DOWN"), nav("MoveCursorDown"), "down16", pos=40)
13541 menu = lambda *args, **kw: report_menu.make_item(self, *args, **kw)
13542 menu(_("Find in Source"), find_in_source, "findsource16", pos=110)
13543 self.link_menu = menu(_("&amp;Link Report"), self.change_link,
13544 check_item=True, pos=120)
13545 self.link_menu.check(self.link_view)
13547 if popup and task:
13548 taskfuncs.make_menu_task_clipboard(ctrl, task, report_menu, 500)
13549 code_item = task._function.code_item
13550 action_filter = ("add", "edit", "extra")
13551 context.CTask(code_item).make_browser_menu(report_menu, action_filter)
13553 return report_menu
13554 </t>
13555 <t tx="michael.20060703233047.15">def navigate(self, function):
13556 method = getattr(self.grid, function)
13557 method(False)
13558 </t>
13559 <t tx="michael.20060703233047.16">def set_grid_notifications(self):
13560 grid = self.grid
13561 wx.grid.EVT_GRID_SELECT_CELL(grid, self.OnCellSelect)
13562 wx.grid.EVT_GRID_CELL_RIGHT_CLICK(grid, self.OnRightDown)
13563 wx.grid.EVT_GRID_CELL_LEFT_CLICK(grid, self.OnLeftDown)
13564 </t>
13565 <t tx="michael.20060703233047.17">def change_link(self):
13566 self.link_view = not self.link_view
13567 self.link_menu.check(self.link_view)
13568 </t>
13569 <t tx="michael.20060703233047.18">def OnLeftDown(self, event):
13570 event.Skip()
13571 self.grid.SetFocus()
13572 </t>
13573 <t tx="michael.20060703233047.19">def OnRightDown(self, event):
13574 top = controller().get_top_menu()
13576 row = event.GetRow()
13577 col = event.GetCol()
13578 task, name = self.code_info.get((row, col), (None, None))
13579 menu = self.make_menu(True, task)
13581 self.PopupMenu(menu.wxobj, event.GetPosition())
13582 </t>
13583 <t tx="michael.20060703233047.20">def OnCellSelect(self, event):
13584 event.Skip()
13585 row = event.GetRow()
13586 col = event.GetCol()
13587 self.grid.MakeCellVisible(row, col)
13588 self.grid.SelectBlock(row, col, row, col)
13590 task, name = self.code_info.get((row, col), (None, None))
13591 if task:
13592 taskfuncs.make_menu_task_clipboard(controller(), task)
13593 if self.link_view:
13594 self.model.show_object(self, task, name)
13595 else:
13596 taskfuncs.remove_menu_task_clipboard(controller())
13597 </t>
13598 <t tx="michael.20060703233047.21">def menu_print_report(self):
13599 path = utils.get_template_path()
13600 path = os.path.join(path, "printing", "report.tmpl")
13601 template = CHTemplate.Template(file=path)
13603 template.report = self.report
13604 template.Cell = faces.report.Cell
13605 template.encoding = chart_tools.chart_encoding
13606 template.compile(file=path)
13607 template.encode = encode
13609 fh, tmpfile = tempfile.mkstemp(".html")
13610 os.close(fh)
13611 out = file(tmpfile, "w")
13612 print &gt;&gt; out, str(template)
13613 out.close()
13614 webbrowser.open("file://%s" % tmpfile, True, False)
13615 controller().session.tmp_files_to_remove.append(tmpfile)
13617 </t>
13618 <t tx="michael.20060703233047.22">def menu_export_csv(self):
13619 dlg = ExportCSV_Dialog(controller().frame,
13620 self.report.__class__.__name__)
13621 if dlg.ShowModal() == wx.ID_OK:
13622 exporter = dlg.data.exporter()
13623 exporter.writerow(map(encode, self.report.headers))
13624 for row in self.report:
13625 exporter.writerow(map(encode, row))
13627 dlg.Destroy()
13628 </t>
13629 <t tx="michael.20060703233047.23">def Destroy(self):
13630 taskfuncs.remove_menu_task_clipboard(controller())
13631 wx.Panel.Destroy(self)
13632 </t>
13633 <t tx="michael.20060703233047.24">def show_object(self, task, attrib, caller=None):
13634 if not self.link_view or not hasattr(task, "_function"): return
13636 rc = (self.grid.GetGridCursorRow(), self.grid.GetGridCursorCol())
13637 cursor_task, cursor_attrib = self.code_info.get(rc, (None, None))
13639 # don't move if the cursor is at the correct position
13640 if cursor_task == task and (not attrib or cursor_attrib == attrib):
13641 return
13643 taskid = task._idendity_()
13644 rc = self.task_info.get((taskid, attrib),
13645 self.task_info.get((taskid, None)))
13647 if rc: self.set_cursor(*rc)
13648 </t>
13649 <t tx="michael.20060703233047.25">def set_cursor(self, row, col, link=True):
13650 row = max(0, row)
13651 col = max(0, col)
13652 row = min(row, self.grid.GetNumberRows() - 1)
13653 col = min(col, self.grid.GetNumberCols() - 1)
13655 link_view = self.link_view
13656 self.link_view &amp;= link
13657 self.grid.SetGridCursor(row, col)
13658 self.grid.MakeCellVisible(row, col)
13659 self.link_view = link_view
13660 </t>
13661 <t tx="michael.20060703233047.26">def replace_data(self, report):
13662 if self.grid:
13663 rc = (self.grid.GetGridCursorRow(), self.grid.GetGridCursorCol())
13664 self.GetSizer().Remove(self.grid)
13665 self.grid.Destroy()
13666 else:
13667 sizer = wx.BoxSizer(wx.VERTICAL)
13668 self.SetSizer(sizer)
13669 rc = (0, 0)
13671 save_execute = controller().session.save_execute
13672 self.report = save_execute(report)
13674 if not self.report: self.report = _ErrorReport()
13675 save_execute(self.__fill_grid)
13676 wx.CallAfter(self.set_cursor, rc[0], rc[1], False)
13677 self.link_view = self.report.link_view
13678 </t>
13679 <t tx="michael.20060703233047.27">def __fill_grid(self):
13680 self.code_info.clear()
13681 self.task_info.clear()
13683 cols = len(self.report.headers)
13684 col_range = range(cols)
13686 grid = self.grid = wx.grid.Grid(self, -1)
13687 grid.SetDefaultRenderer(CellRenderer(weakref.proxy(self)))
13688 grid.EnableGridLines(wx.VERSION[:2] == (2,4))
13689 grid.SetRowLabelSize(0)
13690 grid.CreateGrid(0, cols)
13692 grid.BeginBatch()
13693 try:
13694 r = 0
13695 for row in self.report:
13696 grid.AppendRows(1)
13698 for c in col_range:
13699 try:
13700 val = row[c]
13701 except IndexError:
13702 val = faces.report.Cell("cell not defined")
13703 val.back_color = "red"
13705 try:
13706 strval = val.unicode(chart_tools.chart_encoding)
13707 except AttributeError:
13708 if isinstance(val, str):
13709 strval = unicode(val, chart_tools.chart_encoding)
13710 else:
13711 strval = unicode(val)
13713 grid.SetCellValue(r, c, strval)
13714 grid.SetReadOnly(r, c)
13716 ref = val.get_ref()
13717 self.code_info[(r, c)] = ref[:2]
13718 if ref[0]:
13719 taskid = ref[0]._idendity_()
13720 self.task_info[(taskid, ref[1])] = (r, c)
13721 last_info = self.task_info.get((taskid, None), (r,9999))
13722 self.task_info[(taskid, None)] = min((r, c), last_info)
13724 align = _align_map.get(val.align, wx.ALIGN_LEFT)
13725 grid.SetCellAlignment(r, c, align, wx.ALIGN_TOP)
13727 if val.back_color:
13728 back_color = convert_color(val.back_color)
13729 grid.SetCellBackgroundColour(\
13730 r, c, wx.Colour(*back_color))
13731 else:
13732 grid.SetCellBackgroundColour(\
13733 r, c, grid.GetDefaultCellBackgroundColour())
13735 if val.text_color:
13736 text_color = convert_color(val.text_color)
13737 grid.SetCellTextColour(r, c, wx.Colour(*text_color))
13738 else:
13739 grid.SetCellTextColour(\
13740 r, c, grid.GetDefaultCellTextColour())
13742 is_bold = val.font_bold
13743 is_italic = val.font_italic
13744 is_underline = val.font_underline
13745 font_size = val.font_size
13747 font = grid.GetDefaultCellFont()
13748 if is_bold or is_italic or is_underline or font_size:
13749 style = is_italic and wx.ITALIC or font.GetStyle()
13750 weight = is_bold and wx.BOLD or font.GetWeight()
13751 fsize = self.calc_font_size(font_size)
13753 new_font = wx.Font(\
13754 fsize, font.GetFamily(), style, weight,\
13755 is_underline, font.GetFaceName())
13757 grid.SetCellFont(r, c, new_font)
13758 else:
13759 grid.SetCellFont(r, c, font)
13762 border_val = 0
13763 if val.left_border: border_val += _LEFT
13764 if val.top_border: border_val += _TOP
13765 if val.right_border: border_val += _RIGHT
13766 if val.bottom_border: border_val += _BOTTOM
13767 if border_val != _DEFAULT and wx.VERSION[:2] != (2,4):
13768 attr = grid.GetOrCreateCellAttr(r, c) #bug in 2.4
13769 attr.border_val = border_val
13771 r += 1
13773 try:
13774 for c in col_range:
13775 grid.SetColLabelValue(c, self.report.headers[c])
13776 except:
13777 pass
13779 grid.AutoSizeColumns()
13780 grid.AutoSizeRows()
13781 self.set_grid_notifications()
13784 finally:
13785 grid.EndBatch()
13786 sizer = self.GetSizer()
13787 sizer.Add(grid, 1, wx.EXPAND)
13788 sizer.Layout()
13789 </t>
13790 <t tx="michael.20060703233047.28">def calc_font_size(self, font_size):
13791 grid_font_size = self.grid.GetDefaultCellFont().GetPointSize()
13792 if not font_size: return grid_font_size
13794 old_size = font.fontManager.get_default_size()
13795 font.fontManager.set_default_size(grid_font_size)
13796 fp = font.FontProperties(size=font_size)
13797 fsize = fp.get_size_in_points()
13798 font.fontManager.set_default_size(old_size)
13799 return fsize
13800 </t>
13801 <t tx="michael.20060703233047.29">def accept_sibling(self, new_view):
13802 import editor
13804 if isinstance(new_view, editor.PlanEditorProxy):
13805 return navigator.SIBLING_BELOW
13807 if isinstance(new_view, ReportView):
13808 return navigator.SIBLING_BELOW
13810 return False
13811 </t>
13812 <t tx="michael.20060703233047.30">class ExportCSV_Model(db.Model):
13813 &lt;&lt; class ExportCSV_Model declarations &gt;&gt;
13814 @others
13815 </t>
13816 <t tx="michael.20060703233047.31">filename = db.Text(default="test.csv")
13817 delimiter = db.Text(";")
13818 quotechar = db.Text('"')
13819 quoting = db.Enumerate({ csv.QUOTE_ALL : _("All"),
13820 csv.QUOTE_MINIMAL : _("Minimal"),
13821 csv.QUOTE_NONNUMERIC : _("Non Numeric"),
13822 csv.QUOTE_NONE : _("None") } )
13823 escapechar = db.Text("")
13825 </t>
13826 <t tx="michael.20060703233047.32">def check_constraints(self):
13827 if not self.filename:
13828 error = db.ConstraintError()
13829 error.message["filename"] = _("A filename must be specified")
13830 raise error
13831 </t>
13832 <t tx="michael.20060703233047.33">def exporter(self):
13833 return csv.writer(file(self.filename, "w"),
13834 delimiter=str(self.delimiter),
13835 quoting=self.quoting,
13836 quotechar=str(self.quotechar),
13837 escapechar=str(self.escapechar) or None,
13838 lineterminator="\n")
13839 </t>
13840 <t tx="michael.20060703233047.34">class ExportCSV_View(views.FormView):
13841 __model__ = ExportCSV_Model
13842 __view_name__ = "default"
13843 format = _("""
13844 [File: ] |filename(SaveFile)&gt;
13845 [Delimiter: ] |delimiter
13846 [Quoting:] |quoting
13847 [Quote Char:] |quotechar
13848 [Escape Char:]|escapechar
13849 (0,0)
13851 (buttons)&gt;
13852 """)
13854 format_buttons = "btn_ok{r}|(0,5)|btn_cancel"
13856 @others
13857 </t>
13858 <t tx="michael.20060703233047.36">def prepare(self):
13859 self.grow_col(1)
13860 self.grow_row(-3)
13861 self.buttons.grow_col(0)
13862 self.filename.set_filter(_("CSV (*.csv)|*.csv"))
13863 self.delimiter.set_width("8")
13864 self.delimiter.SetMaxLength(1)
13865 self.quotechar.set_width("8")
13866 self.quotechar.SetMaxLength(1)
13867 self.escapechar.set_width("8")
13868 self.escapechar.SetMaxLength(1)
13869 </t>
13870 <t tx="michael.20060703233047.37">def constitute(self, imodel):
13871 views.FormView.constitute(self, imodel)
13872 self.state_changed("quoting")
13873 </t>
13874 <t tx="michael.20060703233047.38">def state_changed(self, attrib):
13875 if attrib == "quoting":
13876 has_escape = self.imodel.quoting == csv.QUOTE_NONE
13877 self.quotechar.Enable(not has_escape)
13878 self.escapechar.Enable(has_escape)
13879 </t>
13880 <t tx="michael.20060703233047.39">def button_cancel(self):
13881 self.rollback()
13882 self.GetParent().GetParent().EndModal(wx.ID_CANCEL)
13883 </t>
13884 <t tx="michael.20060703233047.40">def button_ok(self):
13885 if self.save():
13886 self.GetParent().GetParent().EndModal(wx.ID_OK)
13887 </t>
13888 <t tx="michael.20060703233047.41">class ExportCSV_Dialog(wx.Dialog):
13889 @others
13890 </t>
13891 <t tx="michael.20060703233047.42">def __init__(self, parent, name):
13892 wx.Dialog.__init__(self, parent, -1, _("Export CSV"),
13893 style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
13894 self.name = name
13895 </t>
13896 <t tx="michael.20060703233047.43">def ShowModal(self):
13897 container = views.ScrollViewContainer(self)
13898 self.data = ExportCSV_Model(filename=self.name + ".csv")
13899 self.data.constitute("default")(container)
13900 container.fit_size()
13901 self.SetClientSize(container.GetSize())
13902 result = wx.Dialog.ShowModal(self)
13903 return result
13905 </t>
13906 <t tx="michael.20060703235036">def _parse_evaluation(self, text):
13907 pos = text.index("=")
13908 if 0 &lt;= text.find("#") &lt; pos:
13909 return False
13911 self._type = EVALUATION
13912 self._name = text[:pos].strip()
13913 self._header = False
13914 return True
13916 </t>
13917 <t tx="michael.20060703235036.2">text = event.GetText()
13918 if text.find("=") &gt;= 0 or not text.strip():
13919 self.context.make_button(self.context_button,
13920 self.get_expression(line))</t>
13921 <t tx="michael.20060703235036.3">self.check_context(line)
13922 self.context.make_button(self.context_button,
13923 self.get_expression(line))
13924 self.move_context_button()</t>
13925 <t tx="michael.20060703235820">def is_project_name(n):
13926 try:
13927 return n[0] != "_" and issubclass(getattr(ftask, n), ftask._ProjectBase)
13928 except TypeError:
13929 return False
13931 project_names = tuple([name for name in dir(ftask) if is_project_name(name)])
13933 del is_project_name
13938 </t>
13939 <t tx="michael.20060703235853">def update_code_info(self, module=None):
13940 session = controller().session
13941 path = self.model.path
13943 for varname, eval in session.evaluations.iteritems():
13944 &lt;&lt; assign tasks to code_items &gt;&gt;
13946 &lt;&lt; assign observers and resources to code_items &gt;&gt;
13947 &lt;&lt; assign evaluations to code_items &gt;&gt;
13948 </t>
13949 <t tx="michael.20060703235912">def sync_text(self, reset_savepoint=False):
13950 try:
13951 self.model.text = self.GetText().encode(self.model.get_encoding())
13952 except AttributeError:
13953 pass
13954 else:
13955 if self.model.text[-1] != "\n":
13956 self.model.text += "\n"
13958 if reset_savepoint:
13959 self.SetSavePoint()
13960 self.check_modified()
13961 </t>
13962 <t tx="michael.20060704001124">def check_modified(self):
13963 frame = controller().frame
13964 try:
13965 if self.GetModify():
13966 self.model.modified(True)
13967 frame.SetStatusText("C", 1)
13968 else:
13969 frame.SetStatusText("", 1)
13970 self.model.modified(False)
13971 except AttributeError:
13972 pass
13973 </t>
13974 <t tx="michael.20060704001124.1">pos = self.GetCurrentPos()
13975 line = self.GetFirstVisibleLine()
13976 offset = self.GetXOffset()</t>
13977 <t tx="michael.20060704001124.2">self.SetUndoCollection(0)
13978 self.SetText(unicode(model.text, model.get_encoding(), "replace"))
13979 self.SetSavePoint()
13980 self.SetUndoCollection(1)</t>
13981 <t tx="michael.20060704001124.3">self.setup_eol()
13982 self.SetCodePage(wx.stc.STC_CP_UTF8)
13983 self.__change_count = 0
13984 self.check_modified()</t>
13985 <t tx="michael.20060704001124.4">if self.__last_module_id != id(module):
13986 self.browse_code()
13987 if module:
13988 self.update_code_info(module)
13989 self.show_call_tips = getattr(module, "faces_show_call_tips", True)
13990 self.dimmer_color = getattr(module, "faces_dimmer_color", "#f0aeb8")
13991 self.task_completions = getattr(module, "faces_task_completions", None)
13993 self.check_context(self.GetCurrentLine())
13994 self.GetParent().browser.refresh()
13995 self.__last_module_id = id(module)
13998 self.setup_style()
13999 </t>
14000 <t tx="michael.20060704001124.6">self.GotoPos(pos)
14001 self.LineScroll(0, line - self.GetFirstVisibleLine())
14002 self.SetXOffset(offset)
14003 self.check_context(self.LineFromPosition(pos))
14004 </t>
14005 <t tx="michael.20060704001244">def show_object(self, search_object, attrib=None, caller=None):
14006 if hasattr(search_object, "_function"):
14007 return self.show_task(search_object, attrib, caller)
14009 for c in self.code_items:
14010 if getattr(c, "obj", None) is search_object:
14011 line = c.get_line()
14012 self.LineScroll(0, line - self.GetFirstVisibleLine())
14013 start = self.PositionFromLine(line)
14014 end = self.GetLineEndPosition(line)
14015 pos = self.FindText(start, end, "class", 0)
14016 self.GotoPos(pos + 4)
14017 self.WordPartRight()
14018 return True
14020 return False
14021 </t>
14022 <t tx="michael.20060704001500">def show_task(self, search_task, attrib=None, caller=None):
14023 obj = None
14024 item = None
14026 def context_result(found_item, found_attrib=False):
14027 if attrib is not None: return found_item, found_attrib
14028 return found_item
14030 for item in self.code_items:
14031 obj = getattr(item, "obj", None)
14032 if isinstance(obj, ftask.Task):
14033 if obj._function.func_code is search_task._function.func_code:
14034 break
14035 else:
14036 return context_result(False)
14038 item_line = item.get_line()
14040 def goto_declaration():
14041 start = self.PositionFromLine(item_line)
14042 end = self.GetLineEndPosition(item_line)
14043 pos = self.FindText(start, end, "def", 0)
14044 self.GotoPos(pos + 3)
14045 self.WordPartRight()
14046 return context_result(True)
14048 self.LineScroll(0, item_line - self.GetFirstVisibleLine())
14049 if not attrib:
14050 return goto_declaration()
14052 line = min(item.get_last_line(), self.next_item_line(item_line + 1))
14053 start = self.GetLineEndPosition(line)
14054 end = self.GetLineEndPosition(item_line)
14055 pos = self.FindText(start, end, attrib, 0)
14056 if pos &lt; 0:
14057 return goto_declaration()
14059 end = start
14060 start = pos + len(attrib)
14062 line_end = self.GetLineEndPosition(self.LineFromPosition(start))
14063 if self.FindText(start, end, "=") &lt; 0:
14064 # attribs have always a = behind
14065 return goto_declaration()
14067 scenario = search_task.root.scenario
14068 tpos = self.FindText(start, end, scenario, 0)
14069 if tpos &gt;= 0: start = tpos + len(scenario)
14071 org_val = search_task._original_values.get(attrib, "") or \
14072 getattr(search_task, attrib, "")
14074 try:
14075 org_val = org_val.decode(self.model.get_encoding())
14076 except AttributeError:
14077 org_val = str(org_val)
14079 if org_val:
14080 tpos = self.FindText(start, end, org_val, 0)
14081 if tpos &gt; 0:
14082 self.GotoPos(tpos)
14083 self.SetSelectionEnd(tpos + len(org_val))
14084 return True, True
14086 self.GotoPos(pos)
14087 return True, False
14088 </t>
14089 <t tx="michael.20060704020852">def eval_expression(self, expression, globvars={}, context=None):
14090 locdict = { }
14091 context = context or self.context
14093 if globvars:
14094 globdict = self.get_module().__dict__.copy()
14095 globdict.update(globvars)
14096 else:
14097 globdict = self.get_module().__dict__
14099 while True:
14100 try:
14101 exec expression in globdict, locdict
14102 return locdict
14103 except NameError, e:
14104 name = str(e).split("'")[1]
14105 obj = context.find_object(name)
14106 if obj is None:
14107 obj = self.guess_object(name, context=context)
14109 if obj is None or globdict.has_key(name):
14110 # may be a python bug but "globdict.has_key(name)" can happen!
14111 raise
14113 globdict[name] = obj
14115 </t>
14116 <t tx="michael.20060704235642">class PlanEditorProxy(wx.PyPanel, View):
14117 @others
14118 </t>
14119 <t tx="michael.20060705002353">def __init__(self, model, parent):
14120 wx.PyPanel.__init__(self, parent)
14122 self.model = weakref.ref(model)
14123 editor = model.editor
14124 editor.show(self)
14126 sizer = wx.BoxSizer(wx.HORIZONTAL)
14127 sizer.Add(editor, 1, wx.EXPAND)
14128 self.SetSizer(sizer)
14130 &lt;&lt; redirect methods &gt;&gt;
14131 </t>
14132 <t tx="michael.20060705002353.1">def Destroy(self):
14133 editor = self.GetChildren()[0]
14134 self.GetSizer().Detach(editor)
14135 editor.hide()
14136 wx.PyPanel.Destroy(self)
14137 </t>
14138 <t tx="michael.20060705003619"></t>
14139 <t tx="michael.20060705003619.1"></t>
14140 <t tx="michael.20060705003619.2"></t>
14141 <t tx="michael.20060705004026"></t>
14142 <t tx="michael.20060705004026.1"></t>
14143 <t tx="michael.20060705004026.2"></t>
14144 <t tx="michael.20060705004818">path = self.get_backup_file()
14145 if self.consider_backup and os.access(path, os.F_OK):
14146 result = wx.MessageBox(_('A backup copy of "%s" exists.\n'
14147 'Should I use it?') % self.path,
14148 _("Backup exists"),
14149 style=wx.YES_NO|wx.ICON_QUESTION)
14150 if result == wx.NO:
14151 path = self.path
14152 else:
14153 path = self.path
14155 </t>
14156 <t tx="michael.20060705013905">self.show_object = editor.show_object
14157 self.sync_text = editor.sync_text
14158 self.refresh = editor.refresh
14159 self.goto_line = editor.goto_line
14160 self.find_in_source = editor.find_in_source
14161 self.SetFocus = editor.editor.SetFocus
14162 self.on_make_menu = editor.browser.on_make_menu
14163 self.find_resource_references = editor.find_resource_references
14164 self.find_task_references = editor.find_task_references</t>
14165 <t tx="michael.20060705164052">def show(self, parent):
14166 self.Reparent(parent)
14168 view_menu = controller().view_menu
14169 self.browser_menu = view_menu.make_item(parent,
14170 _("&amp;Project Browser\tF9"),
14171 self.toggle_browser,
14172 pos=8000,
14173 check_item=True)
14174 view_menu.make_separator(_("&amp;Project Browser\tF9"), True)
14175 self.browser_menu.check(False)
14177 if self.browser.IsShown():
14178 wx.CallAfter(self.toggle_browser, True)
14179 </t>
14180 <t tx="michael.20060705164052.1">def hide(self):
14181 if self.browser.IsShown():
14182 self.browser.open_width = self.browser.GetSize()[0]
14184 self.browser_menu = None
14185 self.Reparent(controller().hidden_parent)
14187 </t>
14188 <t tx="michael.20060707121238">class DimmerStyler(object):
14189 dimmer_color = "#f0aeb8"
14190 _marker_number = 1
14192 @others
14193 </t>
14194 <t tx="michael.20060707125319">def StyleSetSpec(self, style_index, spec):
14195 if style_index != wx.stc.STC_STYLE_LINENUMBER:
14196 spec += ",back:%s" % self.dimmer_color
14198 super(DimmerStyler, self).StyleSetSpec(style_index, spec)
14199 </t>
14200 <t tx="michael.20060707130205">def highlite(self, start_line=0, end_line=0):
14201 end_line = end_line or self.GetLineCount() - 1
14203 self.__start_pos = self.PositionFromLine(start_line)
14204 self.__end_pos = self.GetLineEndPosition(end_line)
14205 self.__last_style_end = 0
14207 self.Freeze()
14209 MarkerAdd = self.MarkerAdd
14210 marker_number = self._marker_number
14211 self.MarkerDeleteAll(marker_number)
14212 for i in range(start_line, end_line + 1):
14213 MarkerAdd(i, marker_number)
14215 self.Thaw()
14216 </t>
14217 <t tx="michael.20060707181914">def __init__(self):
14218 self.__start_pos = self.__end_pos = 0
14219 self.MarkerDefine(self._marker_number,
14220 wx.stc.STC_MARK_BACKGROUND,
14221 "white", "white")
14222 </t>
14223 <t tx="michael.20060708104315">try:
14224 self.highlite(item.get_line(), item.get_last_line())
14225 except AttributeError:
14226 self.highlite()</t>
14227 <t tx="michael.20060713212925">self._raise(RecursionError("A child defines a "\
14228 "recursive definition at %s" % self.path))
14229 </t>
14230 <t tx="michael.20060717214039">@language python
14231 &lt;&lt; Copyright &gt;&gt;
14233 faces project management in python
14235 @var LEFT:
14236 The left border position of a graphical widget.
14238 @var RIGHT:
14239 The right border position of a graphical widget.
14241 @var TOP:
14242 The top border position of a graphical widget.
14244 @var BOTTOM:
14245 The bottom border position of a graphical widget.
14247 @var VCENTER:
14248 The vertical center position of a graphical widget.
14250 @var HCENTER:
14251 The horizontal center position of a graphical widget.
14253 @var VSEP:
14254 Specifies the vertical space equivalent to 1/4 of the height of
14255 the character 'I'.
14257 @var HSEP:
14258 Specifies the horizontal space equivalent to 1/4 of the height of
14259 the character 'I'.
14261 @var FACTOR:
14262 Specifies the height of a graphical widget in units of VSEP.
14266 __version__ = "0.11.7"
14268 from pcalendar import Calendar, WorkingDate, StartDate, EndDate, Minutes
14270 from task import Project, BalancedProject, AdjustedProject, Task, \
14271 STRICT, SLOPPY, SMART, Multi, YearlyMax, WeeklyMax, MonthlyMax, \
14272 DailyMax, VariableLoad
14274 from resource import Resource
14275 from operators import intersect, unify, difference
14276 from charting.tools import VSEP, HSEP, LEFT, RIGHT, BOTTOM, \
14277 TOP, VCENTER, HCENTER, FACTOR, \
14278 set_default_size as set_default_chart_font_size,\
14279 set_encoding as set_chart_encoding, \
14280 chart_encoding
14282 from charting.patches import Arrow, Circle, Polygon, RegularPolygon, \
14283 Shadow, Wedge, Rectangle
14285 from charting.taxis import alt_week_locator
14287 gui_controller = None
14289 __all__ = ("Arrow", "Circle", "Polygon", "RegularPolygon", \
14290 "Shadow", "Wedge", "Rectangle", \
14291 "VSEP", "HSEP", "LEFT", "RIGHT", "BOTTOM", \
14292 "TOP", "VCENTER", "HCENTER", "FACTOR", \
14293 "set_default_chart_font_size",\
14294 "set_chart_encoding", "chart_encoding", "Resource",
14295 "Project", "BalancedProject", "AdjustedProject", "Task", \
14296 "STRICT", "SLOPPY", "SMART", "Multi", \
14297 "YearlyMax", "WeeklyMax", "MonthlyMax", "DailyMax", \
14298 "intersect", "unify", "difference", "Calendar", "gui_controller",
14299 "WorkingDate", "StartDate", "EndDate", "Minutes", "VariableLoad",
14300 "alt_week_locator")
14303 _is_source = True
14304 _DEBUGGING = True
14305 _PROFILING = False
14306 </t>
14307 <t tx="michael.20060718000534">def union(*calendars):
14308 """
14309 returns a calendar that unifies all working times
14311 &lt;&lt; check arguments &gt;&gt;
14312 &lt;&lt; intersect vacations &gt;&gt;
14313 &lt;&lt; unify extra worktime &gt;&gt;
14314 &lt;&lt; unify working times &gt;&gt;
14315 &lt;&lt; create result calendar &gt;&gt;
14316 return result</t>
14317 <t tx="michael.20060718001417">if len(calendars) == 1:
14318 calendars = calendars[0]</t>
14319 <t tx="michael.20060718001417.1">free_time = []
14320 for c in calendars:
14321 for start, end, is_free in c.time_spans:
14322 if is_free:
14323 free_time.append((start, False))
14324 free_time.append((end, True))
14326 count = len(calendars)
14327 open = 0
14328 time_spans = []
14329 free_time.sort()
14330 for date, is_end in free_time:
14331 if is_end:
14332 if open == count:
14333 time_spans.append((start, date, True))
14334 open -= 1
14335 else:
14336 open += 1
14337 start = date
14338 </t>
14339 <t tx="michael.20060718001417.2">for c in calendars:
14340 for start, end, is_free in c.time_spans:
14341 if not is_free:
14342 time_spans = _add_to_time_spans(time_spans, start, end)</t>
14343 <t tx="michael.20060718005323">working_times = {}
14344 for d in range(0, 7):
14345 times = []
14346 for c in calendars:
14347 for start, end in c.working_times.get(d, []):
14348 times.append((start, False))
14349 times.append((end, True))
14351 times.sort()
14352 open = 0
14353 ti = []
14354 start = None
14355 for time, is_end in times:
14356 if not is_end:
14357 if not start: start = time
14358 open += 1
14359 else:
14360 open -= 1
14361 if not open:
14362 ti.append((start, time))
14363 start = None
14365 if ti:
14366 working_times[d] = ti
14367 </t>
14368 <t tx="michael.20060718005402">result = Calendar()
14369 result.working_times = working_times
14370 result.time_spans = time_spans
14371 result._recalc_working_time()
14372 result._build_mapping()</t>
14373 <t tx="michael.20060720224306">"""
14374 This class represents a single task in the project tree. A task
14375 can have other child tasks, or is a leaf of the tree. Resources
14376 will be allocated only to leafes. You will never create task
14377 objects by your self, they are created indirectly by Projects.
14379 @var root:
14380 Returns the root project task.
14382 @var up:
14383 Returns the parent task.
14385 @var title:
14386 Specifies an alternative more descriptive name for the task.
14388 @var start:
14389 The start date of the task. Valid values are expressions and
14390 strings specifing a datatime
14392 @var end:
14393 The end date of the task. Valid values are expressions and
14394 strings.
14396 @var effort:
14397 Specifies the effort needed to complete the task. Valid values
14398 are expressions and strings. (Todo: What happens, in case of
14399 specified performance data...)
14402 @var length:
14403 Specifies the time the task occupies the resources. This is
14404 working time, not calendar time. 7d means 7 working days, not one
14405 week. Whether a day is considered a working day or not depends on
14406 the defined working hours and global vacations.
14408 @var duration:
14409 Specifies the time the task occupies the resources. This is
14410 calendar time, not working time. 7d means one week.
14412 @var buffer:
14413 Specifies the time a task can be delayed, without moving dependend
14414 milestones. A Task with a buffer S{&lt;=} 0d is part of the critical
14415 chain. This attribute is readonly.
14417 @var complete:
14418 Specifies what percentage of the task is already completed.
14420 @var todo:
14421 Specifies the effort, which needs to be done to complete a
14422 task. This is another (indirect) way to specify the ME{complete}
14423 attribute.
14425 @var done:
14426 Specifies the work effort, which has been already done. This
14427 attribute is readonly.
14429 @var estimated_effort:
14430 Specifies the estimated_effort given by setting the effort property.
14432 @var performed:
14433 Specifies a list of actual working times performed on the task.
14434 The format is: C{[ (resource, from, to, time), ... ]}
14436 @var performed_work_time:
14437 Specifies the sum of all working times. This attribute is
14438 readonly.
14440 @var performed_effort:
14441 Specifies the complete effort of all working times. This attribute is
14442 readonly.
14444 @var performed_start:
14445 The start date of the performed data.
14447 @var performed_end:
14448 The end date of the performed data.
14450 @var performed_resource:
14451 The resources who have already performed on the task. This attribute is readonly.
14454 @var balance:
14455 Specifies the resource allocation type. Possible values are
14456 CO{STRICT}, CO{SLOPPY}, CO{SMART}.
14458 @var resource:
14459 Specifies the possible resources, that may be allocated for the
14460 task.
14462 @var booked_resource:
14463 Specifies the allocated resources of a task. This attribute is
14464 readonly.
14466 @var load:
14467 Specifies the daily load of a resource for an allocation of the
14468 specified task. A load of 1.0 (default) means the resource is
14469 allocated for as many hours as specified by
14470 ME{working_hours_per_day}. A load of 0.5 means half that many
14471 hours.
14473 @var max_load:
14474 Specify the maximal allowed load sum of all simultaneously
14475 allocated tasks of a resource. A ME{max_load} of 1.0 (default)
14476 means the resource may be fully allocated. A ME{max_load} of 1.3
14477 means the resource may be allocated with 30% overtime.
14479 @var efficiency:
14480 The efficiency of a resource can be used for two purposes. First
14481 you can use it as a crude way to model a team. A team of 5 people
14482 should have an efficiency of 5.0. Keep in mind that you cannot
14483 track the member of the team individually if you use this
14484 feature. The other use is to model performance variations between
14485 your resources.
14487 @var milestone:
14488 Specified if the task is a milestone. The possible values are
14489 C{True} or "later". If the start date of the milestone is not
14490 a valid working date, the milestone will appear at the previous
14491 working date before the given start date. If "later" is specified
14492 the milestone will appear at the next valid working date.
14493 A milestone has always an effort of 0d.
14495 @var priority:
14496 Specifies a priority between 1 and 1000. A task with higher
14497 priority is more likely to get the requested resources. The
14498 default priority is 500.
14500 @var children:
14501 Specifies a list of all subtasks. A task without children is
14502 called a leaf task index{leaf task} otherwise it is called a
14503 parent task index{parent task}. This attribute is readonly.
14505 @var depth:
14506 Specifies the depth of the task within the hierachy. This
14507 attribute is readonly.
14509 @var index:
14510 Specifies a structural index number. This attribute is readonly.
14512 @var path:
14513 Specifies the path.
14515 @var copy_src:
14516 Specifies the path to an other task. When you set this attribute,
14517 all attributes (except of ME{start} and ME{end}) of copy_src will
14518 be copied to the current task. This is usefull if you want to
14519 define the same task, in diffent project definitions. It acts like
14520 a task link.
14522 @var scenario:
14523 The scenario which is currently evaluated. This attribute is readonly.
14525 @var dont_inherit:
14526 A list of attribute names, which will be not inherited by
14527 subtasks.
14529 @var calendar:
14530 Specifies the task calendar.
14532 @var working_days_per_week:
14533 Specifies the days within a working week. This value is used
14534 internally to convert time differences from weeks to days. The
14535 default value is 5 days.
14537 @var working_days_per_month:
14538 Specifies the days within a working month. This value is used
14539 internally to convert time differences from months to days. The
14540 default value is 20 days.
14542 @var working_days_per_year:
14543 Specifies the days within a working year. This value is used
14544 internally to convert time differences from years to days The
14545 default value is 200 days.
14547 @var working_hours_per_day:
14548 Specifies the hours within a working day. This value is used
14549 internally to convert time differences from are entered in days to
14550 hours. The default value is 8 hours.
14552 @var minimum_time_unit:
14553 Specifies the minimum resolution in minutes for the task
14554 scheduling. The default value is 15 minutes.
14556 @var vacation:
14557 Specifies a public vacation for the calendar. This attribute is
14558 specified as a list of date literals or date literal intervals. Be
14559 aware that the end of an interval is excluded, i.e. it is the
14560 first working date.
14562 @var extra_work:
14563 Specifies additional worktime. This attribute is specified as a
14564 list of date literals or date literal intervals. Be aware that the
14565 end of an interval is excluded, i.e. it is the first working date.
14567 @var working_days:
14568 Specifies the weekly working time within calendar. The format of
14569 this attribute is: [ (day_range, time_range, ...), (day_range, time_range, ...), ... ].
14570 day_range is a comma sperated string of week days. Valid values
14571 are mon, tue, wed, thu, fri, sat, sun.
14572 time_range is string specifing a time interval like
14573 8:00-10:00. You can specified any number of time_ranges, following
14574 the first.
14576 @var now:
14577 Specifies the current daytime and is a date literal. ME{now} is
14578 used to calculate several task attributes.
14580 """</t>
14581 <t tx="michael.20060724135631">def _set_calendar(self, value):
14582 self.calendar = value
14583 self._to_delta = value.Minutes
14584 self._to_start = value.StartDate
14585 self._to_end = value.EndDate
14586 self.__renew_dates()
14588 </t>
14589 <t tx="michael.20060724142145">def __or__(self, other):
14590 if isinstance(other, Calendar):
14591 return union(self, other)
14593 return NotImplemented</t>
14594 <t tx="michael.20060724150058"></t>
14595 <t tx="michael.20060724153604">def clone(self):
14596 result = Calendar()
14597 result.working_times = self.working_times.copy()
14598 result.time_spans = self.time_spans
14599 result._recalc_working_time()
14600 result._build_mapping()
14601 return result</t>
14602 <t tx="michael.20060724164954">def __make_calendar(self):
14603 if not "calendar" in self.__dict__:
14604 cal = self.calendar = self.calendar.clone()
14605 self._to_delta = cal.Minutes
14606 self._to_start = cal.StartDate
14607 self._to_end = cal.EndDate</t>
14608 <t tx="michael.20060724204442">def get_calendar_completions(self, obj=None):
14609 return map(lambda r: (r, r), self.model.calendars.keys())</t>
14610 <t tx="michael.20060724204736">if isinstance(v, _faces.Calendar):
14611 calendars.setdefault(path, {})[k] = v
14612 continue</t>
14613 <t tx="michael.20060726163212">@language python
14614 &lt;&lt; Copyright &gt;&gt;
14616 A collection of classes and functions for editing attributes
14618 &lt;&lt; Imports &gt;&gt;
14620 _is_source_ = True
14621 _ = faces.plocale.get_gettext()
14623 @others</t>
14624 <t tx="michael.20060726163212.1">import wx
14625 import context
14626 import re
14627 import sys
14628 import operator
14629 import faces.plocale
14630 import faces.pcalendar as pcalendar
14631 import faces.task as ftask
14632 import faces.charting
14633 import metapie.dbtransient as db
14634 import metapie.gui.views as views
14635 import metapie.gui.grid as grid
14636 import metapie.gui.widgets as widgets
14637 import metapie.gui.pyeditor as pyeditor
14638 import inspect
14639 import textwrap
14640 import classifiers
14641 import datetime
14642 from metapie.gui import controller
14643 import editorlib
14644 try:
14646 except NameError:
14647 from sets import Set as set
14648 </t>
14649 <t tx="michael.20060726163359"></t>
14650 <t tx="michael.20060726163359.1"></t>
14651 <t tx="michael.20060726163359.2">class Delta(db.Model):
14652 days = db.Float(width=5, precision=1)
14653 hours = db.Float(width=4, precision=1)
14654 minutes = db.Int()
14655 is_duration = False
14657 @others
14658 </t>
14659 <t tx="michael.20060726163359.3">def __init__(self, code_item, attrib, value):
14660 super(Delta, self).__init__()
14661 try:
14662 self.to_delta = code_item.obj._to_delta
14663 except AttributeError:
14664 self.to_delta = pcalendar.Minutes
14666 &lt;&lt; find best value &gt;&gt;
14667 self.minutes = (value.seconds / 60) % 60
14668 self.hours = value.seconds / 3600
14669 self.days = value.days</t>
14670 <t tx="michael.20060726163359.4">try:
14671 value = self.to_delta(value).to_timedelta(self.is_duration)
14672 except ValueError:
14673 try:
14674 value = getattr(code_item.obj, attrib).to_timedelta(self.is_duration)
14675 except AttributeError:
14676 value = datetime.timedelta()</t>
14677 <t tx="michael.20060726163359.5">def __str__(self):
14678 td = datetime.timedelta(days=self.__days,
14679 hours=self.__hours,
14680 minutes=self.__minutes)
14681 return '"%s"' % self.to_delta(td, self.is_duration)\
14682 .strftime(is_duration=self.is_duration)</t>
14683 <t tx="michael.20060726163359.6">class Duration(Delta):
14684 is_duration = True</t>
14685 <t tx="michael.20060726163359.7">class DeltaView(views.FormView):
14686 __model__ = Delta
14687 __view_name__ = "default"
14688 vgap = 0
14690 format = _("""
14691 days|[Days ]|hours|[Hours ]|minutes|[Minutes]
14692 """)</t>
14693 <t tx="michael.20060726163359.8"></t>
14694 <t tx="michael.20060726163359.9">class Date(db.Model):
14695 value = db.DateTime()
14697 @others</t>
14698 <t tx="michael.20060726163359.10">def __init__(self, code_item, attrib, value):
14699 super(Date, self).__init__()
14701 to_date = pcalendar.to_datetime
14703 try:
14704 value = to_date(value)
14705 except ValueError:
14706 &lt;&lt; try alternatives &gt;&gt;
14707 except TypeError:
14708 &lt;&lt; try alternatives &gt;&gt;
14710 self.value = value</t>
14711 <t tx="michael.20060726163359.11">def __str__(self):
14712 return '"%s"' % self.__value.strftime("%x %H:%M")
14713 </t>
14714 <t tx="michael.20060726163359.12">class DateView(views.FormView):
14715 __model__ = Date
14716 __view_name__ = "default"
14717 vgap = 0
14718 format = "value"</t>
14719 <t tx="michael.20060726163359.13"></t>
14720 <t tx="michael.20060726163359.14">class String(db.Model):
14721 value = db.Text()
14723 @others</t>
14724 <t tx="michael.20060726163359.15">def __init__(self, code_item, attrib, value):
14725 super(String, self).__init__()
14726 self.value = value</t>
14727 <t tx="michael.20060726163359.16">def __str__(self):
14728 return '"%s"' % self.value
14729 </t>
14730 <t tx="michael.20060726163359.17">class StringView(views.FormView):
14731 __model__ = String
14732 __view_name__ = "default"
14733 vgap = 0
14734 format = "value&gt;"
14736 def prepare(self):
14737 self.grow_col(0)
14738 </t>
14739 <t tx="michael.20060726163359.33"></t>
14740 <t tx="michael.20060726163359.34">class MultiText(db.Model):
14741 value = db.Text(multi_line=True)
14743 @others</t>
14744 <t tx="michael.20060726163359.35">def __init__(self, code_item, attrib, value):
14745 super(MultiText, self).__init__()
14746 self.value = textwrap.dedent(value or "").strip("\n").decode("utf8")</t>
14747 <t tx="michael.20060726163359.36">def __str__(self):
14748 return '"""\n%s\n"""' % self.__value</t>
14749 <t tx="michael.20060726163359.37">class MultiTextView(views.FormView):
14750 __model__ = MultiText
14751 __view_name__ = "default"
14752 vgap = 0
14753 format = "value&gt;"
14755 @others</t>
14756 <t tx="michael.20060726163359.38">def prepare(self):
14757 self.grow_col(0)
14758 self.grow_row(0)
14759 self.value.set_width("X" * 50)
14760 self.value.set_height(20)</t>
14761 <t tx="michael.20060726163359.39"></t>
14762 <t tx="michael.20060726163359.40">class DateTimeRange(db.Model):
14763 start = db.DateTime(format="HHMM")
14764 end = db.DateTime(format="HHMM")
14766 @others</t>
14767 <t tx="michael.20060726163359.41">def __init__(self, **kwargs):
14768 super(DateTimeRange, self).__init__(**kwargs)
14769 if not kwargs.has_key("start"):
14770 self.start = datetime.datetime.now()</t>
14771 <t tx="michael.20060726163359.42">def _set_start(self, value):
14772 self.end = value.replace(hour=0, minute=0) \
14773 + datetime.timedelta(days=1)
14774 return value</t>
14775 <t tx="michael.20060726163359.43">def __str__(self):
14776 return '("%s", "%s")' \
14777 % (self.start.strftime("%x %H:%M"),
14778 self.end.strftime("%x %H:%M"))</t>
14779 <t tx="michael.20060726163359.44">class DateTimeRanges(db.Model):
14780 @others
14782 db.Relation("tr",
14783 db.End(DateTimeRange, "ranges", multi='*'),
14784 db.End(DateTimeRanges))</t>
14785 <t tx="michael.20060726163359.45">def __init__(self, code_item, attrib, value):
14786 super(DateTimeRanges, self).__init__()
14787 to_datetime = pcalendar.to_datetime
14788 for start, end in value or ():
14789 self.ranges.insert(DateTimeRange(start=to_datetime(start),
14790 end=to_datetime(end)))</t>
14791 <t tx="michael.20060726163359.46">def __str__(self):
14792 ranges = map(str, self.ranges)
14793 return "[%s]" % ",\n".join(ranges)</t>
14794 <t tx="michael.20060726163359.47">class DateTimeRangeGrid(grid.EditGrid, views.GridView):
14795 __model__ = DateTimeRange
14796 columns = ((__model__.start, _("From")),
14797 (__model__.end, _("To")))
14798 resize_col = 0
14801 class DateTimeRangesView(views.FormView):
14802 __model__ = DateTimeRanges
14803 __view_name__ = "default"
14804 vgap = 0
14805 format = """
14806 ranges&gt;
14807 delete
14810 @others</t>
14811 <t tx="michael.20060726163359.48">def create_controls(self):
14812 self.ranges = self.get_control("ranges(DateTimeRangeGrid)")
14813 self.delete = self.ranges.get_delete_button(self)</t>
14814 <t tx="michael.20060726163359.49">def prepare(self):
14815 self.grow_col(0)
14816 self.grow_row(0)</t>
14817 <t tx="michael.20060726164252">try:
14818 value = to_date(getattr(code_item.obj, attrib))
14819 except AttributeError:
14820 value = datetime.datetime.now()</t>
14821 <t tx="michael.20060727133714"></t>
14822 <t tx="michael.20060727171038"></t>
14823 <t tx="michael.20060727171038.1">class ScenarioAttributeEditor(AttributeEditor):
14824 @others
14825 </t>
14826 <t tx="michael.20060727171038.4">def activate(self, context):
14828 activates the editor.
14830 imodel = ScenarioContainer(self.edit_model, context, self.attrib_name,
14831 self.evaluator, self.default)
14832 imodel.show()
14835 </t>
14836 <t tx="michael.20060727171134">tok_identifier = r"([a-zA-Z_][a-zA-Z0-9_]*)"
14837 tok_path = r"(ident(\.ident)*)".replace("ident", tok_identifier)
14838 tok_assignment = r"^(path)\s*=".replace("path", tok_path)
14839 tok_identifier_assignment = r"%s\s*(?P&lt;project&gt;%s)\(" % (tok_assignment, tok_identifier)
14841 reg_assignment = re.compile(tok_assignment)
14842 reg_identifier_assignment = re.compile(tok_identifier_assignment)
14843 reg_identifier = re.compile(tok_identifier + "$")
14844 reg_path = re.compile(tok_path + "$")
14845 </t>
14846 <t tx="michael.20060727171307.1">class Evaluator(object):
14847 def __init__(self, expression, context):
14848 try:
14849 editor = context.code_item.editor
14850 self.attributes = editor.eval_expression(expression, context=context)
14851 except Exception, e:
14852 self.error = e
14857 </t>
14858 <t tx="michael.20060727171438">class AttributeEditor(context.ItemEditor):
14859 evaluator = Evaluator
14861 @others</t>
14862 <t tx="michael.20060727171438.1">def __init__(self, attrib_name, edit_model, default=None):
14863 self.attrib_name = attrib_name
14864 self.edit_model = edit_model
14865 self.default = default</t>
14866 <t tx="michael.20060727171438.2">def apply(self, expression, code_item):
14867 if not expression: return True
14869 mo = reg_assignment.search(expression)
14870 if not mo: return False
14872 path = mo.group(1).split(".")
14873 return path[-1] == self.attrib_name
14875 </t>
14876 <t tx="michael.20060727171438.3">def activate(self, context):
14878 activates the editor.
14880 imodel = SimpleContainer(self.edit_model, context, self.attrib_name,
14881 self.evaluator, self.default)
14882 imodel.show()
14883 return imodel
14884 </t>
14885 <t tx="michael.20060727171523"></t>
14886 <t tx="michael.20060727171523.1">class ScenarioContainer(db.Model):
14887 child = db.Model.type(readonly=True)
14888 error = db.Text()
14889 @others</t>
14890 <t tx="michael.20060727171523.2">def __init__(self, child_model, context, attrib_name, evaluator, default):
14891 self.child_model = child_model
14892 self.code_item = code_item = context.code_item
14893 self.attrib_name = attrib_name
14894 self.scenarios = ["_default"]
14896 &lt;&lt; calculate attribute value &gt;&gt;
14898 child_model = lambda v: self.child_model(self.code_item,
14899 self.attrib_name,
14901 if not isinstance(value, dict):
14902 self.child__default = child_model(value)
14903 self.scenarios = ["_default"]
14904 self.default = value
14905 else:
14906 self.scenarios = []
14908 if "_default" not in value:
14909 value["_default"] = value.values()[0]
14911 self.default = value["_default"]
14913 for k, v in value.iteritems():
14914 setattr(self, "child_%s" % k, child_model(v))
14915 self.scenarios.append(k)
14917 </t>
14918 <t tx="michael.20060727171523.5">def remove_scenario(self, name):
14919 if name == "_default": return None
14921 try:
14922 self.scenarios.remove(name)
14923 except ValueError:
14924 return False
14926 child = getattr(self, "child_%s" % name)
14927 delattr(self, "child_%s" % name)
14928 return child</t>
14929 <t tx="michael.20060727171523.6">def show(self):
14930 #no wizzard while processing
14931 if controller().is_processing(): return
14933 dlg = editorlib.PatchedDialog(controller().frame, -1,
14934 _("Edit %s") % self.attrib_name,
14935 style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
14937 dlg.SetClientSize((10, 10))
14938 view = self.constitute()(dlg)
14939 view.layout()
14940 dlg.simulate_modal(self.code_item.editor)</t>
14941 <t tx="michael.20060727171523.7">def code(self):
14942 default = self.child__default
14943 scenarios = list(self.scenarios)
14944 scenarios.remove("_default")
14946 if scenarios:
14947 first = "%s = Multi(%s" % (self.attrib_name, unicode(default))
14948 others = map(lambda s: '%s=%s' % (s, unicode(getattr(self, "child_%s" % s))), scenarios)
14949 others.insert(0, first)
14950 max_len = sum(map(len, others)) + len(others) * 2 + self.code_item.indent + 4
14951 joiner = max_len &gt; 80 and ",\n" or ", "
14952 return "%s)" % joiner.join(others)
14953 else:
14954 return "%s = %s" % (self.attrib_name, unicode(default))</t>
14955 <t tx="michael.20060727171523.8">def realize(self):
14956 root = get_code_root(self.code_item)
14957 try:
14958 root.all_scenarios.update(self.scenarios)
14959 except AttributeError:
14960 root.all_scenarios = set(self.scenarios)
14962 editor = self.code_item.editor
14963 attribs = editor.get_attribs(self.code_item)
14964 if self.attrib_name in attribs:
14965 editor.replace_expression(self.code(), attribs[self.attrib_name])
14966 else:
14967 editor.insert_expression(self.code_item, self.code())
14968 </t>
14969 <t tx="michael.20060727171523.10">class ScenarioView(editorlib.MainView):
14970 __model__ = ScenarioContainer
14971 __view_name__ = "default"
14972 vgap = 0
14975 format = _("""
14976 error(Static)
14977 lbl_error
14978 new|(0,3)|remove
14979 (0,3)&gt;
14980 --&gt;
14981 notebook(Page_default[_default])&gt;
14982 (0,3)&gt;
14983 --&gt;
14984 (0,3)
14985 (buttons)&gt;
14986 """)
14989 @others</t>
14990 <t tx="michael.20060727171523.11">def create_controls(self):
14991 self.new = self.get_button(_("Add Scenario"))
14992 self.remove = self.get_button(_("Remove Scenario"))
14994 def new_scenario():
14995 simodel = NewScenario(self.imodel)
14996 simodel.show(self)
14998 self.new.attach(new_scenario)
14999 self.remove.attach(self.remove_scenario)
15002 </t>
15003 <t tx="michael.20060727171523.12">def prepare(self):
15004 self.grow_col(-1)
15005 self.grow_row(5)
15006 self.buttons.grow_col(0)
15007 self.error.Hide()
15008 self.error.SetForegroundColour(self.error_colour)
15009 self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
15010 lambda e: self.update_remove_button())
15011 self.update_remove_button()
15013 def update_remove_button(self):
15014 if self.remove:
15015 self.remove.Enable(self.notebook.GetSelection() != 0)
15016 </t>
15017 <t tx="michael.20060727171523.13">def constitute(self, imodel):
15018 super(ScenarioView, self).constitute(imodel)
15019 for s in self.imodel.scenarios:
15020 if s != "_default":
15021 page = self.create_subform(self.notebook, "Page%s" % s)
15022 page.inspect(self.imodel, s)
15023 self.notebook.AddPage(page, s)
15025 if imodel.error: self.error.Show()
15026 self.update_remove_button()</t>
15027 <t tx="michael.20060727171523.14">def update_scenarios(self):
15028 self.scenario.Clear()
15029 map(self.scenario.Append, self.imodel.get_scenarios())
15030 </t>
15031 <t tx="michael.20060727171740">def get_code_root(code_item):
15032 item = code_item
15033 while item:
15034 last = item
15035 item = item.get_parent()
15037 return last</t>
15038 <t tx="michael.20060727172857"></t>
15039 <t tx="michael.20060727172857.1">class SimpleContainer(db.Model):
15040 attrib_name = db.Text()
15041 child = db.Model.type()
15042 error = db.Text()
15043 @others</t>
15044 <t tx="michael.20060727172857.2">def __init__(self, child_model, context, attrib_name, evaluator, default):
15045 self.attrib_name = attrib_name
15046 self.code_item = code_item = context.code_item
15047 &lt;&lt; calculate attribute value &gt;&gt;
15048 self.child = child_model(code_item, attrib_name, value)
15050 </t>
15051 <t tx="michael.20060727172857.6">def show(self):
15052 #no wizzard while processing
15053 if controller().is_processing(): return
15055 dlg = editorlib.PatchedDialog(controller().frame, -1,
15056 _("Edit %s") % self.attrib_name,
15057 style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
15059 dlg.SetClientSize((10, 10))
15060 view = self.constitute()(dlg)
15061 view.layout()
15062 dlg.simulate_modal(self.code_item.editor)</t>
15063 <t tx="michael.20060727172857.7">def code(self):
15064 return "%s = %s" % (self.attrib_name, unicode(self.child))</t>
15065 <t tx="michael.20060727172857.8">def realize(self):
15066 editor = self.code_item.editor
15067 attribs = editor.get_attribs(self.code_item)
15068 if self.attrib_name in attribs:
15069 editor.replace_expression(self.code(), attribs[self.attrib_name])
15070 else:
15071 editor.insert_expression(self.code_item, self.code())
15072 </t>
15073 <t tx="michael.20060727172857.10">class SimpleView(editorlib.MainView):
15074 __model__ = SimpleContainer
15075 __view_name__ = "default"
15076 vgap = 0
15078 format = _("""
15079 error(Static)
15080 lbl_error
15081 child&gt;
15082 (0,3)&gt;
15083 --&gt;
15084 (0,3)
15085 (buttons)&gt;
15086 """)
15088 @others</t>
15089 <t tx="michael.20060727172857.12">def prepare(self):
15090 self.grow_col(-1)
15091 self.grow_row(2)
15092 self.buttons.grow_col(0)
15093 self.error.Hide()
15094 self.error.SetForegroundColour(self.error_colour)</t>
15095 <t tx="michael.20060727172857.13">def constitute(self, imodel):
15096 super(SimpleView, self).constitute(imodel)
15097 if imodel.error: self.error.Show()
15098 </t>
15099 <t tx="michael.20060727174303">class AttributeEditor(AttributeEditor):
15100 evaluator = TaskEvaluator
15101 </t>
15102 <t tx="michael.20060727174639">attribs = code_item.editor.get_attribs(self.code_item)
15103 if self.attrib_name in attribs:
15104 line = attribs[self.attrib_name]
15105 expression = code_item.editor.get_expression(line)
15106 else:
15107 expression = ""
15109 evaluation = evaluator(expression, context)
15110 try:
15111 self.error = "%s: %s" % (evaluation.error.__class__.__name__, \
15112 str(evaluation.error))
15113 value = default
15114 except AttributeError:
15115 if expression:
15116 value = evaluation.attributes.get(attrib_name)
15117 else:
15118 value = default
15120 </t>
15121 <t tx="michael.20060727180105.1"></t>
15122 <t tx="michael.20060727180230"></t>
15123 <t tx="michael.20060727180230.1">class Float(db.Model):
15124 value = db.Float()
15126 @others</t>
15127 <t tx="michael.20060727180230.2">def __init__(self, code_item, attrib, value):
15128 super(Float, self).__init__()
15129 self.value = float(value or 0.0)</t>
15130 <t tx="michael.20060727180230.3">def __str__(self):
15131 return '%.02f' % self.__value
15132 </t>
15133 <t tx="michael.20060727180230.4">class FloatView(views.FormView):
15134 __model__ = Float
15135 __view_name__ = "default"
15136 vgap = 0
15137 format = "value"</t>
15138 <t tx="michael.20060727180601"></t>
15139 <t tx="michael.20060727180601.1">class Boolean(db.Model):
15140 value = db.Boolean()
15142 @others</t>
15143 <t tx="michael.20060727180601.2">def __init__(self, code_item, attrib, value):
15144 super(Boolean, self).__init__()
15145 self.value = bool(value)
15147 </t>
15148 <t tx="michael.20060727180601.3">def __str__(self):
15149 return self.__value and "True" or "False"
15150 </t>
15151 <t tx="michael.20060727180601.4">class BooleanView(views.FormView):
15152 __model__ = Boolean
15153 __view_name__ = "default"
15154 vgap = 0
15155 format = "value(BoolEnum)"
15157 </t>
15158 <t tx="michael.20060728142041"></t>
15159 <t tx="michael.20060728142041.1">class Int(db.Model):
15160 value = db.Int()
15162 @others</t>
15163 <t tx="michael.20060728142041.2">def __init__(self, code_item, attrib, value):
15164 super(Int, self).__init__()
15165 self.value = int(value or 0)</t>
15166 <t tx="michael.20060728142041.3">def __str__(self):
15167 return '%i' % self.__value
15168 </t>
15169 <t tx="michael.20060728142041.4">class IntView(views.FormView):
15170 __model__ = Int
15171 __view_name__ = "default"
15172 vgap = 0
15173 format = "value"</t>
15174 <t tx="michael.20060728153537"></t>
15175 <t tx="michael.20060728153537.1">class ResourceNames(db.Enumerate):
15176 def __init__(self):
15177 super(ResourceNames, self).__init__({"" : ""})
15180 def fill(self, model):
15181 encoding = model.get_encoding()
15182 self.choices.clear()
15184 for d, r in model.resources.iteritems():
15185 if r.name != "Resource":
15186 self.choices[d] = r.title.decode(encoding)
15189 </t>
15190 <t tx="michael.20060728153749">def weekdays():
15191 dt = faces.pcalendar.Calendar.EPOCH
15192 return dict(map(lambda d: (d - 1, dt.replace(day=d).strftime("%A")),
15193 range(1, 8)))
15196 class WorkingTime(db.Model):
15197 day = db.Enumerate(weekdays())
15198 start = db.Time(format="HHMM")
15199 end = db.Time(format="HHMM")</t>
15200 <t tx="michael.20060728153749.1">class WorkingTimes(db.Model):
15201 @others
15203 db.Relation("workingtime",
15204 db.End(WorkingTime, "workingtimes", multi='*'),
15205 db.End(WorkingTimes))</t>
15206 <t tx="michael.20060728153749.2">def __init__(self, code_item, attrib, value):
15207 super(WorkingTimes, self).__init__()
15209 cal = pcalendar.Calendar()
15210 for item in value or ():
15211 cal.set_working_days(*item)
15213 default = pcalendar.DEFAULT_WORKING_DAYS
15214 for d in range(0, 7):
15215 slots = cal.working_times.get(d, default[d])
15216 for start, end in slots:
15217 start = datetime.time(start / 60, start % 60)
15218 end = datetime.time(end / 60, end % 60)
15219 self.workingtimes.insert(\
15220 WorkingTime(day = d, start=start, end=end))</t>
15221 <t tx="michael.20060728153749.3">def __str__(self):
15222 day_names = ("mon", "tue", "wed", "thu", "fri", "sat", "sun")
15223 day_times = {}
15224 for t in self.workingtimes:
15225 start, end = t.start.strftime("%H:%M"), t.end.strftime("%H:%M")
15226 day_times.setdefault(t.day, []).append('"%s-%s"' % (start, end))
15228 tr = []
15229 def make_day(day):
15230 try:
15231 return '("%s", %s)' % (day_names[day],
15232 ", ".join(day_times[day]))
15233 except KeyError:
15234 return '("%s", ())' % day_names[day]
15236 tr = map(make_day, range(0, 7))
15237 return '[%s]' % ",\n".join(tr)</t>
15238 <t tx="michael.20060728153749.4">class WorkingTimesView(views.FormView):
15239 __model__ = WorkingTimes
15240 __view_name__ = "default"
15241 vgap = 0
15242 format = """
15243 workingtimes&gt;
15244 delete
15246 def create_controls(self):
15247 self.workingtimes = self.get_control("workingtimes(WorkingTimeGrid)")
15248 self.delete = self.workingtimes.get_delete_button(self)
15250 def prepare(self):
15251 self.grow_col(0)
15252 self.grow_row(0)</t>
15253 <t tx="michael.20060728153749.5">class WorkingTimeGrid(grid.EditGrid, views.GridView):
15254 __model__ = WorkingTime
15255 columns = ((__model__.day, _("Day")),
15256 (__model__.start, _("From")),
15257 (__model__.end, _("To")))
15258 resize_col = 0</t>
15259 <t tx="michael.20060728153909"></t>
15260 <t tx="michael.20060729171506">def create_editor_menu(menu, context, editors):
15261 #editors is a pair consisting of ("path", attrib_editor)
15262 &lt;&lt; define improve_duplicate_names &gt;&gt;
15263 &lt;&lt; define make_groups &gt;&gt;
15264 &lt;&lt; define create_menu &gt;&gt;
15265 editors = make_groups(editors)
15266 create_menu(menu, editors)
15267 if editors:
15268 menu.make_separator(tuple(menu)[-1].title)
15270 </t>
15271 <t tx="michael.20060801124835">def improve_duplicate_names(editors):
15272 if len(editors[0][0].split("/")) &lt; 2:
15273 #path has no group
15274 return editors
15276 counts = { }
15277 for path, editor in editors:
15278 name = path.split("/")[-1]
15279 counts[name] = counts.get(name, 0) + 1
15281 result = []
15282 for path, editor in editors:
15283 path = path.split("/")
15284 name = path[-1]
15285 if counts[name] &gt; 1:
15286 group = path[-2]
15287 result.append(("%s (%s)" % (name, group), editor))
15288 else:
15289 result.append((name, editor))
15291 return result</t>
15292 <t tx="michael.20060801124835.1">def make_groups(editors):
15294 If there are more than 10 editors arange them in groups
15296 if len(editors) &lt;= 10:
15297 return improve_duplicate_names(editors)
15299 groups = {}
15300 for name, ie in editors:
15301 path = name.split("/")
15302 gl = groups.setdefault(path[0], [])
15303 gl.append(("/".join(path[1:]), ie))
15305 for g, e in groups.iteritems():
15306 if len(g.split("/")) &gt; 1:
15307 groups[g] = make_groups(e)
15309 return groups.items()</t>
15310 <t tx="michael.20060801124835.2">def make_call(item_editor):
15311 def call(): item_editor.activate(context)
15312 return call
15315 def create_menu(parent_menu, editors):
15316 editors.sort()
15317 was_list = False
15318 for name, ie in editors:
15319 path = name.split("/")
15320 menu_title = path[0]
15321 menu_pos = -1
15323 &lt;&lt; extract menu position from title &gt;&gt;
15325 if isinstance(ie, list):
15326 create_menu(parent_menu.make_menu(menu_title, pos=menu_pos), ie)
15327 if not was_list: parent_menu.make_separator(menu_title, True)
15328 was_list = True
15329 else:
15330 parent_menu.make_temp_item(menu_title, make_call(ie), pos=menu_pos,
15331 bitmap=getattr(ie, "__icon__", None))
15332 was_list = False
15333 </t>
15334 <t tx="michael.20060804041654">@language python
15335 &lt;&lt; Copyright &gt;&gt;
15337 A collection of functions for editing tasks and their attributes
15339 &lt;&lt; Imports &gt;&gt;
15341 _is_source_ = True
15342 _ = faces.plocale.get_gettext()
15344 @others</t>
15345 <t tx="michael.20060804041820">registry = context.CResource.editors
15346 std_attributes = _("Standard/%s")
15348 registry[std_attributes % "title..."] = AttributeEditor("title", String, _("Title"))
15349 registry[std_attributes % "max_load..."] = AttributeEditor("max_load", Float, 1.0)
15350 registry[std_attributes % "vacation..."] = AttributeEditor("vacation", DateTimeRanges)
15351 registry[std_attributes % "efficiency..."] = AttributeEditor("efficiency", Float, 1.0)
15352 registry[std_attributes % "Create Resource...(1000)"] = ResourceCreator()
15353 registry[std_attributes % "Rename...(1010)"] = ResourceRenamer()
15354 registry[std_attributes % "Remove...(1020)"] = ResourceRemover()
15355 registry[std_attributes % "Show References...(1900)"] = ReferencePrinter()
15356 del std_attributes
15358 </t>
15359 <t tx="michael.20060804041905">import sys
15360 import faces.plocale
15361 from attribedit import *
15362 import editorlib
15363 try:
15365 except NameError:
15366 from sets import Set as set</t>
15367 <t tx="michael.20060804044438">@language python
15368 &lt;&lt; Copyright &gt;&gt;
15370 A collection of functions for editing tasks and their attributes
15372 &lt;&lt; Imports &gt;&gt;
15374 _is_source_ = True
15375 _ = faces.plocale.get_gettext()
15377 @others</t>
15378 <t tx="michael.20060804044438.1">############################################################################
15379 # Copyright (C) 2005, 2006 by Reithinger GmbH
15380 # mreithinger@web.de
15382 # This file is part of faces.
15384 # faces is free software; you can redistribute it and/or modify
15385 # it under the terms of the GNU General Public License as published by
15386 # the Free Software Foundation; either version 2 of the License, or
15387 # (at your option) any later version.
15389 # faces is distributed in the hope that it will be useful,
15390 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15391 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15392 # GNU General Public License for more details.
15394 # You should have received a copy of the GNU General Public License
15395 # along with this program; if not, write to the
15396 # Free Software Foundation, Inc.,
15397 # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15398 ############################################################################
15400 </t>
15401 <t tx="michael.20060804044438.2">import sys
15402 import inspect
15403 import faces.plocale
15404 import faces.task as ftask
15405 import faces.observer as fobserver
15406 import matplotlib.font_manager as fm
15407 import metapie.gui.pyeditor as pyeditor
15408 import docparser
15409 from metapie.gui.controller import ResourceManager
15410 from attribedit import *
15411 import editorlib
15412 try:
15414 except NameError:
15415 from sets import Set as set</t>
15416 <t tx="michael.20060804044506"></t>
15417 <t tx="michael.20060804044506.1">class AttributeEditor(AttributeEditor):
15418 evaluator = ObserverEvaluator
15419 @others
15420 </t>
15421 <t tx="michael.20060804120410"></t>
15422 <t tx="michael.20060804121345">def register_editors(cls, registry):
15423 super(MatplotChart, cls).register_editors(registry)
15424 registry.Boolean(_("Shape/show_tips..."))
15425 registry.Boolean(_("Chart/scroll_bars..."))
15426 registry.Property(_("Chart/properties..."), cls.create_property_groups)
15428 register_editors = classmethod(register_editors)
15430 def create_property_groups(cls, property):
15431 property.set_default_groups()
15433 create_property_groups = classmethod(create_property_groups)</t>
15434 <t tx="michael.20060804132135">def register_editors(cls, registry):
15435 super(TimeWidgetChart, cls).register_editors(registry)
15436 registry.String(_("Chart/sharex..."), "time_share")
15437 registry.Boolean(_("Chart/show_rowlines..."), False)
15438 registry.Boolean(_("Chart/auto_scale_y..."), True)
15441 register_editors = classmethod(register_editors)</t>
15442 <t tx="michael.20060804133122">def register_editors(cls, registry):
15443 #"time_axis_properties" : 'time_axis_properties = { | }',
15444 super(TimeAxisChart, cls).register_editors(registry)
15445 registry.Boolean(_("Axis/show_grid..."), True)
15446 registry.Boolean(_("Axis/show_scale..."), True)
15447 registry.Boolean(_("Axis/show_free_time..."), True)
15448 registry.Boolean(_("Axis/show_now..."), True)
15449 registry.Property(_("Axis/time_axis_properties..."), cls.create_time_axis_property_groups)
15451 register_editors = classmethod(register_editors)
15453 def create_time_axis_property_groups(cls, property):
15454 property.fill_gc_group("")
15455 property.fill_font_group("")
15456 property.fill_gc_group("now")
15457 property.fill_gc_group("grid")
15458 property.fill_font_group("0")
15459 property.name_groups.append("0.facecolor")
15460 property.name_groups.append("tickers")
15461 property.name_groups.append("facecolor")
15462 property.name_groups.append("free.facecolor")
15463 for t in range(3):
15464 property.fill_font_group(str(t))
15465 property.name_groups.append("%s.facecolor" % str(t))
15468 create_time_axis_property_groups = classmethod(create_time_axis_property_groups)</t>
15469 <t tx="michael.20060804140428"></t>
15470 <t tx="michael.20060804140428.1"></t>
15471 <t tx="michael.20060804140428.2">class MultiEvaluation(db.Model):
15473 An editor for a combination of a modules project data
15475 operator = db.Enumerate({"unify" : _("Unify"),
15476 "intersect" : _("Intersect"),
15477 "difference" : _("Difference") },
15478 default="unify")
15480 @others
15482 db.Relation("evals",
15483 db.End(Evaluation, "evals", multi='*'),
15484 db.End(MultiEvaluation))</t>
15485 <t tx="michael.20060804140428.3">def __init__(self, code_item, attrib, value):
15486 super(MultiEvaluation, self).__init__()
15487 Evaluation.__attributes_map__["value"].fill(code_item.editor.model)
15489 if isinstance(value, tuple):
15490 try:
15491 self.operator = value[0]
15492 except db.ConstraintError:
15493 pass
15494 else:
15495 for ed in value[1]:
15496 self.evals.insert(Evaluation(code_item=code_item, value=ed))
15497 elif isinstance(value, ftask._ProjectBase):
15498 self.evals.insert(Evaluation(code_item=code_item, value=value))
15501 </t>
15502 <t tx="michael.20060804140428.7">def __str__(self):
15503 evals = map(str, self.evals)
15504 if len(evals) &gt; 1:
15505 return "%s(%s)" % (self.operator, ", ".join(evals))
15507 if evals:
15508 return evals[0]
15510 return "()"
15511 </t>
15512 <t tx="michael.20060804140428.8">class MultiEvaluationView(views.FormView):
15513 __model__ = MultiEvaluation
15514 __view_name__ = "default"
15515 vgap = 0
15516 format = _("""
15517 [Operator:]
15518 operator
15519 (0,3)
15520 [Evaluations:]
15521 evals&gt;
15522 (0,3)
15523 delete
15524 """)
15526 @others
15527 </t>
15528 <t tx="michael.20060804140428.9">def create_controls(self):
15529 self.evals = self.get_control("evals(EvaluationGrid)")
15530 self.delete = self.evals.get_delete_button(self)</t>
15531 <t tx="michael.20060804140428.10">def prepare(self):
15532 self.grow_col(0)
15533 self.grow_row(3)</t>
15534 <t tx="michael.20060804140428.12">class Evaluation(db.Model):
15535 value = EvaluationNames()
15537 @others
15538 </t>
15539 <t tx="michael.20060804140428.13">def __str__(self):
15540 return self.value
15541 </t>
15542 <t tx="michael.20060804140428.15">class EvaluationGrid(grid.EditGrid, views.GridView):
15543 __model__ = Evaluation
15544 columns = (("value", _("Name")),)
15545 resize_col = 0
15548 </t>
15549 <t tx="michael.20060804141028">class EvaluationNames(db.Enumerate):
15550 def __init__(self):
15551 super(EvaluationNames, self).__init__({"" : ""})
15554 def fill(self, model):
15555 self.choices.clear()
15557 for k, v in model.evaluations.iteritems():
15558 self.choices[k] = k
15559 </t>
15560 <t tx="michael.20060804143857">class Resource(db.Model):
15561 name = ResourceNames()
15562 load = db.Float(precision=2, default=1.0)
15563 efficiency = db.Float(precision=2, default=1.0)
15565 def __init__(self, resource=None):
15566 super(Resource, self).__init__()
15567 if resource is None:
15568 self.load = 1.0
15569 self.efficiency = 1.0
15570 self.name = self.__attributes_map__["name"].default()
15571 else:
15572 self.name = resource.name
15573 self.load = getattr(resource, "load", 1.0)
15574 self.efficiency = resource.efficiency
15577 def __str__(self):
15578 src = self.parent.model.resources[self.name]
15580 args = []
15581 if self.load != 1.0:
15582 args.append("load=%.02f" % self.load)
15584 if self.efficiency != src.efficiency:
15585 args.append("efficiency=%.02f" % self.efficiency)
15587 if args: return "%s(%s)" % (self.name, ", ".join(args))
15588 return self.name</t>
15589 <t tx="michael.20060804143857.1">class ResourceSet(db.Model):
15590 @others
15592 db.Relation("resources",
15593 db.End(Resource, "resources", multi='*'),
15594 db.End(ResourceSet, "parent", multi=1))</t>
15595 <t tx="michael.20060804143857.2">class ResourceSetView(views.FormView):
15596 __model__ = ResourceSet
15597 __view_name__ = "default"
15598 vgap = 0
15599 format = """
15600 resources&gt;
15601 delete
15603 def create_controls(self):
15604 self.resources = self.get_control("resources(ResourceGrid)")
15605 self.delete = self.resources.get_delete_button(self)
15607 def prepare(self):
15608 self.grow_col(0)
15609 self.grow_row(0)</t>
15610 <t tx="michael.20060804143857.3">class ResourceGrid(grid.EditGrid, views.GridView):
15611 __model__ = Resource
15612 columns = ((__model__.name, _("Resource")),
15613 (__model__.load, _("Load")),
15614 (__model__.efficiency, _("Efficiency")))
15615 resize_col = 0</t>
15616 <t tx="michael.20060804145158"></t>
15617 <t tx="michael.20060804145403">class EvaluationView(views.FormView):
15618 __model__ = Evaluation
15619 __view_name__ = "default"
15620 vgap = 0
15621 format = "value"</t>
15622 <t tx="michael.20060804145710">def __init__(self, code_item=None, attrib=None, value=None):
15623 super(Evaluation, self).__init__()
15625 eval_type = Evaluation.__attributes_map__["value"]
15626 if attrib:
15627 eval_type.fill(code_item.editor.model)
15629 if value:
15630 model = code_item.editor.model
15631 for name, data in model.evaluations.iteritems():
15632 if value is data:
15633 self.value = name
15634 break
15635 else:
15636 self.value = eval_type.choices.keys()[0]
15638 </t>
15639 <t tx="michael.20060804151253">class ObserverEvaluator(object):
15640 def __init__(self, expression, context):
15641 vars = { "unify" : lambda *args: ("unify", args),
15642 "intersect" : lambda *args: ("intersect", args),
15643 "difference" : lambda *args: ("difference", args), }
15644 try:
15645 editor = context.code_item.editor
15646 self.attributes = editor.eval_expression(expression, vars, context)
15647 except Exception, e:
15648 self.error = e
15653 </t>
15654 <t tx="michael.20060804152844">def register_editors(cls, registry):
15655 super(TableChart, cls).register_editors(registry)
15656 registry.Boolean(_("Chart/show_rowlines..."), False)
15657 registry.Boolean(_("Chart/show_collines..."), False)
15660 register_editors = classmethod(register_editors)</t>
15661 <t tx="michael.20060804153528">def register_editors(cls, registry):
15662 super(Gantt, cls).register_editors(registry)
15663 registry.Boolean(_("Shape/show_resource..."), True)
15664 registry.Boolean(_("Chart/show_connectors..."), True)
15665 registry.Boolean(_("Shape/show_complete..."), True)
15666 registry.String(_("Chart/row_attrib..."), "gantt_same_row")
15667 registry.String(_("Chart/accumulate_attrib..."), "gantt_accumulate")
15668 registry.String(_("Chart/shape_attrib..."), "gantt_shape")
15669 registry.String(_("Chart/shape_properties_attrib..."), "gantt_properties")
15670 registry.Shape(_("Shape/parent_shape..."), "brace")
15671 registry.Symbol(_("Shape/milestone_shape..."), "diamond")
15672 registry.Shape(_("Shape/leaf_shape..."), "bar")
15673 registry.String(_("Shape/title_attrib..."), "title")
15675 register_editors = classmethod(register_editors)
15677 def create_property_groups(cls, property):
15678 property.set_default_groups()
15679 property.name_groups.append("bar.height")
15680 property.name_groups.append("complete.height")
15681 property.name_groups.append("magnification")
15682 property.name_groups.append("up")
15684 def add_group(group):
15685 property.fill_font_group(group)
15687 shape = getattr(cls, group + "_shape", "")
15688 if shape.find("_bar_") &gt; 0:
15689 property.name_groups.append(group + ".bar.height")
15690 property.name_groups.append(group + ".complete.height")
15691 property.name_groups.append(group + ".start.magnification")
15692 property.name_groups.append(group + ".end.magnification")
15693 property.name_groups.append(group + ".start.up")
15694 property.name_groups.append(group + ".end.up")
15695 property.fill_patch_group(group + ".complete")
15696 property.fill_patch_group(group + ".bar")
15697 property.fill_patch_group(group + ".start")
15698 property.fill_patch_group(group + ".end")
15699 else:
15700 property.fill_patch_group(group)
15702 if shape == "bar":
15703 property.fill_patch_group(group + ".complete")
15704 property.fill_font_group(group + ".inside")
15706 elif shape in faces.charting.shapes.symbols:
15707 property.name_groups.append(group + ".magnification")
15709 add_group("parent")
15710 add_group("leaf")
15711 add_group("milestone")
15715 create_property_groups = classmethod(create_property_groups)</t>
15716 <t tx="michael.20060804154017">def register_editors(cls, registry):
15717 super(Compare, cls).register_editors(registry)
15718 registry.ColorSet(_("Shape/colors..."), ("navy", "seagreen", "indianred"))
15719 registry.MultiEvaluation(_("Chart/data..."))
15722 register_editors = classmethod(register_editors)
15723 </t>
15724 <t tx="michael.20060804154418"></t>
15725 <t tx="michael.20060804154418.1"></t>
15726 <t tx="michael.20060804154418.2">class Standard(Gantt):
15727 __doc__ = _("""
15728 A Standard gantt chart.
15729 """)
15731 @others
15732 </t>
15733 <t tx="michael.20060804154609">def register_editors(cls, registry):
15734 super(Standard, cls).register_editors(registry)
15735 registry.Evaluation(_("Chart/data..."))
15738 register_editors = classmethod(register_editors)
15739 </t>
15740 <t tx="michael.20060804155401"></t>
15741 <t tx="michael.20060804160034">def __init__(self, code_item, attrib, value):
15742 super(ResourceSet, self).__init__()
15743 self.model = code_item.editor.model
15744 Resource.__attributes_map__["name"].fill(self.model)
15746 for r in value and value()._get_resources(0) or ():
15747 self.resources.insert(Resource(r))</t>
15748 <t tx="michael.20060804160034.1">def __str__(self):
15749 return " &amp; ".join(map(str, self.resources))</t>
15750 <t tx="michael.20060804160034.2">def check_constraints(self):
15751 error = db.ConstraintError()
15753 res = { }
15754 for r in self.resources:
15755 if r.name in res:
15756 error.message["resources"] = \
15757 _("Resource '%s' is specified twice.") \
15758 % r.name
15759 break
15761 res[r.name] = True
15763 if error.message:
15764 raise error</t>
15765 <t tx="michael.20060804161145">class Color(db.Model):
15766 value = db.Text()
15768 def __str__(self):
15769 return '"%s"' % self.value
15771 </t>
15772 <t tx="michael.20060804161145.1">class ColorGrid(grid.EditGrid, views.GridView):
15773 __model__ = Color
15774 columns = (("value(Color)", _("Value")),)
15775 resize_col = 0</t>
15776 <t tx="michael.20060804161145.2">class ColorSet(db.Model):
15777 def __init__(self, code_item, attrib, value):
15778 super(ColorSet, self).__init__()
15779 for c in value or ():
15780 self.colors.insert(Color(value=c))
15783 def __str__(self):
15784 return "[%s]" % ", ".join(map(str, self.colors))
15787 db.Relation("colors",
15788 db.End(Color, "colors", multi='*'),
15789 db.End(ColorSet))</t>
15790 <t tx="michael.20060804161145.3">class ColorSetView(views.FormView):
15791 __model__ = ColorSet
15792 __view_name__ = "default"
15793 vgap = 0
15794 format = """
15795 colors&gt;
15796 delete
15798 def create_controls(self):
15799 self.colors = self.get_control("colors(ColorGrid)")
15800 self.delete = self.colors.get_delete_button(self)
15802 def prepare(self):
15803 self.grow_col(0)
15804 self.grow_row(0)</t>
15805 <t tx="michael.20060804162848"></t>
15806 <t tx="michael.20060804162848.1">class ColorLimit(db.Model):
15807 limit = db.Text()
15808 color = db.Text()
15810 def check_constraints(self):
15811 error = db.ConstraintError()
15812 try:
15813 faces.pcalendar.to_timedelta(self.limit)
15814 except ValueError, e:
15815 error.message["limit"] = str(e)
15816 raise error
15819 def __str__(self):
15820 return '"%s" : "%s"' % (self.limit, self.color)
15821 </t>
15822 <t tx="michael.20060804162848.2">class ColorLimitGrid(grid.EditGrid, views.GridView):
15823 __model__ = ColorLimit
15824 columns = (("limit", _("&lt; Limit")),
15825 ("color(Color)", _("Color")))
15826 resize_col = 0
15827 </t>
15828 <t tx="michael.20060804162848.3">class ColorMap(db.Model):
15829 def __init__(self, code_item, attrib, value):
15830 super(ColorMap, self).__init__()
15831 for limit, color in value.iteritems() or ():
15832 self.colors.insert(ColorLimit(limit=limit, color=color))
15835 def __str__(self):
15836 return "{%s}" % ",\n".join(map(str, self.colors))
15839 db.Relation("colors",
15840 db.End(ColorLimit, "colors", multi='*'),
15841 db.End(ColorMap))</t>
15842 <t tx="michael.20060804162848.4">class ColorMapView(views.FormView):
15843 __model__ = ColorMap
15844 __view_name__ = "default"
15845 vgap = 0
15846 format = """
15847 colors&gt;
15848 delete
15850 def create_controls(self):
15851 self.colors = self.get_control("colors(ColorGrid)")
15852 self.delete = self.colors.get_delete_button(self)
15854 def prepare(self):
15855 self.grow_col(0)
15856 self.grow_row(0)</t>
15857 <t tx="michael.20060804163807">def register_editors(cls, registry):
15858 super(Critical, cls).register_editors(registry)
15859 registry.ColorMap(_("Shape/colors..."), { "0d" : "red" })
15862 register_editors = classmethod(register_editors)
15863 </t>
15864 <t tx="michael.20060804165131"></t>
15865 <t tx="michael.20060804165454">class Symbol(String): pass
15866 class SymbolView(StringView):
15867 __model__ = Symbol
15868 __view_name__ = "default"
15869 format = "value(SymbolCombo)&gt;"
15871 </t>
15872 <t tx="michael.20060804171822">class Shape(String): pass
15873 class ShapeView(StringView):
15874 __model__ = Shape
15875 __view_name__ = "default"
15876 format = "value(ShapeCombo)&gt;"
15878 </t>
15879 <t tx="michael.20060804172453">class PropertyEditor(AttributeEditor):
15880 @others
15881 </t>
15882 <t tx="michael.20060804172453.3">def activate(self, context):
15884 activates the editor.
15886 imodel = super(PropertyEditor, self).activate(context)
15887 Property.init_groups()
15888 self.create_property_groups(Property)
15889 Property.apply_groups()
15890 return imodel
15893 </t>
15894 <t tx="michael.20060804180304">class SymbolCombo(widgets.Combo):
15895 def __init__(self, *args, **kwargs):
15896 widgets.Combo.__init__(self, *args, **kwargs)
15897 map(self.Append, faces.charting.shapes.symbols)</t>
15898 <t tx="michael.20060804180304.1">class ShapeCombo(widgets.Combo):
15899 def __init__(self, *args, **kwargs):
15900 widgets.Combo.__init__(self, *args, **kwargs)
15902 symbols = faces.charting.shapes.symbols
15903 shapes = ["%s_bar_%s" % (i, j) for i in symbols for j in symbols]
15904 shapes.append("bar")
15905 shapes.append("brace")
15906 shapes.sort()
15907 map(self.Append, shapes)</t>
15908 <t tx="michael.20060804180304.2">class BoolEnum(widgets.Enumerate):
15909 __type__ = db.Boolean
15911 def get_choices(self, itype):
15912 return { False : _("False"), True : _("True") }
15914 </t>
15915 <t tx="michael.20060804180304.3"></t>
15916 <t tx="michael.20060804183602"></t>
15917 <t tx="michael.20060804183602.1">class BoolEnum(BoolEnum):
15918 __type__ = db.Text</t>
15919 <t tx="michael.20060804183602.2">class FamilyCombo(widgets.Combo):
15920 def __init__(self, *args, **kwargs):
15921 widgets.Combo.__init__(self, *args, **kwargs)
15922 names = fm.fontManager.ttfdict.keys()
15923 names.sort()
15924 map(self.Append, names)</t>
15925 <t tx="michael.20060804183602.3">class WeightCombo(widgets.Combo):
15926 def __init__(self, *args, **kwargs):
15927 widgets.Combo.__init__(self, *args, **kwargs)
15928 choices = map(lambda kv: (kv[1], kv[0]), fm.weight_dict.items())
15929 choices.sort()
15930 map(self.Append, map(lambda vk: vk[1], choices))</t>
15931 <t tx="michael.20060804183602.4">class SizeCombo(widgets.Combo):
15932 def __init__(self, *args, **kwargs):
15933 widgets.Combo.__init__(self, *args, **kwargs)
15934 choices = map(lambda kv: (kv[1], kv[0]), fm.font_scalings.items())
15935 choices.sort()
15936 map(self.Append, map(lambda vk: vk[1], choices))</t>
15937 <t tx="michael.20060804183602.5">class VariantEnum(widgets.Enumerate):
15938 __type__ = db.Text
15940 def get_choices(self, itype):
15941 return { "capitals" : "capitals",
15942 "small-caps" : "small-caps",
15943 "normal" : "normal" }</t>
15944 <t tx="michael.20060804183602.6">class LinestyleEnum(widgets.Enumerate):
15945 __type__ = db.Text
15947 def get_choices(self, itype):
15948 return { "solid" : "solid",
15949 "dashed" : "dashed",
15950 "dashdot": "dashdot",
15951 "dotted" : "dotted" }</t>
15952 <t tx="michael.20060804183602.7">class JoinstyleEnum(widgets.Enumerate):
15953 __type__ = db.Text
15955 def get_choices(self, itype):
15956 return { "miter" : "miter",
15957 "round" : "round",
15958 "bevel" : "bevel" }</t>
15959 <t tx="michael.20060804183602.8">class StyleEnum(widgets.Enumerate):
15960 __type__ = db.Text
15962 def get_choices(self, itype):
15963 return { "italics" : "italics",
15964 "oblique" : "oblique",
15965 "normal" : "normal" }</t>
15966 <t tx="michael.20060804183602.9">class Property(db.Model):
15967 name_groups = []
15968 name = db.Text()
15969 value = db.Text()
15971 @others
15972 def check_constraints(self):
15973 error = db.ConstraintError()
15974 try:
15975 faces.charting.widgets.check_property(self.name, self.value)
15976 except ValueError, e:
15977 error = db.ConstraintError()
15978 error.message["value"] = str(e)
15979 raise error
15982 def _set_name(self, name):
15983 if self.value:
15984 try:
15985 faces.charting.widgets.check_property(name, self.value)
15986 return name
15987 except ValueError:
15988 pass
15990 self.__name = name
15991 if name.endswith("color"):
15992 self.value = "white"
15993 elif name.endswith("fill"):
15994 self.value = "True"
15995 elif name.endswith("width"):
15996 self.value = 1.0
15997 elif name.endswith("alpha"):
15998 self.value = 1.0
15999 elif name.endswith("height"):
16000 self.value = 4.0
16001 elif name.endswith("magnification"):
16002 self.value = 1.0
16003 elif name.endswith("family"):
16004 self.value = "sans-serif"
16005 elif name.endswith("weight"):
16006 self.value = "normal"
16007 elif name.endswith("size"):
16008 self.value = "medium"
16009 elif name.endswith("variant"):
16010 self.value = "normal"
16011 elif name.endswith("antialiased"):
16012 self.value = "True"
16013 elif name.endswith("up"):
16014 self.value = "True"
16015 elif name.endswith("linestyle"):
16016 self.value = "solid"
16017 elif name.endswith("joinstyle"):
16018 self.value = "miter"
16019 elif name.endswith("style"):
16020 self.value = "normal"
16021 elif name == "tickers":
16022 self.value = "1, 2"
16024 return name
16026 def _set_value(self, val):
16027 def name_is(*options):
16028 for o in options:
16029 if self.name.endswith(o): return True
16030 return False
16032 if name_is("width", "alpha", "magnification", "height"):
16033 try:
16034 val = float(val)
16035 except ValueError:
16036 val = 0.0
16037 elif name_is("fill", "antialiased", "up"):
16038 if str(val).upper() == "FALSE": val = False
16039 else: val = bool(val)
16040 elif name_is("size", "weight"):
16041 val = str(val)
16042 elif self.name == "tickers":
16043 val = str(val).replace("(", "").replace(")", "")
16044 val = tuple(map(int, val.split(",")))
16046 return val
16049 def __str__(self):
16050 def to_float(val):
16051 try:
16052 return "%.1f" % float(val)
16053 except ValueError:
16054 return "0.0"
16056 def to_string(val): return '"%s"' % val
16057 def to_int(val):
16058 try:
16059 return "%i" % int(val)
16060 except ValueError:
16061 return "0"
16063 def name_is(*options):
16064 for o in options:
16065 if self.name.endswith(o): return True
16066 return False
16068 formater = to_string
16069 if name_is("width", "alpha", "magnification", "height"):
16070 formater = to_float
16071 elif name_is("fill", "antialiased", "up"):
16072 formater = to_int
16073 elif self.name == "tickers":
16074 def formater(val):
16075 return "(%s, )" % ", ".join(map(str, val))
16076 elif name_is("size", "weight"):
16077 try:
16078 int(self.value)
16079 formater = to_int
16080 except ValueError:
16081 pass
16083 return '"%s" : %s' % (self.name, formater(self.value))
16086 def init_groups(cls):
16087 cls.name_groups = []
16089 init_groups = classmethod(init_groups)
16091 def fill_gc_group(cls, group):
16092 styles = ("edgecolor", "linewidth", "linestyle",
16093 "antialiased", "alpha", "joinstyle" )
16095 if group: group += "."
16096 cls.name_groups.extend(map(lambda s: group + s, styles))
16099 fill_gc_group = classmethod(fill_gc_group)
16101 def fill_patch_group(cls, group):
16102 styles = faces.charting.widgets._PropertyAware.patch_attribs
16103 cls.name_groups.extend(map(lambda s: group + "." + s, styles))
16105 fill_patch_group = classmethod(fill_patch_group)
16108 def fill_font_group(cls, group):
16109 styles = faces.charting.widgets._PropertyAware.font_attribs
16110 if group: group += "."
16111 cls.name_groups.extend(map(lambda s: group + s, styles))
16112 cls.name_groups.append(group + "color")
16114 fill_font_group = classmethod(fill_font_group)
16117 def apply_groups(cls):
16118 singulized = dict(zip(cls.name_groups, [0]*len(cls.name_groups)))
16119 cls.name_groups = singulized.keys()
16120 cls.name_groups.sort()
16122 apply_groups = classmethod(apply_groups)
16125 def set_default_groups(cls):
16126 cls.fill_gc_group("")
16127 cls.fill_font_group("")
16128 cls.name_groups.append("fill")
16129 cls.name_groups.append("facecolor")
16130 cls.name_groups.append("background.facecolor")
16131 cls.fill_patch_group("marker")
16132 cls.fill_patch_group("focused.marker")
16134 set_default_groups = classmethod(set_default_groups)</t>
16135 <t tx="michael.20060814190211">if length is not None:
16136 length = to_delta(max(length - (task.start - base_start), 0))</t>
16137 <t tx="michael.20060814190211.1">if duration is not None:
16138 delta = task.start.to_datetime() - base_start.to_datetime()
16139 delta = to_delta(delta, True)
16140 duration = to_delta(max(duration - delta, 0), True)</t>
16141 <t tx="michael.20060814190211.2">if end is not None:
16142 length = end - start
16143 if length &lt;= 0: return False</t>
16144 <t tx="michael.20060814190211.3">if effort is not None:
16145 effort -= task.performed_effort
16146 effort = to_delta(max(effort, 0))
16147 if effort &lt;= 0: return False
16149 if length is not None:
16150 #if length and effort is set, the load will be calculated
16151 length = length or task.calendar.minimum_time_unit
16152 loads = self._distribute_len_loads(task, resource,
16153 effort, length)
16154 def calc_load(res):
16155 return loads[res]
16156 else:
16157 #the length depends on the count of resources
16158 factor = sum(map(lambda a: a[0].efficiency * a[1],
16159 loads)) * task.efficiency
16160 length = effort / factor</t>
16161 <t tx="michael.20060814190211.4">if length is not None:
16162 adjust_date = lambda date: date
16163 delta = to_delta(length).round()
16164 else:
16165 assert(duration is not None)
16166 adjust_date = _to_datetime
16167 delta = datetime.timedelta(minutes=duration)</t>
16168 <t tx="michael.20060817115302">class NewScenario(db.Model):
16169 scenario = db.Text("_default")
16171 @others</t>
16172 <t tx="michael.20060817115302.1">class NewScenarioView(editorlib.MainView):
16173 __model__ = NewScenario
16174 __view_name__ = "default"
16175 format = ("""
16176 [Scenario: ]|scenario(Combo)
16177 --&gt;
16178 (buttons)&gt;
16179 """)
16181 format_buttons = """
16182 btn_ok{r}|btn_cancel{r}
16185 @others</t>
16186 <t tx="michael.20060817115418">def constitute(self, imodel):
16187 super(NewScenarioView, self).constitute(imodel)
16188 self.update_scenarios()
16190 </t>
16191 <t tx="michael.20060817140817">def add_scenario(self, name):
16192 if name in self.scenarios: return None
16193 child = self.child_model(self.code_item,
16194 self.attrib_name,
16195 self.default)
16196 setattr(self, "child_%s" % name, child)
16197 self.scenarios.append(name)
16198 return child</t>
16199 <t tx="michael.20060817142344">def add_scenario(self, scenario):
16200 child = self.imodel.add_scenario(scenario)
16201 if child:
16202 page = self.create_subform(self.notebook, "Page%s" % scenario)
16203 page.inspect(self.imodel, scenario)
16204 self.notebook.AddPage(page, scenario, True)
16205 self.remove.Enable(True)
16206 self.update_remove_button()
16208 </t>
16209 <t tx="michael.20060817144005">def modify_subview(self, subview_class, name):
16210 if not name.startswith("Page"): return subview_class
16211 me = self
16213 class Page(subview_class):
16214 format = "child_" + name[4:] + "&gt;"
16216 def get_control(self, name):
16217 if name.startswith("child_"):
16218 name = "child"
16220 return super(Page, self).get_control(name)
16222 def inspect_state(self):
16223 ichild = getattr(self.imodel, "child_%s" % name[4:])
16224 me.transaction.include(ichild)
16225 self.widgets["child"].inspect(self.imodel, "child_%s" % name[4:])
16228 def prepare(self):
16229 self.grow_col(0)
16230 self.grow_row(0)
16232 return Page</t>
16233 <t tx="michael.20060817145008">def remove_scenario(self):
16234 current = self.notebook.GetSelection()
16235 scenario = self.notebook.GetPageText(current)
16236 child = self.imodel.remove_scenario(scenario)
16237 if child:
16238 self.notebook.DeletePage(current)
16239 self.update_remove_button()
16240 #self.transaction.</t>
16241 <t tx="michael.20060817145008.1">def __init__(self, parent_imodel):
16242 self.parent_imodel = parent_imodel</t>
16243 <t tx="michael.20060817145008.2">def get_scenarios(self):
16244 scenarios = set()
16245 parent_imodel = self.parent_imodel
16246 try:
16247 scenarios.update(parent_imodel.code_item.obj.root.all_scenarios)
16248 except AttributeError:
16249 pass
16251 try:
16252 root = get_code_root(parent_imodel.code_item)
16253 scenarios.update(root.all_scenarios)
16254 except AttributeError:
16255 pass
16257 scenarios.update(parent_imodel.scenarios)
16258 return scenarios</t>
16259 <t tx="michael.20060817145008.3">def show(self, parent):
16260 dlg = editorlib.PatchedDialog(controller().frame, -1,
16261 _("Add Scenario"), style=wx.DEFAULT_DIALOG_STYLE)
16263 dlg.SetClientSize((10, 10))
16264 view = self.constitute()(dlg)
16265 view.layout()
16266 self.parent = parent
16267 dlg.simulate_modal(parent)</t>
16268 <t tx="michael.20060817145030">def realize(self):
16269 self.parent.add_scenario(self.scenario)</t>
16270 <t tx="michael.20060821115933">class EditorRegistry(object):
16271 def __init__(self):
16272 self.editors = {}
16275 def register(self, name, type, default):
16276 path = name.split("/")
16277 self.editors[name] = AttributeEditor(path[-1].rstrip("."),
16278 type, default)
16281 def unregister(self):
16282 cls_name = self.cls.__name__
16283 for path in self.editors.keys():
16284 if path.split("/")[0] == cls_name:
16285 del self.editors[path]
16288 def Boolean(self, name, default=True):
16289 self.register(name, Boolean, default)
16291 def Float(self, name, default=1.0):
16292 self.register(name, Float, default)
16295 def Date(self, name, default=None):
16296 self.register(name, Date, default or datetime.datetime.now())
16299 def String(self, name, default=""):
16300 self.register(name, String, default)
16303 def Symbol(self, name, default):
16304 self.register(name, Symbol, default)
16307 def Shape(self, name, default):
16308 self.register(name, Shape, default)
16311 def MultiEvaluation(self, name):
16312 self.register(name, MultiEvaluation, None)
16315 def Evaluation(self, name):
16316 self.register(name, Evaluation, None)
16319 def TwoColorSet(self, name, default):
16320 self.register(name, TwoColorSet, default)
16323 def ColorSet(self, name, default):
16324 self.register(name, ColorSet, default)
16327 def ColorMap(self, name, default):
16328 self.register(name, ColorMap, default)
16331 def Property(self, name, create_property_groups):
16332 path = name.split("/")
16333 self.editors[name] = \
16334 PropertyEditor(path[-1].rstrip("."),
16335 create_property_groups)
16338 def Column(self, name, data_name):
16339 path = name.split("/")
16340 self.editors[name] = ColumnEditor(path[-1].rstrip("."), data_name)
16342 </t>
16343 <t tx="michael.20060821122847">class PropertySet(db.Model):
16344 def __init__(self, code_item, attrib, value):
16345 super(PropertySet, self).__init__()
16346 for k, v in (value or {}).iteritems():
16347 self.properties.insert(Property(name=k, value=v))
16350 def __str__(self):
16351 return "{%s}" % ",\n".join(map(str, self.properties))
16354 db.Relation("properies",
16355 db.End(Property, "properties", multi='*'),
16356 db.End(PropertySet))</t>
16357 <t tx="michael.20060821191020">def __init__(self, attrib_name, create_property_groups):
16358 super(AttributeEditor, self).__init__(attrib_name, PropertySet)
16359 self.create_property_groups = create_property_groups
16360 </t>
16361 <t tx="michael.20060822214147">def register_editors(cls, registry):
16362 pass
16364 register_editors = classmethod(register_editors)
16366 </t>
16367 <t tx="michael.20060822215648">def get_editors(self):
16368 import faces.gui.editor.observer as gobserver
16370 try:
16371 obj = self.code_item.obj
16372 except AttributeError:
16373 obj = self.get_default_pseudo()
16375 registry = gobserver.EditorRegistry()
16376 obj.register_editors(registry)
16377 registry.editors.update(self.editors)
16378 return registry.editors
16379 </t>
16380 <t tx="michael.20060826120325">__assignment_pattern = re.compile(r'([^=#]+)=[^=]')
16382 def get_attribs(self, code_item):
16384 get all assigned attribs of code_item
16386 code_line = code_item.get_line()
16387 last_code_line = code_item.get_last_line() + 1
16388 lines = xrange(code_line, last_code_line)
16390 &lt;&lt; filter out child code &gt;&gt;
16392 if code_item.obj_type == pyeditor.FUNCTION:
16393 def get_attrib(line):
16394 text = self.GetLine(line)
16395 mo = self.__assignment_pattern.match(text)
16396 return mo and (mo.group(1).strip(), line)
16397 else:
16398 def get_attrib(line):
16399 text = self.GetLine(line)
16400 mo = self.__assignment_pattern.match(text)
16401 return mo and (mo.group(1).strip(), line)
16403 return dict(filter(bool, [ get_attrib(l) for l in lines ]))
16407 </t>
16408 <t tx="michael.20060826121701">nline = self.next_item_line(code_line + 1)
16409 if nline &lt; last_code_line:
16410 indent = self.GetLineIndentation(nline)
16411 lines = [ i for i in lines if self.GetLineIndentation(i) &lt;= indent ]</t>
16412 <t tx="michael.20060828215008">def register_editors(cls, registry):
16413 super(Standard, cls).register_editors(registry)
16414 registry.Evaluation(_("Report/data..."))
16415 registry.Column(_("Report/make_report..."), "data")
16417 register_editors = classmethod(register_editors)
16419 </t>
16420 <t tx="michael.20060828221603">def make_browser_menu(self, menu, action_filter=None):
16421 return False</t>
16422 <t tx="michael.20060828221643">def make_browser_menu(self, menu, action_filter=None):
16423 if not is_task(self.code_item): return False
16424 self.amend_browser_menu(menu, action_filter)
16425 return True
16426 </t>
16427 <t tx="michael.20060828221821"></t>
16428 <t tx="michael.20060828221821.1">def make_browser_menu(self, menu, action_filter=()):
16429 if is_resource(self.code_item) or "create" in action_filter:
16430 self.amend_browser_menu(menu, action_filter)
16431 return True
16433 return False</t>
16434 <t tx="michael.20060828221856"></t>
16435 <t tx="michael.20060828221856.1">def make_browser_menu(self, menu, action_filter=None):
16436 if is_observer(self.code_item) or "create" in action_filter:
16437 self.amend_browser_menu(menu, action_filter)
16438 return True
16440 return False
16441 </t>
16442 <t tx="michael.20060828221931">def make_browser_menu(self, menu, action_filter=None):
16443 if is_import(self.code_item) or "create" in action_filter:
16444 self.amend_browser_menu(menu, action_filter)
16445 return True
16447 return False</t>
16448 <t tx="michael.20060831002737">def insert_expression(self, code_item, text, move_cursor=True):
16450 insert the expression after the last non empty line
16451 before the first child
16453 self.BeginUndoAction()
16454 line = code_item.get_line()
16455 indent = code_item.indent
16456 next_line = self.next_item_line(line + 1)
16457 for i in range(next_line - 1, line - 1, -1):
16458 if self.GetLineIndentation(i) &gt; indent \
16459 and self.GetLine(i).strip():
16460 break
16462 start_line = i + 1
16463 text += "\n"
16464 if self.GetLine(start_line).strip():
16465 start_line -= 1
16466 text = "\n" + text
16468 start = self.GetLineEndPosition(start_line)
16469 self.InsertText(start, text)
16471 if move_cursor: self.GotoPos(start + len(text))
16473 lines = text.split("\n")
16474 self.UpdateWindowUI()
16475 &lt;&lt; auto indent text &gt;&gt;
16476 self.EndUndoAction()
16478 </t>
16479 <t tx="michael.20060901114003"></t>
16480 <t tx="michael.20060901114003.1">def make_browser_menu(self, menu, action_filter=None):
16481 if is_project(self.code_item) or "create" in action_filter:
16482 self.amend_browser_menu(menu, action_filter)
16483 return True
16485 return False
16486 </t>
16487 <t tx="michael.20060901185155">def _on_shash_pos_change(self, evt):
16488 width = self.GetClientSize()[0]
16489 sw = self.GetSashSize()
16490 if evt.GetSashPosition() &gt;= width - sw - 1:
16491 evt.SetSashPosition(width - sw - 1)
16492 self.SetSashGravity(1.0)
16493 else:
16494 self.SetSashGravity(0.0)</t>
16495 <t tx="michael.20060901185516">def register_editors(cls, registry):
16496 super(Critical, cls).register_editors(registry)
16497 registry.ColorMap(_("Shape/colors..."), { "0d" : "red" })
16499 register_editors = classmethod(register_editors)
16501 </t>
16502 <t tx="michael.20060901190834">class Balance(db.Model):
16503 value = db.Enumerate(ftask._allocator_strings)
16504 @others
16506 class BalanceView(views.FormView):
16507 __model__ = Balance
16508 __view_name__ = "default"
16509 vgap = 0
16510 format = "value&gt;"
16512 def prepare(self):
16513 self.grow_col(0)
16514 </t>
16515 <t tx="michael.20060901190851">def __init__(self, code_item, attrib, value):
16516 super(Balance, self).__init__()
16517 self.value = value or ftask.SMART</t>
16518 <t tx="michael.20060901190952">def __str__(self):
16519 return '%s' % ftask._allocator_strings[self.value]
16520 </t>
16521 <t tx="michael.20060901200906">class ColumnEditor(AttributeEditor):
16522 @others</t>
16523 <t tx="michael.20060901201020">def apply(self, expression, code_item):
16524 if code_item.obj_type == pyeditor.CLASS:
16525 if not expression:
16526 return self.attrib_name not in map(repr, code_item.get_children())
16528 return False
16530 if code_item.obj_type == pyeditor.FUNCTION:
16531 return code_item.name == self.attrib_name
16533 return False
16536 </t>
16537 <t tx="michael.20060901201827">def apply(self, expression, code_item):
16538 if code_item.obj_type != pyeditor.CLASS: return False
16539 return super(AttributeEditor, self).apply(expression, code_item)
16540 </t>
16541 <t tx="michael.20060901201924">def activate(self, context):
16543 activates the editor.
16545 code_item = context.code_item
16546 if code_item.obj_type == pyeditor.FUNCTION:
16547 code_item = code_item.get_parent()
16549 imodel = ColumnSet(context, self.attrib_name, self.data_name)
16550 imodel.show()
16551 return imodel
16554 </t>
16555 <t tx="michael.20060901202023">def __init__(self, attrib_name, data_name):
16556 self.attrib_name = attrib_name
16557 self.data_name = data_name</t>
16558 <t tx="michael.20060901205413">def make_button(self, button, expression):
16559 &lt;&lt; get editors &gt;&gt;
16561 applies = lambda ne: ne[1].apply("", self.code_item)
16562 editors = filter(applies, editors.iteritems())
16564 if len(editors) != 1:
16565 button.hide()
16566 return
16568 button.set_bitmap("edit16")
16569 item_editor = editors[0][1]
16570 def show_popup(editor):
16571 item_editor.activate(CObserver(self.code_item.get_parent()))
16573 button.action = show_popup
16574 button.Show()</t>
16575 <t tx="michael.20060901205826">import faces.gui.editor.observer as gobserver
16577 parent_item = self.code_item.get_parent()
16578 try:
16579 obj = parent_item.obj
16580 except AttributeError:
16581 try:
16582 obj = get_observer_pseudo(parent_item)
16583 except AttributeError:
16584 obj = None
16586 if obj:
16587 registry = gobserver.EditorRegistry()
16588 obj.register_editors(registry)
16589 editors = registry.editors
16590 else:
16591 editors = {}</t>
16592 <t tx="michael.20060902013502"></t>
16593 <t tx="michael.20060903115207">if not pos:
16594 if context:
16595 end = self.GetLineEndPosition(context.code_item.get_last_line())
16596 else:
16597 end = self.GetCurrentPos()</t>
16598 <t tx="michael.20060906005234">Column.choice = []
16599 self.data_list_len = len(data_list)
16601 for i, c in enumerate(data_list):
16602 attrlist = self.get_object_attribs(c)
16603 var_name = self.get_data_var_name(i)
16604 Column.choice.append(var_name)
16605 for a in attrlist:
16606 Column.choice.append("%s.%s" % (var_name, a))
16608 </t>
16609 <t tx="michael.20060906020338">self.creator_item = None
16610 for c in self.code_item.get_children():
16611 if c.name == attrib_name:
16612 self.creator_item = c
16613 break</t>
16614 <t tx="michael.20060906020338.1">start = editor.PositionFromLine(self.creator_item.get_line())
16615 end = editor.GetLineEndPosition(self.creator_item.get_last_line())
16616 pos = editor.FindText(start, end, "yield", 0)
16617 values = editor.get_expression(editor.LineFromPosition(pos))
16618 values = values[values.index("yield") + 5:].strip()
16619 try:
16620 while values[0] in "([" and values[-1] in ")]":
16621 values = values[1:-1].strip()
16622 except IndexError: pass
16623 values = [ v.strip() for v in values.split(",") ]</t>
16624 <t tx="michael.20060906020338.2">attribs = editor.get_attribs(self.code_item)
16625 try:
16626 headers = editor.get_expression(attribs["headers"])
16627 headers = editor.eval_expression(headers, context=context)["headers"]
16628 except KeyError:
16629 headers = ("",) * len(values)
16631 </t>
16632 <t tx="michael.20060906020656">class Column(db.Model):
16633 value = db.Text()
16634 header = db.Text()
16635 choice = []</t>
16636 <t tx="michael.20060906020656.1">class ColumnSet(SimpleContainer):
16637 error = db.Text()
16639 @others
16641 def get_data_var_name(self, no):
16642 if self.data_list_len == 1: return "t"
16643 return "t%i" % no
16646 db.Relation("columns",
16647 db.End(Column, "columns", multi='*'),
16648 db.End(ColumnSet))</t>
16649 <t tx="michael.20060906020656.2">def __init__(self, context, attrib_name, data_name):
16650 editor = context.code_item.editor
16651 self.attrib_name = attrib_name
16652 self.code_item = context.code_item
16654 &lt;&lt; get the data attribute value &gt;&gt;
16655 &lt;&lt; create the choice list for column values &gt;&gt;
16657 &lt;&lt; get the code_item, that creates the columns &gt;&gt;
16658 if self.creator_item:
16659 &lt;&lt; get column values &gt;&gt;
16660 &lt;&lt; get column headers &gt;&gt;
16662 for value, header in zip(values, headers):
16663 self.columns.insert(Column(value=value.strip(), header=header))
16664 </t>
16665 <t tx="michael.20060906020656.3">class ColumnSetView(editorlib.MainView):
16666 __model__ = ColumnSet
16667 __view_name__ = "default"
16668 vgap = 0
16669 format = """
16670 error(Static)
16671 [Columns:]
16672 columns&gt;
16673 delete
16675 (buttons)&gt;
16677 def create_controls(self):
16678 self.columns = self.get_control("columns(ColumnGrid)")
16679 self.delete = self.columns.get_delete_button(self)
16681 def prepare(self):
16682 self.grow_col(0)
16683 self.grow_row(1)
16684 self.buttons.grow_col(0)
16685 self.error.Hide()
16686 self.error.SetForegroundColour(self.error_colour)
16688 def constitute(self, imodel):
16689 super(ColumnSetView, self).constitute(imodel)
16690 if imodel.error: self.error.Show()
16691 </t>
16692 <t tx="michael.20060906020656.4">class ColumnGrid(grid.EditGrid, views.GridView):
16693 __model__ = Column
16694 columns = (("value(auto_tree)", _("Value")),
16695 ("header", _("Header")))
16696 resize_col = 0
16699 def prepare(self, attribute):
16700 if attribute == "value":
16701 self.value.fill_tree(Column.choice)</t>
16702 <t tx="michael.20060906020907">try:
16703 attribs = editor.eval_expression("evals=%s" % data_name,
16704 context=context)
16705 data = attribs["evals"]
16706 for data_list in data:
16707 break
16709 if not isinstance(data_list, (list, tuple)):
16710 data_list = (data_list,)
16712 except Exception, e:
16713 self.error = "%s: %s" % (e.__class__.__name__, str(e))
16714 data_list = ()</t>
16715 <t tx="michael.20060906182627">def realize(self):
16716 editor = self.code_item.editor
16717 columns = [ c for c in self.columns if c.header or c.value ]
16718 headers = [c.header for c in columns]
16719 has_headers = bool(filter(bool, headers))
16721 try:
16722 header_line = editor.get_attribs(self.code_item)["headers"]
16723 except KeyError:
16724 header_line = None
16726 if has_headers:
16727 headers = "headers = (%s)" % ", ".join(['"%s"' % h for h in headers])
16728 if not header_line:
16729 editor.insert_expression(self.code_item, headers)
16730 else:
16731 editor.replace_expression(headers, header_line)
16732 elif header_line:
16733 editor.replace_expression("", header_line)
16735 data_list = ", ".join([ self.get_data_var_name(i)
16736 for i in range(self.data_list_len) ])
16737 values = [c.value for c in columns]
16738 maxlen = sum(map(len, values)) + len(values) * 2 + self.code_item.indent + 8
16739 joiner = maxlen &gt; 80 and ",\n" or ", "
16740 values = joiner.join(values)
16742 creator_text = "def %s(self, data):\nfor %s in data:\nyield (%s)" \
16743 % (self.attrib_name, data_list, values)
16745 if self.creator_item:
16746 line = self.creator_item.get_line()
16747 editor.replace_expression(creator_text, line)
16748 else:
16749 creator_text = "\n" + creator_text
16750 editor.insert_expression(self.code_item, creator_text)</t>
16751 <t tx="michael.20060907105636">def activate(self, editor, line, prev, next, inside):
16752 if not super(CStructureContext, self)\
16753 .activate(editor, line, prev, next, inside):
16754 self.make_button(None, None)
16755 return False
16757 return True</t>
16758 <t tx="michael.20060907133950">def apply_browser_menu(self, existing_attribs, code_item):
16759 if self.attrib_name in existing_attribs:
16760 return "edit"
16762 return "add"</t>
16763 <t tx="michael.20060907134327">def apply_browser_menu(self, existing_attribs, code_item):
16764 if self.attrib_name in map(repr, code_item.get_children()):
16765 return "edit"
16767 return "add"</t>
16768 <t tx="michael.20060909120029">class PropertySetView(views.FormView):
16769 __model__ = PropertySet
16770 __view_name__ = "default"
16771 vgap = 0
16772 format = """
16773 properties&gt;
16774 delete
16776 def create_controls(self):
16777 self.properties = self.get_control("properties(PropertyGrid)")
16778 self.delete = self.properties.get_delete_button(self)
16780 def prepare(self):
16781 self.grow_col(0)
16782 self.grow_row(0)</t>
16783 <t tx="michael.20060909120029.1">class PropertyGrid(grid.EditGrid, views.GridView):
16784 __model__ = Property
16785 columns = (("name(Combo)", _("Name")),
16786 ("value(Changeling)", _("Value")))
16787 resize_col = 0
16790 def begin_edit(self, name):
16791 if name == "name":
16792 if self.name.GetCount() != len(self.__model__.name_groups):
16793 self.name.Clear()
16794 for a in self.__model__.name_groups:
16795 self.name.Append(a)
16796 return
16798 if name == "value":
16799 if self.imodel.name.endswith("color"):
16800 self.value.change("Color")
16801 elif self.imodel.name.endswith("width"):
16802 self.value.change("Text")
16803 elif self.imodel.name.endswith("fill"):
16804 self.value.change("BoolEnum")
16805 elif self.imodel.name.endswith("family"):
16806 self.value.change("FamilyCombo")
16807 elif self.imodel.name.endswith("weight"):
16808 self.value.change("WeightCombo")
16809 elif self.imodel.name.endswith("size"):
16810 self.value.change("SizeCombo")
16811 elif self.imodel.name.endswith("variant"):
16812 self.value.change("VariantEnum")
16813 elif self.imodel.name.endswith("antialiased"):
16814 self.value.change("BoolEnum")
16815 elif self.imodel.name.endswith("up"):
16816 self.value.change("BoolEnum")
16817 elif self.imodel.name.endswith("linestyle"):
16818 self.value.change("LinestyleEnum")
16819 elif self.imodel.name.endswith("joinstyle"):
16820 self.value.change("JoinstyleEnum")
16821 elif self.imodel.name.endswith("style"):
16822 self.value.change("StyleEnum")
16823 else:
16824 self.value.change("default")
16827 def inserted(self, imodel):
16828 return bool(imodel.name)</t>
16829 <t tx="michael.20060910114955">@language python
16831 A timeaxis for gantt and resource charts.
16833 &lt;&lt; Copyright &gt;&gt;
16834 &lt;&lt; Imports &gt;&gt;
16836 _is_source_ = True
16837 _ = faces.plocale.get_gettext()
16839 _colorConverter = colors.colorConverter
16841 _week_name = _("Week")
16843 def alt_week_locator(alt=True):
16844 global _week_name
16845 if alt:
16846 _week_name = ""
16847 else:
16848 _week_name = _("Week")
16850 @others
16851 </t>
16852 <t tx="michael.20060910114955.1">import matplotlib.font_manager as font
16853 import matplotlib.transforms as mtrans
16854 import matplotlib.colors as colors
16855 import matplotlib.artist as artist
16856 import matplotlib._image as mimage
16857 import datetime
16858 import widgets
16859 import faces.plocale
16860 import locale
16861 from faces.pcalendar import strftime
16862 from tools import *
16865 </t>
16866 <t tx="michael.20060910114955.2">class Locator(object):
16867 &lt;&lt; declarations &gt;&gt;
16868 @others
16869 </t>
16870 <t tx="michael.20060910114955.3">can_locate_free_time = False
16872 </t>
16873 <t tx="michael.20060910114955.4">def __init__(self):
16874 self.tick_pos = (0, 0) # position is 0, the highest positon is 0
16875 self.sizes = {}
16876 self.format_cache = { }
16877 </t>
16878 <t tx="michael.20060910114955.5">def get_marks(self, intervals, scale, transform):
16879 xmin, xmax = transform.get_bbox1().intervalx().get_bounds()
16880 if intervals[0][0] &lt; xmin:
16881 intervals[0] = (xmin, intervals[0][1])
16883 if intervals[-1][1] &gt; xmax:
16884 intervals[-1] = (intervals[-1][0], xmax)
16886 middles = map(lambda i: (i[0] + i[1]) / 2, intervals)
16887 build_mark = self.build_mark
16888 marks = [ build_mark(i, scale, transform) for i in intervals ]
16889 xs = transform.seq_x_y(middles, middles)[0]
16890 return zip(marks, xs)
16891 </t>
16892 <t tx="michael.20060910114955.6">def fits(self, transform, scale):
16893 delta = self._delta(scale)
16894 key = self.tick_pos[0] == self.tick_pos[1] and "top" or "default"
16895 sizes = self.sizes.get(key, self.sizes["default"])[0]
16896 delta = transform(delta)
16897 return sizes[-1][0] &lt; delta
16898 </t>
16899 <t tx="michael.20060910114955.7">def prepare(self, renderer, fonts, tickers):
16900 "precalculates all possible marker sizes"
16901 self.renderer = renderer
16902 self.fonts = zip(tickers, fonts)
16903 self._calc_sizes()
16904 for v in self.sizes.itervalues():
16905 for s in v.itervalues():
16906 s.sort()
16907 s.reverse()
16909 del self.renderer
16910 del self.fonts
16911 </t>
16912 <t tx="michael.20060910114955.8">def _calc_sizes(self):
16913 raise RuntimeError("abstract")
16914 </t>
16915 <t tx="michael.20060910114955.9">def _delta(self, scale):
16916 raise RuntimeError("abstract")
16917 </t>
16918 <t tx="michael.20060910114955.10">def _get_format(self, interval, transform):
16919 delta = int(interval[0] - interval[1])
16920 format = self.format_cache.get(delta)
16921 if format: return format
16923 x, y = transform.seq_x_y(interval, (0, 0))
16924 tdelta = x[1] - x[0]
16925 key = self.tick_pos[0] == self.tick_pos[1] and "top" or "default"
16926 sizes = self.sizes.get(key, self.sizes["default"])[self.tick_pos[0]]
16927 for s, f in sizes:
16928 if s &lt; tdelta:
16929 format = f
16930 break
16931 else:
16932 format = ""
16934 self.format_cache[delta] = format
16935 return format
16936 </t>
16937 <t tx="michael.20060910114955.11">def _calc_markers(self, markers, format, key="default"):
16938 extent = self.renderer.get_text_width_height
16940 key_fonts = self.sizes.get(key)
16941 if not key_fonts:
16942 key_fonts = {}
16943 for i, f in self.fonts: key_fonts[i] = []
16945 if not isinstance(markers, (list, tuple)):
16946 markers = (markers,)
16948 for i, f in self.fonts:
16949 size = max([extent(m, f, False)[0] for m in markers])
16950 key_fonts[i].append((size, str(format)))
16952 self.sizes[key] = key_fonts
16953 </t>
16954 <t tx="michael.20060910114955.12">def is_free(self, num_date):
16955 #num_date is int
16956 return False
16957 </t>
16958 <t tx="michael.20060910114955.13">class DecadeLocator(Locator):
16959 @others
16960 </t>
16961 <t tx="michael.20060910114955.14">def _delta(self, scale):
16962 return scale.week_delta * 52 * 10
16963 </t>
16964 <t tx="michael.20060910114955.15">def _calc_sizes(self):
16965 self._calc_markers("88888", "%D")
16966 </t>
16967 <t tx="michael.20060910114955.16">def __call__(self, left, right, time_scale):
16968 num = time_scale.to_num
16969 dt = datetime.datetime
16970 left = num(int(left))
16971 right = num(int(right))
16972 start = left.to_datetime().year / 10
16973 end = right.to_datetime().year / 10 + 2
16974 locs = map(lambda y: num(dt(y * 10, 1, 1)), range(start, end))
16975 return locs
16976 </t>
16977 <t tx="michael.20060910114955.17">class YearLocator(Locator):
16978 @others
16979 </t>
16980 <t tx="michael.20060910114955.18">def _delta(self, scale):
16981 return scale.week_delta * 52
16982 </t>
16983 <t tx="michael.20060910114955.19">def _calc_sizes(self):
16984 self._calc_markers("88888", "%IY")
16985 </t>
16986 <t tx="michael.20060910114955.20">def __call__(self, left, right, time_scale):
16987 num = time_scale.to_num
16988 dt = datetime.datetime
16989 left = num(int(left))
16990 right = num(int(right))
16991 start = left.to_datetime().year
16992 end = right.to_datetime().year + 2
16993 locs = map(lambda y: num(dt(y, 1, 1)), range(start, end))
16994 return locs
16995 </t>
16996 <t tx="michael.20060910114955.21">class QuaterLocator(Locator):
16997 @others
16998 </t>
16999 <t tx="michael.20060910114955.22">def _delta(self, scale):
17000 return scale.week_delta * 12
17001 </t>
17002 <t tx="michael.20060910114955.23">def _calc_sizes(self):
17003 self._calc_markers("Q 8/88888", "Q %Q/%IY", "top")
17004 self._calc_markers("Q 88", "Q %Q")
17005 </t>
17006 <t tx="michael.20060910114955.24">def __call__(self, left, right, time_scale):
17007 num = time_scale.to_num
17008 dt = datetime.datetime
17009 left = num(int(left))
17010 right = num(int(right))
17011 start = left.to_datetime()
17012 end = right.to_datetime()
17013 start = start.year * 4 + (start.month - 1) / 3
17014 end = end.year * 4 + (end.month - 1) / 3 + 2
17015 locs = map(lambda qy: num(dt(qy/4, (qy%4)*3+1, 1)), range(start, end))
17016 return locs
17017 </t>
17018 <t tx="michael.20060910114955.25">class MonthLocator(Locator):
17019 @others
17020 </t>
17021 <t tx="michael.20060910114955.26">def _delta(self, scale):
17022 return scale.week_delta * 4
17023 </t>
17024 <t tx="michael.20060910114955.27">def _calc_sizes(self):
17025 dt = datetime.datetime
17026 def mlist(format):
17027 return map(lambda m: strftime(dt(2005, m, 1), format), range(1, 13))
17029 self._calc_markers(mlist("%B 88888"), "%B %IY", "top")
17030 self._calc_markers(mlist("%b 88888"), "%b %IY", "top")
17031 self._calc_markers(mlist("%m.88888"), "%m.%IY", "top")
17032 self._calc_markers(mlist("%B"), "%B")
17033 self._calc_markers(mlist("%b"), "%b")
17034 self._calc_markers("8888", "%m")
17035 </t>
17036 <t tx="michael.20060910114955.28">def __call__(self, left, right, time_scale):
17037 num = time_scale.to_num
17038 dt = datetime.datetime
17040 left = num(int(left))
17041 right = num(int(right))
17042 start = left.to_datetime()
17043 end = right.to_datetime()
17044 start = start.year * 12 + start.month - 1
17045 end = end.year * 12 + end.month + 1
17046 locs = map(lambda my: num(dt(my/12, 1+my%12, 1)), range(start, end))
17047 return locs
17048 </t>
17049 <t tx="michael.20060910114955.29">class WeekLocator(Locator):
17050 @others
17051 </t>
17052 <t tx="michael.20060910114955.30">def _delta(self, scale):
17053 return scale.week_delta
17054 </t>
17055 <t tx="michael.20060910114955.31">def _calc_sizes(self):
17056 global _week_name
17058 dt = datetime.datetime
17059 def mlist(format):
17060 return map(lambda m: strftime(dt(2005, m, 1), str(format)), range(1, 13))
17062 if _week_name:
17063 self._calc_markers(mlist("%IW. " + _week_name + " %IB 88888"),
17064 "%IW. " + _week_name + " %IB %IY", "top")
17065 self._calc_markers(mlist("%IW. " + _week_name + " %ib 88888"),
17066 "%IW. " + _week_name + " %ib %IY", "top")
17067 self._calc_markers(mlist("%IW. " + _week_name + " %im.88888"),
17068 "%IW. " + _week_name + " %m.%IY", "top")
17069 self._calc_markers(mlist("%IW %ib 88888"), "%IW %ib %IY", "top")
17070 self._calc_markers(mlist("%IW %im 88888"), "%IW %im.%IY", "top")
17071 self._calc_markers("888. " + _week_name, "%IW. " + _week_name)
17072 self._calc_markers("8888", "%IW")
17073 else:
17074 # in the US week numbers are not used
17075 self._calc_markers(mlist("%B 88"), "%B %d")
17076 self._calc_markers(mlist("%b. 88"), "%b. %d")
17078 </t>
17079 <t tx="michael.20060910114955.32">def __call__(self, left, right, time_scale):
17080 num = time_scale.to_num
17081 left = num(int(left))
17082 right = num(int(right)) + time_scale.week_delta
17083 start = left.to_datetime().replace(hour=0, minute=0)
17084 start -= datetime.timedelta(days=start.weekday())
17085 start = num(start)
17086 locs = range(start, right, time_scale.week_delta)
17087 return locs
17088 </t>
17089 <t tx="michael.20060910114955.33">class DayLocator(Locator):
17090 &lt;&lt; declarations &gt;&gt;
17091 @others
17092 </t>
17093 <t tx="michael.20060910114955.34">can_locate_free_time = True
17096 </t>
17097 <t tx="michael.20060910114955.35">def _delta(self, scale):
17098 return scale.day_delta
17099 </t>
17100 <t tx="michael.20060910114955.36">def _calc_sizes(self):
17101 dt = datetime.datetime
17102 def dlist(format):
17103 return map(lambda d: strftime(dt(2005, 1, d), format), range(1, 8))
17105 self._calc_markers(dlist("%A %x88"), "%A %x", "top")
17106 self._calc_markers(dlist("%a %x88"), "%a %x", "top")
17107 self._calc_markers(dlist("%x88"), "%x", "top")
17108 self._calc_markers(dlist("%A 888."), "%A %d.")
17109 self._calc_markers(dlist("%a 888."), "%a %d.")
17110 self._calc_markers("8888", "%d")
17111 </t>
17112 <t tx="michael.20060910114955.37">def __call__(self, left, right, time_scale):
17113 self.time_scale = time_scale
17114 num = time_scale.to_num
17115 date = time_scale.to_datetime
17116 td = datetime.timedelta
17117 left = date(num(int(left))).replace(hour=0, minute=0)
17118 right = date(num(int(right)))
17119 days = (right - left).days + 2
17120 locs = map(lambda d: num(left + td(days=d)), range(0, days))
17121 return locs
17122 </t>
17123 <t tx="michael.20060910114955.38">def is_free(self, num_date):
17124 return self.time_scale.is_free_day(num_date)
17125 </t>
17126 <t tx="michael.20060910114955.39">class SlotLocator(Locator):
17127 &lt;&lt; declarations &gt;&gt;
17128 @others
17129 </t>
17130 <t tx="michael.20060910114955.40">can_locate_free_time = True
17133 </t>
17134 <t tx="michael.20060910114955.41">def _delta(self, scale):
17135 return scale.slot_delta
17136 </t>
17137 <t tx="michael.20060910114955.42">def __call__(self, left, right, time_scale):
17138 self.time_scale = time_scale
17139 num = time_scale.to_num
17140 date = time_scale.to_datetime
17141 td = datetime.timedelta
17142 left = date(num(int(left))).replace(hour=0, minute=0)
17143 right = date(num(int(right)))
17144 days = (right - left).days + 2
17145 days = map(lambda d: left + td(days=d), range(0, days))
17146 get_working_times = time_scale.chart_calendar.get_working_times
17148 locs = []
17149 for d in days:
17150 slots = get_working_times(d.weekday())
17151 locs.extend(map(lambda s: num(d + td(minutes=s[0])), slots))
17153 return locs
17154 </t>
17155 <t tx="michael.20060910114955.43">def _calc_sizes(self):
17156 self._calc_markers("888:88-88:88", "%(sh)02i:%(sm)02i-%(eh)02i:%(em)02i")
17157 self._calc_markers("888-88", "%(sh)02i-%(eh)02i")
17158 self._calc_markers("888:88", "%(sh)02i:%(sm)02i")
17159 self._calc_markers("888", "%(sh)02i")
17160 </t>
17161 <t tx="michael.20060910114955.44">def get_marks(self, intervals, scale, transform):
17162 def build_mark(interval):
17163 format = self._get_format(interval, transform)
17164 start = scale.to_num(interval[0]).to_datetime()
17165 end = scale.to_num(interval[1]).to_datetime()
17166 vals = { "sh" : start.hour,
17167 "sm" : start.minute,
17168 "eh" : end.hour,
17169 "em" : end.minute }
17170 return format % vals
17172 middles = map(lambda i: (i[0] + i[1]) / 2, intervals)
17173 marks = map(build_mark, intervals)
17174 xs = transform.seq_x_y(middles, (0,)*len(middles))[0]
17175 return zip(marks, xs)
17176 </t>
17177 <t tx="michael.20060910114955.45">def is_free(self, num_date):
17178 return self.time_scale.is_free_slot(num_date)
17179 </t>
17180 <t tx="michael.20060910114955.46">def _zigzag_lines(locs, top, bottom):
17181 xs = locs * 2
17182 xs.sort()
17183 ys = [ top, bottom, bottom, top ] * ((len(locs) + 1) / 2)
17184 if len(locs) % 2: del ys[-2:]
17185 return xs, ys
17186 </t>
17187 <t tx="michael.20060910114955.47">class TimeAxis(artist.Artist, widgets._PropertyAware):
17188 &lt;&lt; declarations &gt;&gt;
17189 @others
17190 </t>
17191 <t tx="michael.20060910114955.48">properties = {
17192 "family": "sans-serif",
17193 #"family": [ "Arial", "Verdana", "Bitstream Vera Sans" ] ,
17194 "weight": "normal",
17195 "size" : "medium",
17196 "style" : "normal",
17197 "variant" : "normal",
17198 "2.weight" : "bold",
17199 "2.size" : "x-large",
17200 "1.weight" : "bold",
17201 "1.size" : "large",
17202 "color": 'black',
17203 "0.facecolor" : 'white',
17204 "facecolor" : 'darkgray',
17205 "edgecolor" : 'black',
17206 "grid.edgecolor" : 'darkgray',
17207 "free.facecolor": "lightgrey",
17208 "linewidth" : 1,
17209 "joinstyle" : 'miter',
17210 "linestyle" : 'solid',
17211 "now.edgecolor" : "black",
17212 "now.linewidth" : 2,
17213 "now.linestyle" : "dashed",
17214 "antialiased" : True,
17215 "alpha" : 1.0,
17216 "tickers" : (1, ) }
17219 zorder = -100
17220 show_grid = True
17221 show_scale = True
17222 show_free_time = True
17223 show_now = True
17224 time_scale = None # must be set by Chart
17226 </t>
17227 <t tx="michael.20060910114955.49">def __init__(self, properties=None):
17228 widgets._PropertyAware.__init__(self, properties)
17229 artist.Artist.__init__(self)
17230 self._locators = tuple(map(lambda l: l(), _locators))
17231 self._last_cache = None
17232 self._last_cache_state = None
17233 self._last_width = 0
17234 self.encoding = locale.getlocale()[1] or "ascii"
17235 </t>
17236 <t tx="michael.20060910114955.50">def calc_height(self):
17237 if not self.show_scale:
17238 self.height = 0
17239 return 0
17241 prop = self.get_property
17242 def_height = font.fontManager.get_default_size()
17244 sep = def_height / 3
17245 tickers = (0,) + prop("tickers")
17246 self.height = 0
17247 for t in tickers:
17248 tsize = self.get_font(str(t)).get_size_in_points()
17249 self.height += tsize + 2 * sep
17251 return self.height
17252 </t>
17253 <t tx="michael.20060910114955.51">def set_transform(self, t):
17254 #a non scaled point y axis
17255 Value = mtrans.Value
17256 Point = mtrans.Point
17257 Bbox = mtrans.Bbox
17258 Transformation = mtrans.SeparableTransformation
17260 fig_point_to_pixel = self.get_figure().dpi / mtrans.Value(72)
17262 view_box = t.get_bbox2()
17263 top = view_box.ur().y()
17264 bottom = view_box.ll().y()
17265 point_height = (bottom - top) / fig_point_to_pixel
17267 bbox = t.get_bbox1()
17268 ll = bbox.ll()
17269 ur = bbox.ur()
17270 new_ll = Point(ll.x(), point_height)
17271 new_ur = Point(ur.x(), Value(0))
17272 data_box = Bbox(new_ll, new_ur)
17274 t = Transformation(data_box, view_box, t.get_funcx(), t.get_funcy())
17275 artist.Artist.set_transform(self, t)
17276 </t>
17277 <t tx="michael.20060910114955.52">__prepared = False
17278 def draw(self, renderer):
17279 if not self.get_visible(): return
17281 trans = self.get_transform()
17282 trans.freeze()
17283 try:
17284 if not self.__prepared:
17285 self.__prepared = True
17286 tickers = (0,) + self.get_property("tickers")
17287 fonts = map(lambda t: self.get_font(str(t)), tickers)
17288 for l in self._locators:
17289 l.prepare(renderer, fonts, tickers)
17291 data_box = trans.get_bbox1()
17292 view_box = trans.get_bbox2()
17293 width = data_box.width()
17295 if self._last_width != width:
17296 self._last_width = width
17297 self.find_ticker(renderer)
17299 cache_state = (self.show_grid + self.show_scale,
17300 view_box.width(), view_box.height(),
17301 renderer, data_box.xmin())
17303 if self._last_cache_state == cache_state and self._last_cache:
17304 try:
17305 #not now because of memory leak
17306 renderer.draw_image(0, 0, self._last_cache, view_box)
17307 #renderer.restore_region(self._last_cache)
17308 return
17309 except:
17310 pass
17312 gc = renderer.new_gc()
17314 if self.get_clip_on():
17315 gc.set_clip_rectangle(self.clipbox.get_bounds())
17317 if self.show_grid: self.draw_grid(renderer, gc, trans)
17318 if self.show_now:
17319 time_scale = self.time_scale
17320 left, right = data_box.intervalx().get_bounds()
17321 if left &lt;= time_scale.now &lt;= right:
17322 top, bottom = data_box.intervaly().get_bounds()
17323 self.set_gc(gc, "now")
17324 renderer.draw_lines(gc,
17325 (time_scale.now, time_scale.now),
17326 (top, bottom), trans)
17328 if self.show_scale: self.draw_scale(renderer, gc, trans)
17330 self._last_cache_state = cache_state
17331 #self._last_cache = renderer.copy_from_bbox(view_box)
17332 try:
17333 self._last_cache = mimage.frombuffer(\
17334 renderer.buffer_rgba(0, 0),
17335 renderer.width,
17336 renderer.height, 1)
17337 except AttributeError:
17338 self._last_cache = None
17340 if self._last_cache:
17341 self._last_cache.flipud_out()
17342 finally:
17343 trans.thaw()
17344 </t>
17345 <t tx="michael.20060910114955.53">def find_ticker(self, renderer):
17346 time_scale = self.time_scale
17348 tickers = self.get_property("tickers")
17349 if not isinstance(tickers, tuple):
17350 tickers = tuple(tickers)
17352 tickers = (0,) + tickers
17353 highest_locator = tickers[-1]
17355 transform = self.get_transform()
17356 origin = transform.xy_tup((0, 0))[0]
17358 def delta_trans(x_delta):
17359 p = transform.xy_tup((x_delta, 0))
17360 return p[0] - origin
17362 def refresh_locators(lowest):
17363 self.ticker = lowest
17364 for t in tickers:
17365 loc = self._locators[lowest + t]
17366 loc.tick_pos = (t, highest_locator)
17367 loc.format_cache.clear()
17369 for ti in range(len(self._locators) - highest_locator):
17370 loc = self._locators[ti]
17371 loc.tick_pos = (0, highest_locator)
17373 if loc.fits(delta_trans, time_scale):
17374 refresh_locators(ti)
17375 break
17376 else:
17377 refresh_locators(len(self._locators) - highest_locator - 1)
17378 </t>
17379 <t tx="michael.20060910114955.54">def draw_scale(self, renderer, gc, trans):
17380 prop = self.get_property
17381 time_scale = self.time_scale
17383 def_height = font.fontManager.get_default_size()
17384 sep = def_height / 3
17385 left, right = trans.get_bbox1().intervalx().get_bounds()
17386 dpi = self.get_figure().get_dpi()
17388 if left &gt;= right: return
17390 self.set_gc(gc)
17391 free_face = _colorConverter.to_rgb(prop("free.facecolor"))
17393 def dline(x1, y1, x2, y2):
17394 draw_line(renderer, gc, x1, y1, x2, y2, trans)
17396 def draw_ticks(bottom, locator, name, show_free_time=False):
17397 fp = self.get_font(name)
17398 top = bottom - fp.get_size_in_points() - 2 * sep
17400 locs = locator(left, right, time_scale)
17401 lintervals = zip(locs[:-1], locs[1:])
17403 face = _colorConverter.to_rgb(prop(name + ".facecolor"))
17404 verts = ((left, -bottom), (left, -top),
17405 (right, -top), (right, -bottom))
17406 verts = trans.seq_xy_tups(verts)
17407 renderer.draw_polygon(gc, face, verts)
17409 if show_free_time and locator.can_locate_free_time:
17410 gc.set_linewidth(0)
17411 for l, r in lintervals:
17412 #if locator.is_free((l + r) / 2):
17413 if locator.is_free(l):
17414 verts = ((l, -bottom), (l, -top),
17415 (r, -top), (r, -bottom))
17416 verts = trans.seq_xy_tups(verts)
17417 renderer.draw_polygon(gc, free_face, verts)
17419 fp = self.get_font(name)
17420 gc.set_foreground(prop(name + ".color"))
17421 x, y = trans.xy_tup((0, -bottom + sep))
17422 markers = locator.get_marks(lintervals, time_scale, trans)
17423 for m, x in markers:
17424 self.draw_text(renderer, gc, x, y, m, fp, "bc", dpi)
17426 gc.set_foreground(prop(name + ".edgecolor"))
17427 gc.set_linewidth(prop(name + ".linewidth"))
17429 xs, ys = _zigzag_lines(locs, -top, -bottom)
17430 renderer.draw_lines(gc, xs, ys, trans)
17432 gc.set_linewidth(prop("linewidth"))
17433 dline(left, -top, right, -top)
17434 dline(left, -bottom, right, -bottom)
17436 return top
17438 tickers = prop("tickers")
17439 bottom = self.height
17440 ticks = self._locators[self.ticker]
17441 bottom = draw_ticks(bottom, ticks, "0", self.show_free_time)
17442 for t in tickers:
17443 ticks = self._locators[self.ticker + t]
17444 bottom = draw_ticks(bottom, ticks, str(t))
17445 </t>
17446 <t tx="michael.20060910114955.55">def draw_grid(self, renderer, gc, trans):
17447 time_scale = self.time_scale
17448 prop = self.get_property
17450 data_box = trans.get_bbox1()
17451 left, right = data_box.intervalx().get_bounds()
17452 top, bottom = data_box.intervaly().get_bounds()
17454 if left &gt;= right: return
17456 locator = self._locators[self.ticker]
17457 locs = locator(left, right, time_scale)
17458 lintervals = zip(locs[:-1], locs[1:])
17460 self.set_gc(gc, "grid")
17461 if self.show_free_time and locator.can_locate_free_time:
17462 gc.set_linewidth(0)
17463 free_face = _colorConverter.to_rgb(prop("free.facecolor"))
17464 for l, r in lintervals:
17465 if locator.is_free((l + r) / 2):
17466 verts = trans.seq_xy_tups(((l, bottom), (l, top),
17467 (r, top), (r, bottom)))
17469 renderer.draw_polygon(gc, free_face, verts)
17472 gc.set_linewidth(prop("grid.linewidth"))
17474 xs, ys = _zigzag_lines(locs, top, bottom)
17475 renderer.draw_lines(gc, xs, ys, trans)
17476 draw_line(renderer, gc, left, bottom, right, bottom, trans)
17477 </t>
17478 <t tx="michael.20060910114955.56">def draw_text(self, renderer, gc, x, y, text, fp, align, dpi):
17480 special draw_text for taxis using the locale encoding which is used by
17481 the strftime functions
17484 if not text: return
17485 text = text.decode(self.encoding)
17487 w, h = renderer.get_text_width_height(text, fp, False)
17488 if align[0] == 'c':
17489 y -= h / 2
17490 elif align[0] == 't':
17491 y -= h
17493 if align[1] == 'c':
17494 x -= w / 2
17495 elif align[1] == 'r':
17496 x -= w
17498 if renderer.flipy():
17499 canvasw, canvash = renderer.get_canvas_width_height()
17500 y = canvash-y
17502 renderer.draw_text(gc, x, y, text, fp, 0, False)
17503 </t>
17504 <t tx="michael.20060910115214">@others
17506 _locators = ( SlotLocator,
17507 DayLocator,
17508 WeekLocator,
17509 MonthLocator,
17510 QuaterLocator,
17511 YearLocator,
17512 DecadeLocator )
17513 </t>
17514 <t tx="michael.20060910151243"></t>
17515 <t tx="michael.20060910154312">class ModuleDoc(DocBase):
17516 @others
17517 </t>
17518 <t tx="michael.20060910154430">def __init__(self, module):
17519 self.description = str(module.__doc__ or "")
17520 </t>
17521 <t tx="michael.20060910160841">def constructor(self, name):
17522 desc = textwrap.fill(self.description,
17523 max(self.min_width, len(name) + 1))
17524 return len(name) + 1, "%s:\n%s" % (name, desc)
17525 </t>
17526 <t tx="michael.20060910220708">def get_object_attribs(self, obj):
17527 try:
17528 attrlist = obj.__all__
17529 except AttributeError:
17530 attrlist = dir(obj)
17532 attrlist = filter(lambda n: n[0] != "_", attrlist)
17534 def make_call(a):
17535 if callable(getattr(obj, a)):
17536 return "%s()" % a
17537 return a
17539 if isinstance(obj, ftask.Task):
17540 #filter out children
17541 attrlist = [ a for a in attrlist
17542 if not isinstance(getattr(obj, a), ftask.Task)]
17543 attrlist = [ make_call(a) for a in attrlist ]
17544 attrlist += [ "to_string.%s" % a for a in attrlist
17545 if a != "_to_string" and a[-1] != ")" ]
17546 attrlist.sort()
17547 else:
17548 attrlist = [ make_call(a) for a in attrlist ]
17550 return attrlist</t>
17551 <t tx="michael.20060912153307">def encode(text):
17552 if type(text) is unicode:
17553 return str(text.encode(chart_tools.chart_encoding))
17554 return str(text)</t>
17555 <t tx="michael.20060912164103">def update_menus(self):
17556 top = controller().get_top_menu()
17557 project_menu = top.make_menu(_("&amp;Project"), pos=110)
17558 view = controller().find_view_of(self)
17559 menu = lambda *args, **kw: project_menu.make_item(view, *args, **kw)
17562 def expand(): self.Expand(self.GetSelection())
17563 def collapse(): self.Collapse(self.GetSelection())
17564 def next():
17565 next = self.GetNextVisible(self.GetSelection())
17566 if next.IsOk():
17567 self.SelectItem(next)
17568 self.EnsureVisible(next)
17570 def prev():
17571 prev = self.get_prev_visible(self.GetSelection())
17572 if prev.IsOk():
17573 self.SelectItem(prev)
17574 self.EnsureVisible(prev)
17576 menu(_("Collapse Item\tALT-LEFT"), collapse, "left16", pos=10)
17577 menu(_("Expand Item\tALT-RIGHT"), expand, "right16", pos=20)
17578 menu(_("Move Item Up\tALT-UP"), prev, "up16", pos=30)
17579 menu(_("Move Item Down\tALT-DOWN"), next, "down16", pos=40)
17581 project_menu.make_separator(_("Move Item Down"), False) </t>
17582 <t tx="michael.20060913121250">for t in eval:
17583 code = t._function.func_code
17584 if path != code.co_filename: continue
17585 line = code.co_firstlineno
17586 item = self.code_item_at(line - 1)
17587 if item and item.name == t.name:
17588 item.obj = t
17589 # The next assignments are needed in correct_code and find_task_references
17590 item.task_path = t.path
17591 t._function.code_item = weakref.proxy(item)
17592 </t>
17593 <t tx="michael.20060913121250.1">is_class = lambda i: i.obj_type == pyeditor.CLASS
17594 for ci in filter(is_class, self.code_items):
17595 v = module.__dict__.get(ci.name)
17596 if inspect.isclass(v): ci.obj = v</t>
17597 <t tx="michael.20060913121250.2">for ci in filter(is_evaluation, self.code_items):
17598 v = module.__dict__.get(ci.name)
17599 if isinstance(v, ftask._ProjectBase): ci.obj = v</t>
17600 <t tx="michael.20060913132734">class TaskCreator(NameEditor):
17601 title = _("Add Task")
17603 @others</t>
17604 <t tx="michael.20060913150931">try:
17605 paren_pos = menu_title.index("(")
17606 menu_pos = int(menu_title[paren_pos + 1:-1])
17607 menu_title = menu_title[:paren_pos]
17608 except ValueError:
17609 pass</t>
17610 <t tx="michael.20060913152318.2">def insert_code(self, code):
17611 indent = self.context.code_item.editor.GetIndent()
17612 self.context.append_item(code, self.context.code_item.indent + indent)
17613 </t>
17614 <t tx="michael.20060914094858">def append_item(self, code, indent=-1, prespace="\n\n"):
17616 appends a new code_item after the current item
17618 editor = self.code_item.editor
17619 editor.BeginUndoAction()
17621 last_line = self.code_item.get_last_line()
17622 line_end = editor.GetLineEndPosition(last_line)
17623 insert_code = "%s%s" % (prespace, code)
17625 editor.InsertText(line_end, insert_code)
17627 start_line = last_line + 2
17628 line_pos = editor.PositionFromLine(start_line)
17629 if indent &gt; -1:
17630 editor.SetLineIndentation(start_line, indent)
17631 else:
17632 editor.autoindent(line_pos, False)
17634 line_count = len(code.split("\n"))
17635 for line in range(start_line + 1, start_line + line_count):
17636 editor.autoindent(editor.PositionFromLine(line), False)
17637 else:
17638 line = start_line + line_count
17640 line_end = editor.GetLineEndPosition(line)
17641 if editor.GetLine(line + 1).strip():
17642 # the next line is not empty ==&gt; insert an extra line
17643 editor.InsertText(line_end, "\n")
17645 editor.GotoPos(line_end)
17646 editor.EndUndoAction()
17647 return start_line, start_line + line_count</t>
17648 <t tx="michael.20060914103204.1">class SubTaskCreator(TaskCreator):
17649 @others</t>
17650 <t tx="michael.20060914103204.2">class TaskSiblingCreator(TaskCreator):
17651 @others</t>
17652 <t tx="michael.20060914103351">def realize_code(self):
17653 now = datetime.datetime.now().strftime("%x %H:%M:%S")
17654 code = 'def %s():\n"Inserted at %s"' % (self.name, now)
17655 self.insert_code(code)
17656 </t>
17657 <t tx="michael.20060914103403">def insert_code(self, code):
17658 self.context.append_item(code, self.context.code_item.indent)
17659 </t>
17660 <t tx="michael.20060914104037">class TaskSiblingBeforeCreator(TaskCreator):
17661 @others</t>
17662 <t tx="michael.20060914104037.1">def insert_code(self, code):
17663 self.context.insert_item(code, self.context.code_item.indent)
17664 </t>
17665 <t tx="michael.20060914113429">@doc
17666 The code must bei inserted before the line marker of the code item!
17667 (Therefore the insertion ahs to be done at prev_line_end)
17668 @code
17669 def insert_item(self, code, indent):
17671 inserts a new code_item beforte the current item
17673 editor = self.code_item.editor
17674 editor.BeginUndoAction()
17676 line = self.code_item.get_line()
17677 prev_line_end = editor.GetLineEndPosition(line - 1)
17679 insert_code = "\n%s\n" % code
17680 editor.InsertText(prev_line_end, insert_code)
17682 start_line = line
17683 line_pos = editor.PositionFromLine(start_line)
17684 editor.SetLineIndentation(start_line, indent)
17686 line_count = len(code.split("\n"))
17687 for line in range(start_line + 1, start_line + line_count):
17688 editor.autoindent(editor.PositionFromLine(line), False)
17689 else:
17690 line = start_line + line_count
17692 line_end = editor.GetLineEndPosition(line)
17693 if editor.GetLine(start_line - 1).strip():
17694 # the before line is not empty ==&gt; insert an extra line
17695 line_before_end = editor.GetLineEndPosition(start_line - 1)
17696 editor.InsertText(line_before_end, "\n")
17698 editor.GotoPos(line_end)
17699 editor.EndUndoAction()
17700 return start_line, start_line + line_count
17701 </t>
17702 <t tx="michael.20060915105317">__correct_code_cal = False
17703 def correct_code(self):
17704 if self.__correct_code_cal: return
17705 self.__correct_code_cal = True
17707 self.should_be_corrected = False
17709 self.BeginUndoAction()
17711 ctrl = controller()
17712 task_items = [ i for i in self.code_items if is_task(i) or is_project(i)]
17713 resource_items = [ i for i in self.code_items if is_resource(i) ]
17715 ctrl.progress_start(_("correct code"),
17716 len(task_items) + len(resource_items))
17718 counter = 1
17720 for ti in task_items:
17721 self.correct_task_code(ti)
17722 ctrl.progress_update(counter)
17723 counter += 1
17725 for r in resource_items:
17726 self.correct_resource_code(r)
17727 ctrl.progress_update(counter)
17728 counter += 1
17730 ctrl.progress_end()
17731 self.EndUndoAction()
17732 self.__correct_code_cal = False
17733 </t>
17734 <t tx="michael.20060915183222">def get_code_item_path(code_item):
17735 item = code_item
17736 path = []
17737 while item:
17738 path.append(item.name)
17739 item = item.get_parent()
17741 path.reverse()
17742 path[0] = "root"
17743 return ".".join(path)
17745 </t>
17746 <t tx="michael.20060915184406">def create_relative_path(from_, to_):
17748 creates a relative path from absolute path
17749 from_ to absolute path to_
17751 from_ = from_.split(".")
17752 to_ = to_.split(".")
17754 for i, parts in enumerate(zip(from_, to_)):
17755 from_part, to_part = parts
17756 if from_part != to_part:
17757 break
17759 from_ = from_[i:]
17760 to_ = to_[i:]
17761 return "up." * len(from_) + ".".join(to_)</t>
17762 <t tx="michael.20060915184406.1">_to_datetime = pcalendar.to_datetime</t>
17763 <t tx="michael.20060915190443">def create_absolute_path(from_, to_):
17765 creates a absolute path from absolute path
17766 from_ to relative path to_
17768 from_ = from_.split(".")
17769 to_ = to_.split(".")
17771 for i, part in enumerate(to_):
17772 if part != "up":
17773 break
17775 from_ = from_[:-i]
17776 to_ = to_[i:]
17777 return "%s.%s" % (".".join(from_), ".".join(to_))
17780 </t>
17781 <t tx="michael.20060915191847">def path_argument(path):
17782 if path.startswith("up."):
17783 return { "path": ftask.create_absolute_path(self.item_path, path),
17784 "relative": True }
17786 return { "path": path,
17787 "relative": False }</t>
17788 <t tx="michael.20060915234005">class TaskUnindenter(object):
17789 __icon__ = "unindent16"
17790 @others</t>
17791 <t tx="michael.20060915234005.1">def apply(self, expression, code_item):
17792 return False
17793 </t>
17794 <t tx="michael.20060915234005.2">def apply_browser_menu(self, existing_attribs, code_item):
17795 parent = code_item.get_parent()
17796 if classifiers.is_task(parent):
17797 return "extra"
17799 return ""
17800 </t>
17801 <t tx="michael.20060915234005.3">def activate(self, context):
17802 code_item = context.code_item
17803 editor = code_item.editor
17804 indent = editor.GetIndent()
17805 start_line = code_item.get_line()
17806 end_line = code_item.get_last_line()
17807 lines = xrange(start_line, end_line + 1)
17808 editor.BeginUndoAction()
17809 for l in lines:
17810 old_indent = editor.GetLineIndentation(l)
17811 editor.SetLineIndentation(l, old_indent - indent)
17813 editor.check_code_updates(start_line, end_line)
17814 editor.correct_task_code(code_item)
17815 editor.EndUndoAction()
17816 </t>
17817 <t tx="michael.20060918124853">class TaskIndenter(object):
17818 __icon__ = "indent16"
17819 @others</t>
17820 <t tx="michael.20060918124853.1">def apply(self, expression, code_item):
17821 return False
17822 </t>
17823 <t tx="michael.20060918124853.2">def apply_browser_menu(self, existing_attribs, code_item):
17824 line = code_item.get_line()
17825 editor = code_item.editor
17826 prev_line = editor.prev_item_line(line - 1)
17827 prev_item = editor.code_item_at(prev_line)
17829 if classifiers.is_task(prev_item) and prev_item.indent &gt;= code_item.indent:
17830 return "extra"
17832 return ""
17833 </t>
17834 <t tx="michael.20060918124853.3">def activate(self, context):
17835 code_item = context.code_item
17836 editor = code_item.editor
17837 indent = editor.GetIndent()
17838 start_line = code_item.get_line()
17839 end_line = code_item.get_last_line()
17840 lines = xrange(start_line, end_line + 1)
17841 editor.BeginUndoAction()
17842 for l in lines:
17843 old_indent = editor.GetLineIndentation(l)
17844 editor.SetLineIndentation(l, old_indent + indent)
17846 editor.check_code_updates(start_line, end_line)
17847 editor.correct_task_code(code_item)
17848 editor.EndUndoAction()
17849 </t>
17850 <t tx="michael.20060918130215">def get_last_code_item(self):
17852 returns the last code item of the context.
17853 This code_item can be used for function append_item
17855 raise RuntimeError("abstract")</t>
17856 <t tx="michael.20060918130628">def get_last_code_item(self):
17857 editor = self.code_item.editor
17858 try:
17859 return [ci for ci in editor.code_items if is_observer(ci) ][-1]
17860 except IndexError:
17861 return CEvaluation(self.code_item).get_last_code_item()
17863 </t>
17864 <t tx="michael.20060918131528"></t>
17865 <t tx="michael.20060918131528.1">def get_last_code_item(self):
17866 editor = self.code_item.editor
17867 try:
17868 return [ci for ci in editor.code_items if is_evaluation(ci) ][-1]
17869 except IndexError:
17870 return CProjectDelaration(self.code_item).get_last_code_item()
17871 </t>
17872 <t tx="michael.20060918131528.2">def make_browser_menu(self, menu, action_filter=None):
17873 if is_evaluation(self.code_item) or "create" in action_filter:
17874 self.amend_browser_menu(menu, action_filter)
17875 return True</t>
17876 <t tx="michael.20060918131942">def get_last_code_item(self):
17877 try:
17878 editor = self.code_item.editor
17879 return [ci for ci in editor.code_items if is_project(ci) ][-1]
17880 except IndexError:
17881 return CResource(self.code_item).get_last_code_item()
17882 </t>
17883 <t tx="michael.20060918132012">def get_last_code_item(self):
17884 editor = self.code_item.editor
17885 try:
17886 return [ci for ci in editor.code_items if is_resource(ci) ][-1]
17887 except IndexError:
17888 return CImport(self.code_item).get_last_code_item()
17889 </t>
17890 <t tx="michael.20060918132238">def get_last_code_item(self):
17891 editor = self.code_item.editor
17892 try:
17893 return [ci for ci in editor.code_items if is_import(ci) ][-1]
17894 except IndexError:
17895 import wx
17896 wx.MessageBox("At least one import has to bei in the code!", "Error")
17897 return None</t>
17898 <t tx="michael.20060918134452"></t>
17899 <t tx="michael.20060918135024">class ResourceCreator(NameEditor):
17900 title = _("Create Resource")
17901 @others</t>
17902 <t tx="michael.20060918135024.5">def realize_code(self):
17903 now = datetime.datetime.now().strftime("%x %H:%M:%S")
17904 code = 'class %s(Resource):\n"Inserted at %s"' % (self.name, now)
17905 context = self.context.__class__(self.context.get_last_code_item())
17906 context.append_item(code, 0)
17908 </t>
17909 <t tx="michael.20060918141622"></t>
17910 <t tx="michael.20060918141622.1">@language python
17911 &lt;&lt; Copyright &gt;&gt;
17912 &lt;&lt; Imports &gt;&gt;
17914 _is_source_ = True
17915 _ = faces.plocale.get_gettext()
17918 papersize = {\
17919 "Letter" : ( 612, 792 ),
17920 "Legal" : ( 612, 1008 ),
17921 "Tabloid" : ( 792, 1224 ),
17922 "Ledger" : ( 792, 1224 ),
17923 "Executive" :( 540, 720 ),
17924 "Monarch" : ( 279, 540 ),
17925 "Statement" :( 396, 612 ),
17926 "Folio" : ( 612, 936 ),
17927 "Quarto" : ( 610, 780 ),
17928 "C5" : ( 459, 649 ),
17929 "B4" : ( 729, 1032 ),
17930 "B5" : ( 516, 729 ),
17931 "Dl" : ( 312, 624 ),
17932 "A0" : ( 2380, 3368 ),
17933 "A1" : ( 1684, 2380 ),
17934 "A2" : ( 1190, 1684 ),
17935 "A3" : ( 842, 1190 ),
17936 "A4" : ( 595, 842 ),
17937 "A5" : ( 420, 595 ),
17938 "A6" : ( 297, 421 ),
17939 "custom" : None }
17941 paper_choices = dict(zip(papersize.keys(), papersize.keys()))
17942 scale_choices = { "no_scale" : _("no scaling") }
17943 scale_choices.update(paper_choices)
17947 @others
17948 </t>
17949 <t tx="michael.20060918141622.2">import wx
17950 import metapie
17951 import metapie.dbtransient as db
17952 import metapie.gui.views as views
17953 import faces.charting.printer as prnt
17954 import faces.charting.charts as charts
17955 import faces.gui.patches as patches
17956 import faces.plocale
17957 import tempfile
17958 import os
17959 import os.path
17960 import utils
17964 </t>
17965 <t tx="michael.20060918141622.3">class ChartPrinter(db.Model):
17966 &lt;&lt; declarations &gt;&gt;
17967 @others
17968 </t>
17969 <t tx="michael.20060918141622.4">filename = db.Text(none=True, default="")
17970 unit = db.Enumerate({ 'cm' : _('cm'),
17971 'mm' : _('mm'),
17972 'inch' : _('inch'),
17973 'point' : _('point'),
17974 'pixel' : _('pixel') },
17975 default="pixel")
17977 scale = db.Enumerate(scale_choices, default="no_scale")
17978 media = db.Enumerate(paper_choices, default="custom")
17979 media_size = db.Text("test")
17980 dpi = db.Int(default=72)
17981 command = db.Text(multi_line=True)
17982 edgecolor = db.Text(default="black")
17983 linewidth = db.Float(1.0)
17984 width = db.Float(width=7)
17985 height = db.Float(width=7)
17986 poster = db.Boolean()
17987 print_out_number = 0
17989 </t>
17990 <t tx="michael.20060918141622.5">def __init__(self, printer):
17991 super(ChartPrinter, self).__init__()
17992 self.filename = None
17993 self.chart_name = printer._chart.__name__
17994 self.printer = printer
17995 self.printer.type = "eps"
17996 self.printer.unit = "mm"
17997 self.refresh()
17998 self.calc_command()
17999 self.attach_weak(self)
18000 self.calc_media_size()
18001 </t>
18002 <t tx="michael.20060918141622.6">def refresh(self):
18003 self.printer.refresh()
18004 self._chart_instance = self.printer._chart_instance
18005 </t>
18006 <t tx="michael.20060918141622.7">def reset_valid(self):
18007 if not self.printer.valid:
18008 self.printer._chart_instance = self._chart_instance
18009 </t>
18010 <t tx="michael.20060918141622.8">def __call__(self, attrib):
18011 if attrib != "command":
18012 self.calc_command()
18014 self._fire_others(attrib)
18016 if attrib in ("unit", "media", "width", "height"):
18017 self.calc_media_size()
18019 if attrib in ("unit", "dpi", "font_size"):
18020 #if the unit changes the size changes also
18021 self.fire("width", "width")
18022 self.fire("height", "height")
18023 return
18024 </t>
18025 <t tx="michael.20060918141622.9">def _fire_others(self, attrib):
18026 pass
18027 </t>
18028 <t tx="michael.20060918141622.10">def _get_filename(self, org):
18029 if org: return self.printer.filename
18030 return org
18031 </t>
18032 <t tx="michael.20060918141622.11">def _set_filename(self, value):
18033 if value:
18034 dpi = self.dpi
18035 self.printer.filename = value
18036 if dpi != self.dpi:
18037 self.dpi = self.dpi
18039 return value
18040 </t>
18041 <t tx="michael.20060918141622.12">def _get_unit(self, org):
18042 return self.printer.unit
18043 </t>
18044 <t tx="michael.20060918141622.13">def _set_unit(self, value):
18045 self.printer.unit = value
18046 return value
18047 </t>
18048 <t tx="michael.20060918141622.14">def _get_width(self, org):
18049 self.reset_valid()
18050 return self.printer.width
18051 </t>
18052 <t tx="michael.20060918141622.15">def _set_width(self, value):
18053 self.reset_valid()
18054 self.printer.width = value
18055 return value
18056 </t>
18057 <t tx="michael.20060918141622.16">def _get_height(self, org):
18058 self.reset_valid()
18059 return self.printer.get_height()
18060 </t>
18061 <t tx="michael.20060918141622.17">def _set_height(self, value):
18062 self.reset_valid()
18063 self.printer.height = value
18064 </t>
18065 <t tx="michael.20060918141622.18">def _get_dpi(self, org):
18066 self.reset_valid()
18067 return int(self.printer.dpi)
18068 </t>
18069 <t tx="michael.20060918141622.19">def _set_dpi(self, value):
18070 self.printer.dpi = value
18071 return self.printer.dpi
18072 </t>
18073 <t tx="michael.20060918141622.20">def calc_media_size(self):
18074 unit = self.unit
18075 if unit == "pixel": unit = "point"
18076 size = papersize.get(self.media)
18077 if not size:
18078 size = (self.width, self.height)
18079 else:
18080 point_factor = prnt.ChartPrinter._point_factor
18081 size = map(lambda s: s / point_factor[unit], size)
18083 if self.printer.width &lt; self.printer.height:
18084 w, h = size
18085 else:
18086 h, w = size
18088 self.media_size = "%0.2f x %0.2f %s" % (w, h, unit)
18090 </t>
18091 <t tx="michael.20060918141622.21">def calc_command(self):
18092 command = "printer = %s.printer()" % self.chart_name
18094 if self.filename is not None:
18095 command += '\nprinter.filename = "%s"' % self.filename
18097 command += '\nprinter.linewidth = %.2f' % self.linewidth
18098 command += '\nprinter.edgecolor = "%s"' % self.edgecolor
18099 command += '\nprinter.unit = "%s"' % self.unit
18101 if self.printer.type != "eps":
18102 command += '\nprinter.dpi = %i' % self.dpi
18104 command = self.add_command_attributes(command)
18106 if self.filename is not None:
18107 command += '\nprinter.save()'
18109 command += '\nprinter.end()'
18110 self.command = command.strip()
18111 </t>
18112 <t tx="michael.20060918141622.22">def add_command_attributes(self, command):
18113 return command
18114 </t>
18115 <t tx="michael.20060918141622.23">def check_constraints(self):
18116 error = db.ConstraintError()
18118 if self.filename:
18119 for e in prnt.ChartPrinter._extensions:
18120 if self.filename.endswith(e): return
18121 else:
18122 error.message["filename"] = _("""File name must have one of the following extensions:
18123 %s""") % str(prnt.ChartPrinter._extensions)
18125 elif self.poster and self.media == "custom":
18126 error.message["media"] = _("""For poster printing, you have to set
18127 a standard output media""")
18129 if error.message:
18130 raise error
18131 </t>
18132 <t tx="michael.20060918141622.24">def save(self):
18133 self.printer.edgecolor = self.edgecolor
18134 self.printer.linewidth = self.linewidth
18136 if self.filename is None:
18137 tmpdir = tempfile.gettempdir()
18138 number = self.__class__.print_out_number
18139 self.__class__.print_out_number += 1
18141 #make shure the temp filename is an 8.3 name
18142 #poster doesn't like larger names under windows
18143 eps_path = os.path.join(tmpdir, "fpr%05i.eps" % number)
18144 self.printer.filename = eps_path
18145 self.printer.refresh()
18146 if self.printer.width &lt; self.printer.height:
18147 self.printer.orientation = "portrait"
18148 else:
18149 self.printer.orientation = "landscape"
18151 to_remove = metapie.controller().session.tmp_files_to_remove
18152 pdf_path = eps_path.replace(".eps", ".pdf")
18153 size = self.printer._figure.get_size_inches()
18155 if self.poster:
18156 to_remove.append(eps_path)
18157 self.printer.save()
18159 if self.scale == "no_scale":
18160 scale = "%.2fx%.2fi" % size
18161 else:
18162 scale = self.scale
18164 ps_path = eps_path.replace(".eps", ".ps")
18165 to_remove.append(ps_path)
18167 media = self.media
18168 if media == "custom":
18169 raise ValueError("media may not be custom")
18171 arguments = ("-p%s" % scale,
18172 "-m%s" % media,
18173 "-o%s" % ps_path,
18174 eps_path)
18176 utils.call_command("poster", arguments,
18177 "Poster",
18178 "http://www.geocities.com/SiliconValley/5682/poster.html")
18180 self.call_ps2pdf(ps_path, pdf_path)
18181 else:
18182 to_remove.append(eps_path)
18183 self.printer.save()
18184 if self.media == "custom":
18185 args = ('-dDEVICEWIDTHPOINTS=%i' % (size[0] * 72),
18186 '-dDEVICEHEIGHTPOINTS=%i' % (size[1] * 72),
18187 '-dEPSFitPage')
18188 else:
18189 args = ('-sPAPERSIZE=%s' % self.media.lower(),)
18190 self.call_ps2pdf(eps_path, pdf_path, args)
18192 #the next two lines would be the easier an cleaner implementation
18193 #but the pdf_backend cannot handle unicode
18194 #self.printer.filename = pdf_path
18195 #self.printer.save()
18197 to_remove.append(pdf_path)
18199 import webbrowser
18200 webbrowser.open("file://%s" % pdf_path, True, False)
18201 else:
18202 self.printer.save()
18203 </t>
18204 <t tx="michael.20060918141622.25">def call_ps2pdf(self, input, output, args=()):
18205 arguments = ('-dCompatibilityLevel=1.4',
18206 "-dQUIET",
18207 '-dNOPAUSE',
18208 '-dBATCH',
18209 '-sDEVICE=pdfwrite',
18210 '-sOutputFile=%s' % output,
18211 '-c.setpdfwrite',
18212 '-f%s' % input) + args
18213 utils.call_command("gs", arguments,
18214 "Ghostscript",
18215 "http://www.cs.wisc.edu/~ghost/doc/GPL/index.htm")
18216 </t>
18217 <t tx="michael.20060918141622.26">#different printers for the type of the widget_axes of the chart
18219 class LimitsPrinter(ChartPrinter):
18220 &lt;&lt; declarations &gt;&gt;
18221 @others
18222 </t>
18223 <t tx="michael.20060918141622.27">xmin = db.Float(width=7)
18224 xmax = db.Float(width=7)
18225 ymin = db.Float(width=7)
18226 ymax = db.Float(width=7)
18229 </t>
18230 <t tx="michael.20060918141622.28">def __init__(self, printer):
18231 super(LimitsPrinter, self).__init__(printer)
18232 </t>
18233 <t tx="michael.20060918141622.29">def zoom(self):
18234 self.printer.autoscale()
18235 self.fire("width", "width")
18236 self.fire("height", "height")
18237 self.fire("xmin", "xmin")
18238 self.fire("ymin", "ymin")
18239 self.fire("tmin", "tmin")
18240 self.fire("xmax", "xmax")
18241 self.fire("ymax", "ymax")
18242 self.fire("tmax", "tmax")
18243 </t>
18244 <t tx="michael.20060918141622.30">def _fire_others(self, attrib):
18245 super(LimitsPrinter, self)._fire_others(attrib)
18247 if attrib == "width":
18248 self.fire("xmin", "xmin")
18249 self.fire("xmax", "xmax")
18250 return
18252 if attrib == "height":
18253 self.fire("ymin", "ymin")
18254 self.fire("ymax", "ymax")
18255 return
18257 if attrib in ("unit", "dpi", "font_size"):
18258 self.fire("xmin", "xmin")
18259 self.fire("ymin", "ymin")
18260 self.fire("tmin", "tmin")
18261 self.fire("xmax", "xmax")
18262 self.fire("ymax", "ymax")
18263 self.fire("tmax", "tmax")
18264 return
18266 if attrib in ("xmin", "xmax"):
18267 self.fire("width", "width")
18268 return
18270 if attrib in ("ymin", "ymax"):
18271 self.fire("height", "height")
18272 return
18273 </t>
18274 <t tx="michael.20060918141622.31">def _set_xmin(self, value):
18275 self.printer.set_xlimits(xmin=value)
18276 return value
18277 </t>
18278 <t tx="michael.20060918141622.32">def _set_xmax(self, value):
18279 self.printer.set_xlimits(xmax=value)
18280 return value
18281 </t>
18282 <t tx="michael.20060918141622.33">def _set_ymin(self, value):
18283 self.printer.set_ylimits(ymin=value)
18284 return value
18285 </t>
18286 <t tx="michael.20060918141622.34">def _set_ymax(self, value):
18287 self.printer.set_ylimits(ymax=value)
18288 return value
18289 </t>
18290 <t tx="michael.20060918141622.35">def _get_xmin(self, value):
18291 self.reset_valid()
18292 return self.printer.get_xlimits()[0]
18293 </t>
18294 <t tx="michael.20060918141622.36">def _get_xmax(self, value):
18295 self.reset_valid()
18296 return self.printer.get_xlimits()[1]
18297 </t>
18298 <t tx="michael.20060918141622.37">def _get_ymin(self, value):
18299 self.reset_valid()
18300 return self.printer.get_ylimits()[0]
18301 </t>
18302 <t tx="michael.20060918141622.38">def _get_ymax(self, value):
18303 self.reset_valid()
18304 return self.printer.get_ylimits()[1]
18305 </t>
18306 <t tx="michael.20060918141622.39">def set_max_limits(self):
18307 self.printer.set_xlimits()
18308 self.printer.set_ylimits()
18309 self.y_limits.min, self.y_limits.max = self.printer.get_ylimits()
18310 </t>
18311 <t tx="michael.20060918141622.40">def add_command_attributes(self, command):
18312 command = super(LimitsPrinter, self).add_command_attributes(command)
18313 command += "\nprinter.set_xlimits(%.2f, %.2f)" % (self.xmin, self.xmax)
18314 command += "\nprinter.set_ylimits(%.2f, %.2f)" % (self.ymin, self.ymax)
18315 return command
18316 </t>
18317 <t tx="michael.20060918141622.41">class WidgetPrinter(LimitsPrinter):
18318 &lt;&lt; declarations &gt;&gt;
18319 @others
18320 </t>
18321 <t tx="michael.20060918141622.42">font_size = db.Int()
18323 </t>
18324 <t tx="michael.20060918141622.43">def _get_font_size(self, org):
18325 return self.printer.font_size
18326 </t>
18327 <t tx="michael.20060918141622.44">def _set_font_size(self, value):
18328 value = max(value, 2)
18329 self.printer.font_size = value
18330 self.refresh()
18331 return value
18332 </t>
18333 <t tx="michael.20060918141622.45">def add_command_attributes(self, command):
18334 command = super(WidgetPrinter, self).add_command_attributes(command)
18335 command += '\nprinter.fontsize = %i' % self.font_size
18336 return command
18337 </t>
18338 <t tx="michael.20060918141622.46">class TimePrinter(db.Model):
18339 &lt;&lt; declarations &gt;&gt;
18340 @others
18341 </t>
18342 <t tx="michael.20060918141622.47">tmin = db.DateTime()
18343 tmax = db.DateTime()
18346 </t>
18347 <t tx="michael.20060918141622.48">def __init__(self, *args, **kwargs):
18348 super(TimePrinter, self).__init__(*args, **kwargs)
18349 </t>
18350 <t tx="michael.20060918141622.49">def _set_tmin(self, value):
18351 self.printer.set_time_limits(min=value)
18352 return value
18353 </t>
18354 <t tx="michael.20060918141622.50">def _set_tmax(self, value):
18355 self.printer.set_time_limits(max=value)
18356 return value
18357 </t>
18358 <t tx="michael.20060918141622.51">def _get_tmin(self, value):
18359 self.reset_valid()
18360 return self.printer.get_time_limits()[0]
18361 </t>
18362 <t tx="michael.20060918141622.52">def _get_tmax(self, value):
18363 self.reset_valid()
18364 return self.printer.get_time_limits()[1]
18365 </t>
18366 <t tx="michael.20060918141622.53">def add_command_attributes(self, command):
18367 command = super(TimePrinter, self).add_command_attributes(command)
18368 command += '\nprinter.width = %.2f' % self.width
18369 return command
18370 </t>
18371 <t tx="michael.20060918141622.54">class TimeWidgetPrinter(TimePrinter, WidgetPrinter, ChartPrinter):
18372 pass
18373 </t>
18374 <t tx="michael.20060918141622.55">class TimePlotPrinter(TimePrinter, LimitsPrinter):
18375 @others
18376 </t>
18377 <t tx="michael.20060918141622.56">def add_command_attributes(self, command):
18378 command = super(TimePlotPrinter, self).add_command_attributes(command)
18379 command += '\nprinter.height = %.2f' % self.height
18380 return command
18381 </t>
18382 <t tx="michael.20060918141622.57">class PointPrinter(WidgetPrinter, LimitsPrinter):
18383 pass
18385 </t>
18386 <t tx="michael.20060918141622.58">class PrinterView(views.FormView):
18387 &lt;&lt; declarations &gt;&gt;
18388 @others
18389 </t>
18390 <t tx="michael.20060918141622.59"> __model__ = ChartPrinter
18391 __view_name__ = "default"
18393 format = _("""
18394 [File: ] |filename(SaveFile)&gt;
18395 [Edgecolor: ]|edgecolor(Color)|[Linewidth: ]|linewidth
18396 [Unit:] |unit
18398 (canvas)&gt;
18400 (cmd_or_print)&gt;
18402 (buttons)&gt;
18403 """)
18405 format_cmd_or_print = """
18406 (Command)&gt;|(Printer)&gt;
18409 format_Printer = _("""
18410 [Printer:]
18411 (0,0) |poster[Print as Poster]
18412 [Scale To Size: ]|scale
18413 [Output Media: ] |media|media_size(Static)
18414 """)
18416 format_Command = _("""
18417 [Command:]
18418 command&gt;
18419 """)
18421 format_buttons = "btn_print{r}|btn_save{r}|(0,5)|btn_cancel"
18422 viewlimit = ""
18423 format_canvas = """
18424 [Canvas Size:]
18425 [ Size: ] |(size)
18426 [ Resolution:] |dpi|[ dpi]
18429 format_size = "width|[ x ]|height|[ ]|unit"
18431 </t>
18432 <t tx="michael.20060918141622.60">def __init__(self, *args, **kwargs):
18433 self.format = self.format % self.viewlimit
18434 super(PrinterView, self).__init__(*args, **kwargs)
18435 </t>
18436 <t tx="michael.20060918141622.61">def create_buttons_controls(self, view):
18437 view.btn_print = view.get_button(wx.ID_PRINT)
18438 def prnt():
18439 if self.save(): self.imodel.save()
18440 view.btn_print.attach(prnt)
18441 </t>
18442 <t tx="michael.20060918141622.62">def prepare(self):
18443 self.grow_col(1)
18444 self.grow_row(-3)
18446 self.cmd_or_print.grow_col(0)
18447 self.cmd_or_print.grow_col(1)
18448 self.cmd_or_print.grow_row(0)
18450 self.cmd_or_print.Printer.grow_col(-1)
18451 self.cmd_or_print.Command.grow_col(0)
18452 self.cmd_or_print.Command.grow_row(1)
18454 self.buttons.grow_col(0)
18455 self.filename.set_filter(_("EPS (*.eps)|*.eps|" \
18456 "SVG (*.svg)|*.svg|" \
18457 "BMP (*.bmp)|*.bmp|" \
18458 "PNG (*.png)|*.png"))
18459 self.filename.set_width("X" * 20)
18460 self.canvas.dpi.set_width("8888")
18461 self.canvas.dpi.SetMaxLength(4)
18462 self.cmd_or_print.Command.command.set_height(6)
18463 self.cmd_or_print.Command.command.SetEditable(False)
18464 self._prepare_others()
18465 </t>
18466 <t tx="michael.20060918141622.63">def modify_subview(self, subview, name):
18467 if name in ("limits", "size"):
18468 subview.hgap = subview.vgap = 0
18470 return subview
18471 </t>
18472 <t tx="michael.20060918141622.64">def _prepare_others(self):
18473 pass
18474 </t>
18475 <t tx="michael.20060918141622.65">def button_cancel(self):
18476 self.rollback()
18477 self.GetParent().GetParent().EndModal(wx.ID_CANCEL)
18478 </t>
18479 <t tx="michael.20060918141622.66">def button_save(self):
18480 if self.save():
18481 self.imodel.save()
18482 self.GetParent().GetParent().EndModal(wx.ID_OK)
18483 </t>
18484 <t tx="michael.20060918141622.67">def make_size_int(self):
18485 self.canvas.size.width.SetFractionWidth(0)
18486 self.canvas.size.height.SetFractionWidth(0)
18487 self.canvas.size.layout()
18488 </t>
18489 <t tx="michael.20060918141622.68">def make_size_float(self):
18490 self.canvas.size.width.SetFractionWidth(2)
18491 self.canvas.size.height.SetFractionWidth(2)
18492 self.canvas.layout()
18493 </t>
18494 <t tx="michael.20060918141622.69">def state_changed(self, attrib):
18495 if attrib == "unit":
18496 if self.imodel.unit in ('pixel', 'mm', 'point'):
18497 self.make_size_int()
18498 else:
18499 self.make_size_float()
18500 return
18502 if attrib == "filename":
18503 value = self.imodel.filename
18505 if not value or value.endswith("ps"):
18506 self.canvas.dpi.Enable(False)
18507 else:
18508 self.canvas.dpi.Enable(True)
18510 if value is None:
18511 self.buttons.btn_save.Hide()
18512 self.cmd_or_print.Command.Hide()
18513 self.buttons.btn_print.Show()
18514 self.cmd_or_print.Printer.Show()
18515 self.cmd_or_print.ungrow_col(0)
18516 self.cmd_or_print.grow_col(1)
18517 self.cmd_or_print.Printer.layout()
18518 else:
18519 self.buttons.btn_save.Show()
18520 self.cmd_or_print.Command.Show()
18521 self.buttons.btn_print.Hide()
18522 self.cmd_or_print.Printer.Hide()
18523 self.cmd_or_print.ungrow_col(1)
18524 self.cmd_or_print.grow_col(0)
18525 self.cmd_or_print.Command.layout()
18527 self.buttons.layout()
18528 return
18530 if attrib == "poster":
18531 self.cmd_or_print.Printer.scale.Enable(self.imodel.poster)
18532 </t>
18533 <t tx="michael.20060918141622.70">def constitute(self, imodel):
18534 views.FormView.constitute(self, imodel)
18535 self.state_changed("filename")
18536 self.state_changed("unit")
18537 self.state_changed("poster")
18538 </t>
18539 <t tx="michael.20060918141622.71">class LimitsPrinterView(object):
18540 viewlimit = """
18541 auto_scale&gt;
18542 (viewlimit)&gt;
18545 format_viewlimit = """
18546 [View Limits:]
18547 [Horizontal: ]|xmin|[ - ]|xmax
18548 [Vertical: ] |ymin|[ - ]|ymax|[]
18552 @others
18553 </t>
18554 <t tx="michael.20060918141622.73">def _prepare_others(self):
18555 self.viewlimit.grow_col(-1)
18556 super(LimitsPrinterView, self)._prepare_others()
18557 </t>
18558 <t tx="michael.20060918141622.74">def create_controls(self):
18559 super(LimitsPrinterView, self).create_controls()
18560 self.auto_scale = self.get_button("Zoom To Extends")
18561 def zoom():
18562 self.imodel.zoom()
18564 self.auto_scale.attach(zoom)
18565 </t>
18566 <t tx="michael.20060918141622.75">class WidgetPrinterView(LimitsPrinterView):
18567 format_canvas = """
18568 [Canvas Size:]
18569 [Size: ] |(size)
18570 [Font size:] |font_size|[ Resolution:] |dpi|[ dpi]
18573 viewlimit = """
18574 auto_scale&gt;
18575 (viewlimit)&gt;"""
18577 @others
18578 </t>
18579 <t tx="michael.20060918141622.77">def _prepare_others(self):
18580 self.canvas.font_size.SetMaxLength(2)
18581 self.canvas.font_size.set_width("88")
18582 self.canvas.font_size.SetToolTipString(_("Size of standard font in Points"))
18583 super(WidgetPrinterView, self)._prepare_others()
18584 </t>
18585 <t tx="michael.20060918141622.78">class TimePrinterView(object):
18586 format_viewlimit = """
18587 [View Limits:]
18588 [Horizontal: ]|tmin|[ - ]|tmax
18589 [Vertical: ] |ymin|[ - ]|ymax
18592 </t>
18593 <t tx="michael.20060918141622.80">class TimePlotPrinterView(TimePrinterView, LimitsPrinterView, PrinterView):
18594 __model__ = TimePlotPrinter
18595 __view_name__ = "default"
18596 </t>
18597 <t tx="michael.20060918141622.82">class TimeWidgetPrinterView(TimePrinterView, WidgetPrinterView, PrinterView):
18598 __model__ = TimeWidgetPrinter
18599 __view_name__ = "default"
18601 </t>
18602 <t tx="michael.20060918141622.84">class PointPrinterView(WidgetPrinterView, PrinterView):
18603 __model__ = PointPrinter
18604 __view_name__ = "default"
18605 </t>
18606 <t tx="michael.20060918141622.86">class PrintChart(patches.PatchedDialog):
18607 @others
18608 </t>
18609 <t tx="michael.20060918141622.87">def __init__(self, parent, chart):
18610 wx.Dialog.__init__(self, parent, -1, _("Print Chart"),
18611 style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
18614 if isinstance(chart, charts.MatplotChart):
18615 try:
18616 axes = chart.widget_axes()
18617 except AttributeError:
18618 axes = chart.axes
18620 figure = axes.get_figure()
18621 kwargs = { "xlimits": axes.get_xlim(),
18622 "ylimits": axes.get_ylim(),
18623 "dpi": figure.get_dpi(),
18624 "size": figure.get_size_inches(),
18625 "type": "png" }
18626 else:
18627 kwargs = {}
18629 printer = chart.printer(**kwargs)
18631 if isinstance(printer, prnt.TimePlotPrinter):
18632 model = TimePlotPrinter
18634 elif isinstance(printer, prnt.TimeWidgetPrinter):
18635 model = TimeWidgetPrinter
18637 elif isinstance(printer, prnt.PointPrinter):
18638 model = PointPrinter
18640 else:
18641 model = ChartPrinter
18643 self.data = model(printer)
18644 </t>
18645 <t tx="michael.20060918141622.88">def simulate_modal(self, focused):
18646 container = views.ScrollViewContainer(self)
18647 view = self.data.constitute("default")(container)
18649 def resize():
18650 w, h = view.GetSize()
18651 container.SetClientSize((w + 10, h + 40))
18652 self.SetClientSize(container.GetSize())
18654 wx.CallAfter(resize)
18656 def end_dialog():
18657 self.data.printer.end()
18658 view.end_inspect()
18660 patches.PatchedDialog.simulate_modal(self, focused, end_dialog)
18661 </t>
18662 <t tx="michael.20060919144445">def _on_menu_open(self, event):
18663 menu = event.GetMenu()
18664 items = self.get_top_menu().items.values()
18666 for item in items:
18667 if item.wxobj == menu:
18668 title = item.title
18669 self.remove_temp_menus()
18670 for v in self.get_all_views():
18671 try:
18672 v.on_make_menu(title)
18673 break
18674 except AttributeError: pass
18675 </t>
18676 <t tx="michael.20060919150620">&lt;&lt; copy &amp; cut patch &gt;&gt;
18678 menu(_("&amp;Undo\tCTRL-Z"), nrc(self.Undo), "undo16", pos=100)
18679 menu(_("&amp;Redo\tCTRL-R"), nrc(self.Redo), "redo16", pos=200)
18680 menu(_("Cut\tCTRL-X"), cut, "editcut16", pos=300)
18681 menu(_("&amp;Copy\tCTRL-C"), nrc(copy), "editcopy16", pos=400)
18682 menu(_("&amp;Paste\tCTRL-V"), nrc(self.Paste), "editpaste16", pos=500)
18683 menu(_("Insert &amp;Date\tCTRL-D"), nrc(self.menu_insert_date), pos=550)
18684 </t>
18685 <t tx="michael.20060919150620.1">menu(_("Co&amp;mment\tCTRL-#"), self.menu_comment_selection, pos=600)
18686 menu(_("&amp;Uncomment"), self.menu_uncomment_selection, pos=601)</t>
18687 <t tx="michael.20060919150620.2">menu(_("&amp;Find\tCTRL-F"), self.menu_find_forward, "find16", pos=700)
18688 menu(_("Find &amp;Backward\tCTRL-B"), self.menu_find_backward, pos=710)
18689 menu(_("Replace"), self.menu_replace, pos=720)
18690 menu(_("Goto &amp;Line\tCTRL-G"), self.menu_goto_line, pos=730)</t>
18691 <t tx="michael.20060919150620.3">mb = menu(_("Start Macro Recording"), self.start_macro, pos=900)
18692 ms = menu(_("Stop Macro Recording"), self.stop_macro, pos=901)
18693 me = menu(_("Execute Macro\tCTRL-E"), self.execute_macro, pos=902)
18695 self.menu_macro_start = mb
18696 self.menu_macro_stop = ms
18697 self.menu_macro_execute = me
18698 if ctrl.macro:
18699 mb.enable(False)
18700 me.enable(False)
18701 ms.enable(True)
18702 else:
18703 me.enable(bool(self.macro))
18704 mb.enable(True)
18705 ms.enable(False)</t>
18706 <t tx="michael.20060919150620.4">def show_completion():
18707 wx.CallAfter(self.show_completion, True)
18709 menu(_("Context..."), show_completion, pos=1010)</t>
18710 <t tx="michael.20060919150620.5">def fmenu(level):
18711 def fold(): self.fold_to_level(level)
18712 fold_menu.make_item(owner,
18713 _("To Level %i\tALT-%i") % (level, level),
18714 fold)
18716 map(fmenu, range(0, 10))</t>
18717 <t tx="michael.20060919150620.6">edit_menu.make_separator(_("Co&amp;mment"), True)
18718 edit_menu.make_separator(_("Toggle Bookmark"), True)
18719 edit_menu.make_separator(_("Cut"), True)
18720 edit_menu.make_separator(_("Find"), True)
18721 edit_menu.make_separator(_("Fold"), True)
18722 edit_menu.make_separator(_("Start Macro Recording"), True)</t>
18723 <t tx="michael.20060919150828">help_menu.make_item(owner, _("Current Calltip\tCTRL-F1"),
18724 self.show_call_tip, pos=10)</t>
18725 <t tx="michael.20060919150828.1">try:
18726 main_buffer_editor = ctrl.session.main_buffer.editor
18727 except AttributeError:
18728 main_buffer_editor = None
18730 file_menu.make_item(owner, _("&amp;Create Snapshot..."),
18731 self.menu_snapshot, "stamp16", pos=45,
18732 help=_("Create a snapshot of the current project."))\
18733 .enable(main_buffer_editor is self.GetParent())</t>
18734 <t tx="michael.20060919151956">def create_context_menu(self, menu, item):
18735 editor = self.GetParent().editor
18737 try:
18738 first_item = editor.code_items[0]
18739 except IndexError:
18740 #at least one code item has to be there
18741 return
18743 if item == self.imports:
18744 context.CImport(first_item).make_browser_menu(menu, ("create",))
18746 elif item == self.resources:
18747 context.CResource(first_item).make_browser_menu(menu, ("create",))
18749 elif item == self.tasks:
18750 context.CProjectDeclaration(first_item).make_browser_menu(menu, ("create",))
18752 elif item == self.evaluations:
18753 context.CEvaluation(first_item).make_browser_menu(menu, ("create",))
18755 elif item == self.observers:
18756 context.CObserver(first_item).make_browser_menu(menu, ("create",))
18758 else:
18759 code_item = self.GetPyData(item)
18760 action_filter = ("add", "edit", "extra")
18762 for c in context.Context.context_list:
18763 c = c.__class__(code_item)
18764 if c.make_browser_menu(menu, action_filter):
18765 break
18767 if is_project(code_item):
18768 self.append_display_eval_data_menu(code_item, item, menu)
18769 </t>
18770 <t tx="michael.20060919153708">project_menu = top.make_menu(_("&amp;Project"), pos=110)
18771 project_menu.make_item(owner, _("Correct Code"), self.correct_code, pos=100,
18772 help=_("Tries to resolve broken references and renamed items"))
18773 project_menu.make_separator(_("Correct Code"))</t>
18774 <t tx="michael.20060919173141">def get_editors(self):
18775 return self.editors</t>
18776 <t tx="michael.20060919173141.1"> @others</t>
18777 <t tx="michael.20060919173151">def amend_browser_menu(self, menu, action_filter=None):
18778 code_item = self.code_item
18779 existing_attribs = code_item.editor.get_attribs(code_item)
18780 editors = self.get_editors()
18782 toadd = []
18783 toedit = []
18784 extra = []
18785 for pe in editors.iteritems():
18786 action = pe[1].apply_browser_menu(existing_attribs, code_item)
18787 if action_filter and action not in action_filter: continue
18788 if action == "add": toadd.append(pe)
18789 elif action == "edit": toedit.append(pe)
18790 elif action in ("extra", "create"): extra.append(pe)
18792 if extra:
18793 create_editor_menu(menu, self, extra)
18795 if toadd:
18796 &lt;&lt; insert "Add Attributes" menu &gt;&gt;
18798 if toedit:
18799 &lt;&lt; insert "Edit Attributes" menu &gt;&gt;
18800 &lt;&lt; insert "Remove Attributes" menu &gt;&gt;
18802 </t>
18803 <t tx="michael.20060919173151.1">add = menu.make_menu(_("Add Attributes"))
18804 create_editor_menu(add, self, toadd)</t>
18805 <t tx="michael.20060919173151.2">edit = menu.make_menu(_("Edit Attributes"))
18806 create_editor_menu(edit, self, toedit)</t>
18807 <t tx="michael.20060919173151.3">remove = menu.make_menu(_("Remove Attributes"))
18808 editor = code_item.editor
18809 def create_remove(line):
18810 def remove_attrib(): editor.replace_expression("", line, True)
18811 return remove_attrib
18813 for p, edit in toedit:
18814 try:
18815 attrib = edit.attrib_name
18816 line = existing_attribs[attrib]
18817 remove.make_temp_item(attrib, create_remove(line))
18818 except KeyError:
18819 pass</t>
18820 <t tx="michael.20060919202707">def on_make_menu(self, menu_title):
18821 if menu_title == _("&amp;Project"):
18822 top = controller().get_top_menu()
18823 project_menu = top.make_menu(_("&amp;Project"), pos=110)
18824 item = self.GetSelection()
18825 if item.IsOk():
18826 self.create_context_menu(project_menu, item)</t>
18827 <t tx="michael.20060921000959">def append_display_eval_data_menu(self, code_item, item, menu):
18828 session = controller().session
18829 editor = self.GetParent().editor
18831 try:
18832 id_ = code_item.obj._idendity_()
18833 except AttributeError: return
18835 evals = [ (k, v) for k, v in session.evaluations.items()
18836 if v._idendity_() == id_ ]
18837 if not evals: return
18839 displayed_eval_name = self.displayed_eval_map.get(id_)
18840 show_menu = menu.make_menu(_("&amp;Displayed Evaluation Data"))
18841 menu.make_separator(_("&amp;Displayed Evaluation Data"), True)
18843 def change_data_call(varname):
18844 def change_data():
18845 self.displayed_eval_map[id_] = varname
18846 self.idle_item = item
18848 return change_data
18850 for varname, eval in evals:
18851 check_item = False
18852 try:
18853 if displayed_eval_name == varname:
18854 check_item = True
18855 except AttributeError: pass
18857 mi = show_menu.make_temp_item(varname,
18858 change_data_call(varname),
18859 check_item=check_item)
18860 if check_item: mi.check()
18861 </t>
18862 <t tx="michael.20060921011201"></t>
18863 <t tx="michael.20060921012719">class SingletonEditor(db.Model, context.ItemEditor):
18864 title = ""
18866 @others</t>
18867 <t tx="michael.20060921012719.1">class TaskRenamer(RenameEditor):
18868 title = _("Rename Task")
18869 __icon__ = "rename16"
18871 def correct_code(self, editor):
18872 editor.correct_task_code(self.context.code_item)</t>
18873 <t tx="michael.20060921012812">def apply(self, expression, code_item):
18874 return False
18875 </t>
18876 <t tx="michael.20060921012921">def apply_browser_menu(self, existing_attribs, code_item):
18877 return "extra"
18878 </t>
18879 <t tx="michael.20060921013128">def activate(self, context):
18881 activates the editor.
18883 if controller().is_processing(): return
18885 self.context = context
18886 self.init_attributes()
18887 dlg = editorlib.PatchedDialog(controller().frame, -1, self.title,
18888 style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
18890 dlg.SetClientSize((10, 10))
18891 view = self.constitute()(dlg)
18892 view.layout()
18893 dlg.simulate_modal(context.code_item.editor)
18894 return self
18895 </t>
18896 <t tx="michael.20060921013128.1">def init_attributes(self):
18897 raise RuntimeError("abstract")</t>
18898 <t tx="michael.20060921013326"></t>
18899 <t tx="michael.20060921013326.1"></t>
18900 <t tx="michael.20060921013326.2">def cancel(self):
18901 del self.context
18902 self.detach_all()</t>
18903 <t tx="michael.20060921013326.3"></t>
18904 <t tx="michael.20060921135700">def get_display_eval_data(self, task):
18905 id_ = task.root._idendity_()
18906 evaluations = controller().session.evaluations
18907 try:
18908 eval_name = self.displayed_eval_map[id_]
18909 try:
18910 return evaluations[eval_name].get_task(task.path)
18911 except KeyError:
18912 del self.displayed_eval_map[id_]
18913 except KeyError: pass
18915 evaluations = evaluations.items()
18916 evaluations.sort()
18918 for varname, eval in evaluations:
18919 if eval._idendity_() == id_:
18920 self.displayed_eval_map[id_] = varname
18921 return eval.get_task(task.path) or task
18923 return task</t>
18924 <t tx="michael.20060921144552.1">class ResourceRenamer(RenameEditor):
18925 title = _("Rename Resource")
18926 __icon__ = "rename16"
18928 def correct_code(self, editor):
18929 editor.correct_resource_code(self.context.code_item)
18930 </t>
18931 <t tx="michael.20060921144959">def realize(self):
18932 self.realize_code()
18933 del self.context
18934 self.detach_all()</t>
18935 <t tx="michael.20060921225151">registry = context.CObserver.editors
18936 registry["Observer/Create...(100)"] = ObserverCreator()
18937 registry["Observer/Rename...(110)"] = ObserverRenamer()
18938 registry["Observer/Remove(120)"] = ObserverRemover()
18941 </t>
18942 <t tx="michael.20060921225322"></t>
18943 <t tx="michael.20060921225442">class NameEditor(SingletonEditor):
18944 name = db.Text()
18945 @others</t>
18946 <t tx="michael.20060921225442.1">def apply_browser_menu(self, existing_attribs, code_item):
18947 return "create"
18948 </t>
18949 <t tx="michael.20060921225442.2">def init_attributes(self):
18950 self.name = ""</t>
18951 <t tx="michael.20060921225442.3">def check_constraints(self):
18952 if not reg_identifier.match(self.name):
18953 error = db.ConstraintError()
18954 error.message["name"] = _("Name is not a valid identifier")
18955 raise error</t>
18956 <t tx="michael.20060921225442.4">def realize_code(self):
18957 raise RuntimeError("abstract")
18959 </t>
18960 <t tx="michael.20060921225700">class NameEditorView(editorlib.MainView):
18961 __model__ = NameEditor
18962 __view_name__ = "default"
18964 format = _("""
18965 [Name: ]|name&gt;
18966 --&gt;
18967 (buttons)&gt;
18968 """)
18970 def prepare(self):
18971 self.grow_col(-1)
18972 self.grow_row(1)
18973 self.buttons.grow_col(0)
18974 self.name.set_width("X"*30)</t>
18975 <t tx="michael.20060921230035">def apply_browser_menu(self, existing_attribs, code_item):
18976 return "extra"
18977 </t>
18978 <t tx="michael.20060921230339">class ObserverRenamer(RenameEditor):
18979 title = _("Rename Observer")
18980 __icon__ = "rename16"
18982 def correct_code(self, editor):
18983 pass
18985 </t>
18986 <t tx="michael.20060921230629">class RenameEditor(NameEditor):
18987 @others
18988 </t>
18989 <t tx="michael.20060921230629.1">def apply_browser_menu(self, existing_attribs, code_item):
18990 return "extra"
18991 </t>
18992 <t tx="michael.20060921230629.2">def init_attributes(self):
18993 self.name = self.context.code_item.name
18994 </t>
18995 <t tx="michael.20060921230629.3">def realize_code(self):
18996 code_item = self.context.code_item
18997 editor = code_item.editor
18998 editor.BeginUndoAction()
18999 code_item.rename(self.name)
19000 self.correct_code(editor)
19001 editor.EndUndoAction()
19003 </t>
19004 <t tx="michael.20060923124429">@doc
19005 returns the code_item, the found line, and the start and end position
19006 @code
19007 def find_resource_references(self, resource_name):
19008 for ci in self.code_items:
19009 if is_task(ci) or is_project(ci):
19010 try:
19011 line = self.get_attribs(ci)["resource"]
19012 except KeyError: continue
19014 start, end = self.get_expression_range(line)
19015 try:
19016 self.GetTextRange(start, end).index(resource_name)
19017 yield ci, line, start, end
19018 except ValueError: pass
19020 </t>
19021 <t tx="michael.20060923124429.1">@doc
19022 code_item has to be a reference on a task
19023 @code
19024 def find_task_references(self, code_item):
19025 try:
19026 task = code_item.obj
19027 except AttributeError: return
19029 #tasks and tasks children dependencies
19030 dependencies = reduce(lambda a, b: a + b,
19031 [ t._dependencies.values() for t in task ])
19033 for path_attrib_map in dependencies:
19034 for path_attrib in path_attrib_map.iterkeys():
19035 path, attrib = ftask._split_path(path_attrib)
19036 dst = task.get_task(path)
19038 try:
19039 dst_item = dst._function.code_item
19040 except AttributeError: continue
19041 except weakref.ReferenceError: continue
19043 try:
19044 line = self.get_attribs(dst_item)[attrib]
19045 except KeyError: continue
19047 yield dst_item, attrib, line
19048 </t>
19049 <t tx="michael.20060923134450">class ReferencePrinter(object):
19050 __icon__ = "list16"
19052 @others</t>
19053 <t tx="michael.20060923134450.1">def apply(self, expression, code_item):
19054 return False
19055 </t>
19056 <t tx="michael.20060923134450.2">def apply_browser_menu(self, existing_attribs, code_item):
19057 return "extra"
19058 </t>
19059 <t tx="michael.20060923134450.3">def activate(self, context):
19060 print_resource_references(context.code_item)
19061 </t>
19062 <t tx="michael.20060923134450.4">def get_planbuffers(self):
19063 models = self.id_to_model.values()
19064 for m in models:
19065 if isinstance(m, PlanBuffer):
19066 yield m</t>
19067 <t tx="michael.20060923140956">class TaskReferencePrinter(object):
19068 __icon__ = "list16"
19070 @others
19071 </t>
19072 <t tx="michael.20060923140956.1">def apply(self, expression, code_item):
19073 return False
19074 </t>
19075 <t tx="michael.20060923140956.2">def apply_browser_menu(self, existing_attribs, code_item):
19076 return "extra"
19077 </t>
19078 <t tx="michael.20060923140956.3">def activate(self, context):
19079 print_task_references(context.code_item)
19080 </t>
19081 <t tx="michael.20060923141119">self.show_object = self.editor.show_object
19082 self.sync_text = self.editor.sync_text
19083 self.refresh = self.editor.refresh
19084 self.find_resource_references = self.editor.find_resource_references
19085 self.find_task_references = self.editor.find_task_references
19086 self.get_module = self.editor.get_module</t>
19087 <t tx="michael.20060923154026">attribs = self.get_attribs(code_item)
19088 for attrib, source_path_attribs in task._sources.iteritems():
19089 try:
19090 line = attribs[attrib]
19091 except KeyError: continue
19093 expr = self.get_expression(line)
19095 for path_attrib in source_path_attribs:
19096 spath, attrib = ftask._split_path(path_attrib)
19097 stask = task.get_task(spath)
19099 try:
19100 sitem = stask._function.code_item
19101 except AttributeError: continue
19102 except weakref.ReferenceError: continue
19104 spath = get_code_item_path(sitem)
19105 rel_path = ftask.create_relative_path(path, spath)
19106 old_rel_path = ftask.create_relative_path(old_path, spath)
19107 expr = expr.replace(old_rel_path, rel_path)
19109 expr = "\n".join([s.strip() for s in expr.split("\n")]) #strip each line
19110 self.replace_expression(expr, line, move_cursor=False)
19111 </t>
19112 <t tx="michael.20060923154026.1">for dst_item, attrib, line in self.find_task_references(code_item):
19113 dst_path = get_code_item_path(dst_item)
19114 expr = self.get_expression(line)
19116 rel_path = ftask.create_relative_path(dst_path, path)
19117 old_rel_path = ftask.create_relative_path(dst_path, old_path)
19118 expr = expr.replace(old_rel_path, rel_path)
19119 expr = expr.replace(old_path, path)
19120 expr = "\n".join([s.strip() for s in expr.split("\n")]) #strip each line
19121 self.replace_expression(expr, line, move_cursor=False)
19122 </t>
19123 <t tx="michael.20060923160547">def print_resource_references(code_item, outstream=None):
19124 outstream = outstream or sys.stdout
19125 rname = code_item.name
19126 print &gt;&gt; outstream, _('The following lines reference the resource "%s":') % rname
19127 for m in controller().get_planbuffers():
19128 for ci, line, start, end in m.editor.find_resource_references(rname):
19129 print &gt;&gt; outstream, _(' object: "%s", File "%s", line %i') % (ci.name, m.path, line + 1)
19131 print &gt;&gt; outstream</t>
19132 <t tx="michael.20060923160547.1">class ResourceRemover(object):
19133 __icon__ = "delete16"
19135 @others
19136 </t>
19137 <t tx="michael.20060923160547.2">def apply(self, expression, code_item):
19138 return False
19139 </t>
19140 <t tx="michael.20060923160547.3">def apply_browser_menu(self, existing_attribs, code_item):
19141 return "extra"
19142 </t>
19143 <t tx="michael.20060923160547.4">def activate(self, context):
19144 references = False
19145 code_item = context.code_item
19146 rname = code_item.name
19147 for m in controller().get_planbuffers():
19148 if list(m.editor.find_resource_references(rname)):
19149 references = True
19150 break
19152 if references:
19153 print_resource_references(context.code_item, sys.stderr)
19154 print &gt;&gt; sys.stderr, _("You have to remove those references before removing the resource!\n")
19155 else:
19156 code_item.remove()
19157 </t>
19158 <t tx="michael.20060923161713">def print_task_references(code_item, outstream=None):
19159 outstream = outstream or sys.stdout
19160 tname = code_item.name
19161 print &gt;&gt; outstream, _('The following lines reference the task "%s":') % tname
19162 find_references = code_item.editor.find_task_references
19163 for ci, attrib, line in find_references(code_item):
19164 print &gt;&gt; outstream, ' task attribute: "%s.%s", File "%s", line %i' \
19165 % (ci.name, attrib, ci.editor.model.path, line + 1)
19167 print &gt;&gt; outstream</t>
19168 <t tx="michael.20060923162103">class TaskRemover(object):
19169 __icon__ = "delete16"
19171 @others
19172 </t>
19173 <t tx="michael.20060923162103.1">def apply(self, expression, code_item):
19174 return False
19175 </t>
19176 <t tx="michael.20060923162103.2">def apply_browser_menu(self, existing_attribs, code_item):
19177 return "extra"
19178 </t>
19179 <t tx="michael.20060923162103.3">def activate(self, context):
19180 code_item = context.code_item
19181 editor = code_item.editor
19183 if list(editor.find_task_references(code_item)):
19184 print_task_references(context.code_item, sys.stderr)
19185 print &gt;&gt; sys.stderr, _("You have to remove those references before removing the task!\n")
19186 else:
19187 code_item.remove()
19188 </t>
19189 <t tx="michael.20060927165817">def _on_change(self, event):
19190 editor = self.GetParent().editor
19192 &lt;&lt; define internal insert function &gt;&gt;
19193 &lt;&lt; split and sort changed items list &gt;&gt;
19195 for l, code_item in removed:
19196 &lt;&lt; remove item &gt;&gt;
19198 for l, code_item in inserted:
19199 &lt;&lt; insert item &gt;&gt;
19201 for l, code_item in changed:
19202 &lt;&lt; change item &gt;&gt;
19204 if self.idle_item:
19205 self.idle_item = self.imports
19206 </t>
19207 <t tx="michael.20060927165817.1">def insert(item):
19208 prev, next = editor.code_items_near(item.get_line() - 1)
19210 def get_parent(item):
19211 parent = self.GetItemParent(item.tree_obj)
19212 return self.GetPyData(parent)
19214 parent = prev
19215 prev = None
19217 while parent and not parent.is_parent(item):
19218 prev = parent
19219 parent = get_parent(parent)
19221 if not parent:
19222 parent = self.get_section(item)
19223 prev = None
19224 else:
19225 parent = parent.tree_obj
19227 if prev:
19228 child = self.InsertItem(parent, prev.tree_obj, item.name)
19229 else:
19230 child = self.PrependItem(parent, item.name)
19232 item.tree_obj = child
19233 self.SetPyData(child, item)
19234 self.modify_item(child)</t>
19235 <t tx="michael.20060927171146">def bind_events(self):
19236 editor = self.GetParent().editor
19237 self.Bind(wx.EVT_TREE_SEL_CHANGED, self._on_sel_changed)
19238 self.Bind(wx.EVT_TREE_ITEM_EXPANDED, self._on_refresh)
19239 self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self._on_refresh)
19240 self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self._on_right_click)
19241 self.Bind(wx.EVT_SIZE, self._on_size)
19242 self.Bind(wx.EVT_IDLE, self._on_idle)
19243 self.Bind(wx.EVT_TREE_BEGIN_DRAG, self._on_begin_drag)
19244 editor.Bind(pyeditor.EVT_CODE_ITEM_CHANGED, self._on_change)
19245 </t>
19246 <t tx="michael.20060927174723">registry = context.CEvaluation.editors
19247 registry[_("Evaluation/Create Project...(1000)")] = ProjectCreator()
19248 registry[_("Evaluation/Create BalancedProject...(1010)")] = BalancedProjectCreator()
19249 registry[_("Evaluation/Create AdjustedProject...(1020)")] = AdjustedProjectCreator()
19250 registry[_("Evaluation/Edit...(1000)")] = ProjectEditor()
19251 registry[_("Evaluation/Edit...(1001)")] = BalancedProjectEditor()
19252 registry[_("Evaluation/Edit...(1002)")] = AdjustedProjectEditor()
19253 registry[_("Evaluation/Show References...(1900)")] = EvaluationReferencePrinter()
19254 registry[_("Evaluation/Remove...(1020)")] = EvaluationRemover()
19256 registry = context.CImport.editors
19257 registry[_("Import/Remove...(1020)")] = ImportRemover()
19258 registry[_("Import/Import Gantt Charts(100)")] = ImportCreator("import faces.lib.gantt as gantt")
19259 registry[_("Import/Import Workbreakdown Charts(110)")] = ImportCreator("import faces.lib.workbreakdown as workbreakdown")
19260 registry[_("Import/Import Resource Charts(120)")] = ImportCreator("import faces.lib.resource as resource_charts")
19261 registry[_("Import/Import Reports(130)")] = ImportCreator("import faces.lib.report as report")
19263 del registry
19265 </t>
19266 <t tx="michael.20060927185257">self.project_map = {}
19267 editor = imodel.context.code_item.editor
19268 module = editor.get_module()
19269 ismodule = inspect.ismodule
19270 val_name_map = dict([ (v, k) for k, v in module.__dict__.iteritems()
19271 if ismodule(v)])
19273 for m in controller().get_planbuffers():
19274 if editor.model.path != m.path:
19275 import_module = m.editor.get_module()
19276 try:
19277 # get modules import name
19278 prefix = val_name_map[import_module] + "."
19279 except KeyError:
19280 continue
19281 else:
19282 prefix = ""
19284 for item in m.editor.editor.code_items:
19285 if item.indent == 0 \
19286 and item.obj_type == pyeditor.FUNCTION \
19287 and not item.get_args():
19288 try:
19289 if not isinstance(item.obj, ftask._ProjectBase): continue
19290 except AttributeError: pass
19291 self.project_map[prefix + item.name] = item
19293 projects = self.project_map.keys()
19294 projects.sort()
19295 self.project.Clear()
19296 for p in projects:
19297 self.project.Append(p)</t>
19298 <t tx="michael.20060927190516">class ProjectCreator(SingletonEditor):
19299 name = db.Text()
19300 scenario = db.Text()
19301 id = db.Text()
19302 project = db.Text()
19303 title = _("Create Project")
19305 @others
19306 </t>
19307 <t tx="michael.20060927190516.1">class ProjectView(editorlib.MainView):
19308 __model__ = ProjectCreator
19309 __view_name__ = "default"
19311 format = _("""
19312 [Project: ] |project(Combo)&gt;
19313 [Scenario: ]|scenario(Combo)&gt;
19314 [Name: ] |name&gt;
19315 [Id: ] |id&gt;
19316 --&gt;
19317 (buttons)&gt;
19318 """)
19320 @others</t>
19321 <t tx="michael.20060927192936">def apply_browser_menu(self, existing_attribs, code_item):
19322 return "create"</t>
19323 <t tx="michael.20060927192936.1">def init_attributes(self):
19324 self.scenario = "_default"
19325 self.project = ""
19326 self.name = ""
19327 self.id = ""
19329 </t>
19330 <t tx="michael.20060927193132"></t>
19331 <t tx="michael.20060927193132.1">def _construct_name(self, project=None, scenario=None):
19332 project = project or self.project
19333 scenario = scenario or self.scenario
19334 if scenario == "_default": scenario = "default"
19335 if not project: return ""
19336 return "%s.%s" % (project, scenario)</t>
19337 <t tx="michael.20060927193132.2">def _set_project(self, value):
19338 if not self.name or self.name == self._construct_name():
19339 self.name = self._construct_name(project=value)
19341 if self.id == self.project or not self.id:
19342 self.id = value
19344 return value
19345 </t>
19346 <t tx="michael.20060927193132.3">def _set_scenario(self, value):
19347 if not self.name or self.name == self._construct_name():
19348 self.name = self._construct_name(scenario=value)
19350 return value</t>
19351 <t tx="michael.20060927193132.5">def check_constraints(self):
19352 error = db.ConstraintError()
19353 if not reg_path.match(self.name):
19354 error.message["name"] = _("Name is not a valid identifier")
19356 if not reg_path.match(self.project):
19357 error.message["project"] = _("project is not a valid identifier")
19359 if not reg_identifier.match(self.id):
19360 error.message["id"] = _("id is not a valid identifier")
19362 if error.message:
19363 raise error</t>
19364 <t tx="michael.20060927193132.6">def realize_code(self):
19365 code = str(self)
19366 context = self.context.__class__(self.context.get_last_code_item())
19367 context.append_item(code, 0, prespace="\n")</t>
19368 <t tx="michael.20060927203751">def prepare(self):
19369 self.grow_col(-1)
19370 self.grow_row(-2)
19371 self.buttons.grow_col(0)</t>
19372 <t tx="michael.20060927203751.1">def constitute(self, imodel):
19373 super(ProjectView, self).constitute(imodel)
19375 &lt;&lt; fill project combo &gt;&gt;
19377 self.scenario.Clear()
19378 self.scenario.Append("_default")</t>
19379 <t tx="michael.20060927203751.2">def state_changed(self, attrib):
19380 if attrib == "project":
19381 self.scenario.Clear()
19382 try:
19383 item = self.project_map[self.imodel.project]
19384 except KeyError:
19385 self.scenario.Append("_default")
19386 else:
19387 try:
19388 all_scenarios = list(item.obj.all_scenarios)
19389 except AttributeError:
19390 self.scenario.Append("_default")
19391 else:
19392 all_scenarios.sort()
19393 for s in all_scenarios:
19394 self.scenario.Append(s)</t>
19395 <t tx="michael.20060927203751.3">class BalancedProjectCreator(ProjectCreator):
19396 balance = db.Enumerate(ftask._allocator_strings)
19397 performed = db.Text()
19398 title = _("Create BalancedProject")
19400 @others</t>
19401 <t tx="michael.20060927204614">def check_constraints(self):
19402 try:
19403 super(BalancedProjectCreator, self).check_constraints()
19404 except db.ConstraintError, error:
19405 pass
19406 else:
19407 error = db.ConstraintError()
19409 if self.performed and not reg_path.match(self.performed):
19410 error.message["performed"] = _("performed is not a valid identifier")
19412 if error.message:
19413 raise error</t>
19414 <t tx="michael.20060927204614.1">class BalancedProjectView(ProjectView):
19415 __model__ = BalancedProjectCreator
19416 __view_name__ = "default"
19418 format = _("""
19419 [Project: ] |project(Combo)&gt;
19420 [Scenario: ] |scenario(Combo)&gt;
19421 [Name: ] |name&gt;
19422 [Balance: ] |balance
19423 [Id: ] |id&gt;
19424 [Performed: ]|performed&gt;
19425 --&gt;
19426 (buttons)&gt;
19427 """)
19428 </t>
19429 <t tx="michael.20060927204924">def __str__(self):
19430 balance = ftask._allocator_strings[self.balance]
19431 if self.performed:
19432 return '%s = BalancedProject(%s, "%s", "%s", %s, %s)' \
19433 % (self.name, self.project, self.scenario,
19434 self.id, balance, self.performed)
19435 else:
19436 return '%s = BalancedProject(%s, "%s", "%s", %s)' \
19437 % (self.name, self.project, self.scenario,
19438 self.id, balance)
19440 </t>
19441 <t tx="michael.20060927205317">class ProjectEditor(ProjectEditorMixin, ProjectCreator):
19442 title = _("Edit Project")
19444 @others</t>
19445 <t tx="michael.20060927211426">class ProjectEditorMixin(object):
19446 __icon__ = "edit16"
19448 @others
19450 </t>
19451 <t tx="michael.20060927211706">def apply_browser_menu(self, existing_attribs, code_item):
19452 if classifiers.is_evaluation(code_item):
19453 expr = code_item.editor.get_expression(code_item.get_line())
19454 if re.search(r"\WProject\W", expr): return "extra"
19455 return ""</t>
19456 <t tx="michael.20060927211820">class BalancedProjectEditor(ProjectEditorMixin, BalancedProjectCreator):
19457 title = _("Edit BalancedProject")
19458 @others</t>
19459 <t tx="michael.20060927211820.1">def init_attributes(self):
19460 obj = super(BalancedProjectEditor, self).init_attributes()
19461 if obj:
19462 self.balance = obj.balance
19463 else:
19464 self.balance = ftask.SMART
19466 self.performed = ""
19467 args = self.context.code_item.get_args()
19468 try:
19469 self.performed = args[4]
19470 except IndexError:
19471 for a in args:
19472 if a.startswith("performed"):
19473 self.performed = a.split("=")[-1].strip()
19474 break
19475 </t>
19476 <t tx="michael.20060927212238">def init_attributes(self):
19477 super(BalancedProjectCreator, self).init_attributes()
19478 self.balancing = ftask.SMART
19479 self.performed = ""
19480 </t>
19481 <t tx="michael.20060929085858">def init_attributes(self):
19482 code_item = self.context.code_item
19483 self.name = code_item.name
19485 editor = code_item.editor
19486 expr = editor.get_expression(code_item.get_line())
19487 dict = editor.eval_expression(expr, context=self.context)
19489 try:
19490 module = editor.get_module()
19491 obj = eval("module.%s" % code_item.name)
19492 except AttributeError:
19493 try:
19494 obj = dict[code_item.name]
19495 except KeyError:
19496 obj = None
19499 if obj:
19500 self.scenario = obj.scenario
19501 self.project = obj._function.__name__
19502 self.id = obj.id
19503 else:
19504 self.scenario = "_default"
19505 self.project = ""
19507 return obj
19509 </t>
19510 <t tx="michael.20060929085928">def apply_browser_menu(self, existing_attribs, code_item):
19511 if classifiers.is_evaluation(code_item):
19512 expr = code_item.editor.get_expression(code_item.get_line())
19513 if re.search(r"\WBalancedProject\W", expr): return "extra"
19514 return ""</t>
19515 <t tx="michael.20060929093150">def __str__(self):
19516 return '%s = Project(%s, "%s", "%s")' \
19517 % (self.name, self.project, self.scenario, self.id)
19518 </t>
19519 <t tx="michael.20060929093303">def realize_code(self):
19520 code = str(self)
19521 code_item = self.context.code_item
19522 editor = code_item.editor
19523 editor.BeginUndoAction()
19524 if code_item.name != self.name:
19525 #name has changed ==&gt; change the name in all references
19526 old_name = code_item.name
19528 iterator = editor.find_evaluation_references(code_item)
19529 refs = dict([ (line, ci) for ci, line in iterator ])
19530 for line in refs.keys():
19531 start = editor.PositionFromLine(line)
19532 end = editor.GetLineEndPosition(line)
19533 editor.SetTargetStart(start)
19534 editor.SetTargetEnd(end)
19535 text = editor.GetTextRange(start, end)
19536 editor.ReplaceTarget(text.replace(old_name, self.name))
19538 code_item.editor.replace_expression(code, code_item.get_line())
19540 editor.EndUndoAction()
19541 </t>
19542 <t tx="michael.20060929093536"></t>
19543 <t tx="michael.20060929093536.1">def _set_project(self, value):
19544 return value</t>
19545 <t tx="michael.20060929093536.2">def _set_scenario(self, value):
19546 return value</t>
19547 <t tx="michael.20060929220600">#scincilla has to format the text before we can correctly autoindent
19548 self.Colourise(start, start + len(text))
19549 self.SetLineIndentation(start_line, start_indent)
19550 line = start_line
19551 for line, line_text in enumerate(lines[1:]):
19552 line += start_line + 1
19553 self.autoindent(self.PositionFromLine(line), False)</t>
19554 <t tx="michael.20060929220600.2">#scincilla has to format the text before we can correctly autoindent
19555 self.Colourise(start, start + len(text))
19556 for line, line_text in enumerate(lines):
19557 line += start_line
19558 self.autoindent(self.PositionFromLine(line), False)</t>
19559 <t tx="michael.20060929224036">class AdjustedProjectCreator(SingletonEditor):
19560 name = db.Text()
19561 base = db.Text()
19562 title = _("Create AdjustedProject")
19564 @others
19565 </t>
19566 <t tx="michael.20060929225058">def apply_browser_menu(self, existing_attribs, code_item):
19567 return "create"</t>
19568 <t tx="michael.20060929225128">def init_attributes(self):
19569 self.scenario = "_default"
19570 self.project = ""
19571 self.name = ""
19572 self.id = ""
19574 #code_item = self.context.code_item
19575 #if classifiers.is_evaluation(code_item):
19578 </t>
19579 <t tx="michael.20060929225233">def realize_code(self):
19580 code = str(self)
19581 context = self.context.__class__(self.context.get_last_code_item())
19582 context.append_item(code, 0, prespace="\n")</t>
19583 <t tx="michael.20060929230703">class AdjustedProjectView(editorlib.MainView):
19584 __model__ = AdjustedProjectCreator
19585 __view_name__ = "default"
19587 format = _("""
19588 [Name: ] |name&gt;
19589 [Base Evaluation: ] |base(Combo)&gt;
19590 --&gt;
19591 (buttons)&gt;
19592 """)
19594 @others</t>
19595 <t tx="michael.20060929230703.1">def prepare(self):
19596 self.grow_col(-1)
19597 self.grow_row(-2)
19598 self.buttons.grow_col(0)</t>
19599 <t tx="michael.20060929230703.2">def constitute(self, imodel):
19600 super(AdjustedProjectView, self).constitute(imodel)
19602 &lt;&lt; fill base combo &gt;&gt;
19603 </t>
19604 <t tx="michael.20060929230703.3">balanced_projects = []
19605 editor = imodel.context.code_item.editor
19606 module = editor.get_module()
19607 ismodule = inspect.ismodule
19608 val_name_map = dict([ (v, k) for k, v in module.__dict__.iteritems()
19609 if ismodule(v)])
19612 for m in controller().get_planbuffers():
19613 if editor.model.path != m.path:
19614 import_module = m.editor.get_module()
19615 try:
19616 # get modules import name
19617 prefix = val_name_map[import_module] + "."
19618 except KeyError:
19619 continue
19620 else:
19621 prefix = ""
19623 for item in m.editor.editor.code_items:
19624 if item.obj_type == classifiers.EVALUATION:
19625 expr = m.editor.editor.get_expression(item.get_line())
19626 try:
19627 expr.index("BalancedProject")
19628 except ValueError:
19629 continue
19630 else:
19631 balanced_projects.append(prefix + item.name)
19633 balanced_projects.sort()
19634 self.base.Clear()
19635 for p in balanced_projects:
19636 self.base.Append(p)</t>
19637 <t tx="michael.20060929231103">def __str__(self):
19638 return '%s = AdjustedProject(%s)' % (self.name, self.base)
19639 </t>
19640 <t tx="michael.20060929231203">def check_constraints(self):
19641 error = db.ConstraintError()
19642 if not reg_path.match(self.name):
19643 error.message["name"] = _("Name is not a valid identifier")
19645 if not reg_path.match(self.base):
19646 error.message["base"] = _("base is not a valid identifier")
19648 if error.message:
19649 raise error</t>
19650 <t tx="michael.20060929231329">class AdjustedProjectEditor(AdjustedProjectCreator):
19651 title = _("Edit AdjustedProject")
19652 __icon__ = "edit16"
19654 @others
19655 </t>
19656 <t tx="michael.20060929231415">def apply_browser_menu(self, existing_attribs, code_item):
19657 if classifiers.is_evaluation(code_item):
19658 expr = code_item.editor.get_expression(code_item.get_line())
19659 if re.search(r"\WAdjustedProject\W", expr): return "extra"
19660 return ""</t>
19661 <t tx="michael.20060929231534">def init_attributes(self):
19662 self.name = self.context.code_item.name
19663 try:
19664 self.base = self.context.code_item.get_args()[0]
19665 except IndexError:
19666 self.base = 0
19667 </t>
19668 <t tx="michael.20060929232917">@doc
19669 returns the code_item and the found line
19670 @code
19671 def find_evaluation_references(self, code_item):
19672 evaluation_name = code_item.name
19673 start = self.PositionFromLine(code_item.get_line() + 1)
19674 end = self.GetLength()
19675 while True:
19676 start = self.FindText(start, end, evaluation_name, \
19677 wx.stc.STC_FIND_MATCHCASE\
19678 |wx.stc.STC_FIND_WHOLEWORD)
19679 if start &lt; 0: break
19680 line = self.LineFromPosition(start)
19681 start += 1
19682 text = self.GetLine(line)
19683 try:
19684 #comments are no references
19685 if text.index("#") &lt; text.index(evaluation_name): continue
19686 except ValueError: pass
19688 yield self.code_item_at(line), line
19691 </t>
19692 <t tx="michael.20060929233107">def print_evaluation_references(code_item, outstream=None):
19693 outstream = outstream or sys.stdout
19694 ename = code_item.name
19695 m = code_item.editor.model
19696 print &gt;&gt; outstream, _('The following lines reference to "%s":') % ename
19697 for ci, line, in code_item.editor.find_evaluation_references(code_item):
19698 print &gt;&gt; outstream, _(' object: "%s", File "%s", line %i') % (str(ci), m.path, line + 1)
19700 print &gt;&gt; outstream</t>
19701 <t tx="michael.20060929233300">class EvaluationReferencePrinter(object):
19702 __icon__ = "list16"
19704 @others
19705 </t>
19706 <t tx="michael.20060929233300.1">def apply(self, expression, code_item):
19707 return False
19708 </t>
19709 <t tx="michael.20060929233300.2">def apply_browser_menu(self, existing_attribs, code_item):
19710 return "extra"
19711 </t>
19712 <t tx="michael.20060929233300.3">def activate(self, context):
19713 print_evaluation_references(context.code_item)
19714 </t>
19715 <t tx="michael.20060929234312">class EvaluationRemover(object):
19716 __icon__ = "delete16"
19718 @others</t>
19719 <t tx="michael.20060929234312.1">def apply(self, expression, code_item):
19720 return False
19721 </t>
19722 <t tx="michael.20060929234312.2">def apply_browser_menu(self, existing_attribs, code_item):
19723 return "extra"
19724 </t>
19725 <t tx="michael.20060929234312.3">def activate(self, context):
19726 code_item = context.code_item
19728 if list(code_item.editor.find_evaluation_references(code_item)):
19729 print_evaluation_references(context.code_item, sys.stderr)
19730 print &gt;&gt; sys.stderr, _("You have to remove those references before removing the evaluation!\n")
19731 else:
19732 code_item.remove()
19733 </t>
19734 <t tx="michael.20060930013205">instrumentation_cache = {}
19735 balancing_cache = {}
19737 def clear_cache():
19738 instrumentation_cache.clear()
19739 balancing_cache.clear()</t>
19740 <t tx="michael.20060930032329">def _clean_up_dragging(self, e=None):
19741 self.ReleaseMouse()
19742 self.SetCursor(wx.NullCursor)
19744 self.Unbind(wx.EVT_KEY_DOWN)
19745 self.Unbind(wx.EVT_RIGHT_DOWN)
19746 self.Unbind(wx.EVT_LEFT_UP)
19747 self.drag_item = None
19750 def _on_begin_drag(self, event):
19751 item = event.GetItem()
19752 code_item = self.GetPyData(item)
19754 if is_task(code_item):
19755 self.drag_item = code_item
19756 hand_cursor = wx.StockCursor(wx.CURSOR_HAND)
19757 self.SetCursor(hand_cursor)
19758 self.CaptureMouse()
19759 drag_item = self.drag_item
19760 &lt;&lt; define temporary event handlers &gt;&gt;
19761 self.SetFocus()
19762 self.Bind(wx.EVT_KEY_DOWN, on_key_down)
19763 self.Bind(wx.EVT_LEFT_UP, self._on_end_drag)
19764 self.Bind(wx.EVT_RIGHT_DOWN, self._clean_up_dragging)
19767 def _on_end_drag(self, event):
19768 if not self.drag_item: return
19769 drag_item = self.drag_item
19771 self._clean_up_dragging()
19773 pos = event.GetPosition()
19774 item, flag, col = self.HitTest(pos)
19775 &lt;&lt; check if drag_item is moved to a valid position &gt;&gt;
19777 children = tuple(drag_item.get_children(True))
19778 editor = self.GetParent().editor
19779 editor.BeginUndoAction()
19780 &lt;&lt; move drag_item &gt;&gt;
19781 &lt;&lt; copy extended CodeItem attributes to new items &gt;&gt;
19783 editor.should_be_corrected = True
19785 editor.EndUndoAction()
19786 wx.CallAfter(self.update_selection, new_item)
19787 </t>
19788 <t tx="michael.20060930115815"></t>
19789 <t tx="michael.20060930115917">class ImportRemover(object):
19790 __icon__ = "delete16"
19792 @others
19793 </t>
19794 <t tx="michael.20060930115917.1">def apply(self, expression, code_item):
19795 return False
19796 </t>
19797 <t tx="michael.20060930115917.2">def apply_browser_menu(self, existing_attribs, code_item):
19798 return "extra"
19799 </t>
19800 <t tx="michael.20060930115917.3">def activate(self, context):
19801 code_item = context.code_item.remove()
19802 </t>
19803 <t tx="michael.20060930120528">class ImportCreator(object):
19804 @others</t>
19805 <t tx="michael.20060930120528.1">def __init__(self, import_string):
19806 self.import_string = import_string</t>
19807 <t tx="michael.20060930120528.2">def apply(self, expression, code_item):
19808 return False
19809 </t>
19810 <t tx="michael.20060930120528.3">def apply_browser_menu(self, existing_attribs, code_item):
19811 return "create"
19812 </t>
19813 <t tx="michael.20060930120528.4">def activate(self, context):
19814 context = context.__class__(context.get_last_code_item())
19815 context.append_item(self.import_string, 0, prespace="\n")</t>
19816 <t tx="michael.20060930134539">class ObserverCreator(SingletonEditor):
19817 name = db.Text()
19818 description = db.Text(multi_line=True)
19819 data = db.Model.type()
19820 observer = None
19821 observer_name = None
19822 title = _("Create Observer")
19824 @others</t>
19825 <t tx="michael.20061002003849">@language python
19826 &lt;&lt; Copyright &gt;&gt;
19827 &lt;&lt; Imports &gt;&gt;
19829 _is_source_ = True
19830 _ = faces.plocale.get_gettext()
19832 __all__ = ("Standard",)
19834 @others
19836 faces.observer.clear_cache_funcs[Standard] = Standard._color_dict.clear
19837 </t>
19838 <t tx="michael.20061002003849.1">import faces.charting.charts as charts
19839 import faces.observer
19840 import faces.task
19841 import faces.resource
19842 import faces.charting.timescale as timescale
19843 import faces.charting.widgets as widget
19844 import faces.charting.patches as patches
19845 import faces.charting.shapes as shapes
19846 import faces.plocale
19847 import matplotlib.font_manager as font
19848 import locale
19849 from faces.charting.tools import *
19851 </t>
19852 <t tx="michael.20061002003849.2">class Standard(charts.TimeAxisWidgetChart):
19854 A standard resource chart.
19856 @var load_factor:
19857 Specifies the height of a load 1.0 bar in units of
19858 the default font size. If the load_factor is 12 and
19859 the default font size is 12 pt, the height of load 1.0 bar
19860 will be 12 * 12 = 144 pt. The default value is 12.
19862 @var start:
19863 The left start date of the chart. If KW{None} it is calculated
19864 automatically.
19866 @var end:
19867 The right end date of the chart. If KW{None} it is calculated
19868 automatically.
19870 @var title_attrib:
19871 A string value specifying the name of the task attribute that
19872 should be displayed at the gantt object, to identify the task.
19874 @var color_index:
19875 A list of tuples defining the facecolor and fontcolor for
19876 the booking bars.
19878 &lt;&lt; declarations &gt;&gt;
19879 @others
19880 </t>
19881 <t tx="michael.20061002003849.3">__type_image__ = "resources"
19882 __editor__ = ("faces.gui.edit_chart", "Resource")
19884 color_index = ( ("navy", "white"),
19885 ("seagreen", "white"),
19886 ("indianred", "white"),
19887 ("violet", "white"),
19888 ("skyblue", "white"),
19889 ("purple", "white"),
19890 ("forestgreen", "white"),
19891 ("limegreen", "white"),
19892 ("darkorchid", "white"),
19893 ("rosybrown", "white") )
19895 properties = { "title.weight" : "bold",
19896 "title.color" : "white",
19897 "row.edgecolor" : "black",
19898 "title.edgecolor" : "black",
19899 "title.facecolor" : "black",
19900 "title.linewidth" : 1,
19901 "title.fill" : 1,
19902 "title.antialiased" : True }
19904 _color_dict = { }
19905 _cindex = 0
19906 load_factor = 12
19907 show_rowlines = True
19908 start = None
19909 end = None
19910 title_attrib = "title"
19912 __attrib_completions__ = charts.TimeAxisWidgetChart.__attrib_completions__.copy()
19913 __attrib_completions__.update({\
19914 "color_index" : 'color_index = [ ("navy", "white"), ("seagreen", "white") ]',
19915 "title_attrib" : 'title_attrib = "title"',
19916 "load_factor" : 'load_factor = 12',
19917 "show_rowlines" : 'show_rowlines = False',
19918 "start" : 'start = "|"',
19919 "end" : 'end = "|"',
19920 "def modify_row" : """def modify_row(self, row_widget, res):
19921 self.add_load_line(row_widget, 1.0, edgecolor="red")
19922 """,
19923 "def modify_bar" : \
19924 """def modify_bar(self, bar_widget, row_widget, task):
19925 bar_widget.text("effort: %s\\nlength: %s" \\
19926 % (task.to_string.effort,
19927 task.to_string.length),
19928 LEFT + 2*HSEP, TOP - 2*VSEP,
19929 horizontalalignment="left",
19930 verticalalignment="top",
19931 color="white")
19932 """})
19935 </t>
19936 <t tx="michael.20061002003849.4">def __init__(self, *args, **kwargs):
19937 charts.TimeAxisWidgetChart.__init__(self, *args, **kwargs)
19938 </t>
19939 <t tx="michael.20061002003849.5">def create_all_widgets(self, start_row):
19940 data = self.data
19942 widgets = []
19944 try:
19945 if isinstance(data, faces.task.Task):
19946 if not self.start: self.start = self.data.start
19947 if not self.end: self.end = self.data.end
19948 self.calendar = self.data.root.calendar
19949 data = data.all_resources()
19950 elif isinstance(data, faces.resource.Resource):
19951 data = ( data, )
19952 elif issubclass(data, faces.resource.Resource):
19953 data = ( data(), )
19954 except TypeError:
19955 raise ValueError("the data attribute is not valid")
19957 if not self.start or not self.end:
19958 raise RuntimeError("You have to specify 'start' and 'end'")
19960 self.time_scale = timescale.TimeScale(self.calendar)
19961 self.start = self.time_scale.to_num(self.start)
19962 self.end = self.time_scale.to_num(self.end)
19964 for resource in iter(data):
19965 row = self.create_row(resource)
19966 bars = self.create_bars(resource(), row)
19967 if bars:
19968 widgets.extend(bars)
19969 else:
19970 # to ensure that the row will be there
19971 dumy = widget.TimeWidget(self.start, self.end, resource, row)
19972 dumy.set_shape(shapes.bar, "bar")
19973 dumy.set_visible(False)
19974 widgets.append(dumy)
19976 if not widgets:
19977 #no resource allocated
19978 raise RuntimeError("no resources defined")
19980 rows = self._finalize_row_widgets(widgets, start_row)
19981 widgets.extend(rows)
19982 return widgets
19983 </t>
19984 <t tx="michael.20061002003849.6">def create_row(self, resource):
19985 row = widget.Row()
19986 row.top_sep = 9
19987 row.bottom_sep = 0
19988 row.fobj = resource
19990 name = resource.name
19991 if resource.title != name:
19992 name += "(%s)" % resource.title
19994 kwargs = make_properties(self.get_property, "title")
19995 row.add_artist(patches.Rectangle((LEFT, TOP - 8 * VSEP),
19996 RIGHT - LEFT, 7 * VSEP,
19997 **kwargs))
19999 row.text(name, LEFT + 2 * HSEP, TOP - 3 * VSEP,
20000 verticalalignment="top",
20001 horizontalalignment ="left",
20002 fontproperties="title")
20004 row.text(name, RIGHT - 2 * HSEP, TOP - 3 * VSEP,
20005 verticalalignment="top",
20006 horizontalalignment ="right",
20007 fontproperties="title")
20009 self.modify_row(row, resource)
20010 return row
20011 </t>
20012 <t tx="michael.20061002003849.7">def modify_row(self, row_widget, resource):
20014 Overwrite this method, to decorate a resource row.
20016 pass
20017 </t>
20018 <t tx="michael.20061002003849.8">def add_load_line(self, row_widget, load, **kwargs):
20020 Adds a horizontal line at a specific load.
20023 offset = self.load_offset(load)
20024 row_widget.add_artist(patches.Polygon(((LEFT, BOTTOM + offset),
20025 (RIGHT, BOTTOM + offset)),\
20026 **kwargs))
20028 row_widget.text("load %0.2f" % load,
20029 RIGHT - 2*HSEP, BOTTOM + offset - 2*VSEP,
20030 horizontalalignment="right",
20031 verticalalignment="top",
20032 fontproperties="left.load_line")
20034 row_widget.text("load %0.2f" % load,
20035 LEFT + 2*HSEP, BOTTOM + offset - 2*VSEP,
20036 horizontalalignment="left",
20037 verticalalignment="top",
20038 fontproperties="right.load_line")
20039 </t>
20040 <t tx="michael.20061002003849.9">add_load_line.__call_completion__ = 'add_load_line(row_widget, 1.0, edgecolor="red")'
20043 def load_offset(self, load):
20045 returns the y position of a specific load.
20047 return load * self.load_factor * font.fontManager.get_default_size()
20048 </t>
20049 <t tx="michael.20061002003849.10">def create_bar(self, task, row, start, end, load, offset):
20050 widget.ResourceBarWidget.load_factor = self.load_factor
20051 facecolor, text_color = self.get_color(task)
20052 props = { "bar.inside.color" : text_color,
20053 "facecolor" : facecolor }
20054 bar = widget.ResourceBarWidget(task, row, start, end,
20055 load, offset, props)
20056 bar.inside_text("%s (%.2f)" % (getattr(task, self.title_attrib), load),
20057 inside_properties="bar.inside")
20058 self.modify_bar(bar, row, task)
20059 return bar
20060 </t>
20061 <t tx="michael.20061002003849.11">def modify_bar(self, bar_widget, row_widget, task):
20063 Overwrite this method, to decorate a var widget.
20065 pass
20066 </t>
20067 <t tx="michael.20061002003849.12">def get_color(cls, task):
20068 id_ = task._idendity_()
20069 if not id_:
20070 #vacations have always the same color
20071 return ("gold", "black")
20073 color = cls._color_dict.get(id_)
20074 if not color:
20075 color = cls._color_dict[id_] = cls.color_index[cls._cindex]
20076 cls._cindex += 1
20077 if cls._cindex &gt;= len(cls.color_index):
20078 cls._cindex = 0
20080 return color
20081 </t>
20082 <t tx="michael.20061002003849.13">get_color = classmethod(get_color)
20085 def create_bars(self, resource, row):
20086 to_num = self.time_scale.to_num
20087 widgets = []
20088 dstart = self.start
20089 dend = self.end
20091 tasks = resource.get_bookings_at(dstart, dend, self.data.scenario)
20093 def make_item(task):
20094 start = to_num(min(task.start, task.book_start))
20095 end = to_num(max(task.end, task.book_end))
20096 return (start, -(end - start), -task.load, task.book_start, task)
20098 book_items = map(make_item, tasks)
20099 book_items.sort()
20100 load_offsets = faces.resource.ResourceCalendar()
20101 used_tasks = {}
20103 def break_booking(start, end):
20104 #breaks a booking into parts with different load offsets
20105 spos, epos, offsets = load_offsets.get_bookings(start, end)
20106 offsets = map(lambda o: (max(to_num(o[0]), start), o[1] / 10000.0),
20107 offsets[spos:epos])
20108 #returns the following sequence:
20109 #[(offset[0], offset[1]), (offset[1], offset[2]), ...]
20110 return zip(offsets, offsets[1:] + [(end,0)])
20112 def feq(f1, f2):
20113 "float equal"
20114 return ("%.3f" % f1) == ("%.3f" % f2)
20116 for s, le, lo, bs, t in book_items:
20117 load = -lo
20119 start = max(to_num(t.book_start), dstart)
20120 end = min(to_num(t.book_end), dend)
20122 breaks = break_booking(start, end)
20123 for sl, el in breaks:
20124 start, offset = sl
20125 end = el[0]
20126 last = used_tasks.get(t._idendity_())
20128 if last and feq(last.offset, offset) and feq(last.load, load):
20129 cal_last_end = self.calendar.EndDate(last.end)
20130 cal_start = self.calendar.EndDate(start)
20131 if cal_last_end &gt;= cal_start:
20132 #connect the two objects
20133 load_offsets.add_load(last.end, end, load)
20134 last.end = end
20135 continue
20137 load_offsets.add_load(start, end, load)
20138 obj = self.create_bar(t, row, start, end, load, offset)
20139 widgets.append(obj)
20140 used_tasks[t._idendity_()] = obj
20142 return widgets
20143 </t>
20144 <t tx="michael.20061002003849.14">def get_tip(self, tipobj):
20145 if not self.show_tips: return
20147 if isinstance(tipobj, widget.ResourceBarWidget):
20148 formats = faces.task.Task.formats
20149 to_minute = self.time_scale.chart_calendar.Minutes
20150 duration = tipobj.fobj.book_end - tipobj.fobj.book_start
20151 duration = to_minute(duration, True)
20152 work_time = to_minute(tipobj.fobj.work_time)
20153 lines = [
20154 (_("Name"), tipobj.fobj.title),
20155 (_("Load"), locale.format("%.2f", tipobj.load, True)),
20156 (_("Worktime"), work_time.strftime(formats["length"])),
20157 (_("Timeframe"), "%s - %s" %
20158 (tipobj.fobj.book_start.strftime(formats["start"]),
20159 tipobj.fobj.book_end.strftime(formats["end"]))),
20160 (_("Duration"), duration.strftime(formats["duration"], True)),
20161 (_("State"), tipobj.fobj.actual and _("actual") or _("planned"))
20164 return lines
20166 return None
20167 </t>
20168 <t tx="michael.20061002004356">def register_editors(cls, registry):
20169 super(Standard, cls).register_editors(registry)
20170 registry.Boolean(_("Chart/show_rowlines..."), True)
20171 registry.Float(_("Chart/load_factor..."), 12)
20172 registry.Date(_("Chart/start..."))
20173 registry.Date(_("Chart/end..."))
20174 registry.String(_("Shape/title_attrib..."), "title")
20175 registry.Evaluation(_("Chart/data..."))
20176 registry.TwoColorSet(_("Chart/color_index..."), cls.color_index)
20179 register_editors = classmethod(register_editors)
20181 def create_property_groups(cls, property):
20182 property.set_default_groups()
20183 property.fill_font_group("title")
20184 property.fill_font_group("left.load_line")
20185 property.fill_font_group("right.load_line")
20186 property.fill_font_group("load_line")
20187 property.fill_font_group("bar.inside")
20190 create_property_groups = classmethod(create_property_groups)</t>
20191 <t tx="michael.20061002010322"></t>
20192 <t tx="michael.20061002010322.1">class TwoColor(db.Model):
20193 face = db.Text()
20194 text = db.Text()
20196 def __str__(self):
20197 return '("%s", "%s")' % (self.face, self.text)
20199 </t>
20200 <t tx="michael.20061002010322.2">class TwoColorGrid(grid.EditGrid, views.GridView):
20201 __model__ = TwoColor
20202 columns = (("face(Color)", _("Face")),
20203 ("text(Color)", _("Text")))
20204 resize_col = 1</t>
20205 <t tx="michael.20061002010322.3">class TwoColorSet(db.Model):
20206 def __init__(self, code_item, attrib, value):
20207 super(TwoColorSet, self).__init__()
20208 for face, text in value or ():
20209 self.colors.insert(TwoColor(face=face, text=text))
20212 def __str__(self):
20213 return "[%s]" % ",\n".join(map(str, self.colors))
20216 db.Relation("colors",
20217 db.End(TwoColor, "colors", multi='*'),
20218 db.End(TwoColorSet))</t>
20219 <t tx="michael.20061002010322.4">class TwoColorSetView(views.FormView):
20220 __model__ = TwoColorSet
20221 __view_name__ = "default"
20222 vgap = 0
20223 format = """
20224 colors&gt;
20225 delete
20227 def create_controls(self):
20228 self.colors = self.get_control("colors(ColorGrid)")
20229 self.delete = self.colors.get_delete_button(self)
20231 def prepare(self):
20232 self.grow_col(0)
20233 self.grow_row(0)</t>
20234 <t tx="michael.20061002011136">def realize_code(self):
20235 raise RuntimeError("abstract")
20236 </t>
20237 <t tx="michael.20061002015044">def check_constraints(self):
20238 if len(self.evals) == 0:
20239 error = db.ConstraintError()
20240 error.message["evals"] = _("You have to input at least one evaluation data.")
20241 raise error</t>
20242 <t tx="michael.20061002020357"></t>
20243 <t tx="michael.20061002020357.1">def apply_browser_menu(self, existing_attribs, code_item):
20244 return "create"</t>
20245 <t tx="michael.20061002020357.2">def init_attributes(self):
20246 self.name = ""
20247 self.observer = None
20248 self.data = None</t>
20249 <t tx="michael.20061002020357.3">def realize_code(self):
20250 now = datetime.datetime.now().strftime("%x %H:%M:%S")
20251 code = 'class %s(%s):\n"Inserted at %s"' \
20252 % (self.name, self.observer_name, now)
20254 if self.data:
20255 code += "\ndata = %s" % str(self.data)
20257 context = self.context.__class__(self.context.get_last_code_item())
20258 context.append_item(code, 0)</t>
20259 <t tx="michael.20061002020357.4">def check_constraints(self):
20260 if not reg_identifier.match(self.name):
20261 error = db.ConstraintError()
20262 error.message["name"] = _("Name is not a valid Identifier")
20263 raise error</t>
20264 <t tx="michael.20061002020357.5">def set_observer(self, observer, name):
20265 code_item = self.context.code_item
20266 description = docparser.ClassDoc(observer).description
20268 registry = EditorRegistry()
20269 observer.register_editors(registry)
20271 for e in registry.editors.itervalues():
20272 if e.attrib_name == "data" \
20273 and e.edit_model in (Evaluation, MultiEvaluation):
20274 self.data = e.edit_model(code_item, "data", None)
20275 break
20276 else:
20277 self.data = None
20279 self.observer_name = name
20280 self.observer = observer
20281 self.description = description or _("No Description")</t>
20282 <t tx="michael.20061002020357.6">class ObserverCreatorView(editorlib.MainView):
20283 __model__ = ObserverCreator
20284 __view_name__ = "default"
20286 format = _("""
20287 lbl_error
20288 observer_list&gt;|[Description:]
20289 "" |description&gt;
20290 "" |[Name: ]
20291 "" |name&gt;
20292 "" |data_label
20293 "" |data&gt;
20294 --&gt;
20295 (buttons)&gt;
20296 """)
20298 @others</t>
20299 <t tx="michael.20061002020357.7">def create_controls(self):
20300 self.observer_list = wx.ListCtrl(self, wx.NewId(),
20301 style=wx.LC_ICON \
20302 |wx.LC_SINGLE_SEL \
20303 |wx.LC_ALIGN_TOP \
20304 |wx.SUNKEN_BORDER)
20305 self.observer_list.Bind(wx.EVT_LIST_ITEM_SELECTED, self._on_select_item)
20306 self.data_label = self.get_label(_("Data:"))</t>
20307 <t tx="michael.20061002020357.8">def prepare(self):
20308 self.grow_col(-1)
20309 self.grow_row(2)
20310 self.buttons.grow_col(0)
20311 self.description.set_width("X" * 40)</t>
20312 <t tx="michael.20061002020357.9">def constitute(self, imodel):
20313 super(ObserverCreatorView, self).constitute(imodel)
20315 self.observer_map = {}
20317 &lt;&lt; fill observer list &gt;&gt;
20318 </t>
20319 <t tx="michael.20061002020357.10">img_list = wx.ImageList(32, 32)
20320 img_name_index_map = {}
20322 observers = []
20323 &lt;&lt; find observers &gt;&gt;
20324 &lt;&lt; fill list control &gt;&gt;
20325 self.observer_list.Arrange()
20326 w, h = self.observer_list.GetViewRect().GetSize()
20327 border = self.observer_list.GetSize() \
20328 - self.observer_list.GetClientSize()
20329 self.observer_list.CacheBestSize((w + border.width,
20330 (height + 40) * 7))
20331 self.observer_list.SetItemState(0, wx.LIST_STATE_SELECTED,
20332 wx.LIST_STATE_SELECTED)
20333 </t>
20334 <t tx="michael.20061002020357.11">module = imodel.context.code_item.editor.get_module()
20335 ismodule = inspect.ismodule
20336 for k, v in module.__dict__.iteritems():
20337 &lt;&lt; filter out non valid modules &gt;&gt;
20338 &lt;&lt; get public attribs of module &gt;&gt;
20339 for attrib in attribs:
20340 obj = getattr(v, attrib, None)
20341 try:
20342 if not issubclass(obj, fobserver.Observer):
20343 continue
20344 except TypeError: continue
20346 &lt;&lt; add observer image in img_list &gt;&gt;
20347 self.observer_map["%s.%s" % (k, attrib)] = obj
20348 observers.append(("%s.%s" % (k, attrib), img_index))
20349 </t>
20350 <t tx="michael.20061002020357.12">if not ismodule(v): continue
20352 try:
20353 if not v._is_source_: continue
20354 except AttributeError: continue</t>
20355 <t tx="michael.20061002020357.13">try:
20356 attribs = v.__all__
20357 except AttributeError:
20358 attribs = dir(v)</t>
20359 <t tx="michael.20061002020357.14">img_name = obj.__type_image__
20360 if img_name:
20361 try:
20362 img_index = img_name_index_map[img_name]
20363 except KeyError:
20364 bmp = ResourceManager.load_bitmap(img_name, (32, 32))
20365 img_index = img_name_index_map[img_name]\
20366 = img_list.Add(bmp)
20367 else:
20368 img_index = -1</t>
20369 <t tx="michael.20061002020357.15">observers.sort()
20370 self.observer_list.AssignImageList(img_list, wx.IMAGE_LIST_NORMAL)
20371 insert_image = self.observer_list.InsertImageStringItem
20372 insert = self.observer_list.InsertStringItem
20373 extent = self.observer_list.GetTextExtent
20375 height = 0
20376 for name, img_index in observers:
20377 w, h = extent(name + "XXX")
20378 height = max(h, height)
20379 if img_index &gt;= 0:
20380 insert_image(sys.maxint, name, img_index)
20381 else:
20382 insert(sys.maxint, name)</t>
20383 <t tx="michael.20061002020357.16">def state_changed(self, attrib):
20384 if attrib == "data":
20385 if self.imodel.data:
20386 self.data.Show()
20387 else:
20388 self.data.Hide()
20390 if isinstance(self.imodel.data, Evaluation):
20391 self.data_label.Show()
20392 else:
20393 self.data_label.Hide()
20395 self.layout()</t>
20396 <t tx="michael.20061002020357.17">def _on_select_item(self, event):
20397 name = event.GetItem().GetText()
20398 observer = self.observer_map[name]
20399 self.imodel.set_observer(observer, name)</t>
20400 <t tx="michael.20061002022123">class ObserverRemover(object):
20401 __icon__ = "delete16"
20403 @others
20404 </t>
20405 <t tx="michael.20061002022123.1">def apply(self, expression, code_item):
20406 return False
20407 </t>
20408 <t tx="michael.20061002022123.2">def apply_browser_menu(self, existing_attribs, code_item):
20409 return "extra"
20410 </t>
20411 <t tx="michael.20061002022123.3">def activate(self, context):
20412 context.code_item.remove()
20414 </t>
20415 <t tx="michael.20061002030802">try:
20416 func = faces.generator.create_generate_html
20417 except AttributeError:
20418 pass
20419 else:
20420 menu = top.make_menu(_("&amp;Tools"), pos=9980)
20421 menu.make_item(owner, _("Generate HTML..."), func(self), "run16", pos=10)</t>
20422 <t tx="michael.20061018160639">if code_item.tree_obj.IsOk():
20423 parent = self.GetItemParent(code_item.tree_obj)
20424 self.Delete(code_item.tree_obj)
20425 &lt;&lt; reinsert still existing children under new parent &gt;&gt;
20426 self.modify_item(parent)</t>
20427 <t tx="michael.20061018160639.1">first_child = None
20428 for c in code_item.get_children(True):
20429 first_child = first_child or c
20430 insert(c)
20432 if first_child:
20433 self.modify_item(self.GetItemParent(first_child.tree_obj))</t>
20434 <t tx="michael.20061018160639.2">try:
20435 if code_item.tree_obj.IsOk():
20436 tree_parent = self.GetItemParent(code_item.tree_obj)
20437 item_parent = code_item.get_parent()
20438 if tree_parent == item_parent.tree_obj:
20439 #this can happen, in drag operations
20440 continue
20441 except AttributeError: pass
20443 insert(code_item)
20444 &lt;&lt; insert children and modify their old parent &gt;&gt;
20445 self.modify_item(self.GetItemParent(code_item.tree_obj)) </t>
20446 <t tx="michael.20061018160639.3">last_parent = None
20447 for c in code_item.get_children(True):
20448 try:
20449 tree_obj = c.tree_obj
20450 except AttributeError: pass
20451 else:
20452 if tree_obj.IsOk():
20453 parent = self.GetItemParent(tree_obj)
20454 if not last_parent: last_parent = parent
20455 self.Delete(tree_obj)
20457 insert(c)
20459 if last_parent:
20460 self.modify_item(last_parent)
20461 self.modify_item(code_item.tree_obj)</t>
20462 <t tx="michael.20061018160639.4">expanded = self.IsExpanded(code_item.tree_obj)
20463 last_parent = self.GetItemParent(code_item.tree_obj)
20465 #remove item
20466 self.Delete(code_item.tree_obj)
20468 #reinsert with children
20469 insert(code_item)
20470 for c in code_item.get_children(True):
20471 insert(c)
20473 self.modify_item(self.GetItemParent(code_item.tree_obj))
20474 self.modify_item(last_parent)
20475 if expanded:
20476 self.Expand(code_item.tree_obj)</t>
20477 <t tx="michael.20061018180317">def on_key_down(evt):
20478 if evt.GetKeyCode() == wx.WXK_ESCAPE:
20479 self._clean_up_dragging()
20481 </t>
20482 <t tx="michael.20061018180317.1">if not flag &amp; (wx.TREE_HITTEST_ONITEMICON | wx.TREE_HITTEST_ONITEMLABEL):
20483 return
20485 ci = self.GetPyData(item)
20486 if not is_task(ci): return</t>
20487 <t tx="michael.20061018180317.2">l, t, w, h = self.GetBoundingRect(item)
20488 q = t + h / 2
20490 if pos.y &lt; q:
20491 new_line = drag_item.move_before(ci)
20492 else:
20493 if self.IsExpanded(item):
20494 item = self.GetNextVisible(item)
20495 ci = self.GetPyData(item)
20496 new_line = drag_item.move_before(ci)
20497 else:
20498 new_line = drag_item.move_after(ci)
20499 </t>
20500 <t tx="michael.20061018180317.3">new_item = editor.code_item_at(new_line)
20501 try:
20502 new_item.obj = drag_item.obj
20503 new_item.task_path = drag_item.task_path
20504 new_item.obj._function.code_item = weakref.proxy(new_item)
20505 except AttributeError: pass
20507 tasks_to_check = list(new_item.get_children(True))
20508 for i, c in enumerate(tasks_to_check):
20509 old = children[i]
20510 try:
20511 c.obj = old.obj
20512 c.task_path = old.task_path
20513 c.obj._function.code_item = weakref.proxy(c)
20514 except AttributeError: pass
20516 tasks_to_check.append(new_item)</t>
20517 <t tx="michael.20061026113601"></t>
20518 <t tx="michael.20061026113601.1"></t>
20519 <t tx="michael.20061026114634">class ProjectTaskCreator(NameEditor):
20520 title = _("Add Project")
20522 @others</t>
20523 <t tx="michael.20061026114839">def apply_browser_menu(self, existing_attribs, code_item):
20524 return "create"
20525 </t>
20526 <t tx="michael.20061026124000">def realize_code(self):
20527 now = datetime.datetime.now().strftime("%x")
20528 code = 'def %s():\nstart = "%s"' % (self.name, now)
20529 ci = self.context.get_last_code_item()
20530 context = self.context.__class__(ci)
20531 start_line, end_line = context.append_item(code, 0)
20532 ci.editor.check_code_updates(start_line, end_line)
20533 ci = ci.editor.code_item_at(start_line)
20534 def dumy(): start = "1.1.2006"
20535 ci.obj = ftask.Project(dumy)
20536 </t>
20537 <t tx="michael.20061026125228">class ProjectTaskRenamer(RenameEditor):
20538 title = _("Rename Project")
20539 __icon__ = "rename16"
20541 @others
20542 </t>
20543 <t tx="michael.20061026130909">def __str__(self):
20544 return "def %s():" % self.name</t>
20545 <t tx="michael.20061026133329">@language python
20546 &lt;&lt; Copyright &gt;&gt;
20547 &lt;&lt; Imports &gt;&gt;
20549 _is_source = True
20550 _to_datetime = pcalendar.to_datetime
20551 _ = plocale.get_gettext()
20553 @others
20554 </t>
20555 <t tx="michael.20061026133329.1">import pcalendar
20556 import datetime
20557 import utils
20558 import string
20559 import bisect
20560 import plocale
20561 </t>
20562 <t tx="michael.20061026133329.2">@doc is used to find snapshot attributes
20563 @code
20564 def _isattrib(obj, a):
20565 return a[0] != "_" \
20566 and not callable(getattr(obj, a)) \
20567 and not a.endswith("_members") \
20568 and a not in ("name")
20569 </t>
20570 <t tx="michael.20061026133329.3">class ResourceCalendar(object):
20572 The resource calendar saves the load time of a resource.
20573 Is ia sequence of time intervals of loads. An example of
20574 such a sequence is:
20575 [ (datetime.min, 0),
20576 (2006/1/1, 1.0),
20577 (2006/1/10, 0.5),
20578 (2006/1/15, 0) ]
20580 That means the resource:
20581 is free till january the first 2006
20582 is fully booked from january the first to january 10th
20583 is half booked from january 10th to january 15th
20584 is free since january 15th
20587 @others
20588 </t>
20589 <t tx="michael.20061026133329.4">def __init__(self, src=None):
20590 if src:
20591 self.bookings = list(src.bookings)
20592 else:
20593 self.bookings = [ (datetime.datetime.min, 0) ]
20594 </t>
20595 <t tx="michael.20061026133329.5">def __str__(self):
20596 return str(self.bookings)
20597 </t>
20598 <t tx="michael.20061026133329.6">def __repr__(self):
20599 return "&lt;ResourceCalendar %s&gt;" % (str(self))
20600 </t>
20601 <t tx="michael.20061026133329.7">def add_load(self, start, end, load):
20602 start = _to_datetime(start)
20603 end = _to_datetime(end)
20605 bookings = self.bookings
20607 # the load will be converted in an integer to avoid
20608 # rouning problems
20609 load = int(load * 10000)
20611 start_item = (start, 0)
20612 start_pos = bisect.bisect_left(bookings, start_item)
20614 left_load = 0
20615 left_load = bookings[start_pos - 1][1]
20617 if start_pos &lt; len(bookings) and bookings[start_pos][0] == start:
20618 prev_load = bookings[start_pos][1]
20619 if prev_load + load == left_load:
20620 del bookings[start_pos]
20621 else:
20622 bookings[start_pos] = (start, prev_load + load)
20623 start_pos += 1
20624 else:
20625 bookings.insert(start_pos, (start, load + left_load))
20626 start_pos += 1
20628 item = (datetime.datetime.min, 0)
20629 for i in range(start_pos, len(bookings)):
20630 end_pos = i
20631 item = bookings[i]
20632 if item[0] &gt;= end: break
20633 bookings[i] = (item[0], item[1] + load)
20634 else:
20635 end_pos = len(bookings)
20637 left_load = bookings[end_pos - 1][1]
20638 if item[0] == end:
20639 if item[1] == left_load:
20640 del bookings[end_pos]
20641 else:
20642 bookings.insert(end_pos, (end, left_load - load))
20643 </t>
20644 <t tx="michael.20061026133329.8">def end_of_booking_interval(self, date):
20645 date = _to_datetime(date)
20646 bookings = self.bookings
20647 date_item = (date, 999999)
20648 date_pos = bisect.bisect_left(bookings, date_item) - 1
20649 next_date = datetime.datetime.max
20650 load = 0
20652 try:
20653 book_item = bookings[date_pos]
20654 load = bookings[date_pos][1] / 10000.0
20655 next_date = bookings[date_pos + 1][0]
20656 except:
20657 pass
20659 return next_date, load
20660 </t>
20661 <t tx="michael.20061026133329.9">def find_free_time(self, start, length, load, max_load):
20662 bookings = self.bookings
20664 if isinstance(start, datetime.datetime):
20665 adjust_date = _to_datetime
20666 else:
20667 adjust_date = start.calendar.EndDate
20669 start = _to_datetime(start)
20670 load = int(load * 10000)
20671 max_load = int(max_load * 10000)
20672 lb = len(bookings)
20674 def next_possible(index):
20675 while index &lt; lb:
20676 sd, lo = bookings[index]
20677 if lo + load &lt;= max_load:
20678 break
20680 index += 1
20682 sd = adjust_date(max(start, sd))
20683 ed = sd + length
20684 end = _to_datetime(ed)
20686 index += 1
20687 while index &lt; lb:
20688 date, lo = bookings[index]
20690 if date &gt;= end:
20691 #I found a good start date
20692 return None, sd
20694 if lo + load &gt; max_load:
20695 return index + 1, None
20697 index += 1
20699 return None, sd
20701 start_item = (start, 1000000)
20702 i = bisect.bisect_left(bookings, start_item) - 1
20704 next_start = None
20705 while not next_start and i &lt; lb:
20706 i, next_start = next_possible(i)
20708 assert(next_start is not None)
20709 return next_start
20710 </t>
20711 <t tx="michael.20061026133329.10">def get_bookings(self, start, end):
20712 start = _to_datetime(start)
20713 end = _to_datetime(end)
20714 bookings = self.bookings
20715 start_item = (start, 0)
20716 start_pos = bisect.bisect_left(bookings, start_item)
20717 if start_pos &gt;= len(bookings) or bookings[start_pos][0] &gt; start:
20718 start_pos -= 1
20720 end_item = (end, 0)
20721 end_pos = bisect.bisect_left(bookings, end_item)
20722 return start_pos, end_pos, bookings
20723 </t>
20724 <t tx="michael.20061026133329.11">def get_load(self, date):
20725 date = _to_datetime(date)
20726 bookings = self.bookings
20727 item = (date, 100000)
20728 pos = bisect.bisect_left(bookings, item) - 1
20729 return bookings[pos][1] / 10000.0
20730 </t>
20731 <t tx="michael.20061026133329.12">class _ResourceBase(object):
20732 pass
20734 </t>
20735 <t tx="michael.20061026133329.13">class _MetaResource(type):
20736 doc_template = """
20737 A resource class. The resources default attributes can
20738 be changed when the class ist instanciated, i.e.
20739 %(name)s(max_load=2.0)
20741 @var max_load:
20742 Specify the maximal allowed load sum of all simultaneously
20743 allocated tasks of a resource. A ME{max_load} of 1.0 (default)
20744 means the resource may be fully allocated. A ME{max_load} of 1.3
20745 means the resource may be allocated with 30%% overtime.
20747 @var title:
20748 Specifies an alternative more descriptive name for the task.
20750 @var efficiency:
20751 The efficiency of a resource can be used for two purposes. First
20752 you can use it as a crude way to model a team. A team of 5 people
20753 should have an efficiency of 5.0. Keep in mind that you cannot
20754 track the member of the team individually if you use this
20755 feature. The other use is to model performance variations between
20756 your resources.
20758 @var vacation:
20759 Specifies the vacation of the resource. This attribute is
20760 specified as a list of date literals or date literal intervals.
20761 Be aware that the end of an interval is excluded, i.e. it is
20762 the first working date.
20765 @others
20766 </t>
20767 <t tx="michael.20061026133329.14">def __init__(self, name, bases, dict_):
20768 super(_MetaResource, self).__init__(name, bases, dict_)
20769 self.name = name
20770 self.title = dict_.get("title", name)
20771 self._calendar = { None: ResourceCalendar() }
20772 self._tasks = { }
20773 self.__set_vacation()
20774 self.__add_resource(bases[0])
20775 self.__doc__ = dict_.get("__doc__", self.doc_template) % locals()
20776 </t>
20777 <t tx="michael.20061026133329.15">def __or__(self, other):
20778 return self().__or__(other)
20779 </t>
20780 <t tx="michael.20061026133329.16">def __and__(self, other):
20781 return self().__and__(other)
20782 </t>
20783 <t tx="michael.20061026133329.17">def __cmp__(self, other):
20784 return cmp(self.name, getattr(other, "name", None))
20785 </t>
20786 <t tx="michael.20061026133329.18">def __repr__(self):
20787 return "&lt;Resource %s&gt;" % self.name
20788 </t>
20789 <t tx="michael.20061026133329.19">def __str__(self):
20790 return repr(self)
20791 </t>
20792 <t tx="michael.20061026133329.20">def __set_vacation(self):
20793 vacation = self.vacation
20795 if isinstance(vacation, (tuple, list)):
20796 for v in vacation:
20797 if isinstance(v, (tuple, list)):
20798 self.add_vacation(v[0], v[1])
20799 else:
20800 self.add_vacation(v)
20801 else:
20802 self.add_vacation(vacation)
20803 </t>
20804 <t tx="michael.20061026133329.21">def __add_resource(self, base):
20805 if issubclass(base, _ResourceBase):
20806 members = getattr(base, base.__name__ + "_members", [])
20807 members.append(self)
20808 setattr(base, base.__name__ + "_members", members)
20809 </t>
20810 <t tx="michael.20061026133329.22">def get_members(self):
20811 return getattr(self, self.__name__ + "_members", [])
20812 </t>
20813 <t tx="michael.20061026133329.23">def add_vacation(self, start, end=None):
20814 start_date = _to_datetime(start)
20816 if not end:
20817 end_date = start_date.replace(hour=23, minute=59)
20818 else:
20819 end_date = _to_datetime(end)
20821 for cal in self._calendar.itervalues():
20822 cal.add_load(start_date, end_date, 1)
20824 tp = Booking()
20825 tp.start = start_date
20826 tp.end = end_date
20827 tp.book_start = start_date
20828 tp.book_end = end_date
20829 tp.work_time = end_date - start_date
20830 tp.load = 1.0
20831 tp.name = tp.title = _("(vacation)")
20832 tp._id = ""
20833 self._tasks.setdefault("", []).append(tp)
20834 </t>
20835 <t tx="michael.20061026133329.24">def make_team(resource):
20836 members = resource.get_members()
20837 if not members:
20838 return resource
20840 result = make_team(members[0])
20841 for r in members[1:]:
20842 result = result &amp; make_team(r)
20844 return result
20845 </t>
20846 <t tx="michael.20061026133329.25">class Booking(object):
20848 A booking unit for a task.
20850 &lt;&lt; declarations &gt;&gt;
20851 @others
20852 </t>
20853 <t tx="michael.20061026133329.26">book_start = datetime.datetime.min
20854 book_end = datetime.datetime.max
20855 actual = False
20856 _id = ""
20858 </t>
20859 <t tx="michael.20061026133329.27">def __init__(self, task=None):
20860 self.__task = task
20861 </t>
20862 <t tx="michael.20061026133329.28">def __cmp__(self, other):
20863 return cmp(self._id, other._id)
20864 </t>
20865 <t tx="michael.20061026133329.29">def path(self):
20866 first_dot = self._id.find(".")
20867 return "root" + self._id[first_dot:]
20869 path = property(path)</t>
20870 <t tx="michael.20061026133329.30">def _idendity_(self):
20871 return self._id
20872 </t>
20873 <t tx="michael.20061026133329.31">def __getattr__(self, name):
20874 if self.__task:
20875 return getattr(self.__task, name)
20877 raise AttributeError("'%s' is not a valid attribute" % (name))
20878 </t>
20879 <t tx="michael.20061026133329.32">class ResourceList(list):
20880 @others
20881 </t>
20882 <t tx="michael.20061026133329.33">def __init__(self, *args):
20883 if args: self.extend(args)
20884 </t>
20885 <t tx="michael.20061026133329.34">class Resource(_ResourceBase):
20886 &lt;&lt; declarations &gt;&gt;
20887 @others
20888 </t>
20889 <t tx="michael.20061026133329.35">__metaclass__ = _MetaResource
20890 __attrib_completions__ = {\
20891 "max_load": 'max_load = ',
20892 "title": 'title = "|"',
20893 "efficiency": 'efficiency = ',
20894 "vacation": 'vacation = [("|2002-02-01", "2002-02-05")]' }
20896 __type_image__ = "resource16"
20898 max_load = None # the maximum sum load for all task
20899 vacation = ()
20900 efficiency = 1.0
20903 </t>
20904 <t tx="michael.20061026133329.36">def __init__(self, **kwargs):
20905 for k, v in kwargs.iteritems():
20906 setattr(self, k, v)
20907 </t>
20908 <t tx="michael.20061026133329.37">def _idendity_(cls):
20909 return "resource:" + cls.__name__
20911 _idendity_ = classmethod(_idendity_)
20912 </t>
20913 <t tx="michael.20061026133329.38">def __repr__(self):
20914 return "&lt;Resource %s&gt;" % self.__class__.__name__
20915 </t>
20916 <t tx="michael.20061026133329.39">def __str__(self):
20917 return repr(self)
20918 </t>
20919 <t tx="michael.20061026133329.40">def __call__(self):
20920 return self
20921 </t>
20922 <t tx="michael.20061026133329.41">def __hash__(self):
20923 return hash(self.__class__)
20924 </t>
20925 <t tx="michael.20061026133329.42">def __cmp__(self, other):
20926 return cmp(self.name, other.name)
20927 </t>
20928 <t tx="michael.20061026133329.43">def __or__(self, other):
20929 if type(other) is _MetaResource:
20930 other = other()
20932 result = Resource()
20933 result._subresource = _OrResourceGroup(self, other)
20934 return result
20935 </t>
20936 <t tx="michael.20061026133329.44">def __and__(self, other):
20937 if type(other) is _MetaResource:
20938 other = other()
20940 result = Resource()
20941 result._subresource = _AndResourceGroup(self, other)
20942 return result
20943 </t>
20944 <t tx="michael.20061026133329.45">def _permutation_count(self):
20945 if hasattr(self, "_subresource"):
20946 return self._subresource._permutation_count()
20948 return 1
20949 </t>
20950 <t tx="michael.20061026133329.46">def _get_resources(self, state):
20951 if hasattr(self, "_subresource"):
20952 result = self._subresource._get_resources(state)
20954 if self.name != "Resource":
20955 result.name = self.name
20957 if self.title != "Resource":
20958 result.title = self.title
20960 return result
20962 result = ResourceList(self)
20963 return result
20964 </t>
20965 <t tx="michael.20061026133329.47">def all_members(self):
20966 if hasattr(self, "_subresource"):
20967 return self._subresource.all_members()
20969 return [ self.__class__ ]
20970 </t>
20971 <t tx="michael.20061026133329.48">def unbook_tasks_of_project(cls, project_id, scenario):
20972 try:
20973 task_list = cls._tasks[scenario]
20974 except KeyError:
20975 return
20977 add_load = cls.calendar(scenario).add_load
20978 for task_id, bookings in task_list.items():
20979 if task_id.startswith(project_id):
20980 for item in bookings:
20981 add_load(item.book_start, item.book_end, -item.load)
20983 del task_list[task_id]
20985 if not task_list:
20986 del cls._tasks[scenario]
20988 unbook_tasks_of_project = classmethod(unbook_tasks_of_project)
20989 </t>
20990 <t tx="michael.20061026133329.49">def unbook_task(cls, task):
20991 identdity = task._idendity_()
20992 scenario = task.scenario
20994 try:
20995 task_list = cls._tasks[scenario]
20996 bookings = task_list[identdity]
20997 except KeyError:
20998 return
21000 add_load = cls.calendar(scenario).add_load
21001 for b in bookings:
21002 add_load(b.book_start, b.book_end, -b.load)
21004 del task_list[identdity]
21005 if not task_list:
21006 del cls._tasks[scenario]
21008 unbook_task = classmethod(unbook_task)
21009 </t>
21010 <t tx="michael.20061026133329.50">def correct_bookings(cls, task):
21011 #correct the booking data with the actual task data
21012 try:
21013 tasks = cls._tasks[task.scenario][task._idendity_()]
21014 except KeyError:
21015 return
21017 for t in tasks:
21018 t.start = task.start.to_datetime()
21019 t.end = task.end.to_datetime()
21021 correct_bookings = classmethod(correct_bookings)
21022 </t>
21023 <t tx="michael.20061026133329.51">def book_task(cls, task, start, end, load, work_time, actual):
21024 if not work_time: return
21026 start = _to_datetime(start)
21027 end = _to_datetime(end)
21029 identdity = task._idendity_()
21030 task_list = cls._tasks.setdefault(task.scenario, {})
21031 bookings = task_list.setdefault(identdity, [])
21032 add_load = cls.calendar(task.scenario).add_load
21034 tb = Booking(task)
21035 tb.book_start = start
21036 tb.book_end = end
21037 tb._id = identdity
21038 tb.load = load
21039 tb.start = _to_datetime(task.start)
21040 tb.end = _to_datetime(task.end)
21041 tb.title = task.title
21042 tb.name = task.name
21043 tb.work_time = int(work_time)
21044 tb.actual = actual
21045 bookings.append(tb)
21046 result = add_load(start, end, load)
21047 return result
21049 book_task = classmethod(book_task)
21050 </t>
21051 <t tx="michael.20061026133329.52">def length_of(cls, task):
21052 cal = task.root.calendar
21053 bookings = cls.get_bookings(task)
21054 return sum(map(lambda b: task._to_delta(b.work_time).round(), bookings))
21056 length_of = classmethod(length_of)
21057 </t>
21058 <t tx="michael.20061026133329.53">def done_of(self, task):
21059 cal = task.root.calendar
21060 now = cal.now
21061 bookings = self.get_bookings(task)
21063 if task.__dict__.has_key("effort"):
21064 efficiency = self.efficiency * task.efficiency
21065 else:
21066 efficiency = 1
21068 def book_done(booking):
21069 if booking.book_start &gt;= now:
21070 return 0
21072 factor = 1
21073 if booking.book_end &gt; now:
21074 start = task._to_start(booking.book_start)
21075 end = task._to_end(booking.book_end)
21076 cnow = task._to_start(now)
21077 factor = float(cnow - start) / ((end - start) or 1)
21079 return factor * booking.work_time * efficiency
21081 return task._to_delta(sum(map(book_done, bookings)))
21082 </t>
21083 <t tx="michael.20061026133329.54">def todo_of(self, task):
21084 cal = task.root.calendar
21085 now = cal.now
21087 bookings = self.get_bookings(task)
21088 if task.__dict__.has_key("effort"):
21089 efficiency = self.efficiency * task.efficiency
21090 else:
21091 efficiency = 1
21093 def book_todo(booking):
21094 if booking.book_end &lt;= now:
21095 return 0
21097 factor = 1
21098 if booking.book_start &lt; now:
21099 start = task._to_start(booking.book_start)
21100 end = task._to_end(booking.book_end)
21101 cnow = task._to_start(now)
21102 factor = float(end - cnow) / ((end - start) or 1)
21104 return factor * booking.work_time * efficiency
21106 return task._to_delta(sum(map(book_todo, bookings)))
21107 </t>
21108 <t tx="michael.20061026133329.55">def get_bookings(cls, task):
21109 return cls._tasks.get(task.scenario, {}).get(task._idendity_(), ())
21111 get_bookings = classmethod(get_bookings)
21112 </t>
21113 <t tx="michael.20061026133329.56">def get_bookings_at(cls, start, end, scenario):
21114 result = []
21116 try:
21117 items = cls._tasks[scenario].iteritems()
21118 except KeyError:
21119 return ()
21121 for task_id, bookings in items:
21122 result += [ booking for booking in bookings
21123 if booking.book_start &lt; end
21124 and booking.book_end &gt; start ]
21126 vacations = cls._tasks.get("", ())
21127 result += [ booking for booking in vacations
21128 if booking.book_start &lt; end
21129 and booking.book_end &gt; start ]
21131 return result
21133 get_bookings_at = classmethod(get_bookings_at)
21134 </t>
21135 <t tx="michael.20061026133329.57">def find_free_time(cls, start, length, load, max_load, scenario):
21136 return cls.calendar(scenario).find_free_time(start, length, load, max_load)
21138 find_free_time = classmethod(find_free_time)
21139 </t>
21140 <t tx="michael.20061026133329.58">def get_load(cls, date, scenario):
21141 return cls.calendar(scenario).get_load(date)
21143 get_load = classmethod(get_load)
21144 </t>
21145 <t tx="michael.20061026133329.59">def end_of_booking_interval(cls, date, task):
21146 return cls.calendar(task.scenario).end_of_booking_interval(date)
21148 end_of_booking_interval = classmethod(end_of_booking_interval)
21149 </t>
21150 <t tx="michael.20061026133329.60">def snapshot(self):
21151 from task import _as_string
21152 def isattrib(a):
21153 if a == "max_load" and self.max_load is None: return False
21154 if a in ("name", "title", "vacation"): return False
21155 return _isattrib(self, a)
21157 attribs = filter(isattrib, dir(self))
21158 attribs = map(lambda a: "%s=%s" % (a, _as_string(getattr(self, a))),
21159 attribs)
21161 return self.name + "(%s)" % ", ".join(attribs)
21162 </t>
21163 <t tx="michael.20061026133329.61">
21165 class _ResourceGroup(object):
21166 @others
21167 </t>
21168 <t tx="michael.20061026133329.62">def __init__(self, *args):
21169 self.resources = []
21170 for a in args:
21171 self.__append(a)
21172 </t>
21173 <t tx="michael.20061026133329.63">def all_members(self):
21174 group = reduce(lambda a, b: a + b.all_members(),
21175 self.resources, [])
21176 group = map(lambda r: (r, True), group)
21177 group = dict(group)
21178 group = group.keys()
21179 return group
21180 </t>
21181 <t tx="michael.20061026133329.64">def _permutation_count(self):
21182 abstract
21183 </t>
21184 <t tx="michael.20061026133329.65">def _refactor(self, arg):
21185 pass
21186 </t>
21187 <t tx="michael.20061026133329.66">def __append(self, arg):
21188 if isinstance(arg, self.__class__):
21189 self.resources += arg.resources
21190 for r in arg.resources:
21191 self._refactor(r)
21192 return
21193 elif isinstance(arg, Resource):
21194 subresources = getattr(arg, "_subresource", None)
21195 if subresources:
21196 self.__append(subresources)
21197 return
21198 else:
21199 self.resources.append(arg)
21200 else:
21201 assert(isinstance(arg, _ResourceGroup))
21202 self.resources.append(arg)
21204 self._refactor(arg)
21205 </t>
21206 <t tx="michael.20061026133329.67">def __str__(self):
21207 op = lower(self.__class__.__name__[0:-13])
21208 return "(" + \
21209 string.join([str(r) for r in self.resources],
21210 " " + op + " ") + \
21212 </t>
21213 <t tx="michael.20061026133329.68">
21215 class _OrResourceGroup(_ResourceGroup):
21216 @others
21217 </t>
21218 <t tx="michael.20061026133329.69">def _get_resources(self, state):
21219 for r in self.resources:
21220 c = r._permutation_count()
21221 if c &lt;= state:
21222 state -= c
21223 else:
21224 return r._get_resources(state)
21226 assert(0)
21227 </t>
21228 <t tx="michael.20061026133329.70">def _permutation_count(self):
21229 return sum([ r._permutation_count() for r in self.resources])
21230 </t>
21231 <t tx="michael.20061026133329.71">
21233 class _AndResourceGroup(_ResourceGroup):
21234 @others
21235 </t>
21236 <t tx="michael.20061026133329.72">def __init__(self, *args):
21237 self.factors = [ 1 ]
21238 _ResourceGroup.__init__(self, *args)
21239 </t>
21240 <t tx="michael.20061026133329.73">def _refactor(self, arg):
21241 count = arg._permutation_count()
21242 self.factors = [ count * f for f in self.factors ]
21243 self.factors.append(1)
21244 </t>
21245 <t tx="michael.20061026133329.74"> #print "AndResourceGroup", count, arg, self.factors
21248 def _permutation_count(self):
21249 return self.factors[0]
21250 </t>
21251 <t tx="michael.20061026133329.75">def _get_resources(self, state):
21252 """delivers None when there are duplicate resources"""
21253 result = []
21254 for i in range(1, len(self.factors)):
21255 f = self.factors[i]
21256 substate = state / f
21257 state %= f
21258 result.append(self.resources[i - 1]._get_resources(substate))
21260 result = ResourceList(*list(utils.flatten(result)))
21261 dupl_test = { }
21262 for r in result:
21263 if dupl_test.has_key(r):
21264 return None
21265 else:
21266 dupl_test[r] = 1
21268 return result
21269 </t>
21270 <t tx="michael.20061026133329.76">def _has_duplicates(self, state):
21271 resources = self._get_resources(state)
21272 tmp = { }
21273 for r in resources:
21274 if tmp.has_key(r):
21275 return True
21277 tmp[r] = 1
21279 return False
21280 </t>
21281 <t tx="michael.20061026224624"></t>
21282 <t tx="michael.20061027120904">def to_value_wrapper(a):
21283 if isinstance(a, _ValueWrapper):
21284 return a
21286 return _ValueWrapper(a, [(None, None)])
21288 def my_max(*args):
21289 return max(map(to_value_wrapper, args))
21291 def my_min(*args):
21292 return min(map(to_value_wrapper, args))
21294 globals_["me"] = me_instance
21296 if self._is_compiled:
21297 globals_["up"] = self.up
21298 globals_["root"] = self.root
21299 else:
21300 globals_["up"] = _Path(self.up, "up")
21301 globals_["root"] = _Path(self.root, "root")
21303 globals_["Delta"] = self._to_delta
21304 globals_["Date"] = self._to_start
21305 globals_["max"] = my_max
21306 globals_["min"] = my_min
21307 globals_["add_attrib"] = me_instance.add_attrib</t>
21308 <t tx="michael.20061027120904.2">@
21309 Is used for functions like YearlyMax, MonthlyMax, ....
21310 @code
21311 for name in self._function.global_names:
21312 try:
21313 obj = globals_[name]
21314 if isinstance(obj, types.FunctionType):
21315 fg = obj.func_globals
21316 if not fg.has_key("me") and "me" in obj.func_code.co_names:
21317 restore_globals.append(fg)
21318 fg["me"] = me_instance
21319 except KeyError: continue</t>
21320 <t tx="michael.20061027120904.3">if do_raise:
21321 try:
21322 self._function()
21323 self._is_compiled = True
21324 except _IncompleteError, e:
21325 src = e.args[1]
21326 if src is not self:
21327 self.__at_compile = e.args[1:]
21328 src._compile([], True)
21330 raise
21331 else:
21332 try:
21333 self._function()
21334 self._is_compiled = True
21335 except AttributeError, e:
21336 #print "AttributeError:", e, self.name, e.is_frozen, do_raise
21337 deferred.append(self)
21338 except _IncompleteError:
21339 #print "_IncompleteError:", id(self), self.name, do_raise
21340 deferred.append(self)
21341 except RecursionError:
21342 self._is_parent_referer = True
21343 deferred.append(self)</t>
21344 <t tx="michael.20061027121652">try:
21345 cal = me.calendar
21346 except NameError:
21347 cal = pcalendar._default_calendar
21349 time_diff = cal.Minutes(value)</t>
21350 <t tx="michael.20061027224620">def _set_hook(cls, attrib_name, function=None):
21351 if function:
21352 cls._setting_hooks[attrib_name] = function
21353 else:
21354 try:
21355 del cls._setting_hooks[attrib_name]
21356 except KeyError: pass
21359 _set_hook = classmethod(_set_hook)</t>
21360 <t tx="michael.20061028111855">def apply(self, expression, code_item):
21361 if not expression: return False
21363 mo = reg_identifier_assignment.search(expression)
21364 if not mo: return False
21366 pname = mo.groupdict()["project"]
21367 return self.__class__.__name__.startswith(pname)
21370 </t>
21371 <t tx="michael.20061028114303">def apply(self, expression, code_item):
21372 return not expression
21373 </t>
21374 <t tx="michael.20061028120746">def activate(self, editor, line, prev, next, inside):
21376 try to activate the context
21378 can_activate = is_evaluation(prev) and line &lt;= prev.get_last_line() + 1
21379 if can_activate:
21380 self.code_item = inside or prev
21381 return True
21382 else:
21383 self.code_item = None
21384 return False</t>
21385 <t tx="michael.20061028124110">def prepare_draw_stage2(self, renderer, point_to_pixel, fig_point_to_pixel):
21386 self.set_font_factor(point_to_pixel, fig_point_to_pixel)
21388 registry = {}
21389 for cell in self.widest_cells:
21390 self.axes.add_widget(cell)
21391 registry[cell] = True
21393 for r, row in enumerate(self.cells):
21394 for c, cell in enumerate(row):
21395 if not cell or cell in registry: continue
21396 self.axes.add_widget(cell)
21398 return True, True
21399 </t>
21400 <t tx="michael.20061028124110.1">def set_pos(self, x, y):
21401 Point = mtrans.Point
21402 BBox = mtrans.Bbox
21403 left = x = Lazy(x)
21404 y = Lazy(y)
21405 w = self.width
21406 h = self.height
21407 bbox = self.bbox = BBox(Point(x.val, y.val), Point(x.val + w.val, y.val + h.val))
21409 ry = Lazy(bbox.ur().y())
21411 widest_cells = self.widest_cells
21412 highest_cells = self.highest_cells
21414 for r, row in enumerate(self.cells):
21415 height = highest_cells[r].height
21416 ry -= height
21417 cx = Lazy(left)
21418 for c, cell in enumerate(row):
21419 width = widest_cells[c].width
21420 ocx = cx
21421 cx += width
21423 if not cell: continue
21424 w, h = cell.width, cell.height
21425 if cell._valign == "top":
21426 y = ry + height - h
21427 elif cell._valign == "center":
21428 y = ry + (height - h) / 2
21429 else:
21430 y = ry.get()
21432 if cell._halign == "right":
21433 x = ocx + width - w
21434 elif cell._halign == "center":
21435 x = ocx + (width - w) / 2
21436 else:
21437 x = ocx
21439 cell.set_pos(x, y)
21441 </t>
21442 <t tx="michael.20061028145753"></t>
21443 <t tx="michael.20061028151207">class ShortConnector(widgets.Widget):
21445 A connector that connects two arbitrary widgets on the shortes path
21447 &lt;&lt; declarations &gt;&gt;
21448 @others
21449 </t>
21450 <t tx="michael.20061028151207.1">properties = {
21451 "connector.linewidth" : 1,
21452 "connector.edgecolor" : "black",
21453 "connector.arrow.width" : 3,
21454 "connector.arrow.height" : 3,
21455 "connector.arrow.edgecolor" : "darkslategray",
21456 "connector.arrow.facecolor" : "darkslategray",
21457 "connector.arrow.open" : False,
21458 "connector.directed" : True
21461 zorder = -100
21463 </t>
21464 <t tx="michael.20061028151207.2">def __init__(self, src, dest, properties=None):
21465 widgets.Widget.__init__(self, properties)
21466 self.src = src
21467 self.dest = dest
21469 #fetch all properties
21470 self.get_patch("connector")
21471 </t>
21472 <t tx="michael.20061028151207.3">def get_bounds(self, renderer):
21473 return self.bbox
21474 </t>
21475 <t tx="michael.20061028151207.4">def contains(self, x, y):
21476 return False
21477 </t>
21478 <t tx="michael.20061028151207.5">def prepare_draw(self, renderer, point_to_pixel, fig_point_to_pixel):
21479 self.set_font_factor(point_to_pixel, fig_point_to_pixel)
21481 HSEP.set(VSEP.get())
21482 Point = mtrans.Point
21483 BBox = mtrans.Bbox
21484 Value = mtrans.Value
21485 Half = Value(0.5)
21487 src_box = self.src.bbox
21488 dst_box = self.dest.bbox
21490 src_x = (src_box.ur().x() + src_box.ll().x()) * Half
21491 src_y = (src_box.ur().y() + src_box.ll().y()) * Half
21492 dst_x = (dst_box.ur().x() + dst_box.ll().x()) * Half
21493 dst_y = (dst_box.ur().y() + dst_box.ll().y()) * Half
21495 self.bbox = BBox(Point(src_x, src_y), Point(dst_x, dst_y))
21498 if self.get_property("connector.directed"):
21499 &lt;&lt; calc arrow position &gt;&gt;
21501 return True, True</t>
21502 <t tx="michael.20061028151207.6">def draw(self, renderer, data_box):
21503 if not self.get_visible() or not self.overlaps(data_box): return False
21504 transform = self.get_transform()
21506 gc = renderer.new_gc()
21507 if self.get_clip_on():
21508 gc.set_clip_rectangle(self.clipbox.get_bounds())
21510 self.set_gc(gc, "connector")
21512 x, y, w, h = self.bbox.get_bounds()
21513 draw_lines(renderer, gc, (x, x + w), (y, y + h), transform)
21515 if self.get_property("connector.directed"):
21516 &lt;&lt; draw arrow &gt;&gt;
21518 return False</t>
21519 <t tx="michael.20061028160826">def intersect(l1, l2):
21521 Intersects two lines:
21522 l = (p, d) == p + a * d
21524 p1 + a * d1 = p2 + b * d2
21526 returns a, b
21528 &lt;&lt; extract coordinates &gt;&gt;
21529 l1x = p1x, d1x
21530 l1y = p1y, d1y
21531 l2x = p2x, d2x
21532 l2y = p2y, d2y
21534 &lt;&lt; define calc &gt;&gt;
21536 try:
21537 a, b = calc(l1x, l1y, l2x, l2y)
21538 return a, b
21539 except ZeroDivisionError: pass
21541 try:
21542 a, b = calc(l1y, l1x, l2y, l2x)
21543 return a, b
21544 except ZeroDivisionError: pass
21546 try:
21547 b, a = calc(l2x, l2y, l1x, l1y)
21548 return a, b
21549 except ZeroDivisionError: pass
21551 try:
21552 b, a = calc(l2y, l2x, l1y, l1x)
21553 return a, b
21554 except ZeroDivisionError:
21555 #lines are parallel
21556 return mtrans.Value(-1), mtrans.Value(-1)
21557 </t>
21558 <t tx="michael.20061028180706">p1, d1 = l1
21559 p2, d2 = l2
21561 p1x, p1y = p1
21562 d1x, d1y = d1
21564 p2x, p2y = p2
21565 d2x, d2y = d2</t>
21566 <t tx="michael.20061028180706.1">def calc(mx, my, nx, ny):
21567 ax, bx = mx
21568 ay, by = my
21569 cx, dx = nx
21570 cy, dy = ny
21572 rf = bx / by
21573 n = ((cx - ax - rf * (cy - ay)))
21574 d = rf * dy - dx
21575 beta = n / d
21576 beta.get()
21578 if bx.get():
21579 alpha = (cx + beta * dx - ax) / bx
21580 else:
21581 alpha = (cy + beta * dy - ay) / by
21583 return alpha, beta</t>
21584 <t tx="michael.20061028180926">self.dx = dx = dst_x - src_x
21585 self.dy = dy = dst_y - src_y
21587 &lt;&lt; calc line equations &gt;&gt;
21589 #find the intersection point
21590 ips = [ intersect(connector, l) for l in (left, right, top, bottom) ]
21591 min_a = min([ (a.get(), a) for a, b in ips if 0 &lt;= b.get() &lt;= 1.0 ])[1]
21593 # arrow stuff
21594 self.len = dx * dx + dy * dy
21595 self.cos = Lazy(1)
21596 self.sin = Lazy(0)
21598 prop = self.get_property
21599 awidth = prop("connector.arrow.width")
21600 aheight = prop("connector.arrow.height")
21602 self.arrow = get_arrow(self.cos, self.sin,
21603 src_x + min_a * dx,
21604 src_y + min_a * dy,
21605 awidth, aheight)</t>
21606 <t tx="michael.20061028180926.1">connector = ((src_x, src_y), (dx, dy))
21607 left = ((dst_box.ll().x(), dst_box.ll().y()),
21608 (Value(0), dst_box.ur().y() - dst_box.ll().y()))
21609 right = ((dst_box.ur().x(), dst_box.ll().y()),
21610 (Value(0), dst_box.ur().y() - dst_box.ll().y()))
21611 top = ((dst_box.ll().x(), dst_box.ur().y()),
21612 (dst_box.ur().x() - dst_box.ll().x(), Value(0)))
21613 bottom = ((dst_box.ll().x(), dst_box.ll().y()),
21614 (dst_box.ur().x() - dst_box.ll().x(), Value(0)))</t>
21615 <t tx="michael.20061028180926.2">l = math.sqrt(self.len.get()) or 1.0
21616 self.cos.set(-self.dx.get() / l)
21617 self.sin.set(-self.dy.get() / l)
21619 self.set_gc(gc, "connector.arrow")
21620 if self.get_property("connector.arrow.open"):
21621 draw_lines(renderer, gc,
21622 map(lambda a: a[0], self.arrow),
21623 map(lambda a: a[1], self.arrow),
21624 transform)
21625 else:
21626 face = self.get_property("connector.arrow.facecolor")
21627 face = _colorConverter.to_rgb(face)
21628 try:
21629 arrow = transform.seq_xy_tups(self.arrow)
21630 except ZeroDivisionError:
21631 print "ZeroDivisionError"
21632 #for c, a in enumerate(self.arrow):
21633 # print " ", c, a[0].get(), a[1].get()
21634 else:
21635 renderer.draw_polygon(gc, face, arrow)</t>
21636 <t tx="michael.20061028181551">class BoxedTextWidget(Widget):
21638 A boxed text widget. The constructor accepts the following
21639 arguments:
21641 Why check_font_factor and all the complicated stuff:
21642 The text width of LazyText does not scale linear, resulting
21643 in text overlapping boxes. check_font_factor calculates a
21644 newbounding box, for a new font_factor
21648 @others</t>
21649 <t tx="michael.20061028181551.1">def __init__(self, text, fobj, properties=None,
21650 fattrib=None, left=4, right=4,
21651 top=4, bottom=4, **kwargs):
21652 super(BoxedTextWidget, self).__init__(properties)
21654 self.fobj = fobj
21655 self.fattrib = fattrib
21656 self.left = left
21657 self.right = right
21658 self.top = top
21659 self.bottom = bottom
21660 kwargs = self._extend_text_properties(kwargs)
21661 self.text = LazyText(LEFT + self.left, BOTTOM + self.bottom,
21662 text, **kwargs)
21663 self.artists.append(self.text)
21666 </t>
21667 <t tx="michael.20061028181551.2">def get_bounds(self, renderer):
21668 self.check_font_factor(renderer)
21669 return self.bbox
21670 </t>
21671 <t tx="michael.20061028181551.3">def prepare_draw(self, renderer, point_to_pixel, fig_point_to_pixel):
21672 self.set_font_factor(point_to_pixel, fig_point_to_pixel)
21674 bbox = self.calc_bounding_box(renderer)
21675 Point = mtrans.Point
21676 BBox = mtrans.Bbox
21677 x = Lazy(0)
21678 y = Lazy(0)
21679 self.width = w = Lazy(0)
21680 self.height = h = Lazy(0)
21681 self.bbox = BBox(Point(x.val, y.val), Point(x.val + w.val, y.val + h.val))
21682 self.width.set(bbox.width())
21683 self.height.set(bbox.height())
21684 self.prepare_draw = self.prepare_draw_stage2
21685 return True, True</t>
21686 <t tx="michael.20061028181551.4">def prepare_draw_stage2(self, renderer, point_to_pixel, fig_point_to_pixel):
21687 self.set_font_factor(point_to_pixel, fig_point_to_pixel)
21688 self.font_factor = Lazy(point_to_pixel / fig_point_to_pixel)
21689 return True, True
21690 </t>
21691 <t tx="michael.20061028181551.5">def set_pos(self, x, y):
21692 Point = mtrans.Point
21693 BBox = mtrans.Bbox
21694 x = Lazy(x)
21695 y = Lazy(y)
21696 w = self.width
21697 h = self.height
21698 self.bbox = BBox(Point(x.val, y.val), Point(x.val + w.val, y.val + h.val))
21699 </t>
21700 <t tx="michael.20061028181551.6">def draw(self, renderer, data_box):
21701 if not self.get_visible() or not self.overlaps(data_box): return False
21702 self.check_font_factor(renderer)
21703 set_helpers(self.bbox, self.bbox)
21704 for a in self.all_artists(): a.draw(renderer)
21705 return True
21706 </t>
21707 <t tx="michael.20061028181843">def set_cell(self, row, col, widget, valign="center", halign="center"):
21708 self.cells[row][col] = widget
21709 widget._valign = valign
21710 widget._halign = halign</t>
21711 <t tx="michael.20061031174101">def correct_resource_code(self, code_item):
21712 try:
21713 if code_item.obj.name == code_item.name: return
21714 except AttributeError: return
21716 refs = self.find_resource_references(code_item.obj.name)
21717 for ci, line, start, end in refs:
21718 text = self.GetTextRange(start, end)
21719 self.SetTargetStart(start)
21720 self.SetTargetEnd(end)
21721 self.ReplaceTarget(text.replace(code_item.obj.name,
21722 code_item.name))
21724 code_item.obj.name = code_item.name
21725 </t>
21726 <t tx="michael.20061031174101.1">def correct_task_code(self, code_item):
21727 self.BeginUndoAction()
21728 try:
21729 task = code_item.obj
21730 old_path = code_item.task_path
21731 except AttributeError: return
21733 path = get_code_item_path(code_item)
21734 if path == old_path: return
21736 code_item.task_path = path
21737 &lt;&lt; change all relative paths of my sources &gt;&gt;
21738 &lt;&lt; change the path in all tasks that depend on me &gt;&gt;
21739 self.EndUndoAction()
21740 </t>
21741 <t tx="michael.20061031175127">def correct_code(self, editor):
21742 editor.correct_code()</t>
21743 <t tx="michael.20061106013825">def check_for_correction(self):
21744 to_correct = [ model.editor.editor
21745 for model in controller().get_planbuffers()
21746 if model.editor.editor.should_be_corrected ]
21747 if to_correct:
21748 answer = wx.MessageBox(_("Should I try to correct your project?"),
21749 _("Recalc Project"),
21750 wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION)
21751 if answer == wx.YES:
21752 for editor in to_correct:
21753 editor.should_be_corrected = False
21754 editor.correct_code()
21755 else:
21756 for editor in to_correct:
21757 editor.should_be_corrected = False</t>
21758 <t tx="michael.20061109163439">def get_main_completion_list(self):
21759 compl = super(CTask, self).get_main_completion_list()
21760 &lt;&lt; add user defined task completions &gt;&gt;
21761 return compl </t>
21762 <t tx="michael.20061109173515">try:
21763 tc = self.code_item.editor.task_completions
21764 if tc: compl += tc
21765 except AttributeError: pass</t>
21766 <t tx="michael.20061109181208">def _refsum(refs):
21767 return reduce(lambda a, b: a + b, refs, [])</t>
21768 <t tx="michael.20061109182534">try:
21769 task = self.__dict__[name]
21770 except KeyError:
21771 task = Task(value, name, self, len(self.children) + 1)
21772 self.children.append(task)
21773 setattr(self, task.name, task)
21774 return</t>
21775 <t tx="michael.20061109182534.1">if type(value) == types.DictionaryType:
21776 self.root.all_scenarios.update(value.keys())
21777 value = value.get(self.scenario, value["_default"])
21779 self.__set_sources(name, value)
21780 self._original_values[name] = value
21781 set_method(_val(value))</t>
21782 <t tx="michael.20061109182534.2">if callable( getattr(self.__class__, name, None)):
21783 raise NameError('You may not use "%s" as attribute' % name)
21785 setattr(self, name, value)
21786 self._properties[name] = True
21787 self.__set_sources(name, value)</t>
21788 <t tx="michael.20061109182534.3">def make_ref(val):
21789 if isinstance(val, _ValueWrapper):
21790 return val._ref
21792 if isinstance(val, Task):
21793 return [(val, "")]
21795 return []
21797 if isinstance(value, (list, tuple)):
21798 sources = _refsum(map(make_ref, value))
21799 else:
21800 sources = make_ref(value)</t>
21801 <t tx="michael.20061110182612">menu(_("Toggle Bookmark\tCTRL-F2"), self.toggle_bookmark, pos=650)
21802 menu(_("Next Bookmark\tF2"), self.goto_next_bookmark, pos=651)
21803 menu(_("Previous Bookmark\tSHIFT-F2"), self.goto_prev_bookmark, pos=652)</t>
21804 <t tx="michael.20061110184924">def toggle_bookmark(self):
21805 line = self.GetCurrentLine()
21806 if self.MarkerGet(line) &amp; 4:
21807 self.MarkerDelete(line, 2)
21808 else:
21809 self.MarkerAdd(line, 2)</t>
21810 <t tx="michael.20061110184924.1">def goto_next_bookmark(self):
21811 next = self.MarkerNext(self.GetCurrentLine() + 1, 4)
21812 if next &lt; 0:
21813 next = self.MarkerNext(0, 4)
21815 if next &gt;= 0:
21816 self.GotoLine(next)
21817 </t>
21818 <t tx="michael.20061110184924.2">def goto_prev_bookmark(self):
21819 prev = self.MarkerPrevious(self.GetCurrentLine() - 1, 4)
21820 if prev &lt; 0:
21821 prev = self.MarkerPrevious(self.GetLineCount(), 4)
21823 if prev &gt;= 0:
21824 self.GotoLine(prev)
21825 </t>
21826 <t tx="michael.20061113154308.1">set_helpers(bbox, bbox)
21827 bbox = self.text.get_window_extent(renderer)
21828 bbox = inverse(self.get_transform(), bbox)
21830 xmin, xmax = bbox.intervalx().get_bounds()
21831 bbox.intervalx().set_bounds(xmin, xmax + self.left + self.right)
21832 ymin, ymax = bbox.intervaly().get_bounds()
21833 bbox.intervaly().set_bounds(ymin, ymax + self.top + self.bottom)
21834 </t>
21835 <t tx="michael.20061113154308.2">set_helpers(bbox, bbox)
21836 extends = [ t.get_window_extent(renderer) for t in self.artists ]
21837 if extends:
21838 bb_all = mtrans.bbox_all(extends)
21839 bb_all = inverse(self.get_transform(), bb_all)
21840 bbox = mtrans.bbox_all((bb_all, bbox))</t>
21841 <t tx="michael.20061114113543">def find_object(self, name):
21843 Find an object by name.
21845 editor = self.code_item.editor
21846 attribs = editor.get_attribs(self.code_item)
21847 try:
21848 expression = editor.get_expression(attribs[name])
21849 attribs = editor.eval_expression(expression, context=self)
21850 return attribs[name]
21851 except Exception, e: pass
21853 obj = self.get_object()
21854 try:
21855 return getattr(obj, name)
21856 except AttributeError, e:
21857 return None
21858 </t>
21859 <t tx="michael.20061114193915">def calc_bounding_box(self, renderer):
21860 inverse = mtrans.inverse_transform_bbox
21861 bbox = mtrans.unit_bbox()
21863 &lt;&lt; calculate bbox based on self.text &gt;&gt;
21864 &lt;&lt; calculate bbox with all artists &gt;&gt;
21865 return bbox</t>
21866 <t tx="michael.20061114193915.1">__last_font_factor = 0
21867 def check_font_factor(self, renderer):
21868 font_factor = self.font_factor.get()
21869 if self.__last_font_factor != font_factor:
21870 self.__last_font_factor = font_factor
21871 bbox = self.calc_bounding_box(renderer)
21872 self.width.set(bbox.width())
21873 self.height.set(bbox.height())
21874 </t>
21875 <t tx="michael.20061114194524">def check_font_factor(self, renderer):
21876 for c in self.widest_cells:
21877 c.check_font_factor(renderer)
21879 </t>
21880 <t tx="michael.20061118232041">inspect_path = to_inspect.path + "."
21881 sources = _get_tasks_of_sources(to_inspect)
21882 sources = [ s + "." for s in sources
21883 if not inspect_path.startswith(s) ]
21885 # the if in the later line ignores assignments like
21886 # like start = up.start (i.e. references to parents)
21887 # this will be handled in the second if of inspect_depends_on
21888 # and can cause errors otherwise
21890 def inspect_depends_on(task):
21891 cmp_path = task.path + "."
21892 for src in sources:
21893 if cmp_path.startswith(src):
21894 #task is a source of to_inspect
21895 return True
21897 if inspect_path.startswith(cmp_path):
21898 #to_inspect is a child of task
21899 return True
21901 return False</t>
21902 <t tx="michael.20061119042333">changed = event.changed
21903 removed = [ (-ci.get_line(), ci) for op, ci in changed if op == "removed" ]
21904 inserted = [ (ci.get_line(), ci) for op, ci in changed if op == "inserted" ]
21905 changed = [ (ci.get_line(), ci) for op, ci in changed if op == "changed" ]
21906 removed.sort()
21907 inserted.sort()
21908 changed.sort()</t>
21909 <t tx="michael.20061119143304">def __iter__(self):
21910 return iter(self.task)</t>
21911 <t tx="michael.20061119143714">def __iter__(self):
21912 return iter(self._task)</t>
21913 <t tx="michael.20061121143813"></t>
21914 <t tx="michael.20061121143813.1">def _set_done(self, value):
21915 raise AttributeError("The attribute 'done' is readonly.")</t>
21916 <t tx="michael.20061121143813.2">def _set_performed_work_time(self, value):
21917 raise AttributeError("The attribute 'performed_work_time' is readonly.")</t>
21918 <t tx="michael.20061121143813.3">def _set_booked_resource(self, value):
21919 raise AttributeError("The attribute 'booked_resource' is readonly.")</t>
21920 <t tx="michael.20061121143813.4">def _set_performed_effort(self, value):
21921 raise AttributeError("The attribute 'performed_effort' is readonly.")</t>
21922 <t tx="michael.20061121143813.5">def _set_children(self, value):
21923 raise AttributeError("The attribute 'children' is readonly.")</t>
21924 <t tx="michael.20061121143813.6">def _set_depth(self, value):
21925 raise AttributeError("The attribute 'depth' is readonly.")</t>
21926 <t tx="michael.20061121143813.7">def _set_index(self, value):
21927 raise AttributeError("The attribute 'index' is readonly.")</t>
21928 <t tx="michael.20061121143813.8">def _set_scenario(self, value):
21929 raise AttributeError("The attribute 'scenario' is readonly.")</t>
21930 <t tx="michael.20061121143813.9">def _set_buffer(self, value):
21931 raise AttributeError("The attribute 'buffer' is readonly.")</t>
21932 <t tx="michael.20061123163317">def __getitem__(self, slice):
21933 return self.__class__(self._value[slice], self._ref)</t>
21934 <t tx="michael.20061129124501">@
21935 A performed path can have sub activities appended to the task path.
21936 like:
21938 root.parent1.parent2.task.subactivity
21940 here rhe correct task path is:
21942 root.parent1.parent2.task
21944 @code
21945 orpath = rpath
21946 while not task:
21947 #path can specify a sub module
21948 #find the correct path to the module
21949 try:
21950 last_dot = rpath.rindex(".", 0, len(rpath))
21951 except ValueError:
21952 break
21954 rpath = rpath[:last_dot]
21955 task = self.get_task(rpath)
21957 item = list(item)
21958 item.append(orpath[len(rpath):])</t>
21959 <t tx="michael.20061201004146">def __calc_estimated_effort(self):
21960 if self.children:
21961 return self._to_delta(sum([ t.estimated_effort for t in self.children ]))
21963 return self.effort
21965 estimated_effort = _TaskProperty(__calc_estimated_effort)
21966 </t>
21967 <t tx="michael.20061230152555">def __calc_performed_effort(self):
21968 if self.children:
21969 return self._to_delta(sum([ t.performed_effort for t in self.children ]))
21971 return pcalendar.Minutes(0)
21973 performed_effort = _TaskProperty(__calc_performed_effort)
21974 </t>
21975 <t tx="michael.20061230173452"></t>
21976 <t tx="michael.20061230173452.1">@doc
21978 </t>
21979 <t tx="michael.20061230174132">@
21980 - Neuer Code Browser ausprobieren. Der folgendermaßen läuft:
21981 1. Läuft in einem extra thread
21982 2. komplettes parsen des files in einer neue strutkur
21983 3. Mittel diff algorithmus die alte strukutur in die neue umwandeln und dabei die obj attribute behalten.
21984 4. Der explorer wird integriert im python editor
21985 5. Der Explorer ist voll drag and drop fähig (auch mit mehreren selektieren einträgen)
21986 6. Alles kommt nach metapie
21989 - Netzwerk graphiken
21991 - Referenz Dokumentation umstellen: (wird gelesen aus den Source Files)
21993 - Tutorial steuerung
21995 - Release Package: Zusammenfassung von funktionen zur Erzeugung von Software releases.
21996 </t>
21997 <t tx="michael.20070112120451">def VariableLoad(limit=0):
21999 Allocates the resource with maximal possible load.
22000 If limit is given, a the load is at least limit or more.
22002 try:
22003 balance = me.balance
22004 except NameError:
22005 balance = SLOPPY
22007 if balance != SLOPPY:
22008 raise RuntimeError("You may specify variable_load only with balance=SLOPPY")
22010 return -limit
22011 </t>
22012 <t tx="michael.20070115161719">def __unicode__(self): return unicode(self._value)</t>
22013 <t tx="michael.20070115170252">@language python
22014 &lt;&lt; Copyright &gt;&gt;
22016 Patched versions of buggy wxpython objects
22018 &lt;&lt; Imports &gt;&gt;
22020 _is_source_ = True
22022 @others</t>
22023 <t tx="michael.20070115170327">import wx
22024 from wx.__version__ import VERSION
22025 from metapie.gui import controller</t>
22026 <t tx="michael.20070115204524">def unicode(self, *args):
22027 if isinstance(self._value, str):
22028 return unicode(self._value, *args)
22030 return unicode(self._value)</t>
22031 <t tx="michael.20070115204909">def unicode(self, *args):
22032 value = self.value
22033 try:
22034 return value.unicode(*args)
22035 except AttributeError:
22036 pass
22038 if isinstance(value, str):
22039 return unicode(value, *args)
22041 return unicode(value)
22042 </t>
22043 <t tx="michael.20070116023524">if self.text.find("efficency") &gt;= 0:
22044 answer = wx.MessageBox(_("The file %s has a misspelled efficiency attribute."\
22045 "Sould I correct it?") % path,
22046 _("Misspelling Bug"),
22047 wx.YES_NO|wx.ICON_QUESTION)
22048 if answer == wx.YES:
22049 self.text = self.text.replace("efficency", "efficiency")</t>
22050 <t tx="michael.20070116120608">def move(self, x, y):
22051 self.MoveXY(x, y)
22052 self.Hide()
22053 self.Show()</t>
22054 <t tx="michael.20070116154322">if indent(line(pos)) &gt;= child_indent:
22055 pos = find(pos - 1, 0, ":")
22056 continue</t>
22057 <t tx="michael.20070117163707">def unicode(self, *args):
22058 if isinstance(self._value, str):
22059 return unicode(self._value, *args)
22061 return repr(self)</t>
22062 <t tx="michael.20070421153201">class TaskBarIcon(wx.TaskBarIcon):
22063 TBMENU_RESTORE = wx.NewId()
22064 TBMENU_CLOSE = wx.NewId()
22066 def __init__(self, frame):
22067 wx.TaskBarIcon.__init__(self)
22068 self.frame = frame
22070 # Set the image
22071 icon = wx.IconFromBitmap(ResourceManager.load_bitmap("gantt"))
22072 self.SetIcon(icon, "Faces")
22073 self.imgidx = 1
22074 print "taskbar"
22075 # bind some events
22076 self.Bind(wx.EVT_TASKBAR_LEFT_DCLICK, self.OnTaskBarActivate)
22077 self.Bind(wx.EVT_MENU, self.OnTaskBarActivate, id=self.TBMENU_RESTORE)
22078 self.Bind(wx.EVT_MENU, self.OnTaskBarClose, id=self.TBMENU_CLOSE)
22081 def CreatePopupMenu(self):
22082 menu = wx.Menu()
22083 menu.Append(self.TBMENU_RESTORE, _("Restore Faces"))
22084 menu.Append(self.TBMENU_CLOSE, _("Close Faces"))
22085 return menu
22088 def MakeIcon(self, img):
22090 The various platforms have different requirements for the
22091 icon size...
22093 if "wxMSW" in wx.PlatformInfo:
22094 img = img.Scale(16, 16)
22095 elif "wxGTK" in wx.PlatformInfo:
22096 img = img.Scale(22, 22)
22097 # wxMac can be any size upto 128x128, so leave the source img alone....
22098 icon = wx.IconFromBitmap(img.ConvertToBitmap() )
22099 return icon
22102 def OnTaskBarActivate(self, evt):
22103 if self.frame.IsIconized():
22104 self.frame.Iconize(False)
22105 if not self.frame.IsShown():
22106 self.frame.Show(True)
22107 self.frame.Raise()
22110 def OnTaskBarClose(self, evt):
22111 self.frame.Close()
22112 </t>
22113 <t tx="michael.20070710231245">def calendar(self, scenario):
22114 try:
22115 return self._calendar[scenario]
22116 except KeyError:
22117 cal = self._calendar[scenario] = ResourceCalendar(self._calendar[None])
22118 return cal
22120 </t>
22121 <t tx="michael.20070716145002">@language python
22122 &lt;&lt; Copyright &gt;&gt;
22124 import matplotlib as _mp
22126 try:
22127 import matplotlib.transforms as _mtrans
22128 except NameError:
22129 _mp.rcParams['numerix'] = "numpy"
22130 import matplotlib.transforms as _mtrans
22132 _mp.use("Agg")
22134 _is_source = True
22135 </t>
22136 <t tx="michael.20070926121838"></t>
22137 <t tx="michael.20070926130714">#self.Copy and self.Cut fill the clipoard only the second time
22138 #when they are called. ==&gt; this is annyoing an they are replaced
22139 #by wxPython clipboard functions
22140 def copy(clear=False):
22141 txt = self.GetSelectedText()
22142 if txt:
22143 clipboard = wx.Clipboard_Get()
22144 if clipboard.Open():
22145 clipboard.SetData(wx.TextDataObject(txt))
22146 clipboard.Close()
22147 if clear:
22148 self.ReplaceSelection("")
22150 def cut():
22151 copy(True)
22152 </t>
22153 <t tx="michael.20071111221700">def build_mark(self, interval, scale, transform):
22154 format = self._get_format(interval, transform)
22155 date = scale.to_num(int(interval[0])).to_datetime()
22156 quater = 1 + (date.month - 1) / 3
22157 decade = 10 * (date.year / 10)
22158 f = format.replace("%Q", str(quater))
22159 f = f.replace("%D", str(decade))
22160 return strftime(date, f)</t>
22161 <t tx="michael.20080106130453">def strftime(dt, format):
22163 an extended version of strftime, that introduces some new
22164 directives:
22165 %IW iso week number
22166 %IY iso year
22167 %IB full month name appropriate to iso week
22168 %ib abbreviated month name appropriate to iso week
22169 %im month as decimal number appropriate to iso week
22171 iso = dt.isocalendar()
22172 if iso[0] != dt.year:
22173 iso_date = dt.replace(day=1, month=1)
22174 format = format \
22175 .replace("%IB", iso_date.strftime("%B"))\
22176 .replace("%ib", iso_date.strftime("%b"))\
22177 .replace("%im", iso_date.strftime("%m"))
22178 else:
22179 format = format \
22180 .replace("%IB", "%B")\
22181 .replace("%ib", "%b")\
22182 .replace("%im", "%m")
22184 format = format \
22185 .replace("%IW", str(iso[1]))\
22186 .replace("%IY", str(iso[0]))\
22188 return dt.strftime(format)
22189 </t>
22190 <t tx="mr7771.20060608154252"></t>
22191 <t tx="mr7771.20060608164004">@doc
22192 Base modules of faces. These are the only modules to run a simple faces file.
22193 </t>
22194 <t tx="mr7771.20060608164004.452">@doc
22195 library of observers.</t>
22196 <t tx="mr7771.20060608164004.453">@doc
22197 package of chart base functionality.</t>
22198 <t tx="mr7771.20060608164004.454"></t>
22199 <t tx="mr7771.20060608165446"></t>
22200 <t tx="mr7771.20060608165446.4">@language python
22201 &lt;&lt; Copyright &gt;&gt;
22203 Different editor contexts, they depend on the
22204 source code environemnt of a cursor position.
22206 &lt;&lt; Imports &gt;&gt;
22208 _is_source = True
22209 _ = faces.plocale.get_gettext()
22211 @others</t>
22212 <t tx="mr7771.20060609151433">############################################################################
22213 # Copyright (C) 2005, 2006, 2007, 2008 by Reithinger GmbH
22214 # mreithinger@web.de
22216 # This file is part of faces.
22218 # faces is free software; you can redistribute it and/or modify
22219 # it under the terms of the GNU General Public License as published by
22220 # the Free Software Foundation; either version 2 of the License, or
22221 # (at your option) any later version.
22223 # faces is distributed in the hope that it will be useful,
22224 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22225 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22226 # GNU General Public License for more details.
22228 # You should have received a copy of the GNU General Public License
22229 # along with this program; if not, write to the
22230 # Free Software Foundation, Inc.,
22231 # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22232 ############################################################################
22234 </t>
22235 <t tx="mr7771.20060609151433.1">@language python
22236 &lt;&lt; Copyright &gt;&gt;
22237 &lt;&lt; Imports &gt;&gt;
22239 _is_source_ = True
22240 _ = faces.plocale.get_gettext()
22242 @others
22243 </t>
22244 <t tx="mr7771.20060609151433.2">from browser import Browser
22245 from editor import Editor
22246 from metapie.gui import controller
22247 from metapie.navigator import View
22248 import weakref
22249 import ConfigParser
22250 import wx
22251 import faces.plocale
22252 import faces.gui.editor.task
22253 import faces.gui.editor.resource</t>
22254 <t tx="mr7771.20060609151433.3">def is_bool_option(name, default=True):
22255 try:
22256 return controller().config.getboolean("DEFAULT", name)
22257 except ConfigParser.NoOptionError:
22258 return default
22259 </t>
22260 <t tx="mr7771.20060609151433.4">class PlanEditor(wx.SplitterWindow):
22261 @others
22262 </t>
22263 <t tx="mr7771.20060609151433.5">def __init__(self, model):
22264 wx.SplitterWindow.__init__(self, controller().hidden_parent,
22265 -1, style=wx.SP_3DSASH)
22266 self.browser_menu = None
22267 self.browser = Browser(self)
22268 self.editor = Editor(model, self)
22269 self.browser.bind_events()
22270 self.Initialize(self.editor)
22271 &lt;&lt; redirect methods &gt;&gt;
22272 self.editor.SetMinSize((0, 0))
22273 self.Bind(wx.EVT_SPLITTER_UNSPLIT, self._on_unsplit)
22274 self.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGING, self._on_shash_pos_change)
22276 if is_bool_option("show_browser"):
22277 wx.CallAfter(self.toggle_browser)</t>
22278 <t tx="mr7771.20060609151433.7">def _on_unsplit(self, event):
22279 if event.GetWindowBeingRemoved() is self.browser:
22280 self.browser.open_width = self.browser.GetSize()[0]
22281 self.browser_menu.check(False)
22282 else:
22283 raise RuntimeError("editor may not unsplit")
22285 </t>
22286 <t tx="mr7771.20060609151433.8">def toggle_browser(self, show=None):
22287 if show is None:
22288 show = not self.browser.IsShown()
22290 if show:
22291 try:
22292 width = self.browser.open_width
22293 except AttributeError:
22294 width = self.browser.width
22296 if self.IsSplit():
22297 self.SetSashPosition(width)
22298 else:
22299 self.browser.Show()
22300 self.SplitVertically(self.browser, self.editor, width)
22302 self.browser.update_menus()
22303 self.SetSashGravity(0.0)
22304 elif self.IsSplit():
22305 self.browser.open_width = self.browser.GetSize()[0]
22306 self.Unsplit(self.browser)
22307 self.browser.Hide()
22309 try:
22310 self.browser_menu.check(show)
22311 except AttributeError: pass
22313 controller().config.set("DEFAULT", "show_browser", str(show))
22314 </t>
22315 <t tx="mr7771.20060609151433.9">def goto_line(self, line):
22316 editor = self.editor
22317 pos = editor.PositionFromLine(line - 1)
22318 editor.GotoPos(pos)
22319 editor.SetFocus()
22320 </t>
22321 <t tx="mr7771.20060609151433.10">def find_in_source(self, obj):
22322 self.editor.show_object(obj)
22323 self.editor.SetFocus()
22324 </t>
22325 <t tx="mr7771.20060609152050">@language python
22326 &lt;&lt; Copyright &gt;&gt;
22327 &lt;&lt; Imports &gt;&gt;
22328 _is_source_ = True
22329 _ = faces.plocale.get_gettext()
22331 @others
22332 </t>
22333 <t tx="mr7771.20060609152050.1">import faces.observer
22334 import wx
22335 import matplotlib.backends.backend_wxagg as wxagg
22336 import matplotlib.backend_bases as bases
22337 import matplotlib.transforms as mtrans
22338 import matplotlib.numerix as numerix
22339 import matplotlib.font_manager as font
22340 import matplotlib.figure as figure
22341 import matplotlib.numerix as numerix
22342 import metapie.navigator as navigator
22343 from metapie.gui import controller
22344 import datetime
22345 import faces.task
22346 import faces.charting.tools as tools
22347 import faces.charting.charts as charts
22348 import faces.gui.editor.context as context
22349 import faces.plocale
22350 import taskfuncs
22351 import sys
22352 import matplot_patches as mpatch
22353 import math
22354 from tipwindow import TipWindow
22355 import print_chart
22359 </t>
22360 <t tx="mr7771.20060609152050.2">def _cint(x):
22361 return int(math.ceil(x))
22362 </t>
22363 <t tx="mr7771.20060609152050.3">def _nop():
22364 pass
22365 </t>
22366 <t tx="mr7771.20060609152050.4">tools.set_default_size(6)
22368 def _chart_factory(title, chart, model):
22369 return lambda parent: ChartView(parent, chart, model, title)
22370 </t>
22371 <t tx="mr7771.20060609152050.5">def _timechart_factory(title, chart, model):
22372 return lambda parent: TimeChartView(parent, chart, model, title)
22373 </t>
22374 <t tx="mr7771.20060609152050.6">
22376 faces.observer.factories["matplot_chart"] = _chart_factory
22377 faces.observer.factories["matplot_pointchart"] = _chart_factory
22378 faces.observer.factories["matplot_timechart"] = _timechart_factory
22381 cursord = {
22382 bases.cursors.MOVE : wx.CURSOR_HAND,
22383 bases.cursors.HAND : wx.CURSOR_HAND,
22384 bases.cursors.POINTER : wx.CURSOR_ARROW,
22385 bases.cursors.SELECT_REGION : wx.CURSOR_CROSS,
22389 class _ErrorChart(charts.TimeAxisWidgetChart):
22390 &lt;&lt; class _ErrorChart declarations &gt;&gt;
22391 @others
22392 </t>
22393 <t tx="mr7771.20060609152050.7">data = True
22394 scroll_bars = False
22396 </t>
22397 <t tx="mr7771.20060609152050.8">def create(self):
22398 self.set_time_axis()
22399 fig = self.figure
22400 fig.clf()
22401 fig.text(0.5, 0.5, 'Error in chart',
22402 fontsize='xx-large',
22403 color='red',
22404 horizontalalignment='center',
22405 verticalalignment='center')
22407 pprop = self.get_patch
22408 self.axes.set_frame_on(False)
22409 self.time_axis.time_scale = self.time_scale
22410 self.time_axis.show_scale = False
22411 self.time_axis.show_grid = False
22412 self.axes.set_time_axis(self.time_axis)
22413 self.axes.xaxis_timescale(self.time_scale)
22414 self.axes.set_marker(pprop("focused.marker"), pprop("marker"))
22416 xmin = self.time_scale.to_num("1.1.2005")
22417 xmax = self.time_scale.to_num("10.1.2005")
22418 self.axes.set_time_lim(xmin, xmax)
22419 self.axes.dataLim.intervalx().set_bounds(xmin, xmax)
22420 self.axes.dataLim.intervaly().set_bounds(0, 1)
22421 </t>
22422 <t tx="mr7771.20060609152050.9">class Toolbar(bases.NavigationToolbar2):
22423 @others
22424 </t>
22425 <t tx="mr7771.20060609152050.10">def _init_toolbar(self):
22426 view = self.canvas.GetParent()
22427 self.create_menus()
22428 </t>
22429 <t tx="mr7771.20060609152050.11">def create_menus(self):
22430 view = self.canvas.GetParent()
22431 ctrl = controller()
22432 toolbar = ctrl.get_toolbar()
22434 def hzin(): view.horz_zoom(2)
22435 def hzout(): view.horz_zoom(-2)
22436 def vzin(): view.vert_zoom(2)
22437 def vzout(): view.vert_zoom(-2)
22439 toolbar.make_tool(view, "home", self.home, "home",
22440 short=_("Home"))
22441 self.back_tool = toolbar.make_tool(view, "back",
22442 self.back, "back",
22443 short=_("Back"))
22444 self.fore_tool = toolbar.make_tool(view, "forward",
22445 self.forward, 'forward',
22446 short=_("Forward"))
22447 self.pan_tool = toolbar.make_tool(view, "move", self.pan, "move",
22448 kind=wx.ITEM_CHECK,
22449 short=_("Move Tool"))
22450 self.zoom_tool = toolbar.make_tool(view, "zoom", self.zoom,
22451 "zoom_to_rect",
22452 kind=wx.ITEM_CHECK,
22453 short=_("Zoom Tool"))
22454 toolbar.make_separator("home", True)
22455 toolbar.make_tool(view, "x-fit", view.zoom_to_fit, "viewmagfit22",
22456 short=_("zoom to fit"))
22457 toolbar.make_tool(view, "x-zoomout", hzout, "mag-horz22",
22458 short=_("zoom out horizontally"))
22459 toolbar.make_tool(view, "x-zoomin", hzin, "mag+horz22",
22460 short=_("zoom in horizontally"))
22461 toolbar.make_tool(view, "y-zoomout", vzout, "mag-vert22",
22462 short=_("zoom out vertically"))
22463 toolbar.make_tool(view, "y-zoomin", vzin, "mag+vert22",
22464 short=_("zoom in vertically"))
22465 toolbar.make_separator("x-fit", True)
22466 self.refresh_buttons()
22467 self.make_menu()
22468 </t>
22469 <t tx="mr7771.20060609152050.12">def make_menu(self, popup=False):
22470 ctrl = controller()
22471 view = self.canvas.GetParent()
22473 if popup:
22474 chart_menu = ctrl.make_menu()
22475 else:
22476 top = ctrl.get_top_menu()
22477 chart_menu = top.make_menu(_("&amp;Chart"), pos=200)
22479 menu = lambda *args, **kw: chart_menu.make_item(view, *args, **kw)
22481 def find_in_source(): view.model.find_in_source(view.chart.__class__)
22483 def menu_print_chart():
22484 dlg = print_chart.PrintChart(controller().frame,
22485 self.canvas.GetParent().chart)
22486 dlg.simulate_modal(self.canvas.GetParent())
22489 menu(_("Print Chart..."), menu_print_chart, "print16", pos=100)
22491 if not popup:
22492 def hzin(): view.horz_zoom(2)
22493 def hzout(): view.horz_zoom(-2)
22494 def vzin(): view.vert_zoom(2)
22495 def vzout(): view.vert_zoom(-2)
22496 menu(_("Horizontal Zoom In\tCTRL-."), hzin, "mag+horz16", pos=10)
22497 menu(_("Horizontal Zoom Out\tCTRL-,"), hzout, "mag-horz16", pos=20)
22498 menu(_("Fit in Window"), view.zoom_to_fit, pos=30)
22499 chart_menu.make_separator(_("Fit in Window"))
22501 menu(_("Duplicate Chart"), view.duplicate, "duplicate_view16", pos=120)\
22502 .enable(not hasattr(view, "_original"))
22503 menu(_("Find in Source"), find_in_source, "findsource16", pos=130)
22504 self.link_menu = menu(_("&amp;Link Chart"), view.change_link,
22505 check_item=True, pos=140)
22506 self.link_menu.check(view.link_view)
22508 chart_menu.make_separator(_("&amp;Link Chart"))
22509 return chart_menu
22511 </t>
22512 <t tx="mr7771.20060609152050.13">def refresh_buttons(self):
22513 if self.pan_tool.is_pressed() != (self._active == 'PAN'):
22514 self.pan_tool.toggle(self._active == 'PAN')
22516 if self.zoom_tool.is_pressed() != (self._active == 'ZOOM'):
22517 self.zoom_tool.toggle(self._active == 'ZOOM')
22518 </t>
22519 <t tx="mr7771.20060609152050.14">def set_history_buttons(self):
22520 can_backward = (self._views._pos &gt; 0)
22521 can_forward = (self._views._pos &lt; len(self._views._elements) - 1)
22522 self.back_tool.enable(can_backward)
22523 self.fore_tool.enable(can_forward)
22524 </t>
22525 <t tx="mr7771.20060609152050.15">def set_cursor(self, cursor):
22526 cursor = wx.StockCursor(cursord[cursor])
22527 self.canvas.SetCursor(cursor)
22528 </t>
22529 <t tx="mr7771.20060609152050.16">__last_rect = None
22530 def draw_rubberband(self, event, x0, y0, x1, y1):
22531 #take from backend_wx
22532 canvas = self.canvas
22533 dc = wx.ClientDC(canvas)
22535 # Set logical function to XOR for rubberbanding
22536 dc.SetLogicalFunction(wx.XOR)
22538 wbrush = wx.Brush(wx.Colour(255,255,255), wx.TRANSPARENT)
22539 wpen = wx.Pen(wx.Colour(200, 200, 200), 1, wx.SOLID)
22540 dc.SetBrush(wbrush)
22541 dc.SetPen(wpen)
22543 dc.ResetBoundingBox()
22544 dc.BeginDrawing()
22545 height = self.canvas.figure.bbox.height()
22546 y1 = height - y1
22547 y0 = height - y0
22549 if y1 &lt; y0: y0, y1 = y1, y0
22550 if x1 &lt; y0: x0, x1 = x1, x0
22552 w = x1 - x0
22553 h = y1 - y0
22555 rect = (int(x0), int(y0), int(w), int(h))
22556 if self.__last_rect: dc.DrawRectangle(*self.__last_rect) #erase last
22557 self.__last_rect = rect
22558 dc.DrawRectangle(*rect)
22559 dc.EndDrawing()
22560 </t>
22561 <t tx="mr7771.20060609152050.17">def release(self, event):
22562 self.__last_rect = None
22563 </t>
22564 <t tx="mr7771.20060609152050.18">def mouse_move(self, event):
22565 bases.NavigationToolbar2.mouse_move(self, event)
22566 self.canvas.GetParent().mouse_over(event)
22567 </t>
22568 <t tx="mr7771.20060609152050.19">class ChartView(wx.PyScrolledWindow, navigator.View):
22569 @others
22570 </t>
22571 <t tx="mr7771.20060609152050.20">def __init__(self, parent, chart, model, title):
22572 wx.PyScrolledWindow.__init__(self, parent, -1)
22574 tmpdc = wx.ClientDC(parent)
22575 dpi = tmpdc.GetPPI()[0]
22576 del tmpdc
22577 self.dpi = float(dpi)
22578 self.has_focus = False
22579 self.canvas = None
22580 self.chart = None
22581 self.model = model
22582 self.marked_widget = None
22583 self._is_ready = False
22584 self.timer = wx.Timer(self)
22585 self.deferred_func = None
22586 self.deferred_args = None
22587 self.link_view = True
22588 self.toolbar = None
22589 self.replace_data(chart)
22590 </t>
22591 <t tx="mr7771.20060609152050.21">def Destroy(self):
22592 self.timer.Stop()
22593 wx.PyScrolledWindow.Destroy(self)
22594 </t>
22595 <t tx="mr7771.20060609152050.22">def replace_data(self, chart):
22596 if self.canvas:
22597 self.figure.clf()
22598 self.canvas.Destroy()
22600 last_trans = None
22601 if self.chart and not isinstance(self.chart, _ErrorChart):
22602 last_trans = self.chart._trans_data
22604 self.figure = figure.Figure(dpi=self.dpi)
22605 self.canvas = mpatch.FigureCanvasWx(self, -1, self.figure)
22606 self.canvas.mpl_connect('button_press_event', self.mouse_button)
22607 charts._figure_manager.canvas = self.canvas
22608 self.SetTargetWindow(self.canvas)
22609 self.create_chart(chart)
22611 if self.toolbar:
22612 views = self.toolbar._views
22613 self.toolbar = Toolbar(self.canvas)
22614 self.toolbar._views = views
22615 else:
22616 self.toolbar = Toolbar(self.canvas)
22618 self.show_horz_bar = self.show_vert_bar = self.chart.scroll_bars
22619 self.link_view = not self.chart.link_view
22620 self.change_link()
22621 self.init_scrolling()
22623 if self.is_visible():
22624 self.become_visible(last_trans)
22625 </t>
22626 <t tx="mr7771.20060609152050.23">def init_scrolling(self):
22627 get_bbox_transform = mtrans.get_bbox_transform
22628 unit_bbox = mtrans.unit_bbox
22629 dlim = self.chart._data_lim.deepcopy()
22630 dlim.intervalx().set_bounds(dlim.xmin(), dlim.xmax())
22631 dlim.intervaly().set_bounds(dlim.ymax(), dlim.ymin())
22632 self.scroll_trans = get_bbox_transform(dlim, unit_bbox())
22633 </t>
22634 <t tx="mr7771.20060609152050.24">def scale_figure(self, trans):
22635 if trans:
22636 self._on_size(None)
22637 self.check_limits()
22638 vb = self.chart._bbox
22639 xmin, ymin = trans.inverse_xy_tup((vb.xmin(), vb.ymin()))
22640 xmax, ymax = trans.inverse_xy_tup((vb.xmax(), vb.ymax()))
22641 self.chart._set_xlim(xmin, xmax)
22642 self.chart._set_ylim(ymin, ymax)
22643 else:
22644 self.SetScrollbar(wx.VERTICAL, 0, 1, 10, False)
22645 self.SetScrollbar(wx.HORIZONTAL, 0, 1, 10, False)
22646 self._on_size(None)
22647 self.check_limits()
22648 self.chart._autoscale_view()
22650 self.setup_scrolling()
22651 </t>
22652 <t tx="mr7771.20060609152050.25">def check_limits(self):
22653 self.chart._check_limits()
22654 </t>
22655 <t tx="mr7771.20060609152050.26">def create_chart(self, chart):
22656 save_execute = controller().session.save_execute
22657 self.chart = save_execute(chart, self.figure)
22658 if not self.chart: self.chart = _ErrorChart(self.figure)
22659 </t>
22660 <t tx="mr7771.20060609152050.27">def _setup_events(self):
22661 wx.EVT_TIMER(self, -1, self._on_timer)
22662 wx.EVT_SIZE(self, self._on_size)
22663 wx.EVT_IDLE(self, self._on_idle)
22664 wx.EVT_SET_FOCUS(self, self._on_set_focus)
22665 wx.EVT_KILL_FOCUS(self, self._on_kill_focus)
22666 </t>
22667 <t tx="mr7771.20060609152050.28">def become_visible(self, last_trans=None):
22668 if not last_trans:
22669 self._setup_events()
22670 self._is_ready = True
22672 self.scale_figure(last_trans)
22673 #force update (inclusive scrolling)
22674 self._last_data_bounds = (0, 0, 0, 0)
22675 self.update_state()
22676 </t>
22677 <t tx="mr7771.20060609152050.29">def duplicate(self):
22678 class Unshared(self.chart.__class__):
22679 sharex = datetime.datetime.today() # should never be shared
22681 org_chart = id(self.chart.__class__)
22683 def is_duplicate(view):
22684 return isinstance(view, ChartView) \
22685 and getattr(view, "_original", 0) == org_chart
22687 duplicates = filter(is_duplicate, controller().get_all_views())
22688 if duplicates:
22689 duplid = max(map(lambda v: v._duplid, duplicates)) + 1
22690 else:
22691 duplid = 1
22693 model = self.model
22694 title = self._nav_title + "(%i)" % duplid
22695 factory_args = (self.__class__, Unshared, model, title)
22696 view = controller().produce_view(model, title, factory_args)
22697 view._original = org_chart
22698 view._duplid = duplid
22699 </t>
22700 <t tx="mr7771.20060609152050.30">def zoom_to_fit(self):
22701 self.chart._autoscale_view()
22702 self.update_state(True)
22703 </t>
22704 <t tx="mr7771.20060609152050.31">def horz_zoom(self, step):
22705 self.chart._zoomx(step)
22706 self.update_state(True)
22707 </t>
22708 <t tx="mr7771.20060609152050.32">def vert_zoom(self, step):
22709 self.chart._zoomy(step)
22710 self.update_state(True)
22711 </t>
22712 <t tx="mr7771.20060609152050.33">def scroll(self, direction, delta):
22713 if direction == wx.HORIZONTAL:
22714 self._scroll_adjustments[4] = self.GetScrollPos(direction) + delta
22715 else:
22716 self._scroll_adjustments[5] = self.GetScrollPos(direction) + delta
22718 self.SetScrollbars(*self._scroll_adjustments)
22719 </t>
22720 <t tx="mr7771.20060609152050.34">def change_link(self):
22721 self.link_view = not self.link_view
22722 self.toolbar.link_menu.check(self.link_view)
22723 </t>
22724 <t tx="mr7771.20060609152050.35">def deferred(self, time_out, func, *args):
22725 self.deferred_func = func
22726 self.deferred_args = args
22727 self.timer.Start(time_out, wx.TIMER_ONE_SHOT)
22728 </t>
22729 <t tx="mr7771.20060609152050.36">def _on_timer(self, event):
22730 self.timer.Stop()
22731 if self.deferred_func:
22732 self.deferred_func(*self.deferred_args)
22733 self.deferred_args = None
22734 self.deferred_func = None
22735 </t>
22736 <t tx="mr7771.20060609152050.37">def mouse_over(self, event):
22737 if event.xdata is None: return
22738 widget = self.chart._widget_at(event.xdata, event.ydata)
22739 if not TipWindow.get().is_widget_active(widget):
22740 self.deferred(1000, self._show_info)
22742 try:
22743 date = event.inaxes.time_scale.to_num(int(event.xdata))
22744 controller().status_bar.SetStatusText(repr(date), 2)
22745 except AttributeError:
22746 pass
22747 </t>
22748 <t tx="mr7771.20060609152050.38">def mark_widget(self, widget, axes=None):
22749 self.marked_widget = widget
22750 return self.chart._mark_widget(widget)
22751 </t>
22752 <t tx="mr7771.20060609152050.39">def mouse_button(self, event):
22753 if self.toolbar._active: return
22755 if event.button in (1, 3):
22756 #mark widget
22757 try:
22758 axes = event.inaxes
22759 widget = self.chart._widget_at(event.xdata, event.ydata)
22760 if self.mark_widget(widget, axes): self.draw()
22761 except AttributeError:
22762 widget = None
22764 fobj = getattr(widget, "fobj", None)
22765 fattrib = getattr(widget, "fattrib", None)
22767 if isinstance(fobj, faces.task.Task):
22768 taskfuncs.make_menu_task_clipboard(controller(), fobj)
22769 else:
22770 taskfuncs.remove_menu_task_clipboard(controller())
22772 if self.link_view and fobj:
22773 self.model.show_object(self, fobj, fattrib)
22776 if event.button == 3:
22777 # context menu
22778 self.timer.Stop()
22779 menu = self.toolbar.make_menu(True)
22781 if fobj:
22782 try:
22783 code_item = fobj._function.code_item
22784 except AttributeError:
22785 pass
22786 else:
22787 taskfuncs.make_menu_task_clipboard(controller(), fobj, menu, 500)
22788 action_filter = ("add", "edit", "extra")
22789 for c in context.Context.context_list:
22790 c = c.__class__(code_item)
22791 if c.make_browser_menu(menu, action_filter):
22792 break
22795 self.PopupMenu(menu.wxobj, (event.x,
22796 self.GetClientSizeTuple()[1] - event.y))
22799 </t>
22800 <t tx="mr7771.20060609152050.40">def _on_size(self, event):
22801 if self.canvas:
22802 self.canvas.SetSize(self.GetClientSizeTuple())
22803 </t>
22804 <t tx="mr7771.20060609152050.41">def _show_info(self):
22805 x, y = self.mouse_pos_data()
22806 if x is None: return
22807 widget = self.chart._widget_at(x, y)
22808 if widget:
22809 info = self.chart.get_tip(widget)
22810 if info:
22811 TipWindow.get().set_info(info, widget)
22812 </t>
22813 <t tx="mr7771.20060609152050.42">def mouse_pos_data(self):
22814 x, y = self.ScreenToClientXY(*wx.GetMousePosition())
22815 w, h = self.GetClientSizeTuple()
22816 if 0 &lt;= x &lt; w and 0 &lt;= y &lt; h:
22817 y = h - y
22818 return self.chart._trans_data.inverse_xy_tup((x, y))
22820 return None, None
22821 </t>
22822 <t tx="mr7771.20060609152050.43">_yscroll = 0
22823 _xscroll = 0
22824 def setup_scrolling(self):
22825 sdata = self.scroll_trans.get_bbox1()
22826 vlim = mtrans.transform_bbox(self.chart._trans_data, sdata)
22827 sview = self.scroll_trans.get_bbox2()
22829 width = _cint(vlim.width())
22830 height = _cint(-vlim.height())
22832 sview.intervalx().set_bounds(0, width)
22833 sview.intervaly().set_bounds(0, height)
22834 self.SetVirtualSize((width, height))
22836 xrate = self.show_horz_bar and 20 or 0
22837 yrate = self.show_vert_bar and 20 or 0
22839 vlim = self.chart._view_lim
22840 x, y = self.scroll_trans.xy_tup((vlim.xmin(), vlim.ymax()))
22841 self._xscroll = _cint(x / 20)
22842 self._yscroll = _cint(y / 20)
22843 self._scroll_adjustments = [xrate, yrate, 10+width/20, 10+height/20,
22844 self._xscroll, self._yscroll, True]
22846 self.SetScrollbars(*self._scroll_adjustments)
22847 self.AdjustScrollbars()
22848 self.EnableScrolling(False, False)
22849 </t>
22850 <t tx="mr7771.20060609152050.44">def _on_set_focus(self, event):
22851 self.has_focus = True
22852 self.toolbar.create_menus()
22853 self.chart._set_focused_on()
22854 self.draw()
22855 </t>
22856 <t tx="mr7771.20060609152050.45">def _on_kill_focus(self, event):
22857 self.has_focus = False
22858 self.chart._set_focused_off()
22859 self.draw()
22860 </t>
22861 <t tx="mr7771.20060609152050.46"> #controller().status_bar.SetStatusText("", 2)
22864 _last_data_bounds = (0, 0, 0, 0)
22865 _last_view_bounds = (0, 0, 1, 1)
22866 def update_state(self, push_view=False):
22867 if not self._is_ready: return
22869 def calc_scale(data, view):
22870 return (int(100 * float(data[2]) / (view[2] or 1.0)),\
22871 int(100 * float(data[3]) / (view[3] or 1.0)))
22873 result = False
22874 trans = self.chart._trans_data
22875 data_box = trans.get_bbox1()
22877 data_bounds = map(int, data_box.get_bounds())
22878 view_bounds = map(int, trans.get_bbox2().get_bounds())
22880 if self._last_data_bounds != data_bounds or \
22881 self._last_view_bounds != view_bounds:
22882 self.check_limits()
22883 data_bounds = map(int, data_box.get_bounds())
22884 last_scale = calc_scale(self._last_data_bounds,
22885 self._last_view_bounds)
22886 scale = calc_scale(data_bounds, view_bounds)
22887 if last_scale != scale:
22888 try:
22889 self.deferred(1000, self.chart._speed_up, 1024*1024*30)
22890 self.chart._clear_speed_cache()
22891 except AttributeError:
22892 pass
22894 self.draw()
22895 self.setup_scrolling()
22896 if push_view: self.toolbar.push_current()
22897 self._last_view_bounds = view_bounds
22898 self._last_data_bounds = data_bounds
22901 x, y = self.GetViewStart()
22902 if y != self._yscroll or x != self._xscroll:
22903 xt, yt = self.scroll_trans.inverse_xy_tup((x * 20, y * 20))
22904 if x != self._xscroll and self.show_horz_bar:
22905 self.chart._set_xlim(xt, xt + data_box.width())
22907 if y != self._yscroll and self.show_vert_bar:
22908 self.chart._set_ylim(yt - data_box.height(), yt)
22909 </t>
22910 <t tx="mr7771.20060609152050.47">def _on_idle(self, event):
22911 try:
22912 if self.has_focus: self.toolbar.refresh_buttons()
22913 self.update_state()
22914 except:
22915 pass
22916 </t>
22917 <t tx="mr7771.20060609152050.48">def show_object(self, fobj, attrib=None, caller=None):
22918 if not self.link_view: return
22919 widget = self.chart._find_widget(fobj)
22920 self.deferred(300, self._show_widget, widget, caller)
22921 </t>
22922 <t tx="mr7771.20060609152050.49">def _show_widget(self, widget, caller):
22923 if widget:
22924 if self.show_x_coord(caller):
22925 self.chart._widget_x_visible(widget)
22927 self.chart._widget_y_visible(widget)
22929 if self.mark_widget(widget):
22930 self._last_view_bounds = (0, 0, 1, 1) # force update
22931 self.update_state()
22932 </t>
22933 <t tx="mr7771.20060609152050.50">def show_x_coord(self, caller):
22934 return True
22935 </t>
22936 <t tx="mr7771.20060609152050.51">def accept_sibling(self, new_view):
22937 import editor
22938 if isinstance(new_view, editor.PlanEditorProxy):
22939 return navigator.SIBLING_BELOW
22941 import repview
22942 if isinstance(new_view, repview.ReportView):
22943 return navigator.SIBLING_BELOW
22945 if isinstance(new_view, ChartView):
22946 return navigator.SIBLING_BELOW
22948 return False
22949 </t>
22950 <t tx="mr7771.20060609152050.52">def draw(self):
22951 self.check_limits()
22952 self.canvas.draw()
22953 </t>
22954 <t tx="mr7771.20060609152050.53">
22957 class TimeViewManager(object):
22958 &lt;&lt; class TimeViewManager declarations &gt;&gt;
22959 @others
22960 </t>
22961 <t tx="mr7771.20060609152050.54">_managers = { }
22963 </t>
22964 <t tx="mr7771.20060609152050.55">def get_manager(view, chart_class):
22965 key = str(chart_class.sharex)
22966 if not key:
22967 key = chart_class.__name__
22969 manager = TimeViewManager._managers.get(key)
22970 if not manager:
22971 manager = TimeViewManager(key)
22972 manager._managers[key] = manager
22974 manager.register(view)
22975 return manager
22976 </t>
22977 <t tx="mr7771.20060609152050.56">get_manager = staticmethod(get_manager)
22979 def __init__(self, key):
22980 self.key = key
22981 self.views = []
22982 self.main_axes = None
22983 self.xmin = sys.maxint
22984 self.xmax = -sys.maxint
22985 </t>
22986 <t tx="mr7771.20060609152050.57">def register(self, view):
22987 self.views.append(view)
22988 </t>
22989 <t tx="mr7771.20060609152050.58">def unregister(self, view, refresh=True):
22990 del self.views[self.views.index(view)]
22991 if not self.views:
22992 del self._managers[self.key]
22993 elif refresh:
22994 self.update_siblings(view)
22995 </t>
22996 <t tx="mr7771.20060609152050.59">def update_siblings(self, caller_view):
22997 if not self.main_axes:
22998 self.main_axes = self.views[0].chart._share_axes
23000 if self.views[0] == caller_view:
23001 v = self.views[0]
23002 axes = v.chart._share_axes
23003 axes.unshare()
23005 show_scale = axes.time_axis.show_scale
23006 if getattr(v, "_show_scale", show_scale) != show_scale:
23007 axes.time_axis.show_scale = v._show_scale
23008 axes.update_time_axis()
23009 v.draw()
23011 v._current_show_scale = show_scale
23012 v.show_horz_bar = v.show_vert_bar
23013 self._update_scroll_info()
23014 return
23016 ctrl = controller()
23017 pos_views = map(lambda v: (ctrl.get_active_view_pos(v), v), self.views)
23018 pos_views.sort()
23020 first = pos_views[0][1]
23021 last = pos_views[-1][1]
23022 for p, v in pos_views:
23023 if not hasattr(v, "_show_scale"):
23024 v._show_scale = v.chart.show_scale
23026 axes = v.chart._share_axes
23027 axes.time_axis.show_scale = v == first
23028 axes.update_time_axis()
23030 v.show_horz_bar = v == last
23031 v.setup_scrolling()
23033 self._update_scroll_info()
23034 </t>
23035 <t tx="mr7771.20060609152050.60">def _update_scroll_info(self):
23036 for v in self.views:
23037 if v.show_horz_bar:
23038 interval = v.scroll_trans.get_bbox1().intervalx()
23039 interval.set_bounds(self.xmin, self.xmax)
23040 v.setup_scrolling()
23041 return
23042 </t>
23043 <t tx="mr7771.20060609152050.61">def update_xlim(self, xmin, xmax):
23044 self.xmin = min(self.xmin, xmin)
23045 self.xmax = max(self.xmax, xmax)
23046 </t>
23047 <t tx="mr7771.20060609152050.62">def shared(self):
23048 return self.main_axes
23049 </t>
23050 <t tx="mr7771.20060609152050.63">def get_sibling_pos(self, view):
23051 key = view.manager.key
23052 if key &lt; self.key:
23053 return navigator.SIBLING_ABOVE
23055 return navigator.SIBLING_BELOW
23056 </t>
23057 <t tx="mr7771.20060609152050.64">
23060 class TimeChartView(ChartView):
23061 @others
23062 </t>
23063 <t tx="mr7771.20060609152050.65">def __init__(self, parent, chart, model, title):
23064 self.manager = None
23065 ChartView.__init__(self, parent, chart, model, title)
23066 </t>
23067 <t tx="mr7771.20060609152050.66">def create_chart(self, chart):
23068 if self.manager: self.manager.unregister(self, self.show_horz_bar)
23069 self.manager = TimeViewManager.get_manager(self, chart)
23070 save_execute = controller().session.save_execute
23071 self.chart = save_execute(chart, self.figure,
23072 sharex=self.manager.shared())
23073 if not self.chart: self.chart = _ErrorChart(self.figure)
23074 </t>
23075 <t tx="mr7771.20060609152050.67">def scale_figure(self, trans):
23076 try:
23077 self.manager.update_siblings(self)
23078 except AttributeError:
23079 #can happen in windows if you click to fast
23080 #for shared charts.
23081 self.show_horz_bar = True # make sure the view can scroll
23083 ChartView.scale_figure(self, trans)
23084 </t>
23085 <t tx="mr7771.20060609152050.68">def Destroy(self):
23086 if self.manager:
23087 self.manager.unregister(self)
23088 self.manager = None
23090 controller().status_bar.SetStatusText("", 2)
23091 ChartView.Destroy(self)
23092 </t>
23093 <t tx="mr7771.20060609152050.69">def accept_sibling(self, new_view):
23094 import editor
23095 if isinstance(new_view, editor.PlanEditorProxy):
23096 return navigator.SIBLING_BELOW
23098 import repview
23099 if isinstance(new_view, repview.ReportView):
23100 return navigator.SIBLING_BELOW
23102 if isinstance(new_view, TimeChartView):
23103 return self.manager.get_sibling_pos(new_view)
23105 return False
23106 </t>
23107 <t tx="mr7771.20060609152050.70">def show_x_coord(self, caller):
23108 return caller not in self.manager.views
23109 </t>
23110 <t tx="mr7771.20060609152050.71">def init_scrolling(self):
23111 get_bbox_transform = mtrans.get_bbox_transform
23112 unit_bbox = mtrans.unit_bbox
23113 dlim = self.chart._data_lim.deepcopy()
23114 self.scroll_trans = get_bbox_transform(dlim, unit_bbox())
23115 dlim.intervaly().set_bounds(dlim.ymax(), dlim.ymin())
23116 self.manager.update_xlim(dlim.xmin() - dlim.width(),
23117 dlim.xmax() + dlim.width())
23118 </t>
23119 <t tx="mr7771.20060609154937">@language python
23120 &lt;&lt; Copyright &gt;&gt;
23122 Project Browser
23124 &lt;&lt; Imports &gt;&gt;
23126 _is_source_ = True
23127 _ = faces.plocale.get_gettext()
23129 @others
23130 </t>
23131 <t tx="mr7771.20060609154937.1">import wx
23132 import wx.stc
23133 import wx.gizmos
23134 import metapie.gui.pyeditor as pyeditor
23135 import itertools
23136 import faces.task as ftask
23137 import faces.resource as fresource
23138 import faces.observer as fobserver
23139 import locale
23140 import weakref
23141 import metapie.gui.pyeditor as pyeditor
23142 import context
23143 from metapie.gui.controller import controller, ResourceManager
23144 import faces.plocale
23145 from classifiers import *
23148 </t>
23149 <t tx="mr7771.20060609154937.2">class Browser(wx.gizmos.TreeListCtrl):
23150 &lt;&lt; declarations &gt;&gt;
23151 @others</t>
23152 <t tx="mr7771.20060609154937.3">img_size = (16, 16)
23153 left_sep = 4 # a work around for the wrong indent
23154 last_item = None
23155 </t>
23156 <t tx="mr7771.20060609154937.4">@doc
23157 displayed_eval_map:
23158 maps a project._idendity_() to the currently displayed evaluation data
23159 @code
23160 def __init__(self, parent):
23161 wx.gizmos.TreeListCtrl.__init__(self, parent, -1,
23162 style= wx.TR_SINGLE | \
23163 wx.TR_HAS_BUTTONS | \
23164 wx.TR_HIDE_ROOT | \
23165 wx.LC_NO_HEADER |\
23166 wx.TR_FULL_ROW_HIGHLIGHT)
23168 self.Hide()
23169 self.idle_item = None
23170 self.drag_item = None
23171 self.image_map = {}
23172 self.displayed_eval_map = {}
23173 self.init_tree()
23174 self.update_menus()
23176 </t>
23177 <t tx="mr7771.20060609154937.5">def get_image_index(self, path):
23178 try:
23179 return self.image_map[path]
23180 except KeyError:
23181 if path is None: return -1
23182 bmp = ResourceManager.load_bitmap(path, self.img_size)
23183 r = self.image_map[path] = self.image_list.Add(bmp)
23184 return r
23185 </t>
23186 <t tx="mr7771.20060609154937.7">def set_image(self, item, closed=None, opened=None):
23187 if closed:
23188 self.SetItemImage(item, self.get_image_index(closed),
23189 which=wx.TreeItemIcon_Normal)
23191 if opened:
23192 self.SetItemImage(item, self.get_image_index(opened),
23193 which=wx.TreeItemIcon_Expanded)
23194 </t>
23195 <t tx="mr7771.20060609154937.8">def get_item_font(self, item):
23196 font = self.GetItemFont(item)
23197 if not font.Ok(): font = self.GetFont()
23198 return font
23199 </t>
23200 <t tx="mr7771.20060609154937.10">def modify_item(self, tree_item):
23201 item = self.GetPyData(tree_item)
23202 if not item: return
23204 iclosed = None
23205 iopened = None
23207 if is_project(item) or is_task(item):
23208 &lt;&lt; make task &gt;&gt;
23210 elif is_resource(item):
23211 &lt;&lt; make resource &gt;&gt;
23213 elif is_observer(item):
23214 &lt;&lt; make observer &gt;&gt;
23216 if not iclosed:
23217 if item.obj_type == pyeditor.FUNCTION:
23218 iopened = iclosed = "exec16"
23219 elif item.obj_type == pyeditor.CLASS:
23220 iopened = iclosed = "class16"
23222 self.set_image(tree_item, iclosed, iopened)
23223 </t>
23224 <t tx="mr7771.20060609154937.11">def get_section(self, code_item):
23225 if is_import(code_item): return self.imports
23226 if is_resource(code_item): return self.resources
23227 if is_project(code_item): return self.tasks
23228 if is_evaluation(code_item): return self.evaluations
23229 if is_observer(code_item): return self.observers
23230 return self.miscellaneous</t>
23231 <t tx="mr7771.20060609154937.12">def refresh(self):
23232 #optimization the module has not changed the browser will not change
23233 editor = self.GetParent().editor
23234 self.idle_item = None
23235 self.Freeze()
23237 &lt;&lt; Delete children &gt;&gt;
23239 &lt;&lt; Declarations &gt;&gt;
23240 &lt;&lt; Insert Nodes &gt;&gt;
23242 self.Thaw()
23244 self.width = width + offset
23245 #start idleing at self.imports
23246 self.idle_item = self.imports
23248 item = editor.current_code_item()
23249 if item: self.update_selection(item)
23250 </t>
23251 <t tx="mr7771.20060609154937.14">def init_tree(self):
23252 img = self.get_image_index
23253 append = self.AppendItem
23254 self.Freeze()
23256 self.width = 0
23257 self.image_list = wx.ImageList(*self.img_size)
23258 self.get_image_index("move")
23259 self.AssignImageList(self.image_list)
23260 self.GetHeaderWindow().Hide()
23262 &lt;&lt; Create Columns &gt;&gt;
23263 &lt;&lt; Insert Header Nodes &gt;&gt;
23264 &lt;&lt; Set Header Node Fonts &gt;&gt;
23265 &lt;&lt; Set Header Node Titles &gt;&gt;
23267 self.imports = imports
23268 self.miscellaneous = miscellaneous
23269 self.resources = resources
23270 self.tasks = tasks
23271 self.evaluations = evaluations
23272 self.observers = observers
23274 self.SelectItem(imports)
23275 self.Thaw()
23277 </t>
23278 <t tx="mr7771.20060609154937.15">def calc_column_widths(self, item=None):
23279 item = item or self.GetFirstChild(self.tasks)[0]
23280 if not item.IsOk(): return
23282 hidden_window = self.GetHeaderWindow()
23283 extent = hidden_window.GetTextExtent
23285 hidden_window.SetFont(self.get_item_font(item))
23286 for i, cw in enumerate(self.col_width):
23287 width = extent(self.GetItemText(item, i + 2))[0]
23288 self.col_width[i] = max(cw, width + 10)
23289 </t>
23290 <t tx="mr7771.20060609154937.17">def _on_size(self, event):
23291 w, h = self.GetClientSize()
23292 self.GetMainWindow().SetDimensions(0, 0, w, h)
23293 self.SetColumnWidth(0, self.left_sep)
23295 if w &gt; self.width:
23296 self.SetColumnWidth(1, self.width)
23297 sw = self.width
23298 fit_col = 1
23299 fit_width = sw
23300 for i, cw in enumerate(self.col_width):
23301 sw += cw
23302 if sw &lt; w:
23303 fit_col = i + 1
23304 fit_width += cw
23305 else:
23306 self.SetColumnWidth(i + 2, 0)
23308 additional = (w - fit_width) / fit_col
23309 for i in range(fit_col):
23310 cw = self.col_width[i]
23311 self.SetColumnWidth(i + 2, cw + additional)
23312 sw += cw
23315 else:
23316 self.SetColumnWidth(1, w)
23317 for i in range(2, self.GetColumnCount()):
23318 self.SetColumnWidth(i, 0)
23319 </t>
23320 <t tx="mr7771.20060609154937.18">def _on_refresh(self, event):
23321 self.Refresh()
23322 </t>
23323 <t tx="mr7771.20060609154937.19">def _on_sel_changed(self, event):
23324 if not self.drag_item:
23325 self.select_item(event.GetItem())
23326 </t>
23327 <t tx="mr7771.20060609154937.20">def select_item(self, item):
23328 try:
23329 editor = self.GetParent().editor
23330 item = self.GetPyData(item)
23331 if editor.context.code_item is item: return
23333 line = item.get_line()
23334 editor.LineScroll(0, line - editor.GetFirstVisibleLine())
23335 editor.GotoPos(editor.PositionFromLine(line))
23336 wx.CallAfter(editor.SetFocus)
23337 except: pass
23338 </t>
23339 <t tx="mr7771.20060609154937.21">def update_selection(self, item):
23340 try:
23341 if not item.tree_obj:
23342 print "error no item.tree_obj", item.name
23343 return
23345 if item.tree_obj.IsOk():
23346 self.SelectItem(item.tree_obj)
23347 return
23348 except AttributeError: pass
23349 </t>
23350 <t tx="mr7771.20060609154937.22">def _on_right_click(self, event):
23351 menu = controller().make_menu()
23352 self.create_context_menu(menu, event.GetItem())
23353 if menu:
23354 self.PopupMenu(menu.wxobj, event.GetPoint())</t>
23355 <t tx="mr7771.20060609154937.23">def move_caret_to_end(self, treeitem):
23356 editor = self.GetParent().editor
23357 last = treeitem
23358 code_item = None
23359 while last.IsOk():
23360 code_item = self.GetPyData(last) or code_item
23361 last = self.GetLastChild(last)
23363 if code_item:
23364 line = code_item.get_last_line()
23365 else:
23366 #the section has no child ==&gt; set the caret before the first child
23367 #of the next section
23368 next = treeitem
23369 line = -1
23370 while True:
23371 next = self.GetNextSibling(next)
23372 if next.IsOk():
23373 child = self.GetFirstChild(next)
23374 if not child.IsOk(): continue
23375 code_item = self.GetPyData(child)
23376 if code_item:
23377 line = code_item.get_line() - 1
23378 break
23379 else:
23380 break
23382 if line &lt; 0: line = editor.GetLineCount() - 1
23384 editor.LineScroll(0, line - editor.GetFirstVisibleLine())
23385 editor.GotoLine(line)</t>
23386 <t tx="mr7771.20060609155425"></t>
23387 <t tx="mr7771.20060609155616"></t>
23388 <t tx="mr7771.20060609160624"></t>
23389 <t tx="mr7771.20060609165227.2">@
23390 Workarround for not implemented GetPrevVisible
23392 def get_prev_visible(self, item):
23393 before = item
23394 next = self.GetItemParent(item)
23395 while next.IsOk() and next != item:
23396 before = next
23397 next = self.GetNextVisible(next)
23399 if before == self.GetRootItem(): return item
23400 return before</t>
23401 <t tx="mr7771.20060609175617">def _on_idle(self, event):
23402 event.Skip()
23403 if not self.idle_item:
23404 return
23406 if not self.idle_item.IsOk():
23407 self.idle_item = None
23408 self.calc_column_widths()
23409 return
23411 if controller().is_processing():
23412 #dont't block another task
23413 return
23415 self.modify_item(self.idle_item)
23416 self.idle_item = self.GetNext(self.idle_item)
23417 event.RequestMore()
23419 if (self.idle_item and self.idle_item.IsOk()):
23420 code_item = self.GetPyData(self.idle_item)
23421 else:
23422 code_item = None
23424 </t>
23425 <t tx="mr7771.20060609222057">self.DeleteChildren(self.imports)
23426 self.DeleteChildren(self.miscellaneous)
23427 self.DeleteChildren(self.resources)
23428 self.DeleteChildren(self.tasks)
23429 self.DeleteChildren(self.evaluations)
23430 self.DeleteChildren(self.observers)</t>
23431 <t tx="mr7771.20060609222057.1">img = self.get_image_index
23432 append = self.AppendItem
23434 hidden_window = self.GetHeaderWindow()
23435 extent = hidden_window.GetTextExtent
23437 font = self.GetFont()
23438 hidden_window.SetFont(font)
23440 triangle = 12
23441 space = 6
23442 offset = self.GetIndent() + triangle \
23443 + 2 * space + self.img_size[0] \
23444 + self.left_sep
23446 depth_width = self.GetIndent() + triangle</t>
23447 <t tx="mr7771.20060609222057.2">hierachy = []
23448 width = 0
23450 for item in editor.code_items:
23451 item_line = item.get_line()
23453 while hierachy:
23454 parent, last_line = hierachy[-1]
23455 if last_line &gt; item.get_line(): break
23456 hierachy.pop()
23457 else:
23458 parent = self.get_section(item)
23460 child = append(parent, item.name)
23461 width = max(width, extent(item.name)[0] \
23462 + len(hierachy) * depth_width)
23464 item.tree_obj = child
23465 self.SetPyData(child, item)
23467 hierachy.append((child, item.get_last_line()))</t>
23468 <t tx="mr7771.20060609222452">import metapie.gui.pyeditor as pyeditor
23469 import faces.observer as fobserver
23470 import faces.resource as fresource
23471 import faces.task as ftask
23472 import faces.plocale
23473 import weakref
23474 import types
23475 import inspect
23476 from classifiers import *
23477 from metapie.gui import controller
23478 </t>
23479 <t tx="mr7771.20060609223152">class CTask(CStructureContext):
23480 editors = {}
23481 @others
23483 Context.context_list.append(CTask())
23484 </t>
23485 <t tx="mr7771.20060609223152.1">class CProjectDeclaration(CTask):
23486 editors = {}
23487 @others
23489 Context.context_list.append(CProjectDeclaration())
23490 </t>
23491 <t tx="mr7771.20060609223152.2">class CImport(Context):
23492 editors = {}
23493 @others
23495 Context.context_list.append(CImport())</t>
23496 <t tx="mr7771.20060609223152.3">self.AddColumn(_(""))
23497 self.AddColumn(_("Name"))
23498 self.AddColumn(_("Start"))
23499 self.AddColumn(_("End"))
23500 self.AddColumn(_("Length"))
23501 self.AddColumn(_("Effort"))
23502 self.SetMainColumn(1)
23503 self.col_width = [ 0 ] * (self.GetColumnCount() - 2)</t>
23504 <t tx="mr7771.20060609223152.4">root = self.AddRoot("root")
23505 imports = append(root, _("Imports"), img("import16"))
23506 miscellaneous = append(root, _("Miscellaneous"), img("misc16"))
23507 resources = append(root, _("Resources"), img("resources16"))
23508 tasks = append(root, _("Tasks"))
23509 evaluations = append(root, _("Evaluations"), img("evaluations16"))
23510 observers = append(root, _("Observers"), img("camera16"))#</t>
23511 <t tx="mr7771.20060609223152.5">header_font = self.get_item_font(imports)
23512 header_font.SetWeight(wx.FONTWEIGHT_BOLD)
23514 self.SetItemFont(imports, header_font)
23515 self.SetItemFont(miscellaneous, header_font)
23516 self.SetItemFont(resources, header_font)
23517 self.SetItemFont(tasks, header_font)
23518 self.SetItemFont(evaluations, header_font)
23519 self.SetItemFont(observers, header_font)</t>
23520 <t tx="mr7771.20060609223152.6">self.SetItemText(resources, _("Efficiency"), 2)
23521 self.calc_column_widths(resources)
23523 self.set_image(tasks, "tasks16", "tasks_open16")
23524 self.SetItemText(tasks, _("Start"), 2)
23525 self.SetItemText(tasks, _("End"), 3)
23526 self.SetItemText(tasks, _("Length"), 4)
23527 self.SetItemText(tasks, _("Effort"), 5)
23528 self.calc_column_widths(tasks)</t>
23529 <t tx="mr7771.20060609224238.1">def can_activate(self, editor, line, prev, next, inside):
23530 return is_import(prev) and line &lt;= prev.get_last_line() + 1 \
23531 or is_import(next) and line &gt;= next.get_line() - 1
23533 </t>
23534 <t tx="mr7771.20060609224238.2">class CMisc(Context):
23535 editor = None
23536 @others
23538 Context.default = CMisc()
23539 </t>
23540 <t tx="mr7771.20060609224238.3">class CResource(CStructureContext):
23541 editors = {}
23542 @others
23544 Context.context_list.append(CResource()) </t>
23545 <t tx="mr7771.20060609224238.4">class CEvaluation(Context):
23546 editors = {}
23548 @others
23550 Context.context_list.append(CEvaluation())
23551 </t>
23552 <t tx="mr7771.20060609224238.5">class CObserver(CStructureContext):
23553 editors = {}
23554 @others
23556 Context.context_list.append(CObserver())</t>
23557 <t tx="mr7771.20060609225045">class Context(object):
23558 context_list = []
23559 code_item = None
23560 editors = {} # attribute editors
23563 def __init__(self, code_item=None):
23564 self.code_item = code_item
23567 def __repr__(self):
23568 return self.__class__.__name__
23570 @others</t>
23571 <t tx="mr7771.20060609231152">@language python
23572 &lt;&lt; Copyright &gt;&gt;
23574 The Editor Control
23576 &lt;&lt; Imports &gt;&gt;
23577 &lt;&lt; Editor Completions &gt;&gt;
23579 _is_source_ = True
23580 _ = faces.plocale.get_gettext()
23582 @others
23583 </t>
23584 <t tx="mr7771.20060609231152.1">import wx
23585 import wx.lib.buttons as buttons
23586 import re
23587 import bisect
23588 import faces
23589 import faces.plocale
23590 import faces.task as ftask
23591 import faces.resource
23592 import faces.gui.snapshot
23593 import faces.generator
23594 import docparser
23595 import inspect
23596 import weakref
23597 import sys
23598 import itertools
23599 from classifiers import *
23600 import metapie.gui.pyeditor as pyeditor
23601 from context import Context, PTask
23602 from metapie.gui import controller, ResourceManager
23603 from dialogs import CalendarDialog
23605 </t>
23606 <t tx="mr7771.20060609231152.2">class SearchTool(pyeditor.SearchControl):
23607 @others
23608 </t>
23609 <t tx="mr7771.20060609231152.3">def __init__(self, parent, id, editor, forward=True):
23610 pyeditor.SearchControl.__init__(self, parent, id, editor, forward)
23611 top = controller().get_top_menu()
23612 edit_menu = top.make_menu(_("&amp;Edit"), pos=100)
23613 menu = lambda *args, **kw: edit_menu.make_item(self, *args, **kw)
23614 menu(_("&amp;Find\tCTRL-F"), self.menu_find_forward)
23615 menu(_("Find &amp;Backward\tCTRL-B"), self.menu_find_backward)
23616 self.SetToolTip(wx.ToolTip(_("Press Ctrl-F for next and Ctrl-B for "\
23617 "Prev\n and Ctrl-W for word")))
23618 </t>
23619 <t tx="mr7771.20060609231152.4">class _EditorBase(pyeditor.PythonEditCtrl):
23620 &lt;&lt; _parse_evaluation &gt;&gt;
23622 class Editor(DimmerStyler, _EditorBase):
23623 &lt;&lt; declarations &gt;&gt;
23624 @others
23625 </t>
23626 <t tx="mr7771.20060609231152.5">show_call_tips = True
23627 task_completions = None
23629 _patterns = _EditorBase._patterns \
23630 + tuple(map(lambda p: ("[a-zA-Z0-9_.]+[ ]*=[ ]*%s(" % p, \
23631 _EditorBase._parse_evaluation), \
23632 project_names))
23634 </t>
23635 <t tx="mr7771.20060609231152.7">def __init__(self, model, parent):
23636 _EditorBase.__init__(self, parent, wx.SUNKEN_BORDER)
23637 DimmerStyler.__init__(self)
23639 self.model = weakref.proxy(model)
23640 self.macro = None
23641 self.last_char = None
23642 self.should_be_corrected = False
23644 self.context = Context.default
23645 self.context.activate(self, 0, None, None, False)
23646 self.context_button = ContextButton(self)
23647 self.context_button.hide()
23649 self.MarkerDefine(2, wx.stc.STC_MARK_ROUNDRECT, "blue", "blue")
23650 self.SetMarginWidth(1, 12)
23651 self.SetMarginMask(1, 5)
23653 self.SetModEventMask(wx.stc.STC_MOD_INSERTTEXT | \
23654 wx.stc.STC_MOD_DELETETEXT | \
23655 wx.stc.STC_MOD_CHANGEFOLD | \
23656 wx.stc.STC_PERFORMED_UNDO | \
23657 wx.stc.STC_PERFORMED_USER | \
23658 wx.stc.STC_PERFORMED_REDO)
23660 &lt;&lt; Editor Adjustments &gt;&gt;
23661 &lt;&lt; Bind Events &gt;&gt;
23662 </t>
23663 <t tx="mr7771.20060609231152.9"></t>
23664 <t tx="mr7771.20060609231152.10">def _on_get_focus(self, event):
23665 event.Skip()
23667 try:
23668 parent = event.GetWindow().GetParent()
23669 except AttributeError:
23670 parent = None
23672 my_parent = self.GetParent()
23673 while parent:
23674 if parent is my_parent: return
23675 parent = parent.GetParent()
23677 self.set_menus()
23678 </t>
23679 <t tx="mr7771.20060609231152.11">__change_count = 0
23680 def _on_change(self, event):
23681 if not self.GetModify(): return
23683 mod_type = event.GetModificationType()
23684 line = self.GetCurrentLine()
23686 if mod_type &amp; (wx.stc.STC_MOD_INSERTTEXT |
23687 wx.stc.STC_MOD_DELETETEXT):
23688 &lt;&lt; make backup if necessary &gt;&gt;
23689 &lt;&lt; change the context button if neccessary &gt;&gt;
23690 self.move_context_button()
23692 if mod_type &amp; wx.stc.STC_MOD_CHANGEFOLD:
23693 line = self.GetCurrentLine()
23694 if line == event.GetLine():
23695 &lt;&lt; renew the context &gt;&gt;
23697 _EditorBase._on_change(self, event)
23698 self.check_modified()
23699 </t>
23700 <t tx="mr7771.20060609231152.13">def _on_find_close(self, event):
23701 event.GetDialog().Destroy()
23702 self.EndUndoAction()
23703 </t>
23704 <t tx="mr7771.20060609231152.14">def _on_find(self, event):
23705 findstr = event.GetFindString()
23706 replacestr = event.GetReplaceString()
23707 ev_type = event.GetEventType()
23708 flags = event.GetFlags()
23710 macro = self.macro
23712 self.macro = None
23713 self.__find(findstr, replacestr, ev_type, flags)
23714 self.macro = macro
23715 if macro:
23716 macro.add_command(self.__find, findstr,
23717 replacestr, ev_type, flags)
23718 </t>
23719 <t tx="mr7771.20060609231152.15">def _on_right_down(self, event):
23720 top = controller().get_top_menu()
23721 menu = top.make_menu(_("&amp;Edit"))
23722 self.PopupMenu(menu.wxobj, event.GetPosition())
23723 </t>
23724 <t tx="mr7771.20060609231152.16">def _on_new_char(self, event):
23725 key_ascii = unichr(event.GetKey())
23726 self.last_char = key_ascii
23727 _EditorBase._on_new_char(self, event)
23728 self.show_completion()
23729 </t>
23730 <t tx="mr7771.20060609231152.17">def _on_macro_notify(self, event):
23731 if self.macro:
23732 msg = event.GetMessage()
23733 if msg == 2170: # == REPLACE_SEL
23734 self.macro.add_command(self.smart_replace_selection,
23735 self.last_char)
23736 else:
23737 self.macro.add_command(self.CmdKeyExecute, msg)
23738 </t>
23739 <t tx="mr7771.20060609231152.18">def _on_insert_completion(self, event):
23740 start_pos = event.GetListType() - 1
23741 text = event.GetText()[start_pos:].replace(r"\n", "\n")
23742 cur_pos = self.GetCurrentPos()
23743 self.AddText(text.replace("|", ""))
23744 lines = len(text.split("\n"))
23745 line = self.LineFromPosition(cur_pos)
23747 cursor = text.rfind("|")
23748 if cursor &gt;= 0:
23749 self.GotoPos(cur_pos + cursor)
23751 for l in range(1, lines):
23752 self.autoindent(self.PositionFromLine(line + l), False)
23754 attrib = event.GetText()
23756 try:
23757 #if text has an = show the call tip for the assigned attribute
23758 attrib = attrib[:attrib.index("=")].strip()
23759 except ValueError:
23760 attrib = None
23762 self.show_call_tip(attrib=attrib)
23764 </t>
23765 <t tx="mr7771.20060609231152.19"></t>
23766 <t tx="mr7771.20060609231152.20">def menu_snapshot(self):
23767 module = controller().session.get_module(self.model.path)
23768 create_snapshot = faces.gui.snapshot.create
23769 recalc, import_name = create_snapshot(module, self.model.get_encoding())
23770 if import_name:
23771 imports = filter(lambda c: c.obj_type == pyeditor.IMPORT,
23772 self.code_items)
23773 if not imports:
23774 #don't know where to place the import statement
23775 #this case should never happen
23776 return
23778 line = imports[-1].get_last_line()
23779 self.InsertText(self.PositionFromLine(line),
23780 _("import %s #This module contains snapshots\n")\
23781 % import_name)
23782 self.sync_text()
23784 if recalc:
23785 controller().session.execute_plan()
23786 </t>
23787 <t tx="mr7771.20060609231152.22">def menu_insert_date(self):
23788 dlg = CalendarDialog(self)
23789 if dlg.ShowModal() == wx.ID_OK:
23790 date = dlg.cal.GetDate()
23791 self.ReplaceSelection('"%s"' % date.FormatDate())
23793 dlg.Destroy()
23794 </t>
23795 <t tx="mr7771.20060609231152.23">__comment_lines_pattern = re.compile(r'^#+', re.MULTILINE)
23796 __free_lines_pattern = re.compile(r'^', re.MULTILINE)
23798 def menu_uncomment_selection(self):
23799 text = self.GetSelectedText()
23800 text = self.__comment_lines_pattern.sub("", text)
23801 self.ReplaceSelection(text)
23802 </t>
23803 <t tx="mr7771.20060609231152.24">def menu_comment_selection(self):
23804 text = self.GetSelectedText()
23805 text = self.__free_lines_pattern.sub("#", text)
23806 self.ReplaceSelection(text)
23807 </t>
23808 <t tx="mr7771.20060609231152.25">def menu_find_forward(self):
23809 macro = controller().macro
23810 if macro: macro.pop()
23811 self.create_search(SearchTool)
23812 </t>
23813 <t tx="mr7771.20060609231152.26">def menu_find_backward(self):
23814 macro = controller().macro
23815 if macro: macro.pop()
23816 self.create_search(SearchTool, False)
23817 </t>
23818 <t tx="mr7771.20060609231152.27">def menu_replace(self):
23819 macro = controller().macro
23820 if macro: macro.pop()
23821 data = wx.FindReplaceData()
23822 data.SetFindString(self.GetSelectedText())
23823 dialog = wx.FindReplaceDialog(self, data, _("Replace"),
23824 wx.FR_REPLACEDIALOG)
23825 dialog.data = data
23826 dialog.Show(True)
23827 self.BeginUndoAction()
23828 </t>
23829 <t tx="mr7771.20060609231152.28">def menu_goto_line(self):
23830 dialog = wx.TextEntryDialog(self, _("Goto Line"), _("Goto Line"))
23831 if dialog.ShowModal() == wx.ID_OK:
23832 val = int(dialog.GetValue()) - 1
23833 self.GotoLine(val)
23834 self.SetFocus()
23836 dialog.Destroy()
23837 </t>
23838 <t tx="mr7771.20060609231152.29"></t>
23839 <t tx="mr7771.20060609231152.30">def no_record_call(self, function, *args):
23840 macro = self.macro
23841 self.macro = None
23842 result = function(*args)
23843 self.macro = macro
23844 return result
23845 </t>
23846 <t tx="mr7771.20060609231152.31">def start_macro(self):
23847 self.menu_macro_execute.enable(False)
23848 self.menu_macro_start.enable(False)
23849 self.menu_macro_stop.enable(True)
23850 ctrl = controller()
23851 ctrl.status_bar.SetStatusText(_("Recording..."), 1)
23852 self.macro = ctrl.start_recording()
23853 self.StartRecord()
23854 </t>
23855 <t tx="mr7771.20060609231152.32">def stop_macro(self):
23856 self.menu_macro_stop.enable(False)
23857 self.menu_macro_start.enable(True)
23858 self.menu_macro_execute.enable(True)
23859 ctrl = controller()
23860 ctrl.status_bar.SetStatusText("", 1)
23861 self.StopRecord()
23862 ctrl.stop_recording()
23863 </t>
23864 <t tx="mr7771.20060609231152.33">def execute_macro(self):
23865 if self.macro:
23866 if not self.macro.execute():
23867 self.macro = None
23868 self.menu_macro_execute.enable(False)
23869 </t>
23870 <t tx="mr7771.20060609231152.36">def __find(self, findstr, replacestr, ev_type, flags):
23871 sflags = 0
23873 if flags &amp; wx.FR_WHOLEWORD: sflags |= wx.stc.STC_FIND_WHOLEWORD
23874 if flags &amp; wx.FR_MATCHCASE: sflags |= wx.stc.STC_FIND_MATCHCASE
23876 utf8findstr = findstr.encode("utf-8", "ignore") # a bug in scincilla
23878 if ev_type == wx.wxEVT_COMMAND_FIND_REPLACE_ALL:
23879 self.BeginUndoAction()
23880 end = self.GetLength()
23881 start = self.FindText(0, end, findstr, sflags)
23882 while start &gt;= 0:
23883 self.GotoPos(start)
23884 self.SetSelectionEnd(start + len(utf8findstr))
23885 self.ReplaceSelection(replacestr)
23886 start = self.FindText(start + len(utf8findstr),
23887 end, findstr, sflags)
23889 self.EndUndoAction()
23890 return
23892 if flags &amp; wx.FR_DOWN:
23893 start = self.GetCurrentPos() + 1
23894 end = self.GetLength()
23895 else:
23896 start = self.GetSelectionStart() - 1
23897 end = 0
23899 pos = self.FindText(start, end, findstr, sflags)
23900 if pos &gt; 0:
23901 self.GotoPos(pos)
23902 self.SetSelectionEnd(pos + len(utf8findstr))
23903 if ev_type == wx.wxEVT_COMMAND_FIND_REPLACE:
23904 self.ReplaceSelection(replacestr)
23905 self.GotoPos(pos)
23906 self.SetSelectionEnd(pos + len(replacestr))
23907 </t>
23908 <t tx="mr7771.20060609231152.37">__last_module_id = 0
23909 def refresh(self, refresh_text=False):
23910 module = self.get_module()
23911 if not refresh_text:
23912 &lt;&lt; module settings &gt;&gt;
23913 return
23915 self.Freeze()
23916 self.unlisten()
23918 if self.AutoCompActive(): self.AutoCompCancel()
23919 model = self.model
23921 &lt;&lt; save current position &gt;&gt;
23922 &lt;&lt; create new document &gt;&gt;
23923 &lt;&lt; misc document settings &gt;&gt;
23924 &lt;&lt; module settings &gt;&gt;
23925 &lt;&lt; restore position &gt;&gt;
23927 self.check_context(line)
23928 self.listen()
23929 self.Thaw()
23930 </t>
23931 <t tx="mr7771.20060609231152.39">def inspect_indent_char(self, key):
23932 super_meth = _EditorBase.inspect_indent_char
23933 return self.no_record_call(super_meth, self, key)
23934 </t>
23935 <t tx="mr7771.20060609231152.42">def show_call_tip(self, obj=None, attrib=None):
23936 if not self.show_call_tips: return False
23938 &lt;&lt; calculate obj and attrib &gt;&gt;
23940 doc = self.get_doc_object(obj)
23941 doc = doc and doc.get_doc(attrib)
23942 if not doc:
23943 try:
23944 val = getattr(obj, attrib)
23945 except AttributeError:
23946 val = getattr(self.get_module(), attrib, None)
23948 if isinstance(val, (ftask.Task, PTask)):
23949 doc = 0, val.title
23950 else:
23951 doc = self.get_doc_object(val)
23952 doc = doc and doc.constructor(attrib)
23953 else:
23954 pass
23956 if doc:
23957 txt = doc[1].decode(self.model.get_encoding(), 'ignore')
23958 self.CallTipShow(self.GetCurrentPos(), txt)
23959 self.CallTipSetHighlight(0, doc[0])
23960 return True
23962 return False
23964 </t>
23965 <t tx="mr7771.20060609231152.43">def get_resource_completions(self, obj=None):
23966 return map(lambda r: (r, r), self.model.resources.keys())</t>
23967 <t tx="mr7771.20060609231152.44">def get_evaluation_completions(self, obj=None):
23968 return map(lambda kv: (kv[0], kv[0]), self.model.evaluations.iteritems())
23970 </t>
23971 <t tx="mr7771.20060609231152.45">def get_doc_object(self, obj):
23972 if not obj or isinstance(obj, (int, basestring)): return None
23974 parser = docparser.ClassDoc
23975 if inspect.isfunction(obj) or inspect.ismethod(obj):
23976 parser = docparser.FunctionDoc
23977 elif inspect.ismodule(obj):
23978 parser = docparser.ModuleDoc
23979 elif not isinstance(obj, type):
23980 try:
23981 obj = obj.__class__
23982 except AttributeError:
23983 pass
23985 id_ = id(obj)
23986 try:
23987 return self.__doc_cache[id_]
23988 except AttributeError:
23989 self.__doc_cache = { id_ : parser(obj) }
23990 except KeyError:
23991 self.__doc_cache[id_] = parser(obj)
23993 return self.__doc_cache[id_]</t>
23994 <t tx="mr7771.20060609231152.46">#caching values
23995 __completion_list = None
23996 __completion_dots = 0
23997 def show_completion(self, force=False):
23998 current = self.GetCurrentPos()
24000 text = self.get_word_at(current)
24001 auto_active = self.AutoCompActive()
24003 if not text and not force:
24004 if auto_active: self.AutoCompCancel()
24005 return
24007 &lt;&lt; check style &gt;&gt;
24009 dots = len(filter(lambda c: c == ".", text))
24010 if not auto_active or self.__completion_dots != dots:
24011 try:
24012 &lt;&lt; try to create dot completion list &gt;&gt;
24013 except ValueError:
24014 &lt;&lt; create non dot completion list &gt;&gt;
24016 self.__completion_dots = dots
24018 compl = self.__completion_list
24019 if compl is None: return
24020 if not compl:
24021 &lt;&lt; find an alternative completion list &gt;&gt;
24023 &lt;&lt; show list &gt;&gt;
24025 </t>
24026 <t tx="mr7771.20060609231152.49">def smart_replace_selection(self, text):
24027 self.ReplaceSelection(text)
24028 self.inspect_indent_char(text)
24029 </t>
24030 <t tx="mr7771.20060609232136">self.Bind(wx.stc.EVT_STC_USERLISTSELECTION, self._on_insert_completion)
24031 self.Bind(wx.stc.EVT_STC_MACRORECORD, self._on_macro_notify)
24032 self.Bind(wx.EVT_RIGHT_DOWN, self._on_right_down)
24033 self.Bind(wx.EVT_SET_FOCUS, self._on_get_focus)
24035 self.Bind(wx.EVT_COMMAND_FIND, self._on_find)
24036 self.Bind(wx.EVT_COMMAND_FIND_NEXT, self._on_find)
24037 self.Bind(wx.EVT_COMMAND_FIND_REPLACE, self._on_find)
24038 self.Bind(wx.EVT_COMMAND_FIND_REPLACE_ALL, self._on_find)
24039 self.Bind(wx.EVT_FIND_CLOSE, self._on_find_close)
24040 </t>
24041 <t tx="mr7771.20060609232136.1">self.AutoCompStops("(){}[]")
24042 self.AutoCompSetSeparator(ord("\t"))
24043 self.AutoCompSetIgnoreCase(0)
24044 self.AutoCompSetDropRestOfWord(1)
24045 self.AutoCompSetAutoHide(1)
24046 self.SetCaretLineVisible(True)</t>
24047 <t tx="mr7771.20060609235111">__pending_check_context = 0
24048 def _on_pos_changed(self, old, new):
24049 line = self.LineFromPosition(new)
24051 if self.LineFromPosition(old or 0) != line:
24052 def check_context():
24053 #enables fast scrolling without getting stuck
24054 self.__pending_check_context -= 1
24055 if self.__pending_check_context &gt; 0: return
24056 self.__pending_check_context = 0
24057 self.check_context(line)
24058 self.context.make_button(self.context_button,
24059 self.get_expression(line))
24060 self.move_context_button()
24062 self.__pending_check_context += 1
24063 wx.FutureCall(70, check_context)
24065 </t>
24066 <t tx="mr7771.20060610004423.1">def can_activate(self, editor, line, prev, next, inside):
24067 return is_resource(inside)
24068 </t>
24069 <t tx="mr7771.20060610005033"></t>
24070 <t tx="mr7771.20060610005033.1">def activate(self, editor, line, prev, next, inside):
24071 self.code_item = inside
24072 self.editor = editor
24073 if not prev:
24074 if next:
24075 return line &lt; next.get_line() - 1
24076 return True
24078 return False
24079 </t>
24080 <t tx="mr7771.20060610005033.6">def can_activate(self, editor, line, prev, next, inside):
24081 if is_task(inside):
24082 self.pseudo = PTask(inside)
24083 return True
24084 else:
24085 self.pseudo = None
24086 return False
24087 </t>
24088 <t tx="mr7771.20060610005713.1">def can_activate(self, editor, line, prev, next, inside):
24089 if is_project(inside):
24090 self.pseudo = PTask(inside)
24091 return True
24092 else:
24093 self.pseudo = None
24094 return False
24095 </t>
24096 <t tx="mr7771.20060613102529"></t>
24097 <t tx="mr7771.20060613111615">class CResourceOrTask(Context):
24098 @others
24100 Context.context_list.append(CResourceOrTask())</t>
24101 <t tx="mr7771.20060613111615.2">def can_activate(self, editor, line, prev, next, inside):
24102 if is_resource(inside): return False
24103 return not is_resource(next) \
24104 and (is_import(prev) \
24105 and line &gt; prev.get_last_line() + 1 \
24106 or is_resource(prev))</t>
24107 <t tx="mr7771.20060613174236">class CTaskOrEvaluation(Context):
24108 @others
24110 Context.context_list.append(CTaskOrEvaluation())</t>
24111 <t tx="mr7771.20060613174515.1">def can_activate(self, editor, line, prev, next, inside):
24112 if is_task(inside): return False
24113 return (is_task(prev) or is_project(prev)) \
24114 and not (is_task(next) or is_project(next))</t>
24115 <t tx="mr7771.20060613224409"></t>
24116 <t tx="mr7771.20060614090309">__last_attrib = None
24117 def check_context(self, line):
24118 prev, next = self.code_items_near(line)
24119 inside = self.code_item_at(line)
24120 ctrl = controller()
24122 last_code_item = self.context.code_item
24123 &lt;&lt; find and activate the current context &gt;&gt;
24124 update_siblings = False
24125 if last_code_item is not self.context.code_item:
24126 item = self.context.code_item
24127 &lt;&lt; update browser and refresh &gt;&gt;
24128 &lt;&lt; highlite context &gt;&gt;
24130 update_siblings = True
24131 self.__last_attrib = None
24133 &lt;&lt; calculate attribute name &gt;&gt;
24135 update_siblings += attrib_name != self.__last_attrib
24136 if update_siblings:
24137 &lt;&lt; update my siblings &gt;&gt;
24138 </t>
24139 <t tx="mr7771.20060614114501">#no completion inside strings an comments
24140 style = self.GetStyleAt(current)
24141 if style in (wx.stc.STC_P_TRIPLEDOUBLE,
24142 wx.stc.STC_P_TRIPLE,
24143 wx.stc.STC_P_STRING,
24144 wx.stc.STC_P_COMMENTLINE,
24145 wx.stc.STC_P_COMMENTBLOCK):
24146 return</t>
24147 <t tx="mr7771.20060614120349">def get_word_at(self, pos=None, complete=False):
24148 pos = pos or self.GetCurrentPos()
24150 #get start of dot sequence
24151 start = self.WordStartPosition(pos, 1)
24152 char_before = chr(self.GetCharAt(start - 1))
24153 while(start &gt; 0 and chr(self.GetCharAt(start - 1)) == "."):
24154 start = self.WordStartPosition(start - 1, 1)
24156 prev_word_start = self.WordStartPosition(start - 1, 1)
24157 if self.GetTextRange(prev_word_start, start).startswith("def"):
24158 #a def will be included despite the space to allow
24159 #the autocomplete of functions
24160 start = prev_word_start
24162 if complete:
24163 return self.GetTextRange(start, self.WordEndPosition(pos, 1))
24164 else:
24165 return self.GetTextRange(start, pos)
24166 </t>
24167 <t tx="mr7771.20060614121509">line = self.LineFromPosition(current)
24168 start = self.PositionFromLine(line)
24169 subname = self.GetTextRange(start, current)
24170 try:
24171 subname = subname[:subname.index("=")].strip()
24172 except ValueError:
24173 try:
24174 subname = subname[:subname.index("(")].strip()
24175 except ValueError:
24176 subname = None
24178 if subname:
24179 self.__completion_list = self.context.get_sub_completion_list(subname)
24180 else:
24181 self.__completion_list = self.context.get_main_completion_list()
24183 </t>
24184 <t tx="mr7771.20060614121949">try:
24185 # cut of last token of dot sequence
24186 text = text[text.rindex(".") + 1:]
24187 except ValueError: pass
24189 compl = filter(lambda c: c[0].startswith(text), compl)
24190 if not compl: return
24192 if len(compl) == 1 and text == compl[0][0]:
24193 try:
24194 self.show_call_tip()
24195 except AttributeError: pass
24196 return
24198 compl = [ c[1].replace("\n", r"\n") for c in compl ]
24199 compl.sort()
24200 self.UserListShow(len(text) + 1, "\t".join(compl))
24201 </t>
24202 <t tx="mr7771.20060614124044"></t>
24203 <t tx="mr7771.20060614124044.1">class CStructureContext(Context):
24204 @others</t>
24205 <t tx="mr7771.20060614124118"> @others</t>
24206 <t tx="mr7771.20060614124301">def get_main_completion_list(self):
24207 obj = self.get_object()
24208 return filter(lambda kv: kv[0][0] != "#",\
24209 obj.__attrib_completions__.items())
24210 </t>
24211 <t tx="mr7771.20060614124301.1"></t>
24212 <t tx="mr7771.20060614124751"> @others</t>
24213 <t tx="mr7771.20060614124751.1">def get_default_pseudo(self):
24214 return None</t>
24215 <t tx="mr7771.20060614124751.2"></t>
24216 <t tx="mr7771.20060614124952">def get_sub_completion_list(self, name):
24217 obj = self.get_object()
24218 compl_dir = obj.__attrib_completions__
24219 try:
24220 compl = compl_dir["#%s" % name]
24221 except KeyError:
24222 return []
24223 else:
24224 if isinstance(compl, basestring):
24225 compl = getattr(self.code_item.editor, compl)(obj)
24226 else:
24227 compl = compl.items()
24229 return compl
24231 </t>
24232 <t tx="mr7771.20060614134507"></t>
24233 <t tx="mr7771.20060614134507.1">def get_default_pseudo(self):
24234 return fresource.Resource</t>
24235 <t tx="mr7771.20060614140603">@language python
24236 &lt;&lt; Copyright &gt;&gt;
24238 Codeitem classifiers.
24240 &lt;&lt; Imports &gt;&gt;
24242 __all__ = ("is_task", "is_resource", "is_observer", \
24243 "is_project", "is_evaluation", "is_import",\
24244 "get_resource_base", "get_observer_base",\
24245 "is_observer_func", "EVALUATION")
24247 _is_source_ = True
24249 @others</t>
24250 <t tx="mr7771.20060614140603.1">import faces.task as ftask
24251 import faces.resource as fresource
24252 import faces.observer as fobserver
24253 import metapie.gui.pyeditor as pyeditor
24254 </t>
24255 <t tx="mr7771.20060614140603.2">def is_task(item):
24256 if not item: return False
24257 try:
24258 return isinstance(item.obj, ftask.Task) \
24259 and not isinstance(item.obj, ftask._ProjectBase)
24260 except AttributeError:
24261 if item.obj_type == pyeditor.FUNCTION and not item.get_args():
24262 parent = item.get_parent()
24263 return is_task(parent) or is_project(parent)
24265 return False
24266 </t>
24267 <t tx="mr7771.20060614141538">def is_resource(item):
24268 try:
24269 return isinstance(item.obj, fresource._MetaResource)
24270 except AttributeError:
24271 return bool(get_resource_base(item))
24272 return False
24275 def get_resource_base(item):
24276 if not item or item.obj_type != pyeditor.CLASS: return None
24277 module = item.editor.get_module()
24278 for base in item.get_args():
24279 try:
24280 cls = eval("module.%s" % base)
24281 if isinstance(cls, fresource._MetaResource):
24282 return cls
24283 except: pass
24284 return None
24285 </t>
24286 <t tx="mr7771.20060614141538.1">
24287 def _sandwich(func):
24288 def save(*args):
24289 try:
24290 return func(*args)
24291 except AttributeError:
24292 return False
24294 return save
24297 EVALUATION = pyeditor.IMPORT + 1
24298 is_project = _sandwich(lambda i: i.obj_type != EVALUATION \
24299 and isinstance(i.obj, ftask._ProjectBase))
24300 is_evaluation = _sandwich(lambda i: i.obj_type == EVALUATION)
24301 is_import = _sandwich(lambda i: i.obj_type == pyeditor.IMPORT)
24303 del _sandwich
24304 </t>
24305 <t tx="mr7771.20060614141538.2">def get_module(self):
24306 return controller().session.get_module(self.model.path)
24307 </t>
24308 <t tx="mr7771.20060614142353">def is_observer_func(item):
24309 try:
24310 if item.obj_type != pyeditor.FUNCTION: return False
24311 while item.obj_type == pyeditor.FUNCTION:
24312 item = item.get_parent()
24313 except AttributeError:
24314 return False
24316 return is_observer(item)
24319 def is_observer(item):
24320 try:
24321 return issubclass(item.obj, fobserver.Observer)
24322 except AttributeError:
24323 return bool(get_observer_base(item))
24325 except TypeError:
24326 return False
24329 def get_observer_base(item):
24330 if not item or item.obj_type != pyeditor.CLASS: return None
24331 module = item.editor.get_module()
24332 for base in item.get_args():
24333 try:
24334 cls = eval("module.%s" % base)
24335 if issubclass(cls, fobserver.Observer):
24336 return cls
24337 except: pass
24338 return None
24339 </t>
24340 <t tx="mr7771.20060614145216">try:
24341 task = item.obj
24342 except AttributeError:
24343 if item.has_children():
24344 iclosed = "folderstar16"
24345 iopened = "folder_openstar16"
24346 else:
24347 iopened = iclosed = "leafstar16"
24348 else:
24349 if item.has_children():
24350 iclosed = "folder16"
24351 iopened = "folder_open16"
24352 else:
24353 iopened = iclosed = "leaf16"
24355 task = self.get_display_eval_data(task)
24356 str_obj = task.to_string
24357 self.SetItemText(tree_item, str_obj.start, 2)
24358 self.SetItemText(tree_item, str_obj.end, 3)
24359 self.SetItemText(tree_item, str_obj.length, 4)
24360 self.SetItemText(tree_item, str_obj.effort, 5)
24362 </t>
24363 <t tx="mr7771.20060614145216.1">try:
24364 self.SetItemText(tree_item,
24365 locale.format("%.2f", item.obj.efficiency),
24367 iclosed = item.obj.__type_image__
24368 except AttributeError:
24369 iclosed = get_resource_base(item).__type_image__</t>
24370 <t tx="mr7771.20060614150422">try:
24371 iclosed = item.obj.__type_image__
24372 except AttributeError:
24373 iclosed = get_observer_base(item).__type_image__</t>
24374 <t tx="mr7771.20060614203356">def activate(self, editor, line, prev, next, inside):
24376 try to activate the context
24378 if self.can_activate(editor, line, prev, next, inside):
24379 self.code_item = inside
24380 return True
24381 else:
24382 self.code_item = None
24383 return False</t>
24384 <t tx="mr7771.20060614203713"></t>
24385 <t tx="mr7771.20060614203713.1">def can_activate(self, editor, line, prev, next, inside):
24386 return is_observer(inside)
24387 </t>
24388 <t tx="mr7771.20060614203713.2">def get_default_pseudo(self):
24389 return get_observer_pseudo(self.code_item)
24390 </t>
24391 <t tx="mr7771.20060616091420">def make_attrib_list(self, obj):
24392 def function_mapper(name):
24393 attr = getattr(obj, name, None)
24394 if not callable(attr): return name
24395 return getattr(attr, "__call_completion__", name)
24397 try:
24398 attrlist = obj.__all__
24399 except AttributeError:
24400 attrlist = dir(obj)
24402 return map(lambda x: (x, function_mapper(x)), \
24403 filter(lambda n: n[0] != "_", attrlist or ()))</t>
24404 <t tx="mr7771.20060616091420.1">def get_session_completions(self, obj=None):
24405 module = self.get_module()
24406 try:
24407 return module.__attrib_completions__
24408 except AttributeError:
24409 return self.make_attrib_list(module)
24412 </t>
24413 </tnodes>
24414 </leo_file>