Merge lp:~nico-inattendu/luciole/dev_nico into lp:luciole/0.7
- dev_nico
- Merge into main
Proposed by
NicoInattendu
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~nico-inattendu/luciole/dev_nico |
Merge into: | lp:luciole/0.7 |
Diff against target: | None lines |
To merge this branch: | bzr merge lp:~nico-inattendu/luciole/dev_nico |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
NicoInattendu | Approve | ||
Review via email: mp+5494@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
NicoInattendu (nico-inattendu) wrote : | # |
Revision history for this message
NicoInattendu (nico-inattendu) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'Makefile' |
2 | --- Makefile 2009-03-30 22:17:30 +0000 |
3 | +++ Makefile 2009-04-13 20:10:28 +0000 |
4 | @@ -73,7 +73,7 @@ |
5 | mkdir -p $(DESTDIR)$(PREFIX)$(LIBDIR)/luciole |
6 | mkdir -p $(DESTDIR)$(PREFIX)$(LIBDIR)/luciole/lucioLib |
7 | mkdir -p $(DESTDIR)$(PREFIX)$(LIBDIR)/luciole/lucioLib/lucioExport |
8 | - mkdir -p $(DESTDIR)$(PREFIX)$(LIBDIR)/luciole/lucioLib/lucioImageCapture |
9 | + mkdir -p $(DESTDIR)$(PREFIX)$(LIBDIR)/luciole/lucioLib/gui |
10 | mkdir -p $(DESTDIR)$(PREFIX)$(LIBDIR)/luciole/lucioLib/lucioWebCamDetect |
11 | mkdir -p $(DESTDIR)$(PREFIX)/share/ |
12 | mkdir -p $(DESTDIR)$(PREFIX)/share/pixmaps |
13 | @@ -88,13 +88,14 @@ |
14 | install -m 644 $(CURDIR)/$(SOURCE_DIR)luciole.py $(DESTDIR)$(PREFIX)$(LIBDIR)/luciole |
15 | install -m 644 $(CURDIR)/$(SOURCE_DIR)_version.py $(DESTDIR)$(PREFIX)$(LIBDIR)/luciole |
16 | install -m 644 $(CURDIR)/$(SOURCE_DIR)images/luciole.glade $(DESTDIR)$(PREFIX)/share/luciole/images |
17 | + install -m 644 $(CURDIR)/$(SOURCE_DIR)images/luciole.xml $(DESTDIR)$(PREFIX)/share/luciole/images |
18 | install -m 644 $(CURDIR)/$(SOURCE_DIR)images/*.png $(DESTDIR)$(PREFIX)/share/luciole/images |
19 | install -m 644 $(CURDIR)/$(SOURCE_DIR)lucioLib/*.py $(DESTDIR)$(PREFIX)$(LIBDIR)/luciole/lucioLib/ |
20 | -install -m 644 $(CURDIR)/$(SOURCE_DIR)lucioLib/*.py[co] $(DESTDIR)$(PREFIX)$(LIBDIR)/luciole/lucioLib/ |
21 | install -m 644 $(CURDIR)/$(SOURCE_DIR)lucioLib/lucioExport/*.py $(DESTDIR)$(PREFIX)$(LIBDIR)/luciole/lucioLib/lucioExport |
22 | -install -m 644 $(CURDIR)/$(SOURCE_DIR)lucioLib/lucioExport/*.py[co] $(DESTDIR)$(PREFIX)$(LIBDIR)/luciole/lucioLib/lucioExport |
23 | - install -m 644 $(CURDIR)/$(SOURCE_DIR)lucioLib/lucioImageCapture/*.py $(DESTDIR)$(PREFIX)$(LIBDIR)/luciole/lucioLib/lucioImageCapture |
24 | - -install -m 644 $(CURDIR)/$(SOURCE_DIR)lucioLib/lucioImageCapture/*.py[co] $(DESTDIR)$(PREFIX)$(LIBDIR)/luciole/lucioLib/lucioImageCapture |
25 | + install -m 644 $(CURDIR)/$(SOURCE_DIR)lucioLib/gui/*.py $(DESTDIR)$(PREFIX)$(LIBDIR)/luciole/lucioLib/gui |
26 | + -install -m 644 $(CURDIR)/$(SOURCE_DIR)lucioLib/gui/*.py[co] $(DESTDIR)$(PREFIX)$(LIBDIR)/luciole/lucioLib/gui |
27 | install -m 644 $(CURDIR)/$(SOURCE_DIR)lucioLib/lucioWebCamDetect/*.py $(DESTDIR)$(PREFIX)$(LIBDIR)/luciole/lucioLib/lucioWebCamDetect |
28 | -install -m 644 $(CURDIR)/$(SOURCE_DIR)lucioLib/lucioWebCamDetect/*.py[co] $(DESTDIR)$(PREFIX)$(LIBDIR)/luciole/lucioLib/lucioWebCamDetect |
29 | install -m 644 $(CURDIR)/$(SOURCE_DIR)templates/*.xml $(DESTDIR)$(PREFIX)/share/luciole/templates |
30 | |
31 | === modified file '_version.py' |
32 | --- _version.py 2009-03-08 18:06:41 +0000 |
33 | +++ _version.py 2009-04-13 19:42:11 +0000 |
34 | @@ -1,36 +1,15 @@ |
35 | #!/usr/bin/env python |
36 | -# |
37 | -# |
38 | -# Copyright Nicolas Bertrand (nico@inattendu.org), 2009 |
39 | -# |
40 | -# This file is part of Luciole. |
41 | -# |
42 | -# Luciole is free software: you can redistribute it and/or modify |
43 | -# it under the terms of the GNU General Public License as published by |
44 | -# the Free Software Foundation, either version 3 of the License, or |
45 | -# (at your option) any later version. |
46 | -# |
47 | -# Luciole is distributed in the hope that it will be useful, |
48 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
49 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
50 | -# GNU General Public License for more details. |
51 | -# |
52 | -# You should have received a copy of the GNU General Public License |
53 | -# along with Luciole. If not, see <http://www.gnu.org/licenses/>. |
54 | -# |
55 | -# |
56 | - |
57 | """This file is automatically generated by generate_version_info |
58 | It uses the current working tree to determine the revision. |
59 | So don't edit it. :) |
60 | """ |
61 | |
62 | -version_info = {'branch_nick': u'luciole-0.6.1', |
63 | - 'build_date': '2009-01-04 23:45:46 +0100', |
64 | +version_info = {'branch_nick': u'dev_nico', |
65 | + 'build_date': '2009-04-13 21:40:48 +0200', |
66 | 'clean': None, |
67 | - 'date': '2009-01-04 23:42:58 +0100', |
68 | - 'revision_id': 'nico@inattendu.org-20090104224258-d8qkwnr6766whnn3', |
69 | - 'revno': 82} |
70 | + 'date': '2009-04-13 21:21:49 +0200', |
71 | + 'revision_id': 'nico@inattendu.org-20090413192149-hydd2h9a4p21pnbc', |
72 | + 'revno': 14} |
73 | |
74 | revisions = {} |
75 | |
76 | |
77 | === modified file 'images/luciole.glade' |
78 | --- images/luciole.glade 2009-04-10 20:10:44 +0000 |
79 | +++ images/luciole.glade 2009-04-13 19:42:11 +0000 |
80 | @@ -1,8 +1,10 @@ |
81 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> |
82 | <!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> |
83 | -<!--Generated with glade3 3.4.5 on Fri Apr 10 22:06:52 2009 --> |
84 | +<!--Generated with glade3 3.4.5 on Mon Apr 13 21:29:08 2009 --> |
85 | <glade-interface> |
86 | <widget class="GtkWindow" id="window1"> |
87 | + <signal name="delete_event" handler="on_window1_delete_event"/> |
88 | + <signal name="destroy_event" handler="on_window1_destroy_event"/> |
89 | <child> |
90 | <widget class="GtkVBox" id="vbox1"> |
91 | <property name="visible">True</property> |
92 | @@ -36,6 +38,53 @@ |
93 | </widget> |
94 | </child> |
95 | <child> |
96 | + <widget class="GtkMenuItem" id="menu_file_open_recent"> |
97 | + <property name="visible">True</property> |
98 | + <property name="label" translatable="yes">Open recent</property> |
99 | + <property name="use_underline">True</property> |
100 | + <child> |
101 | + <widget class="GtkMenu" id="menu_test"> |
102 | + <property name="visible">True</property> |
103 | + <child> |
104 | + <widget class="GtkMenuItem" id="recent1"> |
105 | + <property name="visible">True</property> |
106 | + <property name="label" translatable="yes">project1</property> |
107 | + <property name="use_underline">True</property> |
108 | + </widget> |
109 | + </child> |
110 | + <child> |
111 | + <widget class="GtkMenuItem" id="recent2"> |
112 | + <property name="visible">True</property> |
113 | + <property name="label" translatable="yes">project2</property> |
114 | + <property name="use_underline">True</property> |
115 | + </widget> |
116 | + </child> |
117 | + <child> |
118 | + <widget class="GtkMenuItem" id="recent3"> |
119 | + <property name="visible">True</property> |
120 | + <property name="label" translatable="yes">project3</property> |
121 | + <property name="use_underline">True</property> |
122 | + </widget> |
123 | + </child> |
124 | + <child> |
125 | + <widget class="GtkMenuItem" id="recent4"> |
126 | + <property name="visible">True</property> |
127 | + <property name="label" translatable="yes">project4</property> |
128 | + <property name="use_underline">True</property> |
129 | + </widget> |
130 | + </child> |
131 | + <child> |
132 | + <widget class="GtkMenuItem" id="recent5"> |
133 | + <property name="visible">True</property> |
134 | + <property name="label" translatable="yes">project5</property> |
135 | + <property name="use_underline">True</property> |
136 | + </widget> |
137 | + </child> |
138 | + </widget> |
139 | + </child> |
140 | + </widget> |
141 | + </child> |
142 | + <child> |
143 | <widget class="GtkImageMenuItem" id="file_save"> |
144 | <property name="visible">True</property> |
145 | <property name="label" translatable="yes">gtk-save</property> |
146 | @@ -115,54 +164,30 @@ |
147 | </widget> |
148 | </child> |
149 | <child> |
150 | - <widget class="GtkMenuItem" id="menuitem2"> |
151 | - <property name="visible">True</property> |
152 | - <property name="label" translatable="yes">_Edit</property> |
153 | - <property name="use_underline">True</property> |
154 | - <child> |
155 | - <widget class="GtkMenu" id="menu2"> |
156 | - <property name="visible">True</property> |
157 | - <child> |
158 | - <widget class="GtkImageMenuItem" id="imagemenuitem6"> |
159 | - <property name="visible">True</property> |
160 | - <property name="label" translatable="yes">gtk-cut</property> |
161 | - <property name="use_underline">True</property> |
162 | - <property name="use_stock">True</property> |
163 | - </widget> |
164 | - </child> |
165 | - <child> |
166 | - <widget class="GtkImageMenuItem" id="imagemenuitem7"> |
167 | - <property name="visible">True</property> |
168 | - <property name="label" translatable="yes">gtk-copy</property> |
169 | - <property name="use_underline">True</property> |
170 | - <property name="use_stock">True</property> |
171 | - </widget> |
172 | - </child> |
173 | - <child> |
174 | - <widget class="GtkImageMenuItem" id="imagemenuitem8"> |
175 | - <property name="visible">True</property> |
176 | - <property name="label" translatable="yes">gtk-paste</property> |
177 | - <property name="use_underline">True</property> |
178 | - <property name="use_stock">True</property> |
179 | - </widget> |
180 | - </child> |
181 | - <child> |
182 | - <widget class="GtkImageMenuItem" id="imagemenuitem9"> |
183 | - <property name="visible">True</property> |
184 | - <property name="label" translatable="yes">gtk-delete</property> |
185 | - <property name="use_underline">True</property> |
186 | - <property name="use_stock">True</property> |
187 | - </widget> |
188 | - </child> |
189 | - </widget> |
190 | - </child> |
191 | - </widget> |
192 | - </child> |
193 | - <child> |
194 | <widget class="GtkMenuItem" id="menuitem3"> |
195 | <property name="visible">True</property> |
196 | <property name="label" translatable="yes">_View</property> |
197 | <property name="use_underline">True</property> |
198 | + <child> |
199 | + <widget class="GtkMenu" id="menu4"> |
200 | + <property name="visible">True</property> |
201 | + <child> |
202 | + <widget class="GtkImageMenuItem" id="view_project"> |
203 | + <property name="visible">True</property> |
204 | + <property name="tooltip" translatable="yes">Project Properties</property> |
205 | + <property name="label" translatable="yes">Project Properties</property> |
206 | + <property name="use_underline">True</property> |
207 | + <signal name="activate" handler="on_view_project_activate"/> |
208 | + <child internal-child="image"> |
209 | + <widget class="GtkImage" id="menu-item-image3"> |
210 | + <property name="visible">True</property> |
211 | + <property name="stock">gtk-properties</property> |
212 | + </widget> |
213 | + </child> |
214 | + </widget> |
215 | + </child> |
216 | + </widget> |
217 | + </child> |
218 | </widget> |
219 | </child> |
220 | <child> |
221 | @@ -174,11 +199,13 @@ |
222 | <widget class="GtkMenu" id="menu3"> |
223 | <property name="visible">True</property> |
224 | <child> |
225 | - <widget class="GtkImageMenuItem" id="imagemenuitem10"> |
226 | + <widget class="GtkImageMenuItem" id="help_about"> |
227 | <property name="visible">True</property> |
228 | + <property name="tooltip" translatable="yes">About</property> |
229 | <property name="label" translatable="yes">gtk-about</property> |
230 | <property name="use_underline">True</property> |
231 | <property name="use_stock">True</property> |
232 | + <signal name="activate" handler="on_help_about_activate"/> |
233 | </widget> |
234 | </child> |
235 | </widget> |
236 | @@ -230,184 +257,191 @@ |
237 | </packing> |
238 | </child> |
239 | <child> |
240 | - <widget class="GtkHBox" id="hbox_acquisition"> |
241 | - <property name="height_request">51</property> |
242 | + <widget class="GtkAspectFrame" id="aspectframe2"> |
243 | <property name="visible">True</property> |
244 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
245 | - <child> |
246 | - <widget class="GtkFixed" id="fixed8"> |
247 | - <property name="width_request">20</property> |
248 | - <property name="visible">True</property> |
249 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
250 | - </widget> |
251 | - </child> |
252 | - <child> |
253 | - <widget class="GtkToggleButton" id="acquisition_button"> |
254 | - <property name="width_request">56</property> |
255 | - <property name="height_request">46</property> |
256 | - <property name="visible">True</property> |
257 | - <property name="can_focus">True</property> |
258 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
259 | - <property name="has_tooltip">True</property> |
260 | - <property name="tooltip" translatable="yes">Activate/Deactivate camera preview</property> |
261 | - <property name="focus_on_click">False</property> |
262 | - <property name="response_id">0</property> |
263 | - <signal name="toggled" handler="on_acquisition_button_toggled"/> |
264 | - <child> |
265 | - <widget class="GtkImage" id="acquisition_button_image"> |
266 | - <property name="visible">True</property> |
267 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
268 | + <property name="label_xalign">0</property> |
269 | + <property name="shadow_type">GTK_SHADOW_NONE</property> |
270 | + <child> |
271 | + <widget class="GtkHBox" id="hbox_acquisition"> |
272 | + <property name="height_request">51</property> |
273 | + <property name="visible">True</property> |
274 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
275 | + <child> |
276 | + <widget class="GtkFixed" id="fixed8"> |
277 | + <property name="width_request">20</property> |
278 | + <property name="visible">True</property> |
279 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
280 | + </widget> |
281 | + </child> |
282 | + <child> |
283 | + <widget class="GtkToggleButton" id="acquisition_button"> |
284 | + <property name="width_request">56</property> |
285 | + <property name="height_request">46</property> |
286 | + <property name="visible">True</property> |
287 | + <property name="can_focus">True</property> |
288 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
289 | + <property name="has_tooltip">True</property> |
290 | <property name="tooltip" translatable="yes">Activate/Deactivate camera preview</property> |
291 | - <property name="pixbuf">Luciole-dodo.png</property> |
292 | - </widget> |
293 | - </child> |
294 | - </widget> |
295 | - <packing> |
296 | - <property name="expand">False</property> |
297 | - <property name="fill">False</property> |
298 | - <property name="position">1</property> |
299 | - </packing> |
300 | - </child> |
301 | - <child> |
302 | - <widget class="GtkFixed" id="fixed15"> |
303 | - <property name="width_request">20</property> |
304 | - <property name="visible">True</property> |
305 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
306 | - </widget> |
307 | - <packing> |
308 | - <property name="position">2</property> |
309 | - </packing> |
310 | - </child> |
311 | - <child> |
312 | - <widget class="GtkButton" id="snapshot_button"> |
313 | - <property name="visible">True</property> |
314 | - <property name="can_focus">True</property> |
315 | - <property name="receives_default">True</property> |
316 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
317 | - <property name="has_tooltip">True</property> |
318 | - <property name="tooltip" translatable="yes" comments="Capturer une image">make a snapshot</property> |
319 | - <property name="response_id">0</property> |
320 | - <signal name="clicked" handler="on_button_capture_clicked"/> |
321 | - <accelerator key="c" modifiers="" signal="clicked"/> |
322 | - <child> |
323 | - <widget class="GtkImage" id="image5"> |
324 | - <property name="visible">True</property> |
325 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
326 | - <property name="tooltip" translatable="yes">make a snapshot</property> |
327 | - <property name="pixbuf">capture.png</property> |
328 | - </widget> |
329 | - </child> |
330 | - </widget> |
331 | - <packing> |
332 | - <property name="expand">False</property> |
333 | - <property name="fill">False</property> |
334 | - <property name="position">3</property> |
335 | - </packing> |
336 | - </child> |
337 | - <child> |
338 | - <widget class="GtkFixed" id="fixed11"> |
339 | - <property name="width_request">20</property> |
340 | - <property name="visible">True</property> |
341 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
342 | - </widget> |
343 | - <packing> |
344 | - <property name="position">4</property> |
345 | - </packing> |
346 | - </child> |
347 | - <child> |
348 | - <widget class="GtkVBox" id="vbox9"> |
349 | - <property name="width_request">134</property> |
350 | - <property name="visible">True</property> |
351 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
352 | - <child> |
353 | - <widget class="GtkCheckButton" id="mixer_checkbutton"> |
354 | - <property name="visible">True</property> |
355 | - <property name="can_focus">True</property> |
356 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
357 | - <property name="has_tooltip">True</property> |
358 | - <property name="tooltip" translatable="yes">Mixer activation (onion skin)</property> |
359 | - <property name="label" translatable="yes">Mixer</property> |
360 | - <property name="relief">GTK_RELIEF_HALF</property> |
361 | - <property name="response_id">0</property> |
362 | - <property name="draw_indicator">True</property> |
363 | - <signal name="toggled" handler="on_mixer_checkbutton_toggled"/> |
364 | - </widget> |
365 | - </child> |
366 | - <child> |
367 | - <widget class="GtkHScale" id="alpha_hscale"> |
368 | - <property name="visible">True</property> |
369 | - <property name="can_focus">True</property> |
370 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
371 | - <property name="has_tooltip">True</property> |
372 | - <property name="tooltip" translatable="yes">Transparency level</property> |
373 | - <property name="update_policy">GTK_UPDATE_DISCONTINUOUS</property> |
374 | - <property name="adjustment">1 0 4 1 1 0</property> |
375 | - <property name="digits">0</property> |
376 | - <property name="value_pos">GTK_POS_LEFT</property> |
377 | - <signal name="value_changed" handler="on_alpha_hscale_value_changed"/> |
378 | - </widget> |
379 | - <packing> |
380 | - <property name="position">1</property> |
381 | - </packing> |
382 | - </child> |
383 | - </widget> |
384 | - <packing> |
385 | - <property name="expand">False</property> |
386 | - <property name="fill">False</property> |
387 | - <property name="position">5</property> |
388 | - </packing> |
389 | - </child> |
390 | - <child> |
391 | - <widget class="GtkFixed" id="fixed22"> |
392 | - <property name="width_request">20</property> |
393 | - <property name="visible">True</property> |
394 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
395 | - </widget> |
396 | - <packing> |
397 | - <property name="position">6</property> |
398 | - </packing> |
399 | - </child> |
400 | - <child> |
401 | - <widget class="GtkVBox" id="vbox10"> |
402 | - <property name="visible">True</property> |
403 | - <child> |
404 | - <widget class="GtkLabel" id="label_fpi"> |
405 | - <property name="width_request">104</property> |
406 | - <property name="visible">True</property> |
407 | - <property name="label" translatable="yes">Image per seconds</property> |
408 | - <property name="justify">GTK_JUSTIFY_CENTER</property> |
409 | - </widget> |
410 | - <packing> |
411 | - <property name="fill">False</property> |
412 | - </packing> |
413 | - </child> |
414 | - <child> |
415 | - <widget class="GtkHScale" id="hscale_fps"> |
416 | - <property name="width_request">125</property> |
417 | - <property name="visible">True</property> |
418 | - <property name="can_focus">True</property> |
419 | - <property name="adjustment">1 1 6 1 1 1</property> |
420 | - <property name="digits">0</property> |
421 | - <signal name="value_changed" handler="on_hscale_fps_value_changed"/> |
422 | - <signal name="format_value" handler="on_hscale_fps_format_value"/> |
423 | - </widget> |
424 | - <packing> |
425 | - <property name="fill">False</property> |
426 | - <property name="position">1</property> |
427 | - </packing> |
428 | - </child> |
429 | - </widget> |
430 | - <packing> |
431 | - <property name="position">7</property> |
432 | - </packing> |
433 | - </child> |
434 | - <child> |
435 | - <widget class="GtkFixed" id="fixed4"> |
436 | - <property name="visible">True</property> |
437 | - </widget> |
438 | - <packing> |
439 | - <property name="position">8</property> |
440 | - </packing> |
441 | + <property name="focus_on_click">False</property> |
442 | + <property name="response_id">0</property> |
443 | + <signal name="toggled" handler="on_acquisition_button_toggled"/> |
444 | + <child> |
445 | + <widget class="GtkImage" id="acquisition_button_image"> |
446 | + <property name="visible">True</property> |
447 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
448 | + <property name="tooltip" translatable="yes">Activate/Deactivate camera preview</property> |
449 | + <property name="pixbuf">luciole-dodo.png</property> |
450 | + </widget> |
451 | + </child> |
452 | + </widget> |
453 | + <packing> |
454 | + <property name="expand">False</property> |
455 | + <property name="fill">False</property> |
456 | + <property name="position">1</property> |
457 | + </packing> |
458 | + </child> |
459 | + <child> |
460 | + <widget class="GtkFixed" id="fixed15"> |
461 | + <property name="width_request">20</property> |
462 | + <property name="visible">True</property> |
463 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
464 | + </widget> |
465 | + <packing> |
466 | + <property name="position">2</property> |
467 | + </packing> |
468 | + </child> |
469 | + <child> |
470 | + <widget class="GtkButton" id="snapshot_button"> |
471 | + <property name="visible">True</property> |
472 | + <property name="can_focus">True</property> |
473 | + <property name="receives_default">True</property> |
474 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
475 | + <property name="has_tooltip">True</property> |
476 | + <property name="tooltip" translatable="yes" comments="Capturer une image">make a snapshot</property> |
477 | + <property name="response_id">0</property> |
478 | + <signal name="clicked" handler="on_button_capture_clicked"/> |
479 | + <accelerator key="c" modifiers="" signal="clicked"/> |
480 | + <child> |
481 | + <widget class="GtkImage" id="image5"> |
482 | + <property name="visible">True</property> |
483 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
484 | + <property name="tooltip" translatable="yes">make a snapshot</property> |
485 | + <property name="pixbuf">capture.png</property> |
486 | + </widget> |
487 | + </child> |
488 | + </widget> |
489 | + <packing> |
490 | + <property name="expand">False</property> |
491 | + <property name="fill">False</property> |
492 | + <property name="position">3</property> |
493 | + </packing> |
494 | + </child> |
495 | + <child> |
496 | + <widget class="GtkFixed" id="fixed11"> |
497 | + <property name="width_request">20</property> |
498 | + <property name="visible">True</property> |
499 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
500 | + </widget> |
501 | + <packing> |
502 | + <property name="position">4</property> |
503 | + </packing> |
504 | + </child> |
505 | + <child> |
506 | + <widget class="GtkVBox" id="vbox9"> |
507 | + <property name="width_request">134</property> |
508 | + <property name="visible">True</property> |
509 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
510 | + <child> |
511 | + <widget class="GtkCheckButton" id="mixer_checkbutton"> |
512 | + <property name="visible">True</property> |
513 | + <property name="can_focus">True</property> |
514 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
515 | + <property name="has_tooltip">True</property> |
516 | + <property name="tooltip" translatable="yes">Mixer activation (onion skin)</property> |
517 | + <property name="label" translatable="yes">Mixer</property> |
518 | + <property name="relief">GTK_RELIEF_HALF</property> |
519 | + <property name="response_id">0</property> |
520 | + <property name="draw_indicator">True</property> |
521 | + <signal name="toggled" handler="on_mixer_checkbutton_toggled"/> |
522 | + </widget> |
523 | + </child> |
524 | + <child> |
525 | + <widget class="GtkHScale" id="alpha_hscale"> |
526 | + <property name="visible">True</property> |
527 | + <property name="can_focus">True</property> |
528 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
529 | + <property name="has_tooltip">True</property> |
530 | + <property name="tooltip" translatable="yes">Transparency level</property> |
531 | + <property name="update_policy">GTK_UPDATE_DISCONTINUOUS</property> |
532 | + <property name="adjustment">1 0 4 1 1 0</property> |
533 | + <property name="digits">0</property> |
534 | + <property name="value_pos">GTK_POS_LEFT</property> |
535 | + <signal name="value_changed" handler="on_alpha_hscale_value_changed"/> |
536 | + </widget> |
537 | + <packing> |
538 | + <property name="position">1</property> |
539 | + </packing> |
540 | + </child> |
541 | + </widget> |
542 | + <packing> |
543 | + <property name="expand">False</property> |
544 | + <property name="fill">False</property> |
545 | + <property name="position">5</property> |
546 | + </packing> |
547 | + </child> |
548 | + <child> |
549 | + <widget class="GtkFixed" id="fixed22"> |
550 | + <property name="width_request">20</property> |
551 | + <property name="visible">True</property> |
552 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
553 | + </widget> |
554 | + <packing> |
555 | + <property name="position">6</property> |
556 | + </packing> |
557 | + </child> |
558 | + <child> |
559 | + <widget class="GtkVBox" id="vbox10"> |
560 | + <property name="visible">True</property> |
561 | + <child> |
562 | + <widget class="GtkLabel" id="label_fpi"> |
563 | + <property name="width_request">104</property> |
564 | + <property name="visible">True</property> |
565 | + <property name="label" translatable="yes">Image per seconds</property> |
566 | + <property name="justify">GTK_JUSTIFY_CENTER</property> |
567 | + </widget> |
568 | + <packing> |
569 | + <property name="fill">False</property> |
570 | + </packing> |
571 | + </child> |
572 | + <child> |
573 | + <widget class="GtkHScale" id="hscale_fps"> |
574 | + <property name="width_request">125</property> |
575 | + <property name="visible">True</property> |
576 | + <property name="can_focus">True</property> |
577 | + <property name="adjustment">1 1 6 1 1 1</property> |
578 | + <property name="digits">0</property> |
579 | + <signal name="value_changed" handler="on_hscale_fps_value_changed"/> |
580 | + <signal name="format_value" handler="on_hscale_fps_format_value"/> |
581 | + </widget> |
582 | + <packing> |
583 | + <property name="fill">False</property> |
584 | + <property name="position">1</property> |
585 | + </packing> |
586 | + </child> |
587 | + </widget> |
588 | + <packing> |
589 | + <property name="position">7</property> |
590 | + </packing> |
591 | + </child> |
592 | + <child> |
593 | + <widget class="GtkFixed" id="fixed4"> |
594 | + <property name="visible">True</property> |
595 | + </widget> |
596 | + <packing> |
597 | + <property name="position">8</property> |
598 | + </packing> |
599 | + </child> |
600 | + </widget> |
601 | </child> |
602 | </widget> |
603 | <packing> |
604 | @@ -831,12 +865,30 @@ |
605 | </packing> |
606 | </child> |
607 | <child> |
608 | - <widget class="GtkStatusbar" id="statusbar1"> |
609 | + <widget class="GtkHBox" id="hbox3"> |
610 | <property name="visible">True</property> |
611 | - <property name="spacing">2</property> |
612 | + <child> |
613 | + <widget class="GtkStatusbar" id="statusbar1"> |
614 | + <property name="visible">True</property> |
615 | + <property name="spacing">2</property> |
616 | + </widget> |
617 | + </child> |
618 | + <child> |
619 | + <widget class="GtkProgressBar" id="progressbar_status"> |
620 | + <property name="width_request">200</property> |
621 | + <property name="height_request">10</property> |
622 | + </widget> |
623 | + <packing> |
624 | + <property name="expand">False</property> |
625 | + <property name="fill">False</property> |
626 | + <property name="padding">3</property> |
627 | + <property name="position">1</property> |
628 | + </packing> |
629 | + </child> |
630 | </widget> |
631 | <packing> |
632 | <property name="expand">False</property> |
633 | + <property name="padding">2</property> |
634 | <property name="position">2</property> |
635 | </packing> |
636 | </child> |
637 | @@ -883,8 +935,8 @@ |
638 | <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> |
639 | <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> |
640 | <property name="has_separator">False</property> |
641 | - <property name="program_name">luciole</property> |
642 | - <property name="version">0.5</property> |
643 | + <property name="program_name">Luciole</property> |
644 | + <property name="version">0.7</property> |
645 | <property name="comments" translatable="yes"> |
646 | Tool for video capture, for making animated cartoon from image per image |
647 | </property> |
648 | @@ -907,6 +959,7 @@ |
649 | Inc., 59 Temple Place - |
650 | Suite 330, Boston, MA 02111-1307, USA.</property> |
651 | <property name="authors">nico : nico@inattendu.org</property> |
652 | + <property name="logo">luciole_logo.png</property> |
653 | <child internal-child="vbox"> |
654 | <widget class="GtkVBox" id="dialog-vbox9"> |
655 | <property name="visible">True</property> |
656 | @@ -1199,9 +1252,9 @@ |
657 | <widget class="GtkFileChooserButton" id="filechooserbutton1"> |
658 | <property name="visible">True</property> |
659 | <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
660 | + <property name="do_overwrite_confirmation">True</property> |
661 | <property name="action">GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER</property> |
662 | <property name="use_preview_label">False</property> |
663 | - <property name="do_overwrite_confirmation">True</property> |
664 | <property name="title" translatable="yes">Select a folder</property> |
665 | </widget> |
666 | <packing> |
667 | @@ -1403,4 +1456,38 @@ |
668 | </widget> |
669 | </child> |
670 | </widget> |
671 | + <widget class="GtkDialog" id="dialog_project_properties"> |
672 | + <property name="border_width">5</property> |
673 | + <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> |
674 | + <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> |
675 | + <property name="has_separator">False</property> |
676 | + <child internal-child="vbox"> |
677 | + <widget class="GtkVBox" id="dialog-vbox4"> |
678 | + <property name="visible">True</property> |
679 | + <property name="spacing">2</property> |
680 | + <child> |
681 | + <placeholder/> |
682 | + </child> |
683 | + <child internal-child="action_area"> |
684 | + <widget class="GtkHButtonBox" id="dialog-action_area4"> |
685 | + <property name="visible">True</property> |
686 | + <property name="layout_style">GTK_BUTTONBOX_END</property> |
687 | + <child> |
688 | + <placeholder/> |
689 | + </child> |
690 | + <child> |
691 | + <placeholder/> |
692 | + </child> |
693 | + <child> |
694 | + <placeholder/> |
695 | + </child> |
696 | + </widget> |
697 | + <packing> |
698 | + <property name="expand">False</property> |
699 | + <property name="pack_type">GTK_PACK_END</property> |
700 | + </packing> |
701 | + </child> |
702 | + </widget> |
703 | + </child> |
704 | + </widget> |
705 | </glade-interface> |
706 | |
707 | === modified file 'images/luciole.xml' |
708 | --- images/luciole.xml 2009-04-10 20:10:44 +0000 |
709 | +++ images/luciole.xml 2009-04-13 19:42:11 +0000 |
710 | @@ -1,5 +1,5 @@ |
711 | <?xml version="1.0"?> |
712 | -<!--Generated with glade3 3.4.5 on Fri Apr 10 22:06:52 2009 --> |
713 | +<!--Generated with glade3 3.4.5 on Mon Apr 13 21:29:08 2009 --> |
714 | <interface> |
715 | <object class="GtkAdjustment" id="adjustment1"> |
716 | <property name="upper">4</property> |
717 | @@ -57,6 +57,42 @@ |
718 | </object> |
719 | </child> |
720 | <child> |
721 | + <object class="GtkAction" id="menu_file_open_recent"> |
722 | + <property name="name">menu_file_open_recent</property> |
723 | + <property name="label" translatable="yes">Open recent</property> |
724 | + </object> |
725 | + </child> |
726 | + <child> |
727 | + <object class="GtkAction" id="recent1"> |
728 | + <property name="name">recent1</property> |
729 | + <property name="label" translatable="yes">project1</property> |
730 | + </object> |
731 | + </child> |
732 | + <child> |
733 | + <object class="GtkAction" id="recent2"> |
734 | + <property name="name">recent2</property> |
735 | + <property name="label" translatable="yes">project2</property> |
736 | + </object> |
737 | + </child> |
738 | + <child> |
739 | + <object class="GtkAction" id="recent3"> |
740 | + <property name="name">recent3</property> |
741 | + <property name="label" translatable="yes">project3</property> |
742 | + </object> |
743 | + </child> |
744 | + <child> |
745 | + <object class="GtkAction" id="recent4"> |
746 | + <property name="name">recent4</property> |
747 | + <property name="label" translatable="yes">project4</property> |
748 | + </object> |
749 | + </child> |
750 | + <child> |
751 | + <object class="GtkAction" id="recent5"> |
752 | + <property name="name">recent5</property> |
753 | + <property name="label" translatable="yes">project5</property> |
754 | + </object> |
755 | + </child> |
756 | + <child> |
757 | <object class="GtkAction" id="file_save"> |
758 | <property name="stock_id" translatable="yes">gtk-save</property> |
759 | <property name="name">file_save</property> |
760 | @@ -100,51 +136,32 @@ |
761 | </object> |
762 | </child> |
763 | <child> |
764 | - <object class="GtkAction" id="menuitem2"> |
765 | - <property name="name">menuitem2</property> |
766 | - <property name="label" translatable="yes">_Edit</property> |
767 | - </object> |
768 | - </child> |
769 | - <child> |
770 | - <object class="GtkAction" id="imagemenuitem6"> |
771 | - <property name="stock_id" translatable="yes">gtk-cut</property> |
772 | - <property name="name">imagemenuitem6</property> |
773 | - </object> |
774 | - </child> |
775 | - <child> |
776 | - <object class="GtkAction" id="imagemenuitem7"> |
777 | - <property name="stock_id" translatable="yes">gtk-copy</property> |
778 | - <property name="name">imagemenuitem7</property> |
779 | - </object> |
780 | - </child> |
781 | - <child> |
782 | - <object class="GtkAction" id="imagemenuitem8"> |
783 | - <property name="stock_id" translatable="yes">gtk-paste</property> |
784 | - <property name="name">imagemenuitem8</property> |
785 | - </object> |
786 | - </child> |
787 | - <child> |
788 | - <object class="GtkAction" id="imagemenuitem9"> |
789 | - <property name="stock_id" translatable="yes">gtk-delete</property> |
790 | - <property name="name">imagemenuitem9</property> |
791 | - </object> |
792 | - </child> |
793 | - <child> |
794 | <object class="GtkAction" id="menuitem3"> |
795 | <property name="name">menuitem3</property> |
796 | <property name="label" translatable="yes">_View</property> |
797 | </object> |
798 | </child> |
799 | <child> |
800 | + <object class="GtkAction" id="view_project"> |
801 | + <property name="stock_id">gtk-properties</property> |
802 | + <property name="name">view_project</property> |
803 | + <property name="tooltip" translatable="yes">Project Properties</property> |
804 | + <property name="label" translatable="yes">Project Properties</property> |
805 | + <signal handler="on_view_project_activate" name="activate"/> |
806 | + </object> |
807 | + </child> |
808 | + <child> |
809 | <object class="GtkAction" id="menuitem4"> |
810 | <property name="name">menuitem4</property> |
811 | <property name="label" translatable="yes">_Help</property> |
812 | </object> |
813 | </child> |
814 | <child> |
815 | - <object class="GtkAction" id="imagemenuitem10"> |
816 | + <object class="GtkAction" id="help_about"> |
817 | <property name="stock_id" translatable="yes">gtk-about</property> |
818 | - <property name="name">imagemenuitem10</property> |
819 | + <property name="name">help_about</property> |
820 | + <property name="tooltip" translatable="yes">About</property> |
821 | + <signal handler="on_help_about_activate" name="activate"/> |
822 | </object> |
823 | </child> |
824 | </object> |
825 | @@ -154,6 +171,13 @@ |
826 | <menu action="menu_file"> |
827 | <menuitem action="file_new"/> |
828 | <menuitem action="file_open"/> |
829 | + <menu action="menu_file_open_recent"> |
830 | + <menuitem action="recent1"/> |
831 | + <menuitem action="recent2"/> |
832 | + <menuitem action="recent3"/> |
833 | + <menuitem action="recent4"/> |
834 | + <menuitem action="recent5"/> |
835 | + </menu> |
836 | <menuitem action="file_save"/> |
837 | <menuitem action="imagemenuitem4"/> |
838 | <separator/> |
839 | @@ -163,20 +187,18 @@ |
840 | <menuitem action="file_close"/> |
841 | <menuitem action="file_quit"/> |
842 | </menu> |
843 | - <menu action="menuitem2"> |
844 | - <menuitem action="imagemenuitem6"/> |
845 | - <menuitem action="imagemenuitem7"/> |
846 | - <menuitem action="imagemenuitem8"/> |
847 | - <menuitem action="imagemenuitem9"/> |
848 | + <menu action="menuitem3"> |
849 | + <menuitem action="view_project"/> |
850 | </menu> |
851 | - <menuitem action="menuitem3"/> |
852 | <menu action="menuitem4"> |
853 | - <menuitem action="imagemenuitem10"/> |
854 | + <menuitem action="help_about"/> |
855 | </menu> |
856 | </menubar> |
857 | </ui> |
858 | </object> |
859 | <object class="GtkWindow" id="window1"> |
860 | + <signal handler="on_window1_delete_event" name="delete_event"/> |
861 | + <signal handler="on_window1_destroy_event" name="destroy_event"/> |
862 | <child> |
863 | <object class="GtkVBox" id="vbox1"> |
864 | <property name="visible">True</property> |
865 | @@ -228,181 +250,188 @@ |
866 | </packing> |
867 | </child> |
868 | <child> |
869 | - <object class="GtkHBox" id="hbox_acquisition"> |
870 | - <property name="height_request">51</property> |
871 | + <object class="GtkAspectFrame" id="aspectframe2"> |
872 | <property name="visible">True</property> |
873 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
874 | - <child> |
875 | - <object class="GtkFixed" id="fixed8"> |
876 | - <property name="width_request">20</property> |
877 | - <property name="visible">True</property> |
878 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
879 | - </object> |
880 | - </child> |
881 | - <child> |
882 | - <object class="GtkToggleButton" id="acquisition_button"> |
883 | - <property name="width_request">56</property> |
884 | - <property name="height_request">46</property> |
885 | - <property name="visible">True</property> |
886 | - <property name="can_focus">True</property> |
887 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
888 | - <property name="has_tooltip">True</property> |
889 | - <property name="tooltip-text" translatable="yes">Activate/Deactivate camera preview</property> |
890 | - <property name="focus_on_click">False</property> |
891 | - <signal handler="on_acquisition_button_toggled" name="toggled"/> |
892 | - <child> |
893 | - <object class="GtkImage" id="acquisition_button_image"> |
894 | - <property name="visible">True</property> |
895 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
896 | + <property name="label_xalign">0</property> |
897 | + <property name="shadow_type">GTK_SHADOW_NONE</property> |
898 | + <child> |
899 | + <object class="GtkHBox" id="hbox_acquisition"> |
900 | + <property name="height_request">51</property> |
901 | + <property name="visible">True</property> |
902 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
903 | + <child> |
904 | + <object class="GtkFixed" id="fixed8"> |
905 | + <property name="width_request">20</property> |
906 | + <property name="visible">True</property> |
907 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
908 | + </object> |
909 | + </child> |
910 | + <child> |
911 | + <object class="GtkToggleButton" id="acquisition_button"> |
912 | + <property name="width_request">56</property> |
913 | + <property name="height_request">46</property> |
914 | + <property name="visible">True</property> |
915 | + <property name="can_focus">True</property> |
916 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
917 | + <property name="has_tooltip">True</property> |
918 | <property name="tooltip-text" translatable="yes">Activate/Deactivate camera preview</property> |
919 | - <property name="pixbuf">Luciole-dodo.png</property> |
920 | - </object> |
921 | - </child> |
922 | - </object> |
923 | - <packing> |
924 | - <property name="expand">False</property> |
925 | - <property name="fill">False</property> |
926 | - <property name="position">1</property> |
927 | - </packing> |
928 | - </child> |
929 | - <child> |
930 | - <object class="GtkFixed" id="fixed15"> |
931 | - <property name="width_request">20</property> |
932 | - <property name="visible">True</property> |
933 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
934 | - </object> |
935 | - <packing> |
936 | - <property name="position">2</property> |
937 | - </packing> |
938 | - </child> |
939 | - <child> |
940 | - <object class="GtkButton" id="snapshot_button"> |
941 | - <property name="visible">True</property> |
942 | - <property name="can_focus">True</property> |
943 | - <property name="receives_default">True</property> |
944 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
945 | - <property name="has_tooltip">True</property> |
946 | - <property comments="Capturer une image" name="tooltip-text" translatable="yes">make a snapshot</property> |
947 | - <signal handler="on_button_capture_clicked" name="clicked"/> |
948 | - <accelerator key="c" modifiers="" signal="clicked"/> |
949 | - <child> |
950 | - <object class="GtkImage" id="image5"> |
951 | - <property name="visible">True</property> |
952 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
953 | - <property name="tooltip-text" translatable="yes">make a snapshot</property> |
954 | - <property name="pixbuf">capture.png</property> |
955 | - </object> |
956 | - </child> |
957 | - </object> |
958 | - <packing> |
959 | - <property name="expand">False</property> |
960 | - <property name="fill">False</property> |
961 | - <property name="position">3</property> |
962 | - </packing> |
963 | - </child> |
964 | - <child> |
965 | - <object class="GtkFixed" id="fixed11"> |
966 | - <property name="width_request">20</property> |
967 | - <property name="visible">True</property> |
968 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
969 | - </object> |
970 | - <packing> |
971 | - <property name="position">4</property> |
972 | - </packing> |
973 | - </child> |
974 | - <child> |
975 | - <object class="GtkVBox" id="vbox9"> |
976 | - <property name="width_request">134</property> |
977 | - <property name="visible">True</property> |
978 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
979 | - <child> |
980 | - <object class="GtkCheckButton" id="mixer_checkbutton"> |
981 | - <property name="visible">True</property> |
982 | - <property name="can_focus">True</property> |
983 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
984 | - <property name="has_tooltip">True</property> |
985 | - <property name="tooltip-text" translatable="yes">Mixer activation (onion skin)</property> |
986 | - <property name="label" translatable="yes">Mixer</property> |
987 | - <property name="relief">GTK_RELIEF_HALF</property> |
988 | - <property name="draw_indicator">True</property> |
989 | - <signal handler="on_mixer_checkbutton_toggled" name="toggled"/> |
990 | - </object> |
991 | - </child> |
992 | - <child> |
993 | - <object class="GtkHScale" id="alpha_hscale"> |
994 | - <property name="visible">True</property> |
995 | - <property name="can_focus">True</property> |
996 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
997 | - <property name="has_tooltip">True</property> |
998 | - <property name="tooltip-text" translatable="yes">Transparency level</property> |
999 | - <property name="update_policy">GTK_UPDATE_DISCONTINUOUS</property> |
1000 | - <property name="adjustment">adjustment1</property> |
1001 | - <property name="digits">0</property> |
1002 | - <property name="value_pos">GTK_POS_LEFT</property> |
1003 | - <signal handler="on_alpha_hscale_value_changed" name="value_changed"/> |
1004 | - </object> |
1005 | - <packing> |
1006 | - <property name="position">1</property> |
1007 | - </packing> |
1008 | - </child> |
1009 | - </object> |
1010 | - <packing> |
1011 | - <property name="expand">False</property> |
1012 | - <property name="fill">False</property> |
1013 | - <property name="position">5</property> |
1014 | - </packing> |
1015 | - </child> |
1016 | - <child> |
1017 | - <object class="GtkFixed" id="fixed22"> |
1018 | - <property name="width_request">20</property> |
1019 | - <property name="visible">True</property> |
1020 | - <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
1021 | - </object> |
1022 | - <packing> |
1023 | - <property name="position">6</property> |
1024 | - </packing> |
1025 | - </child> |
1026 | - <child> |
1027 | - <object class="GtkVBox" id="vbox10"> |
1028 | - <property name="visible">True</property> |
1029 | - <child> |
1030 | - <object class="GtkLabel" id="label_fpi"> |
1031 | - <property name="width_request">104</property> |
1032 | - <property name="visible">True</property> |
1033 | - <property name="label" translatable="yes">Image per seconds</property> |
1034 | - <property name="justify">GTK_JUSTIFY_CENTER</property> |
1035 | - </object> |
1036 | - <packing> |
1037 | - <property name="fill">False</property> |
1038 | - </packing> |
1039 | - </child> |
1040 | - <child> |
1041 | - <object class="GtkHScale" id="hscale_fps"> |
1042 | - <property name="width_request">125</property> |
1043 | - <property name="visible">True</property> |
1044 | - <property name="can_focus">True</property> |
1045 | - <property name="adjustment">adjustment2</property> |
1046 | - <property name="digits">0</property> |
1047 | - <signal handler="on_hscale_fps_value_changed" name="value_changed"/> |
1048 | - <signal handler="on_hscale_fps_format_value" name="format_value"/> |
1049 | - </object> |
1050 | - <packing> |
1051 | - <property name="fill">False</property> |
1052 | - <property name="position">1</property> |
1053 | - </packing> |
1054 | - </child> |
1055 | - </object> |
1056 | - <packing> |
1057 | - <property name="position">7</property> |
1058 | - </packing> |
1059 | - </child> |
1060 | - <child> |
1061 | - <object class="GtkFixed" id="fixed4"> |
1062 | - <property name="visible">True</property> |
1063 | - </object> |
1064 | - <packing> |
1065 | - <property name="position">8</property> |
1066 | - </packing> |
1067 | + <property name="focus_on_click">False</property> |
1068 | + <signal handler="on_acquisition_button_toggled" name="toggled"/> |
1069 | + <child> |
1070 | + <object class="GtkImage" id="acquisition_button_image"> |
1071 | + <property name="visible">True</property> |
1072 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
1073 | + <property name="tooltip-text" translatable="yes">Activate/Deactivate camera preview</property> |
1074 | + <property name="pixbuf">luciole-dodo.png</property> |
1075 | + </object> |
1076 | + </child> |
1077 | + </object> |
1078 | + <packing> |
1079 | + <property name="expand">False</property> |
1080 | + <property name="fill">False</property> |
1081 | + <property name="position">1</property> |
1082 | + </packing> |
1083 | + </child> |
1084 | + <child> |
1085 | + <object class="GtkFixed" id="fixed15"> |
1086 | + <property name="width_request">20</property> |
1087 | + <property name="visible">True</property> |
1088 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
1089 | + </object> |
1090 | + <packing> |
1091 | + <property name="position">2</property> |
1092 | + </packing> |
1093 | + </child> |
1094 | + <child> |
1095 | + <object class="GtkButton" id="snapshot_button"> |
1096 | + <property name="visible">True</property> |
1097 | + <property name="can_focus">True</property> |
1098 | + <property name="receives_default">True</property> |
1099 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
1100 | + <property name="has_tooltip">True</property> |
1101 | + <property comments="Capturer une image" name="tooltip-text" translatable="yes">make a snapshot</property> |
1102 | + <signal handler="on_button_capture_clicked" name="clicked"/> |
1103 | + <accelerator key="c" modifiers="" signal="clicked"/> |
1104 | + <child> |
1105 | + <object class="GtkImage" id="image5"> |
1106 | + <property name="visible">True</property> |
1107 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
1108 | + <property name="tooltip-text" translatable="yes">make a snapshot</property> |
1109 | + <property name="pixbuf">capture.png</property> |
1110 | + </object> |
1111 | + </child> |
1112 | + </object> |
1113 | + <packing> |
1114 | + <property name="expand">False</property> |
1115 | + <property name="fill">False</property> |
1116 | + <property name="position">3</property> |
1117 | + </packing> |
1118 | + </child> |
1119 | + <child> |
1120 | + <object class="GtkFixed" id="fixed11"> |
1121 | + <property name="width_request">20</property> |
1122 | + <property name="visible">True</property> |
1123 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
1124 | + </object> |
1125 | + <packing> |
1126 | + <property name="position">4</property> |
1127 | + </packing> |
1128 | + </child> |
1129 | + <child> |
1130 | + <object class="GtkVBox" id="vbox9"> |
1131 | + <property name="width_request">134</property> |
1132 | + <property name="visible">True</property> |
1133 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
1134 | + <child> |
1135 | + <object class="GtkCheckButton" id="mixer_checkbutton"> |
1136 | + <property name="visible">True</property> |
1137 | + <property name="can_focus">True</property> |
1138 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
1139 | + <property name="has_tooltip">True</property> |
1140 | + <property name="tooltip-text" translatable="yes">Mixer activation (onion skin)</property> |
1141 | + <property name="label" translatable="yes">Mixer</property> |
1142 | + <property name="relief">GTK_RELIEF_HALF</property> |
1143 | + <property name="draw_indicator">True</property> |
1144 | + <signal handler="on_mixer_checkbutton_toggled" name="toggled"/> |
1145 | + </object> |
1146 | + </child> |
1147 | + <child> |
1148 | + <object class="GtkHScale" id="alpha_hscale"> |
1149 | + <property name="visible">True</property> |
1150 | + <property name="can_focus">True</property> |
1151 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
1152 | + <property name="has_tooltip">True</property> |
1153 | + <property name="tooltip-text" translatable="yes">Transparency level</property> |
1154 | + <property name="update_policy">GTK_UPDATE_DISCONTINUOUS</property> |
1155 | + <property name="adjustment">adjustment1</property> |
1156 | + <property name="digits">0</property> |
1157 | + <property name="value_pos">GTK_POS_LEFT</property> |
1158 | + <signal handler="on_alpha_hscale_value_changed" name="value_changed"/> |
1159 | + </object> |
1160 | + <packing> |
1161 | + <property name="position">1</property> |
1162 | + </packing> |
1163 | + </child> |
1164 | + </object> |
1165 | + <packing> |
1166 | + <property name="expand">False</property> |
1167 | + <property name="fill">False</property> |
1168 | + <property name="position">5</property> |
1169 | + </packing> |
1170 | + </child> |
1171 | + <child> |
1172 | + <object class="GtkFixed" id="fixed22"> |
1173 | + <property name="width_request">20</property> |
1174 | + <property name="visible">True</property> |
1175 | + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
1176 | + </object> |
1177 | + <packing> |
1178 | + <property name="position">6</property> |
1179 | + </packing> |
1180 | + </child> |
1181 | + <child> |
1182 | + <object class="GtkVBox" id="vbox10"> |
1183 | + <property name="visible">True</property> |
1184 | + <child> |
1185 | + <object class="GtkLabel" id="label_fpi"> |
1186 | + <property name="width_request">104</property> |
1187 | + <property name="visible">True</property> |
1188 | + <property name="label" translatable="yes">Image per seconds</property> |
1189 | + <property name="justify">GTK_JUSTIFY_CENTER</property> |
1190 | + </object> |
1191 | + <packing> |
1192 | + <property name="fill">False</property> |
1193 | + </packing> |
1194 | + </child> |
1195 | + <child> |
1196 | + <object class="GtkHScale" id="hscale_fps"> |
1197 | + <property name="width_request">125</property> |
1198 | + <property name="visible">True</property> |
1199 | + <property name="can_focus">True</property> |
1200 | + <property name="adjustment">adjustment2</property> |
1201 | + <property name="digits">0</property> |
1202 | + <signal handler="on_hscale_fps_value_changed" name="value_changed"/> |
1203 | + <signal handler="on_hscale_fps_format_value" name="format_value"/> |
1204 | + </object> |
1205 | + <packing> |
1206 | + <property name="fill">False</property> |
1207 | + <property name="position">1</property> |
1208 | + </packing> |
1209 | + </child> |
1210 | + </object> |
1211 | + <packing> |
1212 | + <property name="position">7</property> |
1213 | + </packing> |
1214 | + </child> |
1215 | + <child> |
1216 | + <object class="GtkFixed" id="fixed4"> |
1217 | + <property name="visible">True</property> |
1218 | + </object> |
1219 | + <packing> |
1220 | + <property name="position">8</property> |
1221 | + </packing> |
1222 | + </child> |
1223 | + </object> |
1224 | </child> |
1225 | </object> |
1226 | <packing> |
1227 | @@ -820,12 +849,30 @@ |
1228 | </packing> |
1229 | </child> |
1230 | <child> |
1231 | - <object class="GtkStatusbar" id="statusbar1"> |
1232 | + <object class="GtkHBox" id="hbox3"> |
1233 | <property name="visible">True</property> |
1234 | - <property name="spacing">2</property> |
1235 | + <child> |
1236 | + <object class="GtkStatusbar" id="statusbar1"> |
1237 | + <property name="visible">True</property> |
1238 | + <property name="spacing">2</property> |
1239 | + </object> |
1240 | + </child> |
1241 | + <child> |
1242 | + <object class="GtkProgressBar" id="progressbar_status"> |
1243 | + <property name="width_request">200</property> |
1244 | + <property name="height_request">10</property> |
1245 | + </object> |
1246 | + <packing> |
1247 | + <property name="expand">False</property> |
1248 | + <property name="fill">False</property> |
1249 | + <property name="padding">3</property> |
1250 | + <property name="position">1</property> |
1251 | + </packing> |
1252 | + </child> |
1253 | </object> |
1254 | <packing> |
1255 | <property name="expand">False</property> |
1256 | + <property name="padding">2</property> |
1257 | <property name="position">2</property> |
1258 | </packing> |
1259 | </child> |
1260 | @@ -872,8 +919,8 @@ |
1261 | <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> |
1262 | <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> |
1263 | <property name="has_separator">False</property> |
1264 | - <property name="program_name">luciole</property> |
1265 | - <property name="version">0.5</property> |
1266 | + <property name="program_name">Luciole</property> |
1267 | + <property name="version">0.7</property> |
1268 | <property name="comments" translatable="yes"> |
1269 | Tool for video capture, for making animated cartoon from image per image |
1270 | </property> |
1271 | @@ -896,6 +943,7 @@ |
1272 | Inc., 59 Temple Place - |
1273 | Suite 330, Boston, MA 02111-1307, USA.</property> |
1274 | <property name="authors">nico : nico@inattendu.org</property> |
1275 | + <property name="logo">luciole_logo.png</property> |
1276 | <child internal-child="vbox"> |
1277 | <object class="GtkVBox" id="dialog-vbox9"> |
1278 | <property name="visible">True</property> |
1279 | @@ -1192,9 +1240,9 @@ |
1280 | <object class="GtkFileChooserButton" id="filechooserbutton1"> |
1281 | <property name="visible">True</property> |
1282 | <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> |
1283 | + <property name="do_overwrite_confirmation">True</property> |
1284 | <property name="action">GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER</property> |
1285 | <property name="use_preview_label">False</property> |
1286 | - <property name="do_overwrite_confirmation">True</property> |
1287 | <property name="title" translatable="yes">Select a folder</property> |
1288 | </object> |
1289 | <packing> |
1290 | @@ -1395,4 +1443,38 @@ |
1291 | <action-widget response="-7">button18</action-widget> |
1292 | </action-widgets> |
1293 | </object> |
1294 | + <object class="GtkDialog" id="dialog_project_properties"> |
1295 | + <property name="border_width">5</property> |
1296 | + <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> |
1297 | + <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> |
1298 | + <property name="has_separator">False</property> |
1299 | + <child internal-child="vbox"> |
1300 | + <object class="GtkVBox" id="dialog-vbox4"> |
1301 | + <property name="visible">True</property> |
1302 | + <property name="spacing">2</property> |
1303 | + <child> |
1304 | + <placeholder/> |
1305 | + </child> |
1306 | + <child internal-child="action_area"> |
1307 | + <object class="GtkHButtonBox" id="dialog-action_area4"> |
1308 | + <property name="visible">True</property> |
1309 | + <property name="layout_style">GTK_BUTTONBOX_END</property> |
1310 | + <child> |
1311 | + <placeholder/> |
1312 | + </child> |
1313 | + <child> |
1314 | + <placeholder/> |
1315 | + </child> |
1316 | + <child> |
1317 | + <placeholder/> |
1318 | + </child> |
1319 | + </object> |
1320 | + <packing> |
1321 | + <property name="expand">False</property> |
1322 | + <property name="pack_type">GTK_PACK_END</property> |
1323 | + </packing> |
1324 | + </child> |
1325 | + </object> |
1326 | + </child> |
1327 | + </object> |
1328 | </interface> |
1329 | |
1330 | === modified file 'lucioLib/gui/dialog.py' |
1331 | --- lucioLib/gui/dialog.py 2009-03-30 22:19:29 +0000 |
1332 | +++ lucioLib/gui/dialog.py 2009-04-11 16:56:47 +0000 |
1333 | @@ -48,17 +48,19 @@ |
1334 | ErrorMessage = classmethod(ErrorMessage) |
1335 | |
1336 | def QuestionMessage(cls,parent = None ,message = None ): |
1337 | - """ Display a question message. return True if reponse is YES , False in other case """ |
1338 | + """ Display a question message. return True if reponse is YES , FALSE if response is NO. None |
1339 | + if window closed without reponse. """ |
1340 | dialog = gtk.MessageDialog(parent = parent, |
1341 | flags = gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, |
1342 | type = gtk.MESSAGE_QUESTION, |
1343 | - buttons = gtk.BUTTONS_YES_NO, |
1344 | + buttons = gtk.BUTTONS_YES_NO , |
1345 | message_format = message) |
1346 | dialog.show_all() |
1347 | result = dialog.run() |
1348 | + r_val = None |
1349 | if result == gtk.RESPONSE_YES: |
1350 | r_val = True |
1351 | - else : |
1352 | + elif result == gtk.RESPONSE_NO: |
1353 | r_val = False |
1354 | dialog.destroy() |
1355 | return r_val |
1356 | @@ -108,4 +110,4 @@ |
1357 | ImportDialog = classmethod(ImportDialog) |
1358 | |
1359 | |
1360 | - |
1361 | \ No newline at end of file |
1362 | + |
1363 | |
1364 | === added file 'lucioLib/gui/dialog_project_properties.py' |
1365 | --- lucioLib/gui/dialog_project_properties.py 1970-01-01 00:00:00 +0000 |
1366 | +++ lucioLib/gui/dialog_project_properties.py 2009-04-13 19:21:49 +0000 |
1367 | @@ -0,0 +1,243 @@ |
1368 | +#!/usr/bin/env python |
1369 | +# -*- coding: utf-8 -*- |
1370 | +# -*- Mode: Python -*- |
1371 | +# vi:si:ai:et:sw=4:sts=4:ts=4 |
1372 | +# |
1373 | +# Copyright Nicolas Bertrand (nico@inattendu.org), 2009 |
1374 | +# |
1375 | +# This file is part of Luciole. |
1376 | +# |
1377 | +# Luciole is free software: you can redistribute it and/or modify |
1378 | +# it under the terms of the GNU General Public License as published by |
1379 | +# the Free Software Foundation, either version 3 of the License, or |
1380 | +# (at your option) any later version. |
1381 | +# |
1382 | +# Luciole is distributed in the hope that it will be useful, |
1383 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1384 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1385 | +# GNU General Public License for more details. |
1386 | +# |
1387 | +# You should have received a copy of the GNU General Public License |
1388 | +# along with Luciole. If not, see <http://www.gnu.org/licenses/>. |
1389 | +# |
1390 | +# |
1391 | +""" |
1392 | + dialog_project_properties.py : Dialog who display the project properties |
1393 | +""" |
1394 | +from gettext import gettext as _ |
1395 | +import gtk |
1396 | +import pango |
1397 | + |
1398 | +from .. import luciole_constants as LCONST |
1399 | + |
1400 | +(LABEL,ENTRY)=range(2) |
1401 | + |
1402 | +class Project_properties(object): |
1403 | + |
1404 | + # This tow 2 tables descibes how to display project info |
1405 | + _PROJECT_PREFS = { |
1406 | + 'project_dir' : { |
1407 | + 'desc' : _('Project folder :'), |
1408 | + 'type' : LABEL |
1409 | + }, |
1410 | + 'project_name' : { |
1411 | + 'desc' : _('Project name :'), |
1412 | + 'type' : LABEL |
1413 | + }, |
1414 | + 'xml_filename' : { |
1415 | + 'desc' : _('XML file :'), |
1416 | + 'type' : LABEL |
1417 | + }, |
1418 | + |
1419 | + 'fpi' : { |
1420 | + 'desc' : _('Number of frames / image'), |
1421 | + 'type' : LABEL |
1422 | + }, |
1423 | + 'hardtype' : { |
1424 | + 'desc' : _('Device type'), |
1425 | + 'type' : LABEL |
1426 | + }, |
1427 | + |
1428 | + } |
1429 | + |
1430 | + _WEBCAM_PREFS = { |
1431 | + 'device' : { |
1432 | + 'desc' : _('Device :'), |
1433 | + 'type' : ENTRY |
1434 | + }, |
1435 | + 'name' : { |
1436 | + 'desc' : _('Webcam name :'), |
1437 | + 'type' : LABEL |
1438 | + }, |
1439 | + |
1440 | + 'source_input' : { |
1441 | + 'desc' : _('Video capture driver :'), |
1442 | + 'type' : LABEL |
1443 | + }, |
1444 | + 'width' : { |
1445 | + 'desc' : _('Video width :'), |
1446 | + 'type' : LABEL |
1447 | + }, |
1448 | + 'height' : { |
1449 | + 'desc' : _('Video height :'), |
1450 | + 'type' : LABEL |
1451 | + }, |
1452 | + } |
1453 | + |
1454 | + |
1455 | + _title = _('Project properties') |
1456 | + |
1457 | + def __init__(self,main_window, project) : |
1458 | + """ create a Dialog with project properties and disqpay it""" |
1459 | + |
1460 | + self._dialog = gtk.Dialog ( self._title, |
1461 | + main_window, |
1462 | + gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, |
1463 | + ( gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL, |
1464 | + gtk.STOCK_CLOSE,gtk.RESPONSE_CLOSE, |
1465 | + gtk.STOCK_APPLY,gtk.RESPONSE_APPLY) |
1466 | + ) |
1467 | + self._project = project |
1468 | + |
1469 | + # make dialog displays |
1470 | + self.make_widget() |
1471 | + self._dialog.show_all() |
1472 | + |
1473 | + # run dialog |
1474 | + result = self._dialog.run() |
1475 | + |
1476 | + # wait for reponse |
1477 | + # nbd@grape : missing what to do when info changed |
1478 | + # probably add callback to update project |
1479 | + if result == gtk.RESPONSE_CANCEL : |
1480 | + self._dialog.destroy() |
1481 | + elif result == gtk.RESPONSE_CLOSE : |
1482 | + self._dialog.destroy() |
1483 | + |
1484 | + |
1485 | + def make_title_label(self, text) : |
1486 | + """ set a title label (i.e 1st column of table): play wiyh pango""" |
1487 | + label= gtk.Label() |
1488 | + label.set_text("%s"%text) |
1489 | + attrs = pango.AttrList() |
1490 | + attrs.insert( pango.AttrWeight(pango.WEIGHT_BOLD,0, -1)) |
1491 | + label.set_attributes(attrs) |
1492 | + |
1493 | + # positionning of label |
1494 | + label.set_alignment(xalign=0.0,yalign=0.5) # left justification of label |
1495 | + # Insert label into the upper left quadrant of the table |
1496 | + label.show() |
1497 | + return label |
1498 | + |
1499 | + def make_table_title(self,title) : |
1500 | + """ set a Table title : play with pango""" |
1501 | + label= gtk.Label() |
1502 | + label.set_text(title) |
1503 | + attrs = pango.AttrList() |
1504 | + attrs.insert( pango.AttrWeight(pango.WEIGHT_BOLD,0, -1)) |
1505 | + attrs.insert( pango.AttrSize(18000,0, -1)) |
1506 | + label.set_attributes(attrs) |
1507 | + |
1508 | + # positionning of label |
1509 | + label.set_alignment(xalign=0.5,yalign=0.5) # center |
1510 | + # Insert label into the upper left quadrant of the table |
1511 | + label.show() |
1512 | + return label |
1513 | + |
1514 | + |
1515 | + |
1516 | + def make_table_row(self,table,row,key): |
1517 | + """ Craate the row for the gtk.Table used for project properties display """ |
1518 | + label= self.make_title_label(self._PROJECT_PREFS[key]['desc']) |
1519 | + table.attach(label, 0, 1, row, row +1 ,xpadding = 10 ) |
1520 | + |
1521 | + widget = None |
1522 | + if key == 'hardtype' : |
1523 | + widget = gtk.Label(LCONST.HardTypeName[self._project[key]] ) |
1524 | + else : |
1525 | + if self._PROJECT_PREFS[key]['type'] == LABEL : |
1526 | + widget = gtk.Label(self._project[key]) |
1527 | + |
1528 | + widget.set_alignment(xalign=0.0,yalign=0.5) # left justification of label |
1529 | + widget.show() |
1530 | + table.attach(widget, 1, 2, row, row+1,xpadding = 10 ) |
1531 | + |
1532 | + def make_table_webcam_row(self,table,row,key): |
1533 | + """ Craate the row for the gtk.Table used for webcam properties display """ |
1534 | + label= self.make_title_label(self._WEBCAM_PREFS[key]['desc']) |
1535 | + table.attach(label, 0, 1, row, row +1 ,xpadding = 10 ) |
1536 | + |
1537 | + widget = None |
1538 | + if self._WEBCAM_PREFS[key]['type'] == ENTRY : |
1539 | + widget = gtk.Entry() |
1540 | + widget.set_alignment(xalign=0.0) # left justification of label |
1541 | + else: |
1542 | + widget = gtk.Label() |
1543 | + widget.set_alignment(xalign=0.0,yalign=0.5) # left justification of label |
1544 | + widget.set_text(self._project['webcam_data'][key]) |
1545 | + |
1546 | + widget.show() |
1547 | + table.attach(widget, 1, 2, row, row+1,xpadding = 10 ) |
1548 | + |
1549 | + |
1550 | + def make_webcam_data(self) : |
1551 | + """ build widgets for display of webcam properties""" |
1552 | + self._dialog.vbox.pack_start( child = gtk.HSeparator(), |
1553 | + expand = True, |
1554 | + fill = True, |
1555 | + padding = 5 |
1556 | + ) |
1557 | + |
1558 | + label = self.make_table_title(_('Webcam properties')) |
1559 | + self._dialog.vbox.pack_start( child = label, |
1560 | + expand = True, |
1561 | + fill = True, |
1562 | + padding = 10 |
1563 | + ) |
1564 | + |
1565 | + table = gtk.Table() |
1566 | + table.set_homogeneous(False) |
1567 | + self.make_table_webcam_row(table,0,'name') |
1568 | + self.make_table_webcam_row(table,1,'width') |
1569 | + self.make_table_webcam_row(table,2,'height') |
1570 | + self.make_table_webcam_row(table,3,'source_input') |
1571 | + self.make_table_webcam_row(table,4,'device') |
1572 | + |
1573 | + self._dialog.vbox.pack_start( child = table, |
1574 | + expand = True, |
1575 | + fill = True, |
1576 | + padding = 10 |
1577 | + ) |
1578 | + |
1579 | + def make_widget(self) : |
1580 | + """ build widgets for display of project properties """ |
1581 | + label = self.make_table_title(self._title) |
1582 | + self._dialog.vbox.pack_start( child = label, |
1583 | + expand = True, |
1584 | + fill = True, |
1585 | + padding = 10 |
1586 | + ) |
1587 | + |
1588 | + table = gtk.Table(2, 2, True) |
1589 | + table.set_homogeneous(False) |
1590 | + self.make_table_row(table,0,'project_name') |
1591 | + self.make_table_row(table,1,'project_dir') |
1592 | + self.make_table_row(table,2,'xml_filename') |
1593 | + self.make_table_row(table,3,'fpi') |
1594 | + self.make_table_row(table,4,'hardtype') |
1595 | + table.show() |
1596 | + self._dialog.vbox.pack_start( child = table, |
1597 | + expand = True, |
1598 | + fill = True, |
1599 | + padding = 10 |
1600 | + ) |
1601 | + |
1602 | + if self._project['hardtype'] == LCONST.WEBCAM : |
1603 | + # if webcam based project display webcam properties |
1604 | + self.make_webcam_data() |
1605 | + |
1606 | + |
1607 | + |
1608 | + |
1609 | + |
1610 | + |
1611 | |
1612 | === modified file 'lucioLib/gui/gui_controller.py' |
1613 | --- lucioLib/gui/gui_controller.py 2009-04-10 19:50:00 +0000 |
1614 | +++ lucioLib/gui/gui_controller.py 2009-04-13 19:42:11 +0000 |
1615 | @@ -45,8 +45,12 @@ |
1616 | import dialog as GDIALOG |
1617 | import open_project as GOF |
1618 | import luciole_export_window as GEXPORT |
1619 | +import open_project_widget as GOPEN |
1620 | +import dialog_project_properties as GDIALOG_PROJ |
1621 | from .. import luciole_constants as LCONST |
1622 | |
1623 | +import _version |
1624 | + |
1625 | # nbd@grape : APP NAME place to change |
1626 | |
1627 | APP_NAME = "luciole" |
1628 | @@ -57,6 +61,50 @@ |
1629 | main file for gui management |
1630 | gui init and call backs |
1631 | """ |
1632 | +class Gui_status_controller(object) : |
1633 | + |
1634 | + def __init__(self, status_bar, progress_bar=None) : |
1635 | + """ init gui status controller """ |
1636 | + self._status_bar = status_bar |
1637 | + self._context_id = self._status_bar.get_context_id("Statusbar example") |
1638 | + self._progress_bar = progress_bar |
1639 | + |
1640 | + def on_progress(self,msg,ratio) : |
1641 | + """ update status and progress bar """ |
1642 | + self._status_bar.push(self._context_id, msg) |
1643 | + if self._progress_bar != None : |
1644 | + # if a ratio is given update progress bar with set fraction if not update with just a pulse |
1645 | + if ratio != None : |
1646 | + self._progress_bar.set_fraction(ratio) |
1647 | + else : |
1648 | + self._progress_bar.pulse() |
1649 | + |
1650 | + |
1651 | + def start(self,msg) : |
1652 | + """ Start progress/status bar """ |
1653 | + self._status_bar.push(self._context_id, msg) |
1654 | + if self._progress_bar != None : |
1655 | + self._progress_bar.show() |
1656 | + self._progress_bar.set_fraction(0.0) |
1657 | + |
1658 | + def stop(self,msg) : |
1659 | + """ Stop progress/status bar """ |
1660 | + self._status_bar.push(self._context_id, msg) |
1661 | + if self._progress_bar != None : |
1662 | + self._progress_bar.set_fraction(1.0) |
1663 | + self._progress_bar.hide() |
1664 | + |
1665 | + def display_message(self,msg) : |
1666 | + """ display a message on status bar """ |
1667 | + self._status_bar.push(self._context_id, msg) |
1668 | + |
1669 | + def clear_message(self,msg) : |
1670 | + """ clear a message on status bar """ |
1671 | + self._status_bar.pop(self._context_id) |
1672 | + |
1673 | + |
1674 | + |
1675 | + |
1676 | |
1677 | class Gui_controller(object): |
1678 | """ class handling interface with GUI/glade """ |
1679 | @@ -80,6 +128,11 @@ |
1680 | self.PreviewObj.pixbufToDisplay = x |
1681 | pixbufToDisplay = property(f_get_pixbufToDisplay,f_set_pixbufToDisplay,None,"Pixbuf to display") |
1682 | |
1683 | + def f_get_ui_manager(self) : return self.builder.get_object('uimanager1') |
1684 | + ui_manager = property(f_get_ui_manager,None,None, 'The GUI UI manager') |
1685 | + |
1686 | + def f_get_status_progress_bar(self) : return Gui_status_controller(self._status_bar,self._status_progress_bar) |
1687 | + status_progress_bar = property(f_get_status_progress_bar,None,None, 'The status progress bar') |
1688 | |
1689 | def __init__(self, ctrl_obj) : |
1690 | |
1691 | @@ -151,7 +204,6 @@ |
1692 | 'on_button_capture_to_montage_clicked' :self.on_button_capture_to_montage_clicked, |
1693 | 'on_button_import_clicked' : self.on_button_import_clicked, |
1694 | 'on_button_play_toggled' : self.on_button_play_toggled, |
1695 | - 'on_button_clear_clicked' : self.on_button_clear_clicked, # test button |
1696 | 'on_mixer_checkbutton_toggled' : self.on_mixer_checkbutton_toggled, |
1697 | 'on_alpha_hscale_value_changed' : self.on_alpha_hscale_value_changed, |
1698 | 'on_hscale_fps_value_changed' : self.on_hscale_fps_value_changed, |
1699 | @@ -164,6 +216,12 @@ |
1700 | 'on_file_export_activate' : self.on_file_export_activate, |
1701 | 'on_file_quit_activate' : self.on_file_quit_activate, |
1702 | 'on_file_close_activate' : self.on_file_close_activate, |
1703 | + 'on_view_project_activate' : self.on_view_project_activate, |
1704 | + 'on_help_about_activate' : self.on_help_about_activate, |
1705 | + |
1706 | + 'on_window1_delete_event' : self.on_window_delete_event, |
1707 | + 'on_window1_destroy_event' : self.on_window_delete_event, |
1708 | + |
1709 | |
1710 | } |
1711 | self.builder.connect_signals(callbacks) |
1712 | @@ -190,17 +248,22 @@ |
1713 | self._play_button = self.builder.get_object('button_play') |
1714 | self._play_pause_image = self.builder.get_object('image_play_pause') |
1715 | |
1716 | + # widgets for project init |
1717 | + self._init_project_buttons() |
1718 | + |
1719 | # acquistion buttons initialization |
1720 | self._init_acquistion_buttons() |
1721 | |
1722 | - # fpi widget init |
1723 | - self._init_fpi_buttons() |
1724 | + |
1725 | + #status bar |
1726 | + self._status_bar = self.builder.get_object('statusbar1') |
1727 | + self._status_progress_bar = self.builder.get_object('progressbar_status') |
1728 | + |
1729 | + |
1730 | |
1731 | def _init_acquistion_buttons(self) : |
1732 | """ acquisition buttons init """ |
1733 | #get objects from glade |
1734 | - self._acq_button = self.builder.get_object('acquisition_button') |
1735 | - self._acq_button_image = self.builder.get_object('acquisition_button_image') |
1736 | self._snapshot_button = self.builder.get_object('snapshot_button') |
1737 | self._mixer_checkbutton = self.builder.get_object('mixer_checkbutton') |
1738 | self._alpha_hscale = self.builder.get_object('alpha_hscale') |
1739 | @@ -228,7 +291,6 @@ |
1740 | """ Set acquisition for acquisition show """ |
1741 | # wake up luciole; i.e. change acquisition button logo |
1742 | self._acq_button_image.set_from_pixbuf(self._pxb_luciole_wakedup) |
1743 | - |
1744 | self._snapshot_button.show() # snapshot button hide by default |
1745 | self._mixer_checkbutton.show() # mixer checkbox hide by default |
1746 | # if toggle butoon not acive : acivate it |
1747 | @@ -236,22 +298,51 @@ |
1748 | # the set_active function cause the toggle button signal emitted |
1749 | self._acq_button.set_active(True) |
1750 | |
1751 | - def _init_fpi_buttons(self) : |
1752 | + def _init_project_buttons(self) : |
1753 | """ initialisation of fpi buttons """ |
1754 | + |
1755 | + # get Hbox with acquistion widgets nas prent of this box |
1756 | + self._hbox_acq = self.builder.get_object('hbox_acquisition') |
1757 | + self._parent_hbox_acq = self._hbox_acq.get_parent() |
1758 | + |
1759 | + # create the open/new project widget |
1760 | + self._open_project_wdg = GOPEN.Gui_open_project_widget(self.on_file_new_activate,self.on_file_open_activate) |
1761 | + |
1762 | + # set open/new project widgets |
1763 | + self.project_open_widgets() |
1764 | + |
1765 | # get fpi hscale |
1766 | + self._acq_button = self.builder.get_object('acquisition_button') |
1767 | + self._acq_button_image = self.builder.get_object('acquisition_button_image') |
1768 | self._fpi_hscale = self.builder.get_object('hscale_fps') |
1769 | self._fpi_label = self.builder.get_object('label_fpi') |
1770 | - self.fpi_widget_hide() |
1771 | - |
1772 | - def fpi_widget_hide(self) : |
1773 | - """ hide fpi wigets """ |
1774 | - self._fpi_hscale.hide() |
1775 | - self._fpi_label.hide() |
1776 | - |
1777 | - def fpi_widget_show(self) : |
1778 | - """ show fpi widgets """ |
1779 | - self._fpi_hscale.show() |
1780 | - self._fpi_label.show() |
1781 | + |
1782 | + |
1783 | + def project_open_widgets(self) : |
1784 | + """ When this function is called the project open/new buttons are dispalyed |
1785 | + The acquisistion buttons are hidden |
1786 | + """ |
1787 | + child = self._parent_hbox_acq.get_child() |
1788 | + if child != None : |
1789 | + self._parent_hbox_acq.remove(child) |
1790 | + self._parent_hbox_acq.add(self._open_project_wdg) |
1791 | + |
1792 | + #self._acq_button.hide() |
1793 | + #self._fpi_hscale.hide() |
1794 | + #self._fpi_label.hide() |
1795 | + |
1796 | + def project_acquistion_widgets(self) : |
1797 | + """ When this function is called the acquisition widgets are displayed. |
1798 | + The open.new buttons are hidden |
1799 | + """ |
1800 | + child = self._parent_hbox_acq.get_child() |
1801 | + if child != None : |
1802 | + self._parent_hbox_acq.remove(child) |
1803 | + self._parent_hbox_acq.add(self._hbox_acq) |
1804 | + |
1805 | + #self._acq_button.show() |
1806 | + #self._fpi_hscale.show() |
1807 | + #self._fpi_label.show() |
1808 | |
1809 | |
1810 | |
1811 | @@ -373,7 +464,6 @@ |
1812 | return filename |
1813 | |
1814 | def set_programbar(self,text, isModified = False) : |
1815 | - |
1816 | if isModified == True : |
1817 | self.window.set_title( "%s : %s (*)"%(APP_NAME,text ) ) |
1818 | else : |
1819 | @@ -414,7 +504,16 @@ |
1820 | if l_fpi == fpi : |
1821 | index = k |
1822 | self._fpi_hscale.set_value(float(index)) |
1823 | - |
1824 | + |
1825 | + |
1826 | + def quit(self): |
1827 | + """ quit appluication/gui """ |
1828 | + gtk.main_quit() |
1829 | + |
1830 | + |
1831 | + def display_project_properties(self,project) : |
1832 | + GDIALOG_PROJ.Project_properties(self.window, |
1833 | + project) |
1834 | |
1835 | ############################################################################ |
1836 | # glade/XML builder callbacks |
1837 | @@ -538,8 +637,34 @@ |
1838 | print "file close activate " |
1839 | self.ctrl_obj.close() |
1840 | |
1841 | - def on_button_clear_clicked(self,widget) : |
1842 | - print "BUTTON clear clicked" |
1843 | - self.PreviewObj.isDisplayAllowed = False |
1844 | - |
1845 | - |
1846 | + def on_file_close_activate(self,widget): |
1847 | + print "file close activate " |
1848 | + self.ctrl_obj.close() |
1849 | + |
1850 | + def on_view_project_activate(self,widget): |
1851 | + print " view project ptoperties " |
1852 | + self.ctrl_obj.project_properties() |
1853 | + |
1854 | + |
1855 | + def __UpdateAbout(self, aboutWidget) : |
1856 | + """ Update with version of about window""" |
1857 | + strRev= '%(revno)d' % _version.version_info |
1858 | + strBranch = '%(branch_nick)s'% _version.version_info |
1859 | + strVersion = "\n %s (%s)"%(strBranch,strRev) |
1860 | + aboutWidget.set_version(strVersion) |
1861 | + |
1862 | + def on_help_about_activate(self,widget): |
1863 | + print "On help about activate" |
1864 | + aboutdialog = self.builder.get_object('aboutdialog') |
1865 | + self.__UpdateAbout(aboutdialog) |
1866 | + aboutdialog.show_all() |
1867 | + result = aboutdialog.run() |
1868 | + aboutdialog.destroy() |
1869 | + |
1870 | + |
1871 | + def on_window_delete_event(self,widget,event): |
1872 | + print " destroy/delete event : ", event.type |
1873 | + self.ctrl_obj.quit() |
1874 | + # the 'return true' avoid the automatic close of application |
1875 | + return True |
1876 | + |
1877 | |
1878 | === modified file 'lucioLib/gui/luciole_drawaera.py' |
1879 | --- lucioLib/gui/luciole_drawaera.py 2009-04-10 10:22:46 +0000 |
1880 | +++ lucioLib/gui/luciole_drawaera.py 2009-04-13 20:10:28 +0000 |
1881 | @@ -33,13 +33,11 @@ |
1882 | @version 1 |
1883 | """ |
1884 | |
1885 | -from .. import luciole_global as MG |
1886 | -from .. import luciole_acquisition as MA |
1887 | -from .. import luciole_tools as MT |
1888 | -from .. import luciole_exceptions as M_EXCEP |
1889 | +from .. import luciole_tools as LT |
1890 | +from .. import luciole_exceptions as L_EXCEP |
1891 | import gtk |
1892 | |
1893 | -class PreviewPixbuf(MT.Singleton) : |
1894 | +class PreviewPixbuf(LT.Singleton) : |
1895 | """ Class for mamaging the display of image/pixbuf in the Preview window (drawing area)""" |
1896 | |
1897 | def f_get_pixbufToDisplay(self) : |
1898 | @@ -71,7 +69,7 @@ |
1899 | """ init of module PreviewPixbuf""" |
1900 | if DAwidget == None : |
1901 | # raise exception no drawarea widget given |
1902 | - raise M_EXCEP.LucioException,"No Drawing area defined" |
1903 | + raise L_EXCEP.LucioException,"No Drawing area defined" |
1904 | else : |
1905 | self.__DAwidget = DAwidget #drawingArea widget |
1906 | self.__DAwidget.connect("expose-event",self.on_expose_event) |
1907 | @@ -118,34 +116,4 @@ |
1908 | self.displayDefault() |
1909 | |
1910 | |
1911 | -class CameraPixbuf(PreviewPixbuf) : |
1912 | - """ Class for mamaging the display of image/pixbuf in the Camera window (drawing area). Inherited |
1913 | - from PreviewPixbuf. """ |
1914 | - |
1915 | - def __init__(self,DAwidget): |
1916 | - """ init of module CameraPixbuf.""" |
1917 | - PreviewPixbuf.__init__(self,DAwidget) |
1918 | - |
1919 | - def _PreviewImage(self,pixbuf): |
1920 | - """ Display of the pixbuf image in the Camera drawing area. |
1921 | - An image can be displayed only when streaming display is not active.""" |
1922 | - #test if acquisition obj exist |
1923 | - if not MA.luciole_acquisition.__name__ in MG.luciole_global.dico: |
1924 | - # pas d object acquisition on peut afficher |
1925 | - PreviewPixbuf._PreviewImage(self,pixbuf) |
1926 | - elif not MG.luciole_global.dico[MA.luciole_acquisition.__name__].IsStreamingActive : |
1927 | - # streaming is not active, Display is allowed |
1928 | - PreviewPixbuf._PreviewImage(self,pixbuf) |
1929 | - |
1930 | - def displayDefault(self): |
1931 | - """ When no image/pixbuf need to be displayed, a black background screen is displayed |
1932 | - The background is dispalyed when streaming display is not active.""" |
1933 | - #test if acquisition obj exist |
1934 | - if not MA.luciole_acquisition.__name__ in MG.luciole_global.dico: |
1935 | - # pas d object acquisition on peut afficher |
1936 | - PreviewPixbuf.displayDefault(self) |
1937 | - elif not MG.luciole_global.dico[MA.luciole_acquisition.__name__].IsStreamingActive : |
1938 | - # streaming is not active, Display is allowed |
1939 | - PreviewPixbuf.displayDefault(self) |
1940 | - |
1941 | - |
1942 | + |
1943 | |
1944 | === added file 'lucioLib/gui/open_project_widget.py' |
1945 | --- lucioLib/gui/open_project_widget.py 1970-01-01 00:00:00 +0000 |
1946 | +++ lucioLib/gui/open_project_widget.py 2009-04-13 11:02:22 +0000 |
1947 | @@ -0,0 +1,69 @@ |
1948 | +#!/usr/bin/env python |
1949 | +# -*- coding: utf-8 -*- |
1950 | +# -*- Mode: Python -*- |
1951 | +# vi:si:ai:et:sw=4:sts=4:ts=4 |
1952 | +# |
1953 | +# Copyright Nicolas Bertrand (nico@inattendu.org), 2009 |
1954 | +# |
1955 | +# This file is part of Luciole. |
1956 | +# |
1957 | +# Luciole is free software: you can redistribute it and/or modify |
1958 | +# it under the terms of the GNU General Public License as published by |
1959 | +# the Free Software Foundation, either version 3 of the License, or |
1960 | +# (at your option) any later version. |
1961 | +# |
1962 | +# Luciole is distributed in the hope that it will be useful, |
1963 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1964 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1965 | +# GNU General Public License for more details. |
1966 | +# |
1967 | +# You should have received a copy of the GNU General Public License |
1968 | +# along with Luciole. If not, see <http://www.gnu.org/licenses/>. |
1969 | +# |
1970 | +# |
1971 | +""" |
1972 | + widgets who propose open/new project when no project are loaded |
1973 | +""" |
1974 | + |
1975 | +import gtk |
1976 | +from gettext import gettext as _ |
1977 | + |
1978 | +class Gui_open_project_widget(gtk.HButtonBox) : |
1979 | + """ widget for diplay New/open project buttons """ |
1980 | + |
1981 | + # some constants for widget |
1982 | + _WIDTH_REQUEST =-1 |
1983 | + _HEIGHT_REQUEST = 51 # same value as hbox_acquisition in glade |
1984 | + _IMAGE_POS = gtk.POS_TOP |
1985 | + |
1986 | + def __init__(self,cb_new,cb_open) : |
1987 | + super(Gui_open_project_widget,self).__init__() |
1988 | + |
1989 | + # ste widget properties |
1990 | + self.set_name('hbox_open_project') |
1991 | + self.set_size_request(self._WIDTH_REQUEST, self._HEIGHT_REQUEST) |
1992 | + self.set_layout(gtk.BUTTONBOX_SPREAD) |
1993 | + self.set_spacing(25) |
1994 | + self.set_homogeneous(True) |
1995 | + |
1996 | + # create New button project |
1997 | + msg = _('Create a new project') |
1998 | + Button = gtk.Button(msg) |
1999 | + Button.set_image(gtk.image_new_from_stock(gtk.STOCK_NEW,gtk.ICON_SIZE_BUTTON)) |
2000 | + Button.set_property('image-position',self._IMAGE_POS) |
2001 | + Button.connect('clicked',cb_new) |
2002 | + self.pack_start(Button,expand = False, fill = False) |
2003 | + Button.show() |
2004 | + |
2005 | + # create open button project |
2006 | + msg = _('Open an existing project') |
2007 | + Button = gtk.Button(msg) |
2008 | + Button.set_image(gtk.image_new_from_stock(gtk.STOCK_OPEN,gtk.ICON_SIZE_BUTTON)) |
2009 | + Button.set_property('image-position',self._IMAGE_POS) |
2010 | + Button.connect('clicked',cb_open) |
2011 | + self.pack_start(Button,expand = False, fill = False) |
2012 | + Button.show() |
2013 | + |
2014 | + # show widget |
2015 | + self.show() |
2016 | + |
2017 | |
2018 | === removed directory 'lucioLib/lucioImageCapture' |
2019 | === removed file 'lucioLib/lucioImageCapture/__init__.py' |
2020 | --- lucioLib/lucioImageCapture/__init__.py 2009-03-08 18:06:41 +0000 |
2021 | +++ lucioLib/lucioImageCapture/__init__.py 1970-01-01 00:00:00 +0000 |
2022 | @@ -1,25 +0,0 @@ |
2023 | -#!/usr/bin/env python |
2024 | -# -*- coding: utf-8 -*- |
2025 | -# -*- Mode: Python -*- |
2026 | -# vi:si:ai:et:sw=4:sts=4:ts=4 |
2027 | -# |
2028 | -# |
2029 | -# Copyright Nicolas Bertrand (nico@inattendu.org), 2009 |
2030 | -# |
2031 | -# This file is part of Luciole. |
2032 | -# |
2033 | -# Luciole is free software: you can redistribute it and/or modify |
2034 | -# it under the terms of the GNU General Public License as published by |
2035 | -# the Free Software Foundation, either version 3 of the License, or |
2036 | -# (at your option) any later version. |
2037 | -# |
2038 | -# Luciole is distributed in the hope that it will be useful, |
2039 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
2040 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2041 | -# GNU General Public License for more details. |
2042 | -# |
2043 | -# You should have received a copy of the GNU General Public License |
2044 | -# along with Luciole. If not, see <http://www.gnu.org/licenses/>. |
2045 | -# |
2046 | -# |
2047 | -from luciole_capture_image import * |
2048 | |
2049 | === removed file 'lucioLib/lucioImageCapture/luciole_capture_image.py' |
2050 | --- lucioLib/lucioImageCapture/luciole_capture_image.py 2009-03-08 18:06:41 +0000 |
2051 | +++ lucioLib/lucioImageCapture/luciole_capture_image.py 1970-01-01 00:00:00 +0000 |
2052 | @@ -1,177 +0,0 @@ |
2053 | -#!/usr/bin/env python |
2054 | -# -*- coding: utf-8 -*- |
2055 | -# |
2056 | -# |
2057 | -# Copyright Nicolas Bertrand (nico@inattendu.org), 2009 |
2058 | -# |
2059 | -# This file is part of Luciole. |
2060 | -# |
2061 | -# Luciole is free software: you can redistribute it and/or modify |
2062 | -# it under the terms of the GNU General Public License as published by |
2063 | -# the Free Software Foundation, either version 3 of the License, or |
2064 | -# (at your option) any later version. |
2065 | -# |
2066 | -# Luciole is distributed in the hope that it will be useful, |
2067 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
2068 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2069 | -# GNU General Public License for more details. |
2070 | -# |
2071 | -# You should have received a copy of the GNU General Public License |
2072 | -# along with Luciole. If not, see <http://www.gnu.org/licenses/>. |
2073 | -# |
2074 | -# |
2075 | -import os |
2076 | -import sys |
2077 | -import dircache |
2078 | -import fnmatch |
2079 | -import shutil |
2080 | -import time |
2081 | -import subprocess as SP |
2082 | -import threading |
2083 | -from .. import luciole_exceptions as M_EXCEP |
2084 | - |
2085 | -class luciole_capture_image(object) : |
2086 | - """ class for acquiring and transformaing images from an external source""" |
2087 | - |
2088 | - class mythread(threading.Thread) : |
2089 | - def __init__(self,myId,convert_cmd) : |
2090 | - self.myId = myId |
2091 | - self.convert_cmd = convert_cmd |
2092 | - threading.Thread.__init__(self) |
2093 | - def run(self): |
2094 | - print " converting %s with id %s"%(self.convert_cmd,self.myId) |
2095 | - pconvert =SP.call(self.convert_cmd,shell=True) |
2096 | - |
2097 | - |
2098 | - ############################################################ |
2099 | - # PROPERTIES DECLARATION |
2100 | - ############################################################ |
2101 | - def _get_ImageSourcePath(self) : return self._imageSourcePath |
2102 | - def _set_ImageSourcePath(self,path) : |
2103 | - try : |
2104 | - self._imageSourcePath =self.mkdirs(path) |
2105 | - except M_EXCEP.LucioException,err : |
2106 | - raise M_EXCEP.LucioException, err.message |
2107 | - |
2108 | - imageSourcePath=property(_get_ImageSourcePath,_set_ImageSourcePath,doc ="Path from where the image souce is") |
2109 | - |
2110 | - def _get_rawImageStorePath(self) : return self._rawImageStorePath |
2111 | - def _set_rawImageStorePath(self,path) : |
2112 | - try : |
2113 | - self._rawImageStorePath =self.mkdirs(path) |
2114 | - except M_EXCEP.LucioException,err : |
2115 | - raise M_EXCEP.LucioException, err.message |
2116 | - rawImageStorePath=property(_get_rawImageStorePath,_set_rawImageStorePath,doc ="Path to store the raw images") |
2117 | - |
2118 | - def _get_scaledImageStorePath(self) : return self._scaledImageStorePath |
2119 | - def _set_scaledImageStorePath(self,path) : |
2120 | - try : |
2121 | - self._scaledImageStorePath=self.mkdirs(path) |
2122 | - except M_EXCEP.LucioException,err : |
2123 | - raise M_EXCEP.LucioException, err.message |
2124 | - scaledImageStorePath=property(_get_scaledImageStorePath,_set_scaledImageStorePath,doc ="Path to store the scaled images") |
2125 | - |
2126 | - |
2127 | - ############################################################ |
2128 | - ### CONSTRUCTOR |
2129 | - ############################################################ |
2130 | - def __init__(self,imageSourcePath,rawImageStorePath,scaledImageStorePath) : |
2131 | - """ luciole_capture_image class_constructor""" |
2132 | - # properties local variable init |
2133 | - try : |
2134 | - self._imageSourcePath =self.mkdirs(imageSourcePath) |
2135 | - except M_EXCEP.LucioException,err : |
2136 | - raise M_EXCEP.LucioException, err.message |
2137 | - try : |
2138 | - self._rawImageStorePath =self.mkdirs(rawImageStorePath) |
2139 | - except M_EXCEP.LucioException,err : |
2140 | - print err.message |
2141 | - try : |
2142 | - self._scaledImageStorePath =self.mkdirs(scaledImageStorePath) |
2143 | - except M_EXCEP.LucioException,err : |
2144 | - print err.message |
2145 | - |
2146 | - |
2147 | - ############################################################ |
2148 | - ### PUBLIC METHODS |
2149 | - ############################################################ |
2150 | - |
2151 | - def test_image_source(self) : |
2152 | - """ test if the image source is available. |
2153 | - Return True if it is detected. """ |
2154 | - Valid = False |
2155 | - if os.path.exists(self._imageSourcePath): Valid =True |
2156 | - return Valid |
2157 | - |
2158 | - def get_images_from_source(self) : |
2159 | - """ method to get all the images from the source""" |
2160 | - fl = dircache.listdir(self._imageSourcePath) |
2161 | - patternMatch="*.[Jj][Pp][GgeE]*" |
2162 | - filterList =fnmatch.filter(fl,patternMatch) |
2163 | - time_cpStart =time.time() |
2164 | - for file in filterList : |
2165 | - shutil.copy2(os.path.join(self._imageSourcePath,file),self._rawImageStorePath) |
2166 | - time_cpStop =time.time() |
2167 | - print " Copy duration %s s "%(time_cpStop-time_cpStart) |
2168 | - |
2169 | - #transform image |
2170 | - t0 = os.times() |
2171 | - #stdoutmutex = threading.Lock() |
2172 | - threads=[] |
2173 | - count = 0 |
2174 | - for file in filterList : |
2175 | - convert_cmd = "convert "+os.path.join(self._rawImageStorePath,file) + " -resize 720x576\> -size 720x576 xc:black +swap -gravity center -composite "+os.path.join(self.scaledImageStorePath,file) |
2176 | - #print convert_cmd |
2177 | - #thread.start_new(self.image_conversion,(convert_cmd,)) |
2178 | - #self.image_conversion(convert_cmd) |
2179 | - thread =self.mythread(count,convert_cmd) |
2180 | - thread.start() |
2181 | - threads.append(thread) |
2182 | - count = count+1 |
2183 | - for thread in threads: |
2184 | - thread.join() |
2185 | - print " Main thread exiting" |
2186 | - t1=os.times() |
2187 | - print " Conversion duration %s s"%(t1[4] - t0[4]) |
2188 | - print " sub process time %s s"%(t1[2] - t0[2]) |
2189 | - |
2190 | - filterList = map(lambda x:os.path.join(self.scaledImageStorePath,x),filterList) |
2191 | - return filterList |
2192 | - |
2193 | -# def image_conversion(self,convert_cmd) : |
2194 | -# pconvert =SP.call(convert_cmd,shell=True) |
2195 | - |
2196 | - ############################################################ |
2197 | - ### PRIVATE METHODS |
2198 | - ############################################################ |
2199 | - def mkdirs(self,Path) : |
2200 | - """ makedirs used for import""" |
2201 | - if not os.path.exists(Path): |
2202 | - try : |
2203 | - os.makedirs(Path) |
2204 | - except OSError,err : |
2205 | - raise M_EXCEP.LucioException, err.strerror + " on : "+err.filename |
2206 | - finally : |
2207 | - ValidPath=Path |
2208 | - else : |
2209 | - ValidPath=Path |
2210 | - print "chemin =", ValidPath |
2211 | - return ValidPath |
2212 | - |
2213 | - |
2214 | -#try : |
2215 | -# X=luciole_capture_image('/var/log/photos','/var/log/src','/var/log/capture') |
2216 | -#except M_EXCEP.LucioException,err : |
2217 | -# print err.message |
2218 | - |
2219 | -#try : |
2220 | -# X=luciole_capture_image('photos','src','capture') |
2221 | -#except M_EXCEP.LucioException,err : |
2222 | -# print err.message |
2223 | -#else : |
2224 | -# X.get_images_from_source() |
2225 | - |
2226 | -#while 1: |
2227 | -# if raw_input() == 'q' : break |
2228 | - |
2229 | - |
2230 | |
2231 | === modified file 'lucioLib/luciole_acquisition.py' |
2232 | --- lucioLib/luciole_acquisition.py 2009-04-10 17:24:54 +0000 |
2233 | +++ lucioLib/luciole_acquisition.py 2009-04-13 20:10:28 +0000 |
2234 | @@ -30,7 +30,6 @@ |
2235 | import luciole_constants as LCONST |
2236 | import luciole_exceptions as M_EXCEP |
2237 | import os.path |
2238 | -import lucioImageCapture |
2239 | |
2240 | |
2241 | class luciole_acquisition(object) : |
2242 | @@ -185,9 +184,7 @@ |
2243 | luciole_acquisition.__init__(self,display,False,LCONST.DIGICAM,None) |
2244 | try : |
2245 | pass |
2246 | - # WARNING the src dir object is missing !!! |
2247 | - # to define coorectly |
2248 | - # self.importObj = lucioImageCapture.luciole_capture_image(os.path.expandvars('$HOME'),self.ProjectObj.src_dir,self.ProjectObj.capture_dir) |
2249 | + # tbd |
2250 | except M_EXCEP.LucioException, err: |
2251 | print err.message |
2252 | |
2253 | |
2254 | === removed file 'lucioLib/luciole_class.py' |
2255 | --- lucioLib/luciole_class.py 2009-03-08 18:06:41 +0000 |
2256 | +++ lucioLib/luciole_class.py 1970-01-01 00:00:00 +0000 |
2257 | @@ -1,794 +0,0 @@ |
2258 | -#!/usr/bin/env python |
2259 | -# -*- coding: UTF-8 -*- |
2260 | -# |
2261 | -# Copyright Nicolas Bertrand (nico@inattendu.org), 2009 |
2262 | -# |
2263 | -# This file is part of Luciole. |
2264 | -# |
2265 | -# Luciole is free software: you can redistribute it and/or modify |
2266 | -# it under the terms of the GNU General Public License as published by |
2267 | -# the Free Software Foundation, either version 3 of the License, or |
2268 | -# (at your option) any later version. |
2269 | -# |
2270 | -# Luciole is distributed in the hope that it will be useful, |
2271 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
2272 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2273 | -# GNU General Public License for more details. |
2274 | -# |
2275 | -# You should have received a copy of the GNU General Public License |
2276 | -# along with Luciole. If not, see <http://www.gnu.org/licenses/>. |
2277 | -# |
2278 | -# |
2279 | - |
2280 | -# |
2281 | -# Copyright Nicolas Bertrand (nico@inattendu.org), 2009 |
2282 | -# |
2283 | -# This file is part of Luciole. |
2284 | -# |
2285 | -# Luciole is free software: you can redistribute it and/or modify |
2286 | -# it under the terms of the GNU General Public License as published by |
2287 | -# the Free Software Foundation, either version 3 of the License, or |
2288 | -# (at your option) any later version. |
2289 | -# |
2290 | -# Luciole is distributed in the hope that it will be useful, |
2291 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
2292 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2293 | -# GNU General Public License for more details. |
2294 | -# |
2295 | -# You should have received a copy of the GNU General Public License |
2296 | -# along with Luciole. If not, see <http://www.gnu.org/licenses/>. |
2297 | -# |
2298 | -# |
2299 | - |
2300 | -import pygtk |
2301 | -pygtk.require("2.0") |
2302 | - |
2303 | -import os.path |
2304 | -import shutil |
2305 | -import gtk |
2306 | -import gtk.glade |
2307 | -import luciole_global as MG |
2308 | -import luciole_file_in_out as MF |
2309 | -import luciole_constants as MCONST |
2310 | -import luciole_tools as MT |
2311 | -import luciole_exceptions as M_EXCEP |
2312 | -import gobject |
2313 | -import threading |
2314 | - |
2315 | -import time |
2316 | - |
2317 | -from gettext import gettext as _ |
2318 | - |
2319 | -class MyThumbThread(threading.Thread): |
2320 | - """ Thread class for genertion of a thumbnail""" |
2321 | - |
2322 | - def __init__(self,image,index,liststore): |
2323 | - """ class creation for thread : |
2324 | - inputs are ; |
2325 | - image : image object to generate thumbnail |
2326 | - index : position of image in image list |
2327 | - liststore : treeview model |
2328 | - """ |
2329 | - super(MyThumbThread, self).__init__() |
2330 | - self.quit = False |
2331 | - self.image = image |
2332 | - self.index = index |
2333 | - self.liststore = liststore |
2334 | - |
2335 | - def updateTreeview(self, liststore, image,index): |
2336 | - """ callback to be executed when thread run is finished. |
2337 | - Update the treeview with the generated thumnbnail""" |
2338 | - iter = liststore.get_iter( (index,) ) # get iter from treeview |
2339 | - liststore.set_value(iter,LucioleGtkTreeView.COL_PIXBUF,image.pixbuf_icon) # update of treeview |
2340 | - return False |
2341 | - |
2342 | - def run(self): |
2343 | - """ Thread execution --> generation of thumbnail""" |
2344 | - self.image.load_pixbuf_icon() |
2345 | - gobject.idle_add(self.updateTreeview, self.liststore,self.image, self.index) |
2346 | - |
2347 | -class ThumbTimer(object) : |
2348 | - """ |
2349 | - This class schedule the generation of thumbnail with a timer. |
2350 | - Periodically parse the imagelist for not generated thumbnail |
2351 | - """ |
2352 | - |
2353 | - def __init__(self, timeout_ms = 50 , startTimer = False,image_list =None, liststore=None) : |
2354 | - """ |
2355 | - Class init. |
2356 | - inputs : |
2357 | - - timeout_ms : period of the timer in ms |
2358 | - - startTimer : to start immediatly the timer after object creation |
2359 | - - image_list : The image list to parse |
2360 | - - liststore : Treeview model , used for update treeview with generated thumbnail |
2361 | - """ |
2362 | - self._timer_id = None |
2363 | - self._timeout_ms = timeout_ms |
2364 | - self._image_list = image_list |
2365 | - self._liststore = liststore |
2366 | - self._nbThreadsMax=2 # nb of thread to start at the same time |
2367 | - |
2368 | - if (startTimer) : self._start_timer() |
2369 | - |
2370 | - def _start_timer(self) : |
2371 | - """ start the timer """ |
2372 | - self._timer_id=gobject.timeout_add(self._timeout_ms,self._on_timeout) |
2373 | - self._t0 = os.times() |
2374 | - self.PJL = True |
2375 | - |
2376 | - def _on_timeout (self) : |
2377 | - """ |
2378 | - callback called each timer time_out. |
2379 | - Parse the image list looking for not generated pixbuf, when occurs start a thread for thumbnail generation. |
2380 | - """ |
2381 | - nbThreads=0 |
2382 | - for index,image in enumerate(self._image_list) : |
2383 | - if not image.is_icon_loaded : |
2384 | - # launch thread for icon generation |
2385 | - t = MyThumbThread(image,index,self._liststore) |
2386 | - t.start() |
2387 | - nbThreads += 1 |
2388 | - # stop the loop when max number of thread is reach |
2389 | - if nbThreads >= self._nbThreadsMax : break |
2390 | - return True |
2391 | - |
2392 | -class LucioleImage(object): |
2393 | - """Managing Images inside luciole""" |
2394 | - |
2395 | - def __init__(self,imagePath,iconDefault,imageDefault): |
2396 | - """ init of Luciole Image """ |
2397 | - #splash=gtk.gdk.pixbuf_new_from_file("images/black.png") |
2398 | - self._iconPixbufDefault= iconDefault |
2399 | - self._normalPixbufDefault= imageDefault |
2400 | - self._load_from_file(imagePath) |
2401 | - |
2402 | - def _get_imageName(self): return self.__imageName |
2403 | - def _set_imageName(self, value): self.__imageName = value |
2404 | - def _del_imageName(self): del self.__imageName |
2405 | - imageName = property(_get_imageName, _set_imageName, _del_imageName, "Image's name. ") |
2406 | - |
2407 | - def _get_imagePath(self): return self.__imagePath |
2408 | - def _set_imagePath(self, value): self.__imagePath = value |
2409 | - def _del_imagePath(self): del self.__imagePath |
2410 | - imagePath = property(_get_imagePath, _set_imagePath, _del_imagePath, "Image's location/path.") |
2411 | - |
2412 | - def _get_fullName(self): return os.path.join(self.__imagePath,self.__imageName) |
2413 | - fullName = property (_get_fullName,None,None," Image complete path") |
2414 | - |
2415 | - def get_pixbuf_icon(self): return self.__pixbuf_icon |
2416 | - def set_pixbuf_icon(self, value): self.__pixbuf_icon = value |
2417 | - def del_pixbuf_icon(self): del self.__pixbuf_icon |
2418 | - pixbuf_icon = property(get_pixbuf_icon, set_pixbuf_icon, del_pixbuf_icon, "GtkPixbuf object of icon image.") |
2419 | - |
2420 | - def get_is_icon_loaded(self): return self.__is_icon_loaded |
2421 | - def set_is_icon_loaded(self, value): self.__is_icon_loaded = value |
2422 | - def del_is_icon_loaded(self): del self.__is_icon_loaded |
2423 | - is_icon_loaded = property(get_is_icon_loaded, set_is_icon_loaded, del_is_icon_loaded, "True if the icon is computed (pixbuf Transformation)") |
2424 | - |
2425 | - def get_pixbuf_normal(self): return self.__pixbuf_normal |
2426 | - def set_pixbuf_normal(self, value): self.__pixbuf_normal = value |
2427 | - def del_pixbuf_normal(self): del self.__pixbuf_normal |
2428 | - pixbuf_normal = property(get_pixbuf_normal, set_pixbuf_normal, del_pixbuf_normal, "GtkPixbuf object of icon image.") |
2429 | - |
2430 | - def get_is_normal_loaded(self): return self.__is_normal_loaded |
2431 | - def set_is_normal_loaded(self, value): self.__is_normal_loaded = value |
2432 | - def del_is_normal_loaded(self): del self.__is_normal_loaded |
2433 | - is_normal_loaded = property(get_is_normal_loaded, set_is_normal_loaded, del_is_normal_loaded, " True if icon image is loaded") |
2434 | - |
2435 | - def load_pixbuf_icon(self): |
2436 | - """Load pixbuf for thumbnail in treeview""" |
2437 | - pixbuf=gtk.gdk.pixbuf_new_from_file(self.__imagePath+"/"+self.__imageName) |
2438 | - self.__pixbuf_icon=pixbuf.scale_simple(MCONST.VIDEO_PAL_RES[0]/16, MCONST.VIDEO_PAL_RES[1]/16,gtk.gdk.INTERP_BILINEAR) |
2439 | - # set as computed |
2440 | - self.__is_icon_loaded = True |
2441 | - return self.__pixbuf_icon |
2442 | - |
2443 | - def load_pixbuf_normal(self): |
2444 | - """Load pixbuf for image to Display""" |
2445 | - pixbuf=gtk.gdk.pixbuf_new_from_file(self.__imagePath+"/"+self.__imageName) |
2446 | - self.__pixbuf_normal=pixbuf.scale_simple(MCONST.VIDEO_PAL_RES[0], MCONST.VIDEO_PAL_RES[1],gtk.gdk.INTERP_BILINEAR) |
2447 | - self.__is_normal_loaded =True |
2448 | - return self.__pixbuf_normal |
2449 | - |
2450 | - def load_from_file(self,imageLocation) : |
2451 | - """load a luciole image from a file""" |
2452 | - self._load_from_file(self,imageLocation) |
2453 | - |
2454 | - def _load_from_file(self,imageLocation) : |
2455 | - """ Private function for loading images""" |
2456 | - if os.path.isfile(imageLocation) : |
2457 | - tsplit=os.path.split(imageLocation) |
2458 | - self.__imagePath=tsplit[0] |
2459 | - self.__imageName=tsplit[1] |
2460 | - self.__pixbuf_icon = self._iconPixbufDefault |
2461 | - self.__is_icon_loaded = False |
2462 | - self.__pixbuf_normal=self._normalPixbufDefault |
2463 | - self.__is_normal_loaded = False |
2464 | - else : |
2465 | - print " Not a file :",imageLocation |
2466 | - |
2467 | - |
2468 | -class LucioleImageList(list): |
2469 | - """ List of luciole image """ |
2470 | - def __init__(self): |
2471 | - """ Init of luciole image list """ |
2472 | - list.__init__(self) |
2473 | - splash =gtk.gdk.pixbuf_new_from_file("images/black.png") |
2474 | - self._black_icon=splash.scale_simple(MCONST.VIDEO_PAL_RES[0]/16, MCONST.VIDEO_PAL_RES[1]/16,gtk.gdk.INTERP_BILINEAR) |
2475 | - self._black_normal=splash.scale_simple(MCONST.VIDEO_PAL_RES[0], MCONST.VIDEO_PAL_RES[1],gtk.gdk.INTERP_BILINEAR) |
2476 | - |
2477 | - |
2478 | - def move_after(self,src,dest) : |
2479 | - """ Insert src element after dest element""" |
2480 | - x = self[src] |
2481 | - self.insert(dest+1,x) |
2482 | - del self[src] |
2483 | - |
2484 | - def move_before(self,src,dest) : |
2485 | - """ Insert src element before dest elemenst""" |
2486 | - x = self[src] |
2487 | - del self[src] |
2488 | - self.insert(dest,x) |
2489 | - |
2490 | - def append_from_file(self,ImagePath) : |
2491 | - """ Append a pixbuf from file """ |
2492 | - x=LucioleImage(ImagePath,self._black_icon,self._black_normal) |
2493 | - self.append(x) |
2494 | - return x |
2495 | - |
2496 | -class LucioleGtkTreeView(object) : |
2497 | - """ gtk Treeview for handling the cpature Treeview""" |
2498 | - |
2499 | - ############################################################ |
2500 | - ### Class properties |
2501 | - ############################################################ |
2502 | - |
2503 | - def _get_widgetName(self): return self.__widgetName |
2504 | - def _set_widgetName(self, value): self.__widgetName = value |
2505 | - def _del_widgetName(self): del self.__widgetName |
2506 | - widgetName = property(_get_widgetName, _set_widgetName, _del_widgetName, " Treeview name") |
2507 | - |
2508 | - def _get_imageFileIndex(self): return self.__imageFileIndex |
2509 | - def _set_imageFileIndex(self, value): self.__imageFileIndex = value |
2510 | - def _del_imageFileIndex(self): del self.__imageFileIndex |
2511 | - imageFileIndex = property(_get_imageFileIndex, _set_imageFileIndex, _del_imageFileIndex, "Image file index ") |
2512 | - |
2513 | - __titreList = { |
2514 | - "treeview_capture" : 'image', |
2515 | - "treeview_montage" : 'image' |
2516 | - } |
2517 | - |
2518 | - liststore=None |
2519 | - (COL_NUM, COL_PIXBUF, COL_IMAGENAME, COL_TS ) = range(4) |
2520 | - |
2521 | - def __init__(self,TreeViewWidget, previsuArea,CameraArea) : |
2522 | - if (TreeViewWidget.get_name() in self.__titreList) : |
2523 | - #init of global dictionary |
2524 | - if not self.__class__.__name__ in MG.luciole_global.dico : |
2525 | - MG.luciole_global.dico[self.__class__.__name__] = self |
2526 | - else : |
2527 | - print "l objet",self.__class__.__name__," existe deja" |
2528 | - return None |
2529 | - #mode save (CAPTURE or CHRONO) |
2530 | - self.mode = MG.luciole_global.CAPTURE |
2531 | - #sauvergarde du widget de previsu |
2532 | - self.__previewObj = previsuArea |
2533 | - self.__CamPreviewObj = CameraArea |
2534 | - # definition of Treeview wigdet |
2535 | - self.TreeViewWidget = TreeViewWidget |
2536 | - self.__widgetName = TreeViewWidget.get_name() |
2537 | - # TreeView model init |
2538 | - self.liststore = gtk.ListStore(int,gtk.gdk.Pixbuf,str,float) |
2539 | - self.TreeViewWidget.set_model(self.liststore) |
2540 | - #colonne Image et Icone |
2541 | - __column = gtk.TreeViewColumn() |
2542 | - __column.set_title(_('image')) |
2543 | - self.TreeViewWidget.append_column(__column) |
2544 | - __renderer = gtk.CellRendererPixbuf() |
2545 | - __column.pack_start(__renderer, expand=False) |
2546 | - __column.add_attribute(__renderer, 'pixbuf', self.COL_PIXBUF) |
2547 | - __renderer = gtk.CellRendererText() |
2548 | - __column.pack_start(__renderer, expand=True) |
2549 | - __column.add_attribute(__renderer, 'text', self.COL_IMAGENAME) |
2550 | - # settings de la fenetre TreeView |
2551 | - # make treeview searchable |
2552 | - self.TreeViewWidget.set_search_column(0) |
2553 | - # Allow sorting on the column |
2554 | - __column.set_sort_column_id(0) |
2555 | - # Allow drag and drop reordering of rows |
2556 | - self.TreeViewWidget.set_reorderable(True) |
2557 | - |
2558 | - # init de la list |
2559 | - self.imageList = LucioleImageList() |
2560 | - |
2561 | - #on recuperere le widget treeSelection |
2562 | - self.treeselection = self.TreeViewWidget.get_selection() |
2563 | - # allow multiple selection |
2564 | - self.treeselection.set_mode(gtk.SELECTION_MULTIPLE) |
2565 | - # image File name index init |
2566 | - self.__imageFileIndex = 0 |
2567 | - |
2568 | - #tests sur le drag and drop |
2569 | - self.TARGETS = [ |
2570 | - ('MY_TREE_MODEL_ROW', gtk.TARGET_SAME_WIDGET, 0), |
2571 | - ('text/plain', 0, 1), |
2572 | - ('TEXT', 0, 2), |
2573 | - ('STRING', 0, 3), |
2574 | - ] |
2575 | - self.TreeViewWidget.enable_model_drag_source( gtk.gdk.BUTTON1_MASK, |
2576 | - self.TARGETS, |
2577 | - gtk.gdk.ACTION_DEFAULT| |
2578 | - gtk.gdk.ACTION_COPY) |
2579 | - #self.treeview.enable_model_drag_dest(self.TARGETS, |
2580 | - #gtk.gdk.ACTION_DEFAULT) |
2581 | - self.TreeViewWidget.connect("drag_data_get", self._drag_data_get_data) |
2582 | - #self.treeview.connect("drag_data_received", |
2583 | - #self.drag_data_received_data) |
2584 | - |
2585 | - # handle of "cursor-changed" signal |
2586 | - self.TreeViewWidget.connect("cursor-changed",self.cb_cursor_changed) |
2587 | - |
2588 | - # start timer for generation of thumbs |
2589 | - ThumbsTimer = ThumbTimer(startTimer=True,image_list=self.imageList,liststore=self.liststore) |
2590 | - global _ |
2591 | - |
2592 | - ############################################################ |
2593 | - ### CALLBACKS |
2594 | - ############################################################ |
2595 | - |
2596 | - def cb_cursor_changed(self,treeview): |
2597 | - """ Call back on cursor change to allow display of an image when it is seleted """ |
2598 | - |
2599 | - # get cursor position |
2600 | - (path_cursor,col) = treeview.get_cursor() |
2601 | - # display selected image |
2602 | - self.previsualisation(self.liststore.get_iter(path_cursor)) |
2603 | - |
2604 | - |
2605 | - ############################################################ |
2606 | - ### PUBLIC METHODS |
2607 | - ############################################################ |
2608 | - |
2609 | - def AppendFromCapture(self,ImagePath) : |
2610 | - """Append an image from a display capture. the last available number and save the pixbuf to file.""" |
2611 | - |
2612 | - #get the listore len |
2613 | - file_index= len( self.liststore) + 1 |
2614 | - |
2615 | - # deplacement de l element |
2616 | - Filename ="capture_%05d"%self.__imageFileIndex + ".jpeg" |
2617 | - Path=MG.luciole_global.dico[MF.luciole_project_file.__name__].datas.capture_dir |
2618 | - DestPath = os.path.join(Path,Filename) |
2619 | - try : |
2620 | - MT.movef(ImagePath,DestPath) |
2621 | - except M_EXCEP.LucioException,err : |
2622 | - raise M_EXCEP.LucioException,err |
2623 | - DestPath = None |
2624 | - else : |
2625 | - # et on l ajoute a la liste |
2626 | - self.append(DestPath) |
2627 | - # affichage de l image captures dans la fenetre de previsu |
2628 | - self.previsualisation(self.liststore.get_iter((file_index-1,))); |
2629 | - # this function returns the Path of the image ; used for onion skin |
2630 | - |
2631 | - return DestPath |
2632 | - |
2633 | - def append(self,element,fromFile=False) : |
2634 | - """Add an element to Treeview and luciole Image List. |
2635 | - The fromFile boolean check if the append command is coming from the GUI (default), |
2636 | - of from an append commande comoing from a file load""" |
2637 | - if os.path.exists(element) : |
2638 | - x = self.imageList.append_from_file(element) |
2639 | - addedElem= self.liststore.append([len( self.liststore),x.pixbuf_icon,x.imageName,1.5]) |
2640 | - |
2641 | - if not fromFile : |
2642 | - # add on XML structure |
2643 | - ProjectFileObj = MG.luciole_global.dico[MF.luciole_project_file.__name__] |
2644 | - ProjectFileObj.append(self.mode,x.imageName) |
2645 | - # increment image index |
2646 | - self.__imageFileIndex =self.__imageFileIndex +1 |
2647 | - |
2648 | - treeselection = self.TreeViewWidget.get_selection() |
2649 | - treeselection.select_path((len(self.liststore) - 1,) ) |
2650 | - self.TreeViewWidget.scroll_to_cell((len(self.liststore)-1 ,)) |
2651 | - self.TreeViewWidget.set_cursor((len(self.liststore) -1 ,)) |
2652 | - |
2653 | - def LoadImagesfromProject(self,imageList): |
2654 | - """ Load a list of image from the project. ImageList is a list |
2655 | - with the absolute path to the image. """ |
2656 | - for image in imageList : |
2657 | - self.append(image,True) |
2658 | - # start timer for generation of thumbs |
2659 | - #ThumbsTimer = ThumbTimer(startTimer=True,image_list=self.imageList,liststore=self.liststore) |
2660 | - |
2661 | - def GetLastImagePath(self) : |
2662 | - """ return the last image of the tree """ |
2663 | - n_rows = len(self.liststore) |
2664 | - ImgPath = None |
2665 | - if (n_rows) : |
2666 | - iterL= self.liststore.get_iter( (n_rows-1,) ) |
2667 | - if (iterL) : |
2668 | - Image = self.get_LucioleImage(iterL) |
2669 | - ImgPath = os.path.join (Image.get_imagePath(),Image.get_imageName()) |
2670 | - |
2671 | - return ImgPath |
2672 | - |
2673 | - def clear_all(self): |
2674 | - """ Free all the elements in the list/tree """ |
2675 | - #remove all elements in imageList |
2676 | - self.imageList[:] =[] |
2677 | - self.liststore.clear() |
2678 | - self.__previewObj.pixbufToDisplay=None |
2679 | - return self.liststore |
2680 | - |
2681 | - def get_LucioleImage(self,iter): |
2682 | - """ From an iter return the image relative to the iter in treeview.""" |
2683 | - path = self.liststore.get_path(iter) |
2684 | - if (path) : |
2685 | - return self.imageList[path[0]] |
2686 | - |
2687 | - def remove_selection(self) : |
2688 | - """ remove selected items """ |
2689 | - (model, pathlist) = self.treeselection.get_selected_rows() |
2690 | - |
2691 | - # get the iter just after the selection |
2692 | - nextIter = self.liststore.iter_next(self.liststore.get_iter(pathlist[-1])) |
2693 | - iterList = map(lambda x : self.liststore.get_iter(x), pathlist) |
2694 | - # remove items |
2695 | - map(self._remove_iter,iterList) |
2696 | - #Select the next image |
2697 | - if (nextIter) : |
2698 | - # select nextIter |
2699 | - self.treeselection.select_iter(nextIter) |
2700 | - # previsualize net iter |
2701 | - self.previsualisation(nextIter) |
2702 | - else : |
2703 | - # lastitem was removed |
2704 | - # try to display the last image of the tree if not empty |
2705 | - if ( len(self.liststore) !=0 ) : |
2706 | - lastIter = self.liststore.get_iter((len(self.liststore) -1,)) |
2707 | - self.treeselection.select_iter(lastIter) |
2708 | - self.previsualisation(lastIter) |
2709 | - else : |
2710 | - # display nothing |
2711 | - self.previsualisation(None) |
2712 | - |
2713 | - def previsualisation(self,iter,display=MCONST.SCREEN_PREVIEW) : |
2714 | - """Preview of the image of a selected object in the treeview. |
2715 | - This method returns the path to the image.""" |
2716 | - #test on screen to be used |
2717 | - if (display == MCONST.SCREEN_CAMERA) : |
2718 | - displayObj = self.__CamPreviewObj |
2719 | - else : |
2720 | - displayObj = self.__previewObj |
2721 | - # recuperation du path de l'image puis display de l'image associé dans la liste |
2722 | - ImgPath = None |
2723 | - if (iter) : |
2724 | - path = self.liststore.get_path(iter) |
2725 | - if (path) : |
2726 | - ImgPath = os.path.join ( self.imageList[path[0]].imagePath , self.imageList[path[0]].imageName) |
2727 | - if(self.imageList[path[0]].pixbuf_normal) : |
2728 | - # test on availability of image to Display, if not compute pixbuf |
2729 | - if not self.imageList[path[0]].is_normal_loaded : |
2730 | - # pixbuf not available compute_it |
2731 | - self.imageList[path[0]].load_pixbuf_normal() |
2732 | - displayObj.pixbufToDisplay =self.imageList[path[0]].pixbuf_normal |
2733 | - else : |
2734 | - displayObj.displayDefault() |
2735 | - else : |
2736 | - displayObj.displayDefault() |
2737 | - else : |
2738 | - displayObj.displayDefault() |
2739 | - return ImgPath |
2740 | - |
2741 | - def GetImagePath(self,widget,iter) : |
2742 | - """ Get the image path of a selected image in treeview.""" |
2743 | - ImgPath = None |
2744 | - if (iter) : |
2745 | - path = self.liststore.get_path(iter) |
2746 | - if (path) : |
2747 | - ImgPath = os.path.join ( self.imageList[path[0]].imagePath , self.imageList[path[0]].imageName) |
2748 | - return ImgPath |
2749 | - |
2750 | - |
2751 | - ############################################################ |
2752 | - ### PRIVATE METHODS |
2753 | - ############################################################ |
2754 | - def _remove_iter(self,iter) : |
2755 | - """ Remove the selected element in treeview.""" |
2756 | - path = self.liststore.get_path(iter) |
2757 | - (imagePath,imageElement) =(self.imageList[path[0]].imagePath,self.imageList[path[0]].imageName) |
2758 | - ProjectFileObj = MG.luciole_global.dico[MF.luciole_project_file.__name__] |
2759 | - ProjectFileObj.remove(self.mode,path[0]) |
2760 | - |
2761 | - #MF.luciole_file_tools.move_to_trash(imagePath,imageElement) |
2762 | - # on la supprime d'image List |
2763 | - del self.imageList[path[0]] |
2764 | - # on la supprime de la treeview |
2765 | - self.liststore.remove(iter) |
2766 | - |
2767 | - def _drag_data_get_data(self, treeview, context, selection, target_id,etime): |
2768 | - """ Experrimental function for drag and drop . Not Implemented yet""" |
2769 | - treeselection = treeview.get_selection() |
2770 | - model, iter = treeselection.get_selected() |
2771 | - data = model.get_value(iter, self.COL_IMAGENAME) |
2772 | - selection.set('text/plain', 8, data) |
2773 | - |
2774 | - def _swap_iter(self,iter1,iter2) : |
2775 | - """ Swap of 2 elements in treeview. Swap of Image and image Name. The project |
2776 | - XML file is also updated""" |
2777 | - path1 = self.liststore.get_path(iter1) |
2778 | - path2 = self.liststore.get_path(iter2) |
2779 | - |
2780 | - pixbuf=self.liststore.get_value(iter1,self.COL_PIXBUF) |
2781 | - imageName=self.liststore.get_value(iter1,self.COL_IMAGENAME) |
2782 | - Lucioleimage = self.imageList[path1[0]] |
2783 | - self.liststore.set_value(iter1,self.COL_PIXBUF,self.liststore.get_value(iter2,self.COL_PIXBUF)) |
2784 | - self.liststore.set_value(iter1,self.COL_IMAGENAME,self.liststore.get_value(iter2,self.COL_IMAGENAME)) |
2785 | - self.imageList[path1[0]] = self.imageList[path2[0]] |
2786 | - self.liststore.set_value(iter2,self.COL_PIXBUF,pixbuf) |
2787 | - self.liststore.set_value(iter2,self.COL_IMAGENAME,imageName) |
2788 | - self.imageList[path2[0]] = Lucioleimage |
2789 | - |
2790 | - #on swap dans le fichier xml |
2791 | - ProjectFileObj = MG.luciole_global.dico['luciole_project_file'] |
2792 | - ProjectFileObj.swap(self.mode,path1[0],path2[0]) |
2793 | - |
2794 | - |
2795 | - def _testIter(self): |
2796 | - """ Test Function """ |
2797 | - treeiter = self.liststore.get_iter_first() |
2798 | - path=self.liststore.get_path(treeiter) |
2799 | - row =self.liststore[0] |
2800 | - for value in self.liststore : |
2801 | - print "coucou liststore " , value[0] |
2802 | - |
2803 | - def _dumpStore(self) : |
2804 | - """Test function""" |
2805 | - for value in self.liststore : |
2806 | - print str(value[self.COL_NUM]),str(value[self.COL_PIXBUF]),str(value[self.COL_IMAGENAME]) |
2807 | - |
2808 | - def _dumpImageList(self) : |
2809 | - """Test function""" |
2810 | - print "Image list " |
2811 | - for image in self.imageList : |
2812 | - print"\t",str(image.imageName) |
2813 | - |
2814 | - def treeview_idle(self) : |
2815 | - """ Executed in background""" |
2816 | - print "treeview_idle" |
2817 | - # Try on cursor move |
2818 | - #(dummy_model, iter) = self.treeselection.get_selected() |
2819 | - #if(iter): |
2820 | - # reucperation du chemin |
2821 | - # path = self.liststore.get_path(iter) |
2822 | - |
2823 | -class LucioleGtkTreeViewChrono(LucioleGtkTreeView) : |
2824 | - """ Manage The chrono TreeView . Inherited from LucioleGtkTreeView""" |
2825 | - def __init__(self,TreeViewWidget,previsuArea,CameraArea) : |
2826 | - """ init of LucioleGtkTreeViewChrono Module""" |
2827 | - LucioleGtkTreeView.__init__(self,TreeViewWidget,previsuArea,CameraArea) |
2828 | - |
2829 | - # init du type de mode |
2830 | - self.mode = MG.luciole_global.CHRONO |
2831 | - #colonne numero |
2832 | - __column = gtk.TreeViewColumn() |
2833 | - __column.set_title(_('Number')) |
2834 | - self.TreeViewWidget.insert_column(__column,self.COL_NUM) |
2835 | - __renderer = gtk.CellRendererText() |
2836 | - __column.pack_start(__renderer, expand=True) |
2837 | - __column.add_attribute(__renderer, 'text', self.COL_NUM) |
2838 | - # colonne timestamp |
2839 | - __column = gtk.TreeViewColumn() |
2840 | - __column.set_title(_('Timestamp')) |
2841 | - self.TreeViewWidget.insert_column(__column,self.COL_TS) |
2842 | - __renderer = gtk.CellRendererText() |
2843 | - __column.pack_start(__renderer, expand=True) |
2844 | - __column.add_attribute(__renderer, 'text', self.COL_TS) |
2845 | - # recuperation du widget entry du fpi |
2846 | - appGuiObj=MG.luciole_global.dico['appgui'] |
2847 | - self._fpi_widget=appGuiObj.wTree.get_widget('hscale1_fps') |
2848 | - |
2849 | - # callback tests |
2850 | -# def cb_cursor_changed(self,treeview): |
2851 | -# """ test """ |
2852 | -# print "chrono : cb_cursor_changed" |
2853 | -# print treeview |
2854 | - |
2855 | - ############################################################ |
2856 | - ### PUBLIC METHODS |
2857 | - ############################################################ |
2858 | - |
2859 | - def append(self,element,fromFile=False) : |
2860 | - """Add an element to Treeview and luciole Image List in chronologie""" |
2861 | - if os.path.exists(element) : |
2862 | - x=self.imageList.append_from_file(element) |
2863 | - # calul de la durée fpi pour timeline |
2864 | - ImageTime =float( len(self.imageList) -1) *float((1.0*MG.luciole_global.dico[MF.luciole_project_file.__name__].fpi)/MCONST.VIDEO_PAL_FPS) |
2865 | - self.liststore.append([len( self.liststore),x.pixbuf_icon,x.imageName,ImageTime]) |
2866 | - if not fromFile : |
2867 | - ProjectFileObj = MG.luciole_global.dico[MF.luciole_project_file.__name__] |
2868 | - # add on XML structure |
2869 | - ProjectFileObj.append(self.mode,x.imageName) |
2870 | - # now that we removed the selection, play nice with |
2871 | - # the user and select the last item |
2872 | - treeselection = self.TreeViewWidget.get_selection() |
2873 | - #(model, iter_list) = treeselection.get_selected_rows() |
2874 | - treeselection.select_path((len(self.liststore) - 1,) ) |
2875 | - self.TreeViewWidget.set_cursor((len(self.liststore) - 1,)) |
2876 | - self.TreeViewWidget.scroll_to_cell((len(self.liststore) - 1,)) |
2877 | - |
2878 | - |
2879 | - def MoveToChrono(self,LucioTreeviewFrom): |
2880 | - """ Move selection from capture in chrono treeview""" |
2881 | - if ( LucioTreeviewFrom.treeselection.count_selected_rows() > 0): |
2882 | - # almost one element is selected |
2883 | - (model_capture, pathlist) = LucioTreeviewFrom.treeselection.get_selected_rows() |
2884 | - # get original position for the selection of all the transfered images |
2885 | - # after the transfer |
2886 | - (initial_path,col) = self.TreeViewWidget.get_cursor() |
2887 | - for mypath in pathlist : |
2888 | - # loop on image selected in capture view |
2889 | - iter_capture = LucioTreeviewFrom.liststore.get_iter(mypath) |
2890 | - M_image_to_shift = LucioTreeviewFrom.get_LucioleImage(iter_capture) |
2891 | - # copy from capture to chrono |
2892 | - try : |
2893 | - ProjectFileObj = MG.luciole_global.dico[MF.luciole_project_file.__name__] |
2894 | - MT.copyf(M_image_to_shift.fullName,ProjectFileObj.chrono_dir ) |
2895 | - except M_EXCEP.LucioException,err : |
2896 | - #raise M_EXCEP.LucioException,err |
2897 | - print " exception dans MoveToChrono : \n " + err.message |
2898 | - else : |
2899 | - self.insert(M_image_to_shift) |
2900 | - |
2901 | - |
2902 | - # select the transfered images |
2903 | - if (initial_path) : |
2904 | - self.treeselection.select_range((initial_path[0]+1,),(initial_path[0] + len(pathlist),)) |
2905 | - else : |
2906 | - # if no data in chrono selected select the last images transfered |
2907 | - start_path = len(self.liststore) -len(pathlist) |
2908 | - end_path = len(self.liststore) -1 |
2909 | - self.treeselection.select_range( (start_path,), (end_path,) ) |
2910 | - |
2911 | - def insert(self,element ) : |
2912 | - |
2913 | - if isinstance(element,LucioleImage) : |
2914 | - (model, pathlist) = self.treeselection.get_selected_rows() # treeselection on chrono view |
2915 | - (path_cursor,col) =self.TreeViewWidget.get_cursor() # cursor on chrono view |
2916 | - if (path_cursor and isinstance(element,LucioleImage)) : |
2917 | - iter_cursor = self.liststore.get_iter(path_cursor) |
2918 | - # copy image in chrono dir and update xml file |
2919 | - ProjectFileObj = MG.luciole_global.dico[MF.luciole_project_file.__name__] |
2920 | - ProjectFileObj.insert(self.mode,path_cursor[0] +1, element.imageName) |
2921 | - self.imageList.insert(path_cursor[0]+1,element) |
2922 | - self.liststore.insert_after(iter_cursor,[0,element.pixbuf_icon,element.imageName,0]) |
2923 | - self.liststore.foreach(self._foreach_updateNumAndtime,MG.luciole_global.dico[MF.luciole_project_file.__name__].fpi) |
2924 | - |
2925 | - self.TreeViewWidget.set_cursor(path_cursor[0]+1 ) |
2926 | - else : |
2927 | - #nothing is selected or treeview empty append element |
2928 | - self.append(element.fullName) |
2929 | - |
2930 | - |
2931 | - #def insert(self,i,x) : |
2932 | - # """Add an element to Treeview and luciole Image List in chronologie""" |
2933 | - # if isinstance(x,LucioleImage) : |
2934 | - # #maj d'image Lis |
2935 | - # self.imageList.append(i,x) |
2936 | - # #maj du fichier xml |
2937 | - # ProjectFileObj = MG.luciole_global.dico['luciole_project_file'] |
2938 | - # ProjectFileObj.insert(self.mode,i,element.imageName) |
2939 | - # ImageTime =(1.*i) *float((1.0*MG.luciole_global.dico[MF.luciole_project_file.__name__].fpi)/MCONST.VIDEO_PAL_FPS) |
2940 | - # return self.liststore.append([len( self.liststore),x.pixbuf_icon,x.imageName,ImageTime]) |
2941 | - |
2942 | - def update_fpi_label(self,fpi) : |
2943 | - """ Update the value of fpi in GUI""" |
2944 | - pos = 1 |
2945 | - for (k,v) in MCONST.VIDEO_FPS_TABLE.iteritems() : |
2946 | - # find the position |
2947 | - (a,b) = v |
2948 | - if b == fpi : pos=k |
2949 | - self._fpi_widget.set_value(pos) |
2950 | - |
2951 | - def up(self) : |
2952 | - """ Move up one position a selection in treeview""" |
2953 | - (dummy_model, pathList) = self.treeselection.get_selected_rows() |
2954 | - first_selected = pathList[0] |
2955 | - last_selected = pathList[-1] |
2956 | - if (not ( first_selected[0] == 0 )) : |
2957 | - # the first element is not at the top level (i.e. position 0) |
2958 | - |
2959 | - # moving up is to put the previous sibling of the selection after the |
2960 | - # last element of the selection |
2961 | - |
2962 | - # get previous iter |
2963 | - prevIter = self.liststore.get_iter( (first_selected[0] -1,)) |
2964 | - #move it after last element of the selection |
2965 | - self._move_after(prevIter,self.liststore.get_iter(last_selected)) |
2966 | - |
2967 | - self._dumpImageList() |
2968 | - |
2969 | - # keep the same selected rows, move selection rage by -1 |
2970 | - self.treeselection.unselect_all() |
2971 | - self.treeselection.select_range((first_selected[0] -1,),(last_selected[0] -1,)) |
2972 | - # scroll also to the first selected |
2973 | - self.TreeViewWidget.scroll_to_cell((first_selected[0] -1,),None,True,0.5) |
2974 | - |
2975 | - def down(self) : |
2976 | - """ Move down one position a selection in treeview""" |
2977 | - (dummy_model, pathList) = self.treeselection.get_selected_rows() |
2978 | - first_selected = pathList[0] |
2979 | - last_selected = pathList[-1] |
2980 | - if (last_selected[0] != ( len(self.liststore) -1 ) ): |
2981 | - # the last element is not at the bottom of the list |
2982 | - |
2983 | - # moving down is to put the next sibling of the selection before the |
2984 | - # first element of the selection |
2985 | - |
2986 | - # get next iter |
2987 | - nextIter = self.liststore.get_iter( (last_selected[0] +1,)) |
2988 | - #move it before the first element of the selection |
2989 | - self._move_before(nextIter,self.liststore.get_iter(first_selected)) |
2990 | - self._dumpImageList() |
2991 | - # keep the same selected rows, move selection range by +1 |
2992 | - self.treeselection.unselect_all() |
2993 | - self.treeselection.select_range((first_selected[0] +1,),(last_selected[0] +1,)) |
2994 | - # scroll also to the first selected |
2995 | - self.TreeViewWidget.scroll_to_cell((last_selected[0] +1,),None,True,0.5) |
2996 | - |
2997 | - ############################################################ |
2998 | - ### PRIVATE METHODS |
2999 | - ############################################################ |
3000 | - |
3001 | - def _foreach_updateNumAndtime(self,model,path,iter,fpi) : |
3002 | - """foreach handler of Gtk.treemodel for upate of timestamp and num of image.""" |
3003 | - ImageTime =(1.*path[0]) *float((1.0*MG.luciole_global.dico[MF.luciole_project_file.__name__].fpi)/MCONST.VIDEO_PAL_FPS) |
3004 | - model.set_value(iter,self.COL_TS,ImageTime) |
3005 | - model.set_value(iter,self.COL_NUM,path[0]) |
3006 | - |
3007 | - def upadteTreeviewTime(self,fpi) : |
3008 | - """ Update treeview time according fpi value. """ |
3009 | - self.liststore.foreach(self._foreach_update_time,fpi) |
3010 | - |
3011 | - def _foreach_update_time(self,model,path,iter,fpi) : |
3012 | - """foreach handler of Gtk.treemodel for upate of image time.""" |
3013 | - ImageTime =(1.*path[0]) *float((1.0*MG.luciole_global.dico[MF.luciole_project_file.__name__].fpi)/MCONST.VIDEO_PAL_FPS) |
3014 | - model.set_value(iter,self.COL_TS,ImageTime) |
3015 | - |
3016 | - |
3017 | - def _move_after(self,iter_src,iter_dest): |
3018 | - """ Move an element in treeview and update list, imageList and xml file """ |
3019 | - #get path |
3020 | - path_src = self.liststore.get_path(iter_src) |
3021 | - path_dest = self.liststore.get_path(iter_dest) |
3022 | - #update imageList |
3023 | - self.imageList.move_after(path_src[0],path_dest[0]) |
3024 | - #update XML project file |
3025 | - ProjectFileObj = MG.luciole_global.dico[MF.luciole_project_file.__name__] |
3026 | - ProjectFileObj.move_after(self.mode,path_src[0],path_dest[0]) |
3027 | - |
3028 | - #update liststore |
3029 | - self.liststore.move_after(iter_src,iter_dest) |
3030 | - #update Numerotation and time |
3031 | - self.liststore.foreach(self._foreach_updateNumAndtime,MG.luciole_global.dico[MF.luciole_project_file.__name__].fpi) |
3032 | - |
3033 | - def _move_before(self,iter_src,iter_dest): |
3034 | - """ Move an element in treeview and update list, imageList and xml file """ |
3035 | - #get path |
3036 | - path_src = self.liststore.get_path(iter_src) |
3037 | - path_dest = self.liststore.get_path(iter_dest) |
3038 | - #update imageList |
3039 | - self.imageList.move_before(path_src[0],path_dest[0]) |
3040 | - #update XML project file |
3041 | - ProjectFileObj = MG.luciole_global.dico[MF.luciole_project_file.__name__] |
3042 | - ProjectFileObj.move_before(self.mode,path_src[0],path_dest[0]) |
3043 | - |
3044 | - #update liststore |
3045 | - self.liststore.move_before(iter_src,iter_dest) |
3046 | - #update Numerotation and time |
3047 | - self.liststore.foreach(self._foreach_updateNumAndtime,MG.luciole_global.dico[MF.luciole_project_file.__name__].fpi) |
3048 | - |
3049 | - |
3050 | - |
3051 | - |
3052 | |
3053 | === modified file 'lucioLib/luciole_conf.py' |
3054 | --- lucioLib/luciole_conf.py 2009-03-08 18:06:41 +0000 |
3055 | +++ lucioLib/luciole_conf.py 2009-04-11 16:57:27 +0000 |
3056 | @@ -26,9 +26,8 @@ |
3057 | """ file lucio_conf.py """ |
3058 | |
3059 | import os.path |
3060 | -from . import luciole_exceptions as M_EXCEP |
3061 | +import luciole_exceptions as M_EXCEP |
3062 | import luciole_tools as MT |
3063 | -import luciole_global as MG |
3064 | |
3065 | from xml.sax.handler import ContentHandler |
3066 | from xml.sax import make_parser |
3067 | @@ -39,8 +38,9 @@ |
3068 | class LucioleConf(object): |
3069 | """ Manage the configuration file of luciole """ |
3070 | |
3071 | - __USER_MYRTILLE_DIR = ".luciole" |
3072 | + __USER_LUCIOLE_DIR = ".luciole" |
3073 | __CONF_FILE_NAME = "lucioleConf.xml" |
3074 | + __ORIGINAL_DIR = "templates" |
3075 | |
3076 | def _get_conf_options(self): |
3077 | """ get method for option dicrionary """ |
3078 | @@ -53,20 +53,12 @@ |
3079 | - if conf file does not exist in user dir create it |
3080 | - parse xml conf file |
3081 | """ |
3082 | - # search for luciole conf if not create it |
3083 | - # in /home/user/.luciole/luciole_conf.py |
3084 | - if not self.__class__.__name__ in MG.luciole_global.dico : |
3085 | - MG.luciole_global.dico[self.__class__.__name__] = self |
3086 | - else : |
3087 | - print "l objet", self.__class__.__name__, " existe deja" |
3088 | - return None |
3089 | - |
3090 | self._home_dir = os.path.expandvars('$HOME') |
3091 | self._option_dict = dict() |
3092 | self._option_dict["LastProjects"] = list() |
3093 | self._conf_et = None |
3094 | # verify if luciole confile exits |
3095 | - conf_file_path = os.path.join(self.__USER_MYRTILLE_DIR, self.__CONF_FILE_NAME) |
3096 | + conf_file_path = os.path.join(self.__USER_LUCIOLE_DIR, self.__CONF_FILE_NAME) |
3097 | self._conf_file_path = os.path.join(self._home_dir, conf_file_path) |
3098 | if os.path.exists(self._conf_file_path) : |
3099 | # luciole file exist parse it |
3100 | @@ -74,7 +66,7 @@ |
3101 | else : |
3102 | try : |
3103 | # copy file to local dir |
3104 | - self._copy_conf_file("/usr/share/luciole/templates/lucioleConf.xml") |
3105 | + self._copy_conf_file(os.path.join(self.__ORIGINAL_DIR,self.__CONF_FILE_NAME)) |
3106 | # and parse it |
3107 | self._parse_conf_file() |
3108 | |
3109 | @@ -104,7 +96,7 @@ |
3110 | def _copy_conf_file(self, source_conf_file) : |
3111 | """ copy config file to user dir """ |
3112 | #check if user luciole dir exist |
3113 | - ldir = os.path.join(self._home_dir, self.__USER_MYRTILLE_DIR) |
3114 | + ldir = os.path.join(self._home_dir, self.__USER_LUCIOLE_DIR) |
3115 | if os.path.exists(ldir) : |
3116 | if os.path.isdir(ldir) : |
3117 | # cp luciole_conf file |
3118 | |
3119 | === modified file 'lucioLib/luciole_constants.py' |
3120 | --- lucioLib/luciole_constants.py 2009-04-08 19:58:11 +0000 |
3121 | +++ lucioLib/luciole_constants.py 2009-04-12 15:53:50 +0000 |
3122 | @@ -74,5 +74,15 @@ |
3123 | ######################################## |
3124 | # IMAGE FORMATS |
3125 | ######################################## |
3126 | -THUMB_RATIO = 5.0 # ration normal/thumbnail. To set size ot thumbnail images in treeview. |
3127 | +THUMB_RATIO = 5 # ration normal/thumbnail. To set size ot thumbnail images in treeview. |
3128 | +# clor in rgb format muliply by 255 each level to go in gtk.gdk.Color format |
3129 | +THUMB_COLOR_RATIO = 256 |
3130 | +THUMB_TEXT_COLOR = ( |
3131 | + 191 * THUMB_COLOR_RATIO, |
3132 | + 244 * THUMB_COLOR_RATIO, |
3133 | + 75 * THUMB_COLOR_RATIO |
3134 | + ) |
3135 | +THUMB_TEXT_SIZE = 8200 # text size |
3136 | +THUMB_TEXT_FAMILY = 'sans' # font family |
3137 | + |
3138 | |
3139 | |
3140 | === modified file 'lucioLib/luciole_controller.py' |
3141 | --- lucioLib/luciole_controller.py 2009-04-10 19:50:00 +0000 |
3142 | +++ lucioLib/luciole_controller.py 2009-04-13 19:21:49 +0000 |
3143 | @@ -33,9 +33,14 @@ |
3144 | import luciole_constants as LCONST |
3145 | import luciole_exceptions as L_EXCEP |
3146 | import luciole_player as LPLAYER |
3147 | +import luciole_conf as LCONF |
3148 | +import luciole_manage_recent as LRECENT |
3149 | +import luciole_controller_import as LC_IMAGE |
3150 | |
3151 | import gui as LTK |
3152 | - |
3153 | +import gobject |
3154 | +import threading |
3155 | +import time |
3156 | |
3157 | import re |
3158 | import os.path |
3159 | @@ -45,7 +50,53 @@ |
3160 | |
3161 | # project type status |
3162 | (NO_PROJECT,ON_CONFIGURATION,LOADED,MODIFIED) = range(4) |
3163 | - |
3164 | + |
3165 | +class rush_loader_thread(threading.Thread): |
3166 | + """ this thread is used to load the rush images, its take a while so this action is threaded """ |
3167 | + def __init__(self,progress_bar_widget,cb_on_finish,project) : |
3168 | + """ initilise thread |
3169 | + progress_bar : the status/progres bar for diplay info about project load |
3170 | + cb_on_finish : The callback function when thread is finished, the rush_obj is returned by thread |
3171 | + project : the project dictionary |
3172 | + """ |
3173 | + # init thread |
3174 | + super(rush_loader_thread, self).__init__() |
3175 | + |
3176 | + self._progress_bar_widget = progress_bar_widget |
3177 | + self._cb_on_finish = cb_on_finish |
3178 | + self.project = project |
3179 | + self.rush_obj = None |
3180 | + |
3181 | + def run(self) : |
3182 | + """ run thread """ |
3183 | + self._progress_bar_clear() # clear progress bar |
3184 | + |
3185 | + # create rush list object |
3186 | + rush_dir = os.path.join(self.project['project_dir'],self.project['rush_dir']) |
3187 | + rush_obj = LI.Rush_images(rush_dir,self.project['rush_images'],self._progress_bar_on_progress) |
3188 | + |
3189 | + self._progress_bar_complete() |
3190 | + self._cb_on_finish(rush_obj) # Thread finished execute callback |
3191 | + |
3192 | + def _progress_bar_clear(self): |
3193 | + """ Clear progress bar """ |
3194 | + msg = _('Project Load started') |
3195 | + # use of idle_add because gui update not in the same thread |
3196 | + gobject.idle_add( self._progress_bar_widget.start,msg) |
3197 | + |
3198 | + def _progress_bar_complete(self): |
3199 | + """ Progress bar full : Project loaded """ |
3200 | + msg = _('Project %s is loaded'%self.project['project_name']) |
3201 | + # use of idle_add because gui update not in the same thread |
3202 | + gobject.idle_add( self._progress_bar_widget.stop,msg) |
3203 | + |
3204 | + def _progress_bar_on_progress(self,ratio = None): |
3205 | + """ indicate that detection is going on """ |
3206 | + msg = _('Project %s is loading'%self.project['project_name']) |
3207 | + # use of idle_add because gui update not in the same thread |
3208 | + gobject.idle_add( self._progress_bar_widget.on_progress,msg,ratio) |
3209 | + |
3210 | + |
3211 | class Luciole_controller(object) : |
3212 | __metaclass__ = LT.SingletonType |
3213 | |
3214 | @@ -57,6 +108,15 @@ |
3215 | # init project object |
3216 | self.project_ctrller = LP.project_controller() |
3217 | |
3218 | + # init Luciole conf obj |
3219 | + self.conf_obj = LCONF.LucioleConf() |
3220 | + |
3221 | + # get the recent project list |
3222 | + self.recent_project_list = self.conf_obj.conf_options["LastProjects"] |
3223 | + |
3224 | + # init the recent project manager |
3225 | + self.recent_project_obj = LRECENT.luciole_recent(self.recent_project_list, self.gui.ui_manager, self.open_project ,self.conf_obj) |
3226 | + |
3227 | self.acq_obj = None |
3228 | self.rush_obj = None |
3229 | self.project = None |
3230 | @@ -97,32 +157,31 @@ |
3231 | |
3232 | # 3. load created project in application |
3233 | self.__load_project_in_app() |
3234 | - |
3235 | - self.project['is_modified'] = LCONST.PROJECT_NOT_MODIFIED |
3236 | |
3237 | def open_project(self,project_path = None) : |
3238 | """ open project if param projecet_path is None |
3239 | start a Gui dialog """ |
3240 | if project_path == None : |
3241 | + # if no project_path as paramter open dialog to choose one |
3242 | project_path = self.gui.open_project() |
3243 | - |
3244 | - # management of modified project |
3245 | - # save not save and ask for save shall be done here |
3246 | |
3247 | - if self.project != None : self.close() |
3248 | + if self.project != None : |
3249 | + # if a project is loaded close it |
3250 | + self.close() |
3251 | |
3252 | self.project = self.project_ctrller.open(project_path) |
3253 | |
3254 | # 3. load project in application |
3255 | self.__load_project_in_app() |
3256 | |
3257 | - self.project['is_modified'] = LCONST.PROJECT_NOT_MODIFIED |
3258 | - |
3259 | def save_project(self): |
3260 | """ save the current project """ |
3261 | self.project_ctrller.save(self.project) |
3262 | self.project['is_modified'] = LCONST.PROJECT_NOT_MODIFIED |
3263 | self.gui.set_programbar(self.project['project_name'],False) |
3264 | + |
3265 | + # add project to recent list |
3266 | + self.recent_project_obj.add_project(os.path.join( self.project['project_dir'], self.project['xml_filename'] )) |
3267 | |
3268 | def save_as_project(self,path): |
3269 | """ save into a new project""" |
3270 | @@ -147,18 +206,29 @@ |
3271 | def image_import(self) : |
3272 | """ import images from external source """ |
3273 | if self.project != None : |
3274 | - #import imges ony if a project is loaded |
3275 | + # import imges ony if a project is loaded |
3276 | + |
3277 | + # open filename chooser dialog |
3278 | filenames = self.gui.import_dialog() |
3279 | - for filename in filenames : |
3280 | - #1. copy image to rush folder and resize it. |
3281 | - l_image_name = self.__copy_import_to_rush_folder(filename) |
3282 | - |
3283 | - #2. add image to rush and capyure obj |
3284 | - self.__append_image_to_project(l_image_name) |
3285 | + |
3286 | + if filenames != [] : |
3287 | + # start import thread |
3288 | + import_thread = LC_IMAGE.import_controller_boss( |
3289 | + self.gui.status_progress_bar, |
3290 | + filenames, |
3291 | + self.project, |
3292 | + self.rush_index, |
3293 | + self.rush_obj, |
3294 | + self.__on_import_finish) |
3295 | + import_thread.start() |
3296 | |
3297 | else : |
3298 | LTK.Dialog.ErrorMessage(self.gui.window, _('Image cannot be imported if a project is not open')) |
3299 | |
3300 | + |
3301 | + |
3302 | + |
3303 | + |
3304 | def image_preview(self,image_obj) : |
3305 | """ image preview """ |
3306 | # image preview when image is not in correct foramt not allowed when player is active |
3307 | @@ -299,43 +369,64 @@ |
3308 | |
3309 | # 5. Clear program name bar |
3310 | |
3311 | - # 6. hide fpi widgets |
3312 | - self.gui.fpi_widget_hide() |
3313 | + # 6. show open/new project widgets |
3314 | + self.gui.project_open_widgets() |
3315 | |
3316 | + msg = _('Project %s is closed'%self.project['project_name']) |
3317 | + status_bar = self.gui.status_progress_bar |
3318 | + status_bar.display_message(msg) |
3319 | + |
3320 | # 7.. Remove project obj |
3321 | self.project = None |
3322 | |
3323 | + |
3324 | def start_acquisition(self) : |
3325 | """ start the acquisition """ |
3326 | - # test if player is not active |
3327 | - if self._player_active == False : |
3328 | - if self.acq_obj != None : |
3329 | - # acqusition is not active so it can be started |
3330 | - if self._acquirer_active == False : |
3331 | - self.acq_obj.start_acquisition() |
3332 | - self.gui.acquisition_widget_show() |
3333 | - |
3334 | - self._set_acquirer(True) # set acquirer as active |
3335 | - self._set_imager(False) # set imager as inactive |
3336 | - self._set_player(False) # set player as inactive |
3337 | - else : |
3338 | - #acquisition yet started |
3339 | - print "acquisition Yet started : Not expected event " |
3340 | - # State not normal - stop acquirer |
3341 | - self._set_acquirer(False) # stop acquirer |
3342 | - self._set_imager(True) # allow imager |
3343 | - self._set_player(False) # diasallow player |
3344 | - |
3345 | + |
3346 | + if self.project != None : |
3347 | + #a project is loaded |
3348 | + # test if player is not active |
3349 | + if self._player_active == False : |
3350 | + if self.acq_obj != None : |
3351 | + # acqusition is not active so it can be started |
3352 | + if self._acquirer_active == False : |
3353 | + self.acq_obj.start_acquisition() |
3354 | + self.gui.acquisition_widget_show() |
3355 | + |
3356 | + self._set_acquirer(True) # set acquirer as active |
3357 | + self._set_imager(False) # set imager as inactive |
3358 | + self._set_player(False) # set player as inactive |
3359 | + else : |
3360 | + #acquisition yet started |
3361 | + print "acquisition Yet started : Not expected event " |
3362 | + # State not normal - stop acquirer |
3363 | + self._set_acquirer(False) # stop acquirer |
3364 | + self._set_imager(True) # allow imager |
3365 | + self._set_player(False) # diasallow player |
3366 | + else : |
3367 | + # deactivate acqusition button acquisition not allowed when palyer is active |
3368 | + self.gui.acquisition_widget_hide() |
3369 | + self._set_acquirer(False) # stop acquirer |
3370 | + |
3371 | + |
3372 | + else : |
3373 | + # deactivate acqusitionn button |
3374 | + self.gui.acquisition_widget_hide() |
3375 | + msg = _(' Can not start acquisition when no project are loaded.') |
3376 | + LTK.Dialog.ErrorMessage(self.gui.window, msg) |
3377 | + #robustness |
3378 | + self._set_acquirer(False) # stop acquirer |
3379 | + self._set_imager(True) # allow imager |
3380 | + self._set_player(False) # diasallow player |
3381 | |
3382 | def stop_acquisition(self) : |
3383 | """ stop the acquisition """ |
3384 | - if self.acq_obj != None : |
3385 | - # acqusition active so it can be stoped |
3386 | - # check also used to avoid loopback problem with the toggle button of acquisition |
3387 | - if self._acquirer_active == True : |
3388 | - self._set_acquirer(False) # deactivate acquirer |
3389 | - self._set_imager(True) # allow imager |
3390 | - self._set_player(False) # Player not activated (robsutness) |
3391 | + # acqusition active so it can be stoped |
3392 | + # check also used to avoid loopback problem with the toggle button of acquisition |
3393 | + if self._acquirer_active == True : |
3394 | + self._set_acquirer(False) # deactivate acquirer |
3395 | + self._set_imager(True) # allow imager |
3396 | + self._set_player(False) # Player not activated (robsutness) |
3397 | |
3398 | def move_to_chrono(self) : |
3399 | """ move selected images in capture view to Montage view """ |
3400 | @@ -413,8 +504,30 @@ |
3401 | if self.project != None : |
3402 | # update fpi on projetct |
3403 | self.project_change('fpi',fpi) |
3404 | - |
3405 | |
3406 | + def quit(self) : |
3407 | + """ quit application """ |
3408 | + |
3409 | + if self.project != None : |
3410 | + # project exist |
3411 | + if self.project['is_modified'] == LCONST.PROJECT_MODIFIED : |
3412 | + # nbd@grape : ask for save if save set status as loaded |
3413 | + l_bRes = LTK.Dialog.QuestionMessage(self.gui.window, _('Project modified. Save project before exit ?')) |
3414 | + if l_bRes == True : |
3415 | + self.save_project() |
3416 | + self.gui.quit() |
3417 | + elif l_bRes == False : |
3418 | + self.gui.quit() |
3419 | + else : |
3420 | + self.gui.quit() |
3421 | + else : |
3422 | + self.gui.quit() |
3423 | + |
3424 | + def project_properties(self) : |
3425 | + """ request Display of project properties """ |
3426 | + if self.project != None : |
3427 | + self.gui.display_project_properties(self.project) |
3428 | + |
3429 | |
3430 | #################################################################################################### |
3431 | ##### PRIVATE METHODS |
3432 | @@ -448,13 +561,20 @@ |
3433 | # print "**%s** : %s "%(k,v) |
3434 | #print "---------------------------------------------------------------------" |
3435 | |
3436 | - # create rush list object |
3437 | - rush_dir = os.path.join(self.project['project_dir'],self.project['rush_dir']) |
3438 | - self.rush_obj = LI.Rush_images(rush_dir,self.project['rush_images']) |
3439 | + # Initilaisation of rush ogbj is threaded because its take a while (generation of images pixbufs) |
3440 | + # When rush load is finish : __on_rush_finish is called |
3441 | + rush_thread = rush_loader_thread(self.gui.status_progress_bar,self.__on_rush_finish,self.project) |
3442 | + rush_thread.start() |
3443 | + |
3444 | + |
3445 | + def __on_rush_finish(self,rush_obj): |
3446 | + """ callaback for rush tghread finsihed. Continue the project load """ |
3447 | + if rush_obj != None : |
3448 | + self.rush_obj = rush_obj |
3449 | |
3450 | # load treeviews |
3451 | self.gui.load_treeviews(self.rush_obj, self.project['capture_images'], self.project['chrono_images']) |
3452 | - |
3453 | + |
3454 | # update acquisition object |
3455 | if self.project['hardtype'] == LCONST.DIGICAM : |
3456 | # acquisition for digital camera |
3457 | @@ -482,8 +602,6 @@ |
3458 | # get rush image index |
3459 | self.rush_index = self.__get_rush_number_index() |
3460 | |
3461 | - # update project name on Main bar |
3462 | - self.gui.set_programbar(self.project['project_name'],False) |
3463 | |
3464 | |
3465 | # for mixer initialisation set image to miw with the last image of the capture view. only if capture image is not empty |
3466 | @@ -493,9 +611,20 @@ |
3467 | |
3468 | # update fpi on gui and show it |
3469 | self.gui.update_fpi(int(self.project['fpi'])) |
3470 | - self.gui.fpi_widget_show() |
3471 | + |
3472 | + # show project acquisition widgets |
3473 | + self.gui.project_acquistion_widgets() |
3474 | + |
3475 | + # add project to recent list |
3476 | + self.recent_project_obj.add_project(os.path.join( self.project['project_dir'], self.project['xml_filename'] )) |
3477 | + |
3478 | + # set projetc as not modified |
3479 | + self.project['is_modified'] = LCONST.PROJECT_NOT_MODIFIED |
3480 | + # update project name on Main bar |
3481 | + self.gui.set_programbar(self.project['project_name'],False) |
3482 | + |
3483 | else : |
3484 | - msg = _("Failed to load project : %s"%project_path) |
3485 | + msg = _("Failed to load project ") |
3486 | LTK.Dialog.ErrorMessage(self.gui.window, msg) |
3487 | |
3488 | def __move_capture_to_rush_folder(self): |
3489 | @@ -537,44 +666,6 @@ |
3490 | self.rush_index += 1 |
3491 | return l_basename |
3492 | |
3493 | - def __copy_import_to_rush_folder(self,p_image_path): |
3494 | - """ copy imported image to rush dir : |
3495 | - 1. copy image to tmp dir. |
3496 | - 2. resize it. |
3497 | - 3. move it to rush image dir """ |
3498 | - |
3499 | - # build temp impage path |
3500 | - l_temp_dir = os.path.join(self.project['project_dir'], LCONST.TMP_DIR) |
3501 | - # copy name |
3502 | - l_ac_image_temp = os.path.join(l_temp_dir,LCONST.ACQUIRED_IMAGE_NAME) |
3503 | - # resized copy name |
3504 | - l_ac_image_temp_rz = os.path.join(l_temp_dir,LCONST.ACQUIRED_IMAGE_NAME_RZ) |
3505 | - |
3506 | - # build rush image name |
3507 | - l_basename = LCONST.RUSH_FILENAME_TPL%self.rush_index |
3508 | - l_rush_image = os.path.join(self.project['project_dir'], self.project['rush_dir']) |
3509 | - l_rush_image = os.path.join(l_rush_image, l_basename) |
3510 | - |
3511 | - try : |
3512 | - # 1. move image acquired image to tmp dir |
3513 | - LT.copyf(p_image_path,l_ac_image_temp) |
3514 | - |
3515 | - # 2. resize image result is in l_ac_image_temp_rz |
3516 | - l_rz_obj = LI.Image_resize(l_ac_image_temp,l_ac_image_temp_rz ) |
3517 | - l_rz_obj.convert() |
3518 | - |
3519 | - # 3. move resized image to rush dire |
3520 | - LT.movef(l_ac_image_temp_rz,l_rush_image) |
3521 | - |
3522 | - except L_EXCEP.LucioException,err : |
3523 | - raise L_EXCEP.LucioException,err |
3524 | - l_basename = None |
3525 | - else : |
3526 | - # move and resize OK : increment rush index |
3527 | - self.rush_index += 1 |
3528 | - return l_basename |
3529 | - |
3530 | - |
3531 | |
3532 | def __append_image_to_project(self, p_image_name): |
3533 | """ append an imge to the project. |
3534 | @@ -588,7 +679,22 @@ |
3535 | # 2. append image object to capture list |
3536 | l_rush_image = self.rush_obj.get_image(p_image_name) |
3537 | self.gui.append_capture(l_rush_image) |
3538 | - |
3539 | + |
3540 | + |
3541 | + def __on_import_finish(self, image_objs = None, rush_index = 0) : |
3542 | + """ call back for import finish """ |
3543 | + if image_objs != None : |
3544 | + print self.rush_obj.dump_image_name() |
3545 | + self.project_change('rush_images',self.rush_obj.dump_image_name()) |
3546 | + |
3547 | + # update rush index |
3548 | + self.rush_index = rush_index |
3549 | + |
3550 | + # This opeation is not done in thread because interacts whith gui treeview |
3551 | + for image_obj in image_objs : |
3552 | + self.gui.append_capture(image_obj) |
3553 | + |
3554 | + |
3555 | def _stop_acquisition(self): |
3556 | """ private stop acquisition method """ |
3557 | if self.acq_obj != None : |
3558 | @@ -625,3 +731,4 @@ |
3559 | if (type(is_active) == bool) and (self._mixer_active != is_active) : |
3560 | self._mixer_active = is_active |
3561 | |
3562 | + |
3563 | |
3564 | === added file 'lucioLib/luciole_controller_import.py' |
3565 | --- lucioLib/luciole_controller_import.py 1970-01-01 00:00:00 +0000 |
3566 | +++ lucioLib/luciole_controller_import.py 2009-04-13 13:59:33 +0000 |
3567 | @@ -0,0 +1,182 @@ |
3568 | +#!/usr/bin/env python |
3569 | +# -*- coding: utf-8 -*- |
3570 | +# -*- Mode: Python -*- |
3571 | +# vi:si:ai:et:sw=4:sts=4:ts=4 |
3572 | +# |
3573 | +# |
3574 | +# Copyright Nicolas Bertrand (nico@inattendu.org), 2009 |
3575 | +# |
3576 | +# This file is part of Luciole. |
3577 | +# |
3578 | +# Luciole is free software: you can redistribute it and/or modify |
3579 | +# it under the terms of the GNU General Public License as published by |
3580 | +# the Free Software Foundation, either version 3 of the License, or |
3581 | +# (at your option) any later version. |
3582 | +# |
3583 | +# Luciole is distributed in the hope that it will be useful, |
3584 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
3585 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3586 | +# GNU General Public License for more details. |
3587 | +# |
3588 | +# You should have received a copy of the GNU General Public License |
3589 | +# along with Luciole. If not, see <http://www.gnu.org/licenses/>. |
3590 | +# |
3591 | +# |
3592 | +""" |
3593 | +luciole_controller_import.py : |
3594 | + Manages the image import |
3595 | +""" |
3596 | + |
3597 | +from gettext import gettext as _ |
3598 | + |
3599 | +import gobject |
3600 | +import threading |
3601 | +import time |
3602 | +import os.path |
3603 | + |
3604 | +import luciole_constants as LCONST |
3605 | +import luciole_exceptions as L_EXCEP |
3606 | +import luciole_image as LI |
3607 | +import luciole_tools as LT |
3608 | + |
3609 | +class import_controller_boss(threading.Thread) : |
3610 | + """ Thread who manages the import work, schedule image import """ |
3611 | + |
3612 | + def __init__(self,progress_bar_widget, filenames, project, rush_index, rush_obj, cb_on_finish = None) : |
3613 | + """ init thread : |
3614 | + progress_bar_widget : widget for progress bar update |
3615 | + filenames : the image filenames list to import |
3616 | + project : The project dictionary |
3617 | + rush_index : the index of the last rush image |
3618 | + rush_obj : the rush image object |
3619 | + cb_on_finish : callback function when thread is finish |
3620 | + """ |
3621 | + |
3622 | + # init thread |
3623 | + super(import_controller_boss, self).__init__() |
3624 | + |
3625 | + self._progress_bar_widget = progress_bar_widget |
3626 | + self._filenames = filenames |
3627 | + self._project = project |
3628 | + self._rush_index = rush_index |
3629 | + self._rush_obj = rush_obj |
3630 | + self._cb_on_finish = cb_on_finish |
3631 | + self._image_obj_list = [] |
3632 | + |
3633 | + def run(self) : |
3634 | + """ run thread """ |
3635 | + self._progress_bar_clear() # clear progress bar |
3636 | + for (index,filename) in enumerate(self._filenames) : |
3637 | + # init worker thread |
3638 | + t_worker = import_controller_worker(filename,self._project, self._rush_index,self._rush_obj,self._cb_worker_finsih) |
3639 | + |
3640 | + # start wrok |
3641 | + t_worker.start() |
3642 | + |
3643 | + # wait worker finished |
3644 | + while t_worker.isAlive() : |
3645 | + time.sleep(0.1) |
3646 | + |
3647 | + #update progress bar |
3648 | + ratio = (index +1.0) / len(self._filenames) |
3649 | + self._progress_bar_on_progress(ratio) |
3650 | + |
3651 | + |
3652 | + self._progress_bar_complete() |
3653 | + if self._cb_on_finish != None : self._cb_on_finish(self._image_obj_list,self._rush_index) |
3654 | + |
3655 | + def _cb_worker_finsih(self,image_obj,rush_index) : |
3656 | + """ callback executed when worker as finished """ |
3657 | + self._image_obj_list.append(image_obj) |
3658 | + self._rush_index = rush_index |
3659 | + |
3660 | + def _progress_bar_clear(self): |
3661 | + """ Clear progress bar """ |
3662 | + msg = _('Image import started') |
3663 | + # use of idle_add because gui update not in the same thread |
3664 | + gobject.idle_add( self._progress_bar_widget.start,msg) |
3665 | + |
3666 | + def _progress_bar_complete(self): |
3667 | + """ Progress bar full : Project loaded """ |
3668 | + msg = _('Image import finished') |
3669 | + # use of idle_add because gui update not in the same thread |
3670 | + gobject.idle_add( self._progress_bar_widget.stop,msg) |
3671 | + |
3672 | + def _progress_bar_on_progress(self,ratio = None): |
3673 | + """ indicate that detection is going on """ |
3674 | + msg = _('Importing images.') |
3675 | + # use of idle_add because gui update not in the same thread |
3676 | + gobject.idle_add( self._progress_bar_widget.on_progress,msg,ratio) |
3677 | + |
3678 | + |
3679 | + |
3680 | +class import_controller_worker(threading.Thread) : |
3681 | + """ Worker import thread : Do the job, i.e copy image to rush folder, resize it, and generate pixbufs """ |
3682 | + |
3683 | + def __init__(self, filename, project, rush_index, rush_obj,cb_on_finish = None) : |
3684 | + """ init thread : |
3685 | + filename : A image filename |
3686 | + project : The project dictionary |
3687 | + rush_index : the index of the last rush image |
3688 | + rush_obj : the rush image object |
3689 | + cb_on_finish : callback function when thread is finish |
3690 | + """ |
3691 | + |
3692 | + # init thread |
3693 | + super(import_controller_worker, self).__init__() |
3694 | + self._filename = filename |
3695 | + self._project = project |
3696 | + self._rush_index = rush_index |
3697 | + self._rush_obj = rush_obj |
3698 | + self._cb_on_finish = cb_on_finish |
3699 | + |
3700 | + def run(self) : |
3701 | + """ run the thread """ |
3702 | + # copy image to rush folder and resize it |
3703 | + l_rush_image_name = self.__copy_import_to_rush_folder(self._filename) |
3704 | + |
3705 | + # append image to rush list : usage of append_threaded special for thread execution |
3706 | + image = self._rush_obj.append_threaded(l_rush_image_name) |
3707 | + |
3708 | + # work finish : do callback |
3709 | + if self._cb_on_finish != None : self._cb_on_finish(image,self._rush_index) |
3710 | + |
3711 | + def __copy_import_to_rush_folder(self,p_image_path): |
3712 | + """ copy imported image to rush dir : |
3713 | + 1. copy image to tmp dir. |
3714 | + 2. resize it. |
3715 | + 3. move it to rush image dir """ |
3716 | + |
3717 | + # build temp impage path |
3718 | + l_temp_dir = os.path.join(self._project['project_dir'], LCONST.TMP_DIR) |
3719 | + # copy name |
3720 | + l_ac_image_temp = os.path.join(l_temp_dir,LCONST.ACQUIRED_IMAGE_NAME) |
3721 | + # resized copy name |
3722 | + l_ac_image_temp_rz = os.path.join(l_temp_dir,LCONST.ACQUIRED_IMAGE_NAME_RZ) |
3723 | + |
3724 | + # build rush image name |
3725 | + l_basename = LCONST.RUSH_FILENAME_TPL%self._rush_index |
3726 | + l_rush_image = os.path.join(self._project['project_dir'], self._project['rush_dir']) |
3727 | + l_rush_image = os.path.join(l_rush_image, l_basename) |
3728 | + |
3729 | + try : |
3730 | + # 1. move image acquired image to tmp dir |
3731 | + LT.copyf(p_image_path,l_ac_image_temp) |
3732 | + |
3733 | + # 2. resize image result is in l_ac_image_temp_rz |
3734 | + l_rz_obj = LI.Image_resize(l_ac_image_temp,l_ac_image_temp_rz ) |
3735 | + l_rz_obj.convert() |
3736 | + |
3737 | + # 3. move resized image to rush dire |
3738 | + LT.movef(l_ac_image_temp_rz,l_rush_image) |
3739 | + |
3740 | + except L_EXCEP.LucioException,err : |
3741 | + raise L_EXCEP.LucioException,err |
3742 | + l_basename = None |
3743 | + else : |
3744 | + # move and resize OK : increment rush index |
3745 | + self._rush_index += 1 |
3746 | + return l_basename |
3747 | + |
3748 | + |
3749 | + |
3750 | |
3751 | === removed file 'lucioLib/luciole_file_in_out.py' |
3752 | --- lucioLib/luciole_file_in_out.py 2009-03-08 18:06:41 +0000 |
3753 | +++ lucioLib/luciole_file_in_out.py 1970-01-01 00:00:00 +0000 |
3754 | @@ -1,695 +0,0 @@ |
3755 | -#!/usr/bin/env python |
3756 | -# -*- coding: utf-8 -*- |
3757 | -# -*- Mode: Python -*- |
3758 | -# vi:si:ai:et:sw=4:sts=4:ts=4 |
3759 | -# |
3760 | -# |
3761 | -# Copyright Nicolas Bertrand (nico@inattendu.org), 2009 |
3762 | -# |
3763 | -# This file is part of Luciole. |
3764 | -# |
3765 | -# Luciole is free software: you can redistribute it and/or modify |
3766 | -# it under the terms of the GNU General Public License as published by |
3767 | -# the Free Software Foundation, either version 3 of the License, or |
3768 | -# (at your option) any later version. |
3769 | -# |
3770 | -# Luciole is distributed in the hope that it will be useful, |
3771 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
3772 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3773 | -# GNU General Public License for more details. |
3774 | -# |
3775 | -# You should have received a copy of the GNU General Public License |
3776 | -# along with Luciole. If not, see <http://www.gnu.org/licenses/>. |
3777 | -# |
3778 | -# |
3779 | - |
3780 | -import pygtk |
3781 | -pygtk.require("2.0") |
3782 | - |
3783 | -import os.path |
3784 | -import shutil |
3785 | -import gtk |
3786 | - |
3787 | -import gtk.glade |
3788 | - |
3789 | - |
3790 | -import luciole_class as MC |
3791 | -import luciole_global as MG |
3792 | -import luciole_acquisition as MACQ |
3793 | -import luciole_constants as MCONST |
3794 | -import luciole_tools as MT |
3795 | -import luciole_manage_recent as MMR |
3796 | -import string |
3797 | -import copy |
3798 | -#import elementtree.ElementTree as ET |
3799 | -import xml.etree.ElementTree as ET #python 2.5 |
3800 | -import re |
3801 | -from gettext import gettext as _ |
3802 | - |
3803 | - |
3804 | -class luciole_fileChooser(object) : |
3805 | - |
3806 | - open_project_filename = "" |
3807 | - def __init__(self,gladefile) : |
3808 | - """Init of object luciole_fileChooser.""" |
3809 | - self._gladefile=gladefile |
3810 | - def load_file(self,windowname) : |
3811 | - """Load a project file from GUI.""" |
3812 | - self.openFileWindow=gtk.glade.XML(self._gladefile,windowname) |
3813 | - dialog = self.openFileWindow.get_widget(windowname) |
3814 | - dic = { |
3815 | - } |
3816 | - self.openFileWindow.signal_autoconnect (dic) |
3817 | - response = dialog.run() |
3818 | - if response == gtk.RESPONSE_OK: |
3819 | - self.open_project_filename = dialog.get_filename() |
3820 | - projectObj = MG.luciole_global.dico[luciole_project_file.__name__] |
3821 | - projectObj.load_from_file(self.open_project_filename) |
3822 | - elif response == gtk.RESPONSE_CANCEL: |
3823 | - print 'Closed, no files selected' |
3824 | - #on ferme la fenetre |
3825 | - dialog.destroy() |
3826 | - |
3827 | - ##### CALLBACKS |
3828 | - def open_destroy(self,widget): |
3829 | - pass |
3830 | - def save(self) : |
3831 | - """Save a project from GUI.""" |
3832 | - projectObj = MG.luciole_global.dico[luciole_project_file.__name__] |
3833 | - projectObj.save_to_file() |
3834 | - def save_as(self,windowname) : |
3835 | - """Save as another project from GUI.""" |
3836 | - self.openFileWindow=gtk.glade.XML(self._gladefile,windowname) |
3837 | - dialog = self.openFileWindow.get_widget(windowname) |
3838 | - dic = { |
3839 | - } |
3840 | - self.openFileWindow.signal_autoconnect (dic) |
3841 | - response = dialog.run() |
3842 | - if response == gtk.RESPONSE_OK: |
3843 | - # les folder se recupere aussi via filename |
3844 | - self.open_project_folder = dialog.get_filename() |
3845 | - projectObj = MG.luciole_global.dico[luciole_project_file.__name__] |
3846 | - projectObj.save_to_new_project(self.open_project_folder) |
3847 | - elif response == gtk.RESPONSE_CANCEL: |
3848 | - print 'Closed, no files selected' |
3849 | - #on ferme la fenetre |
3850 | - dialog.destroy() |
3851 | - |
3852 | -class luciole_project_file(object): |
3853 | - """Class used to manage the files saving/reading using element tree""" |
3854 | - |
3855 | - ### Class properties |
3856 | - def get_filename(self): |
3857 | - return self.__filename |
3858 | - def set_filename(self,filename) : |
3859 | - self.__filename=filename |
3860 | - filename = property(get_filename,set_filename,None,"pathname to a luciole xml file") |
3861 | - |
3862 | - def get_capture_dir(self): |
3863 | - return self.datas.capture_dir |
3864 | - capture_dir=property(get_capture_dir,None,None,"Path to capture directory") |
3865 | - |
3866 | - def get_project_dir(self): |
3867 | - return self.datas.project_dir |
3868 | - project_dir=property(get_project_dir,None,None,"Path to project directory") |
3869 | - |
3870 | - def get_src_dir(self): return self.datas.src_dir |
3871 | - src_dir=property(get_src_dir,None,None,"Path to project directory") |
3872 | - |
3873 | - def get_export_dir(self): return self.datas.export_dir |
3874 | - export_dir=property(get_export_dir,None,None,"Path to export directory") |
3875 | - |
3876 | - def get_chrono_dir(self):return self.datas.chrono_dir |
3877 | - chrono_dir=property(get_chrono_dir,None,None,"Path to chronology directory") |
3878 | - |
3879 | - def get_ProjectLoaded(self): return self.__ProjectLoaded |
3880 | - ProjectLoaded=property(get_ProjectLoaded,None,None,"Project Loaded status") |
3881 | - |
3882 | - def get_acquisition(self): return self.__acquisition |
3883 | - acquisition=property(get_acquisition,None,None,"Returns the acquisition object") |
3884 | - |
3885 | - def get_projectmodified(self): return self.datas.projectmodified |
3886 | - projectmodified=property(get_projectmodified,None,None,"Returns the projectmodified object") |
3887 | - |
3888 | - def get_fpi(self) : return int(self.datas._fpi) |
3889 | - def set_fpi(self,x) : |
3890 | - self.datas._fpi=int(x) |
3891 | - # if fpi is changed project is changed, update of XML file is needed |
3892 | - elem=self.__doc_et.find("metas/fpi") |
3893 | - elem.text=str(self.datas._fpi) |
3894 | - self.datas.projectmodified = MCONST.PROJECT_MODIFIED |
3895 | - self.__ChronoWidget.upadteTreeviewTime(self.datas._fpi) |
3896 | - fpi = property(get_fpi,set_fpi,None,"Number of frame per Image") |
3897 | - |
3898 | - def __init__(self,filename=None) : |
3899 | - """init function of luciole_project file""" |
3900 | - #init du dictionnaire global d'objet |
3901 | - if not self.__class__.__name__ in MG.luciole_global.dico : |
3902 | - MG.luciole_global.dico[self.__class__.__name__] = self |
3903 | - else : |
3904 | - print "l objet",self.__class__.__name__," existe deja" |
3905 | - return None |
3906 | - |
3907 | - #recuperation des objetsCapture et Chrono et appgui |
3908 | - self.__CaptureWidget = MG.luciole_global.dico[MC.LucioleGtkTreeView.__name__] |
3909 | - self.__ChronoWidget = MG.luciole_global.dico[MC.LucioleGtkTreeViewChrono.__name__] |
3910 | - |
3911 | - # init des datas |
3912 | - self.datas=luciole_project_datas() |
3913 | - self.datas.projectmodified = MCONST.PROJECT_NOT_MODIFIED |
3914 | - |
3915 | - #par defaut pas de projet |
3916 | - self.__ProjectLoaded=False |
3917 | - |
3918 | - # list of file to suppress. Empty at startup |
3919 | - self.__fileToSuppress=[] |
3920 | - self.__filename = None |
3921 | - |
3922 | - if (filename): |
3923 | - self.__load_from_file(filename) |
3924 | - else : |
3925 | - # pas de fichier on creer un structure vide |
3926 | - self.__load_dummy() |
3927 | - |
3928 | - ### PUBLIC METHODS |
3929 | - def load_from_file(self,infile,checkModified=False) : |
3930 | - """Load a project from file. Interface method. |
3931 | - if current project modified ask for loading |
3932 | - """ |
3933 | - if checkModified : |
3934 | - if self.datas.projectmodified == self.__filename : |
3935 | - print "Project modified ask for keep or save" |
3936 | - # build dialog to interaction with user |
3937 | - # get appgui object for message display |
3938 | - self._GuiObj = MG.luciole_global.dico['appgui'] |
3939 | - msg = _('Current open project has been modified.\n Save before opening new project ?') |
3940 | - diaQuestion = self._GuiObj.buildDialog(msg, |
3941 | - gtk.STOCK_DIALOG_WARNING, |
3942 | - (gtk.STOCK_YES,gtk.RESPONSE_YES), |
3943 | - (gtk.STOCK_NO,gtk.RESPONSE_NO) , |
3944 | - (gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL) |
3945 | - ) |
3946 | - diaQuestion.show_all() |
3947 | - resultQuestion= diaQuestion.run() |
3948 | - if (resultQuestion == gtk.RESPONSE_YES) : |
3949 | - # save project and load new one |
3950 | - self.__save_to_file() |
3951 | - self.__load_from_file(infile) |
3952 | - if (resultQuestion == gtk.RESPONSE_NO) : |
3953 | - # load new project without save |
3954 | - self.__load_from_file(infile) |
3955 | - diaQuestion.destroy() |
3956 | - # load project only if project is not the same |
3957 | - elif infile != self.__filename: self.__load_from_file(infile) |
3958 | - # load project only if project is not the same |
3959 | - elif infile != self.__filename: self.__load_from_file(infile) |
3960 | - |
3961 | - def save_to_file(self, file =None): |
3962 | - """ Save Project to a file. Inerface Method.""" |
3963 | - self.__save_to_file(file) |
3964 | - |
3965 | - def save_to_new_project(self,projectdir): |
3966 | - """ Save Luciole project to a new directory.""" |
3967 | - # get the name of the new dir |
3968 | - newdir = os.path.basename(projectdir) |
3969 | - newprojectXmlfile=newdir+".xml" |
3970 | - # TODO : |
3971 | - # copy images to new dir |
3972 | - folders=["work","export","src"] |
3973 | - for folder in folders : |
3974 | - luciole_file_tools.copytree(os.path.join(self.datas.project_dir,folder),os.path.join(projectdir,folder)) |
3975 | - # update element tree file |
3976 | - elem=self.__doc_et.find("metas/projectName") |
3977 | - elem.text=newdir |
3978 | - elem=self.__doc_et.find("metas/projectPath") |
3979 | - elem.text=projectdir |
3980 | - # update XML file with new dir |
3981 | - # luciole_project_datas.project_dir is update here because method |
3982 | - # __save_to_file use thi property as basename |
3983 | - self.datas.project_dir=projectdir |
3984 | - self.__save_to_file(newprojectXmlfile) |
3985 | - # load in luciole saved project to update all datas in project |
3986 | - self.__load_from_file(os.path.join(projectdir,newprojectXmlfile)) |
3987 | - |
3988 | - def new_project(self,projectdir,projectData) : |
3989 | - """ Set a new project.""" |
3990 | - #create the new dirrectory |
3991 | - os.mkdir(projectdir) |
3992 | - # create the directories structure |
3993 | - folders=["work","work/capture","work/chrono","work/trash","export","src",] |
3994 | - for folder in folders : |
3995 | - os.mkdir(os.path.join(projectdir,folder)) |
3996 | - |
3997 | - # get the name of the new dir |
3998 | - newdir = os.path.basename(projectdir) |
3999 | - |
4000 | - # Full path to Xml project file |
4001 | - newprojectXmlfile=newdir+".xml" |
4002 | - |
4003 | - #load element template elementreefile |
4004 | - self.__doc_et=ET.parse("./templates/project_template.xml") |
4005 | - # update element tree file |
4006 | - elem=self.__doc_et.find("metas/projectName") |
4007 | - elem.text = newdir |
4008 | - elem=self.__doc_et.find("metas/projectPath") |
4009 | - elem.text = projectdir |
4010 | - #update fpi |
4011 | - elem=self.__doc_et.find("metas/fpi") |
4012 | - if (projectData['FPI']): |
4013 | - elem.text=str(projectData['FPI']) |
4014 | - else : |
4015 | - elem.text=str(4) |
4016 | - print " !!! No FPI selected, default value 5 frame per image is set " |
4017 | - |
4018 | - #update hardtype |
4019 | - elem=self.__doc_et.find("metas/hardtype") |
4020 | - if (projectData['HardType']): |
4021 | - elem.attrib['id']=str(projectData['HardType']) |
4022 | - hard_type_desc = ET.SubElement(elem, 'hard_type_desc') |
4023 | - hard_type_desc.text=MCONST.HardTypeName[projectData['HardType']] |
4024 | - # in case of webcam save specific data |
4025 | - if projectData['HardType'] == MCONST.WEBCAM and projectData['webcam_bin_data'] != None : |
4026 | - hard_type_data = ET.SubElement(elem, 'hard_type_data') |
4027 | - # create new elements with same tage name as dictionary |
4028 | - for k,v in projectData['webcam_bin_data'].iteritems() : |
4029 | - t_elem = ET.SubElement(hard_type_data,k) |
4030 | - t_elem.attrib['key'] = str(v) |
4031 | - else : |
4032 | - elem.attrib['id']=str(MCONST.FAKE) |
4033 | - elem.text=MCONST.HardTypeName[MCONST.FAKE] |
4034 | - print " !!! No hardware selected, FAKE hardware selected" |
4035 | - |
4036 | - self.datas.project_dir=projectdir |
4037 | - self.__save_to_file(os.path.join(projectdir,newprojectXmlfile)) |
4038 | - # load in luciole saved project to update all datas in project |
4039 | - self.__load_from_file(os.path.join(projectdir,newprojectXmlfile)) |
4040 | - |
4041 | - def insert(self,type,i,file) : |
4042 | - """Add an image to luciole file structure, acccording the type of image.""" |
4043 | - |
4044 | - #on recupere les infos de type |
4045 | - dico_type=self.__set_type_vars(type) |
4046 | - (TagTypeName,TagImage) = (dico_type['TagTypeName'],dico_type['TagImage']) |
4047 | - |
4048 | - #on recupere l'element contenant les listes d'images |
4049 | - ListImageTag=self.__doc_et.find(TagTypeName) |
4050 | - ListImageTag.insert(i,luciole_project_file.__createImageElement(TagImage,file)) |
4051 | - self.datas.projectmodified = MCONST.PROJECT_MODIFIED |
4052 | - |
4053 | - def swap(self,type,pos1,pos2): |
4054 | - """On swape 2 position d images.""" |
4055 | - #on recupere les infos de type |
4056 | - dico_type=self.__set_type_vars(type) |
4057 | - (TagTypeName,TagImage) = (dico_type['TagTypeName'],dico_type['TagImage']) |
4058 | - |
4059 | - #on recupere l'element contenant les listes d'images |
4060 | - ListImageTag=self.__doc_et.find(TagTypeName) |
4061 | - |
4062 | - #on recupere l'element en position 1 et 2 |
4063 | - elem1 = ListImageTag.__getitem__(pos1) |
4064 | - elem2 = ListImageTag.__getitem__(pos2) |
4065 | - |
4066 | - # puis on swappe |
4067 | - ListImageTag.__setitem__(pos1,elem2) |
4068 | - ListImageTag.__setitem__(pos2,elem1) |
4069 | - self.datas.projectmodified = MCONST.PROJECT_MODIFIED |
4070 | - |
4071 | - def move_after(self,type,pos_src,pos_dest) : |
4072 | - """ move image tag in pos_src after image tag in pos_dest""" |
4073 | - # get type info |
4074 | - dico_type=self.__set_type_vars(type) |
4075 | - (TagTypeName,TagImage) = (dico_type['TagTypeName'],dico_type['TagImage']) |
4076 | - |
4077 | - # get image's list element |
4078 | - ListImageTag=self.__doc_et.find(TagTypeName) |
4079 | - |
4080 | - # get src elem |
4081 | - src_elem = ListImageTag.__getitem__(pos_src) |
4082 | - # insert it after dest pos. |
4083 | - ListImageTag.insert(pos_dest+1,src_elem) |
4084 | - # remove src_elem |
4085 | - ListImageTag.__delitem__(pos_src) |
4086 | - |
4087 | - self.datas.projectmodified = MCONST.PROJECT_MODIFIED |
4088 | - |
4089 | - def move_before(self,type,pos_src,pos_dest) : |
4090 | - """ move image tag in pos_src before image tag in pos_dest""" |
4091 | - # get type info |
4092 | - if ( (pos_src > pos_dest) ) : |
4093 | - dico_type=self.__set_type_vars(type) |
4094 | - (TagTypeName,TagImage) = (dico_type['TagTypeName'],dico_type['TagImage']) |
4095 | - |
4096 | - # get image's list element |
4097 | - ListImageTag=self.__doc_et.find(TagTypeName) |
4098 | - |
4099 | - # get src elem |
4100 | - src_elem = ListImageTag.__getitem__(pos_src) |
4101 | - # remove src_elem |
4102 | - ListImageTag.__delitem__(pos_src) |
4103 | - # insert it before dest pos. |
4104 | - ListImageTag.insert(pos_dest,src_elem) |
4105 | - |
4106 | - self.datas.projectmodified = MCONST.PROJECT_MODIFIED |
4107 | - |
4108 | - |
4109 | - def append(self,type,file) : |
4110 | - """Add an image to luciole file structure, acccording the type of image.""" |
4111 | - |
4112 | - #TBD: When image have to be stored . Here copied from source to data or during capture |
4113 | - |
4114 | - #on recupere les infos de type |
4115 | - dico_type=self.__set_type_vars(type) |
4116 | - (TagTypeName,TagImage) = (dico_type['TagTypeName'],dico_type['TagImage']) |
4117 | - |
4118 | - #on recupere l'element contenant les listes d'images |
4119 | - ListImageTag=self.__doc_et.find(TagTypeName) |
4120 | - ListImageTag.append(luciole_project_file.__createImageElement(TagImage,file)) |
4121 | - self.datas.projectmodified = MCONST.PROJECT_MODIFIED |
4122 | - |
4123 | - def remove(self,type,pos): |
4124 | - """ Remove a file from the project.""" |
4125 | - #on recupere les infos de type |
4126 | - dico_type=self.__set_type_vars(type) |
4127 | - (TagTypeName,TagImage,BaseImagePath) = (dico_type['TagTypeName'],dico_type['TagImage'],dico_type['BaseImagePath']) |
4128 | - |
4129 | - ListImageTag=self.__doc_et.find(TagTypeName) |
4130 | - # get the image name of the image to suppress and add it on list of file to suppress |
4131 | - elemToSuppr = ListImageTag.__getitem__(pos) |
4132 | - self.__fileToSuppress.append(os.path.join(BaseImagePath,elemToSuppr.findtext("name").strip())) |
4133 | - # suppress the tag in XML file |
4134 | - ListImageTag.__delitem__(pos) |
4135 | - self.datas.projectmodified = MCONST.PROJECT_MODIFIED |
4136 | - |
4137 | - |
4138 | - def ErrMessage(self,message) : |
4139 | - messageToDisplay = message |
4140 | - if (not message) : |
4141 | - messageToDisplay="Troubles in loading the project" |
4142 | - MG.luciole_global.dico['appgui'].ErrMessage(messageToDisplay) |
4143 | - |
4144 | - ### PRIVATE METHODS |
4145 | - def __load_from_file(self,filename): |
4146 | - """ Internal function for loading a project from file.""" |
4147 | - if os.path.isfile(filename) : |
4148 | - #save name of previously loaded project |
4149 | - if self.__ProjectLoaded : |
4150 | - ManagerObj = MG.luciole_global.dico[MMR.luciole_recent.__name__] |
4151 | - ManagerObj.add_project(self.__filename) |
4152 | - |
4153 | - self.__filename=filename |
4154 | - self.__doc_et=ET.parse(self.filename) |
4155 | - self.__doc_original = copy.copy(self.__doc_et) # make a copy , keep the original version |
4156 | - self.datas.filename= os.path.basename(self.__filename) |
4157 | - self.__parse_file() |
4158 | - # update the Main window title |
4159 | - MG.luciole_global.dico['appgui'].update_main_window_name(self.datas.project_name) |
4160 | - # projet chargé |
4161 | - self.__ProjectLoaded=True |
4162 | - #project not modified yet |
4163 | - self.datas.projectmodified = MCONST.PROJECT_NOT_MODIFIED |
4164 | - # list of file to suppress. Empty when a project is loaded |
4165 | - # clear displays |
4166 | - MG.luciole_global.dico['appgui'].ClearDisplays(MCONST.SCREEN_BOTH) |
4167 | - # stop acquisition if needed, deactive capture button |
4168 | - MG.luciole_global.dico['appgui'].inactive_apercu() |
4169 | - # active some menu |
4170 | - MG.luciole_global.dico['appgui'].activate_project_menu() |
4171 | - self.__fileToSuppress=[] |
4172 | - else : |
4173 | - self.__filename="" |
4174 | - self.datas.filename= os.path.basename(self.__filename) |
4175 | - print self.__class__.__name__," --- Not a file " |
4176 | - |
4177 | - def __load_dummy(self) : |
4178 | - """Load a dummy file create the XML structure.""" |
4179 | - pass |
4180 | - |
4181 | - def __set_type_vars(self,type) : |
4182 | - """Set xml tags according treeview to update.Returns a dictionary.""" |
4183 | - dico_type=dict() |
4184 | - if type == MG.luciole_global.CAPTURE: |
4185 | - dico_type['TagTypeName'] = "captureDatas" |
4186 | - dico_type['TagImage'] = "capture_image" |
4187 | - dico_type['BaseImagePath'] = str(self.datas.capture_dir)+"/" |
4188 | - dico_type['ListType']= self.__CaptureWidget |
4189 | - elif type == MG.luciole_global.CHRONO : |
4190 | - dico_type['TagTypeName'] = "chronoDatas" |
4191 | - dico_type['TagImage'] = "chrono_image" |
4192 | - dico_type['BaseImagePath'] = str(self.datas.chrono_dir)+"/" |
4193 | - dico_type['ListType']= self.__ChronoWidget |
4194 | - elif type == MG.luciole_global.SRC : |
4195 | - dico_type['TagTypeName'] = "srcDatas" |
4196 | - dico_type['TagImage'] = "src_image" |
4197 | - dico_type['BaseImagePath'] = str(self.datas.src_dir)+"/" |
4198 | - dico_type['ListType']="" |
4199 | - else: |
4200 | - print "ERR -format inconnu dans", self.__loadImage.__name__, "(",__name__,")" |
4201 | - return dico_type |
4202 | - |
4203 | - def __loadImage(self,type) : |
4204 | - """Load images from xml file.""" |
4205 | - |
4206 | - # on configure on fonction du type |
4207 | - dico_type=self.__set_type_vars(type) |
4208 | - (TagTypeName,TagImage,BaseImagePath,ListType) = (dico_type['TagTypeName'],dico_type['TagImage'],dico_type['BaseImagePath'],dico_type['ListType']) |
4209 | - |
4210 | - #d'abord on clear les images |
4211 | - ListType.clear_all() |
4212 | - #get an elemnttree iterator on images |
4213 | - CaptureTag=self.__doc_et.find(TagTypeName) |
4214 | - list_capture = CaptureTag.getiterator(TagImage) |
4215 | - if (len(list_capture) != 0): |
4216 | - #image exists |
4217 | - imageLoaded=[] |
4218 | - imageListTreeview =[] |
4219 | - for image in list_capture : |
4220 | - imageLoaded.append(image.findtext("name").strip()) |
4221 | - imagePath = BaseImagePath+(image.findtext("name").strip()) |
4222 | - if os.path.exists(imagePath) : |
4223 | - imageListTreeview.append(imagePath) |
4224 | - else : |
4225 | - print "Image %s not in dir imagePath "%imagePath |
4226 | - |
4227 | - ListType.LoadImagesfromProject(imageListTreeview) |
4228 | - # get the highest image name indice |
4229 | - filelist = MT.filesInDir(BaseImagePath,'*.jpeg') |
4230 | - # clean the image directory with the unused images for coherency between xml file and data in directory |
4231 | - # for this operation sets are used |
4232 | - diffImg = set(filelist).difference(set(imageLoaded)) |
4233 | - if diffImg : |
4234 | - for imgToRemove in diffImg : |
4235 | - #delete the unused images |
4236 | - os.remove(os.path.join(os.path.normpath(BaseImagePath),imgToRemove)) |
4237 | - #update directory content |
4238 | - filelist = MT.filesInDir(BaseImagePath,'*.jpeg') |
4239 | - pattern = re.compile(r'\d+') # search sequence of number |
4240 | - # filesInDir returns a sorted list from min to max so we get the last element :(filelist[-1]) |
4241 | - # and findall return a list with all the match, we have just one match we take the first element. |
4242 | - MaxIndice = int(pattern.findall(filelist[-1])[0]) |
4243 | - ListType.imageFileIndex=MaxIndice+1 # update image index |
4244 | - else : |
4245 | - #No image to load |
4246 | - ListType.imageFileIndex=0 |
4247 | - |
4248 | - def __parse_file(self) : |
4249 | - "parse the file for data retrieval from load_file" |
4250 | - |
4251 | - #recuperation du nom du projet et des path utilisees par le projet |
4252 | - self.datas.project_name = self.__doc_et.findtext("metas/projectName") |
4253 | - self.datas.project_dir = self.__doc_et.findtext("metas/projectPath") |
4254 | - self.datas.export_dir = self.__doc_et.findtext("metas/export_dir") |
4255 | - self.datas.capture_dir = self.datas.project_dir+"/"+self.__doc_et.findtext("metas/capture_dir") |
4256 | - self.datas.chrono_dir = self.datas.project_dir+"/"+self.__doc_et.findtext("metas/chrono_dir") |
4257 | - self.datas.project_trash = self.datas.project_dir+"/"+self.__doc_et.findtext("metas/trash_dir") |
4258 | - # worlaround to be added in XML file . |
4259 | - self.datas.src_dir = os.path.join(self.datas.project_dir,"src") |
4260 | - |
4261 | - # get hardtype |
4262 | - elem=self.__doc_et.find("metas/hardtype") |
4263 | - self.datas.hardtype = int(elem.attrib["id"]) |
4264 | - |
4265 | - #update fpi in project and Gui |
4266 | - self.datas.fpi = self.__doc_et.findtext("metas/fpi") |
4267 | - self.__ChronoWidget.update_fpi_label(self.datas.fpi) |
4268 | - |
4269 | - self.__loadImage(MG.luciole_global.CAPTURE) |
4270 | - self.__loadImage(MG.luciole_global.CHRONO) |
4271 | - |
4272 | - |
4273 | - # create acquisition object |
4274 | - display = MG.luciole_global.dico['appgui'].CameraArea |
4275 | - if (self.datas.hardtype == MCONST.DIGICAM) : |
4276 | - self.__acquisition = MACQ.luciole_acquisition_digicam(display) |
4277 | - elif (self.datas.hardtype == MCONST.WEBCAM) : |
4278 | - # loop on webcam datas |
4279 | - et_webcam_data = self.__doc_et.find("//hard_type_data") |
4280 | - if et_webcam_data != None : |
4281 | - # loop on webcam data and save on data dictionary |
4282 | - webcam_data={} |
4283 | - for my_item in et_webcam_data.getchildren() : |
4284 | - webcam_data[my_item.tag] = my_item.attrib.get("key") |
4285 | - # create acquisition object |
4286 | - self.__acquisition = MACQ.luciole_acquisition_webcam( |
4287 | - display, |
4288 | - data = webcam_data |
4289 | - ) |
4290 | - else : |
4291 | - print " No webcam data found " |
4292 | - else : |
4293 | - self.__acquisition = MACQ.luciole_acquisition(display,False,self.datas.hardtype) |
4294 | - |
4295 | - def __save_to_file(self,file=None): |
4296 | - # si file et vide alors on sauve sur le fichier actuel |
4297 | - if not file : |
4298 | - # no file name given get stored filename |
4299 | - file_temp = self.__filename |
4300 | - else : |
4301 | - file_temp = file |
4302 | - |
4303 | - #indentation du fichier pour meilleure presentation du fichier XML |
4304 | - self.__indent(self.__doc_et.getroot()) |
4305 | - self.__doc_et.write(file_temp,"UTF-8") |
4306 | - # remove the suppressed files from dir |
4307 | - for filetoRemove in self.__fileToSuppress : |
4308 | - print " file removed : ",filetoRemove |
4309 | - if os.path.exists(filetoRemove) : os.remove(filetoRemove) |
4310 | - |
4311 | - # add saved project to history |
4312 | - ManagerObj = MG.luciole_global.dico[MMR.luciole_recent.__name__] |
4313 | - ManagerObj.add_project(file_temp) |
4314 | - |
4315 | - self.datas.projectmodified = MCONST.PROJECT_NOT_MODIFIED |
4316 | - |
4317 | - ### STATIC METHODS |
4318 | - def __indent(elem, level=0): |
4319 | - i = "\n" + level*" " |
4320 | - if len(elem): |
4321 | - if not elem.text or not elem.text.strip(): |
4322 | - elem.text = i + " " |
4323 | - for elem in elem: |
4324 | - luciole_project_file.__indent(elem, level+1) |
4325 | - if not elem.tail or not elem.tail.strip(): |
4326 | - elem.tail = i |
4327 | - else: |
4328 | - if level and (not elem.tail or not elem.tail.strip()): |
4329 | - elem.tail = i |
4330 | - __indent=staticmethod(__indent) |
4331 | - |
4332 | - def __createImageElement(TagImage,text) : |
4333 | - """Creation of image element""" |
4334 | - #create image element |
4335 | - el_image=ET.Element(TagImage) |
4336 | - #create name elemnet |
4337 | - el_name=ET.Element("name") |
4338 | - el_name.text=text |
4339 | - #insert name elmt. in image elmt. |
4340 | - el_image.append(el_name) |
4341 | - return el_image |
4342 | - __createImageElement=staticmethod(__createImageElement) |
4343 | - |
4344 | - |
4345 | -class luciole_project_datas(object): |
4346 | - "storage of global project datas" |
4347 | - |
4348 | - def f_get_project_dir(self) : |
4349 | - return self._project_dir |
4350 | - def f_set_project_dir(self,x): |
4351 | - if os.path.isdir(x): |
4352 | - self._project_dir=x |
4353 | - project_dir = property(f_get_project_dir,f_set_project_dir,None,"Path to project") |
4354 | - |
4355 | - def f_get_src_dir(self) : |
4356 | - return self._src_dir |
4357 | - def f_set_src_dir(self,x): |
4358 | - if os.path.isdir(x): |
4359 | - self._src_dir=x |
4360 | - src_dir = property(f_get_src_dir,f_set_src_dir,None,"Src dir") |
4361 | - |
4362 | - |
4363 | - def f_get_project_name(self) : |
4364 | - return self._project_name |
4365 | - def f_set_project_name(self,x) : |
4366 | - self._project_name=x |
4367 | - project_name = property(f_get_project_name,f_set_project_name,None,"Path to project") |
4368 | - |
4369 | - def f_get_project_trash(self) : |
4370 | - return self._project_trash |
4371 | - def f_set_project_trash(self,x) : |
4372 | - self._project_trash=x |
4373 | - project_trash = property(f_get_project_trash,f_set_project_trash,None,"Trash directory of project") |
4374 | - |
4375 | - def f_get_export_dir(self) : |
4376 | - return self._export_dir |
4377 | - def f_set_export_dir(self,x) : |
4378 | - self._export_dir=x |
4379 | - export_dir = property(f_get_export_dir,f_set_export_dir,None,"export directory of project") |
4380 | - |
4381 | - |
4382 | - def f_get_filename(self) : |
4383 | - return self._filename |
4384 | - def f_set_filename(self,x) : |
4385 | - self._filename=x |
4386 | - filename = property(f_get_filename,f_set_filename,None,"Name of project file") |
4387 | - |
4388 | - def f_get_fpi(self) : |
4389 | - return int(self._fpi) |
4390 | - def f_set_fpi(self,x) : |
4391 | - self._fpi=int(x) |
4392 | - fpi = property(f_get_fpi,f_set_fpi,None,"Frame per second rate") |
4393 | - |
4394 | - def f_get_hardtype(self) : |
4395 | - return self._hardtype |
4396 | - def f_set_hardtype(self,x) : |
4397 | - self._hardtype=x |
4398 | - hardtype = property(f_get_hardtype,f_set_hardtype,None,"Hard type of the project") |
4399 | - |
4400 | - def f_get_projectmodified(self) : |
4401 | - return self.__projectmodified |
4402 | - |
4403 | - def f_set_projectmodified(self,x) : |
4404 | - if (self.__projectmodified != x ) : |
4405 | - #the project as changed his state |
4406 | - if ( x == MCONST.PROJECT_NOT_MODIFIED ) : |
4407 | - #change to not modified |
4408 | - self.__projectmodified = x |
4409 | - # update the Main window title |
4410 | - MG.luciole_global.dico['appgui'].update_main_window_name(self._project_name) |
4411 | - elif ( x == MCONST.PROJECT_MODIFIED ) : |
4412 | - #change to modified |
4413 | - self.__projectmodified = x |
4414 | - # update the Main window title |
4415 | - MG.luciole_global.dico['appgui'].update_main_window_name(self._project_name+"(*)") |
4416 | - |
4417 | - projectmodified = property(f_get_projectmodified,f_set_projectmodified,None," project is modified or not") |
4418 | - |
4419 | - |
4420 | - def __init__(self) : |
4421 | - self.__projectmodified = MCONST.PROJECT_NOT_MODIFIED |
4422 | - pass |
4423 | - |
4424 | -class luciole_file_tools(object) : |
4425 | - |
4426 | - def copy(cls,src,dest) : |
4427 | - """ Copie de fichier.""" |
4428 | - return shutil.copy(src,dest) |
4429 | - copy = classmethod(copy) |
4430 | - |
4431 | - def move(cls,src,dest) : |
4432 | - """ move de fichier.""" |
4433 | - return shutil.move(src,dest) |
4434 | - move = classmethod(move) |
4435 | - |
4436 | - def copytree(cls,src,dest) : |
4437 | - """ Copie d arboresence.""" |
4438 | - return shutil.copytree(src,dest) |
4439 | - copytree = classmethod(copytree) |
4440 | - |
4441 | - def move_to_trash(cls,path,file) : |
4442 | - src= os.path.join(path,file) |
4443 | - dest = os.path.join(MG.luciole_global.dico[luciole_project_file.__name__].datas.project_trash,file) |
4444 | - luciole_file_tools.move(src,dest) |
4445 | - move_to_trash = classmethod(move_to_trash) |
4446 | - |
4447 | - def __init__(self) : |
4448 | - pass |
4449 | - |
4450 | |
4451 | === removed file 'lucioLib/luciole_global.py' |
4452 | --- lucioLib/luciole_global.py 2009-03-29 21:48:15 +0000 |
4453 | +++ lucioLib/luciole_global.py 1970-01-01 00:00:00 +0000 |
4454 | @@ -1,41 +0,0 @@ |
4455 | -#!/usr/bin/env python |
4456 | -# -*- coding: utf-8 -*- |
4457 | -# |
4458 | -# |
4459 | -# Copyright Nicolas Bertrand (nico@inattendu.org), 2009 |
4460 | -# |
4461 | -# This file is part of Luciole. |
4462 | -# |
4463 | -# Luciole is free software: you can redistribute it and/or modify |
4464 | -# it under the terms of the GNU General Public License as published by |
4465 | -# the Free Software Foundation, either version 3 of the License, or |
4466 | -# (at your option) any later version. |
4467 | -# |
4468 | -# Luciole is distributed in the hope that it will be useful, |
4469 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
4470 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4471 | -# GNU General Public License for more details. |
4472 | -# |
4473 | -# You should have received a copy of the GNU General Public License |
4474 | -# along with Luciole. If not, see <http://www.gnu.org/licenses/>. |
4475 | -# |
4476 | -# |
4477 | - |
4478 | -class luciole_global(object): |
4479 | - dico=dict() |
4480 | - |
4481 | - (CAPTURE,CHRONO,SRC)=range(3) |
4482 | - |
4483 | - def __init__(self) : |
4484 | - print "ON passe par DICO" |
4485 | - self.dico=dict() |
4486 | - pass |
4487 | - |
4488 | - @classmethod |
4489 | - def dump_dico(cls) : |
4490 | - print "---------------------------------------------------------" |
4491 | - print "dictionnaire de :", cls.__name__ |
4492 | - for cle,valeur in cls.dico.items() : |
4493 | - print cle, ",",valeur |
4494 | - print "---------------------------------------------------------" |
4495 | - |
4496 | |
4497 | === modified file 'lucioLib/luciole_gstreamer.py' |
4498 | --- lucioLib/luciole_gstreamer.py 2009-04-08 19:59:23 +0000 |
4499 | +++ lucioLib/luciole_gstreamer.py 2009-04-13 20:10:28 +0000 |
4500 | @@ -35,9 +35,6 @@ |
4501 | import gst.interfaces |
4502 | import gtk |
4503 | |
4504 | -import luciole_global as MG |
4505 | -import luciole_file_in_out as MF |
4506 | -import luciole_class as MC |
4507 | import luciole_constants as MCONST |
4508 | import luciole_tools as MT |
4509 | import os.path |
4510 | |
4511 | === modified file 'lucioLib/luciole_image.py' |
4512 | --- lucioLib/luciole_image.py 2009-04-10 15:37:06 +0000 |
4513 | +++ lucioLib/luciole_image.py 2009-04-13 13:59:33 +0000 |
4514 | @@ -5,15 +5,52 @@ |
4515 | |
4516 | import os.path |
4517 | import gtk |
4518 | +import pango |
4519 | import subprocess as SP |
4520 | +import threading |
4521 | +import gobject |
4522 | +import time |
4523 | |
4524 | import luciole_tools as LT |
4525 | import luciole_constants as LCONST |
4526 | |
4527 | + |
4528 | #i18n support |
4529 | import gettext |
4530 | _ = gettext.gettext |
4531 | |
4532 | +class MyThumbThread(threading.Thread): |
4533 | + """ Thread class for genertion of thumbnails """ |
4534 | + |
4535 | + def __init__(self,image_list,cb_progression=None): |
4536 | + """ |
4537 | + image_list : list of Image object |
4538 | + cb_progression : callback to indicate progression |
4539 | + """ |
4540 | + super(MyThumbThread, self).__init__() |
4541 | + self._image_list = image_list |
4542 | + self.finish = False |
4543 | + self._cb_progression = cb_progression |
4544 | + |
4545 | + def run(self): |
4546 | + """ Thread execution --> generation of thumbnail""" |
4547 | + |
4548 | + #images are generated one by ons : |
4549 | + # the image.generate_pixbuf() is done with idle_add so in gui thread . |
4550 | + # pixbuf shall be made in gui thread to avoid lock problmes on gui |
4551 | + # the thread wait generaiotn of a pixbuf is done before generating a new one |
4552 | + # nbd : think about mulyople threads for this work (cf. old luciole_class) |
4553 | + for index,image in enumerate(self._image_list) : |
4554 | + image.generate_pixbuf_in_gui_thread() |
4555 | + |
4556 | + #xait for pixbuf generation by gui thread |
4557 | + while image.generated == False : |
4558 | + time.sleep(0.05) |
4559 | + if self._cb_progression != None : self._cb_progression(index +1) # indicate progression |
4560 | + self.finish = True |
4561 | + |
4562 | + |
4563 | + |
4564 | class Image(object): |
4565 | |
4566 | # class attributes : |
4567 | @@ -36,24 +73,81 @@ |
4568 | |
4569 | |
4570 | def __init__(self, image_path = None, generate_pixbuf = False, thumb_ratio = LCONST.THUMB_RATIO ): |
4571 | - |
4572 | + """ init Image object |
4573 | + image_path : absolute imapge path |
4574 | + generate_pixbuf : set to True to generate pixbuf during init |
4575 | + thumb_ratio : A thumb ratio from Normal size. Should be an integer value |
4576 | + """ |
4577 | self._load_from_file(image_path) |
4578 | |
4579 | self._pixbuf_normal = None |
4580 | self._pixbuf_thumb = None |
4581 | self._thumb_ratio = thumb_ratio |
4582 | + self.generated = False |
4583 | + |
4584 | if generate_pixbuf == True : |
4585 | - # generate normal and thumb pixbuf if requested |
4586 | - self._pixbuf_normal = gtk.gdk.pixbuf_new_from_file(self._image_path) |
4587 | - |
4588 | - # generate thumbnail according the given ratio and image size |
4589 | - width = self._pixbuf_normal.get_width() / self._thumb_ratio |
4590 | - height = self._pixbuf_normal.get_height() / self._thumb_ratio |
4591 | - self._pixbuf_thumb = self._pixbuf_normal.scale_simple( width , |
4592 | - height , |
4593 | - gtk.gdk.INTERP_BILINEAR) |
4594 | - |
4595 | - |
4596 | + # launch generation of poixbuf at init. Not threaded |
4597 | + self._generare_pixbuf() |
4598 | + |
4599 | + |
4600 | + def generate_pixbuf_in_gui_thread(self) : |
4601 | + """ generate pixbuf in gui thread : usage of idle_add""" |
4602 | + gobject.idle_add(self._generare_pixbuf) |
4603 | + |
4604 | + |
4605 | + def _generare_pixbuf(self) : |
4606 | + """ Generation of normal and thumbnail pixbuf """ |
4607 | + self.generated = False |
4608 | + # generate normal and thumb pixbuf if requested |
4609 | + self._pixbuf_normal = gtk.gdk.pixbuf_new_from_file(self._image_path) |
4610 | + |
4611 | + # generate thumbnail according the given ratio and image size |
4612 | + width = self._pixbuf_normal.get_width() / self._thumb_ratio |
4613 | + height = self._pixbuf_normal.get_height() / self._thumb_ratio |
4614 | + |
4615 | + self._pixbuf_thumb = self._pixbuf_normal.scale_simple( width , |
4616 | + height , |
4617 | + gtk.gdk.INTERP_BILINEAR) |
4618 | + |
4619 | + |
4620 | + # This technique is used to compose image with text |
4621 | + # create a pixmap with the data of the pixbuf then insert text |
4622 | + # cf. pygtk FAQ How do I draw a text [or something else] on a gtk.gdk.pixbuf? for mor explication |
4623 | + # (http://faq.pygtk.org/index.py?req=show&file=faq08.020.htp ) |
4624 | + |
4625 | + pixmap,mask = self._pixbuf_thumb.render_pixmap_and_mask() |
4626 | + |
4627 | + # graphic context and Drawarea any created to allow generation of pixbuf composition |
4628 | + gc = pixmap.new_gc() |
4629 | + area = gtk.DrawingArea() |
4630 | + # create pango layout |
4631 | + self.pangolayout = area.create_pango_layout("") |
4632 | + |
4633 | + # extract only the image name without extenstion |
4634 | + text_buffer, ext = os.path.splitext(self._name) |
4635 | + text_buffer =" "+text_buffer+" " |
4636 | + self.pangolayout.set_text(text_buffer) |
4637 | + # set text attributes |
4638 | + attrs = pango.AttrList() |
4639 | + attrs.insert(pango.AttrFamily(LCONST.THUMB_TEXT_FAMILY,0,-1)) |
4640 | + attrs.insert(pango.AttrStyle(pango.STYLE_ITALIC,0, -1)) |
4641 | + attrs.insert(pango.AttrForeground(LCONST.THUMB_TEXT_COLOR[0],LCONST.THUMB_TEXT_COLOR[1],LCONST.THUMB_TEXT_COLOR[2],0,-1)) |
4642 | + attrs.insert(pango.AttrBackground(0,0,0,0,-1)) |
4643 | + attrs.insert(pango.AttrSize(LCONST.THUMB_TEXT_SIZE,0,-1)) |
4644 | + self.pangolayout.set_attributes(attrs) |
4645 | + |
4646 | + # compute text layout position and set it on pixmap |
4647 | + (w,h) = (self._pixbuf_thumb.get_width(),self._pixbuf_thumb.get_height()) |
4648 | + (lw,lh) = self.pangolayout.get_pixel_size() |
4649 | + pixmap.draw_layout(gc, (w-lw)//2, (h -lh -2), self.pangolayout) |
4650 | + |
4651 | + # function get_from_drawable gets the the pixbuf from the pixmap |
4652 | + # no need to affect resuly to a new pisbuf: self._pixbuf_thumb is changed whe get_from_drawable is used |
4653 | + self._pixbuf_thumb.get_from_drawable(pixmap, pixmap.get_colormap(), 0, 0, 0, 0, -1, -1) |
4654 | + |
4655 | + self.generated =True |
4656 | + |
4657 | + |
4658 | def _load_from_file(self, image_path) : |
4659 | """ Private function for loading images""" |
4660 | if os.path.isfile(image_path) : |
4661 | @@ -64,15 +158,47 @@ |
4662 | |
4663 | class Rush_images(list): |
4664 | """ list of images sources """ |
4665 | - # attributes : |
4666 | - # rush_folder |
4667 | |
4668 | - def __init__(self,rush_folder,images_list=None) : |
4669 | - if os.path.exists(rush_folder) : |
4670 | + def __init__(self,rush_folder,images_list=None,cb_progress = None) : |
4671 | + """ Warning : the init of Rush_images shall be done inside a thread or thread not in gui thead |
4672 | + rush_folder : folder whe re the images are : |
4673 | + images_list : list of image to generate |
4674 | + cb_progress : used to indicate rush_obj progress creation : (ie number of image object generated |
4675 | + """ |
4676 | + if (os.path.exists(rush_folder)) : |
4677 | self._rush_folder = rush_folder |
4678 | - for image in images_list : |
4679 | - image_path = os.path.join(self._rush_folder,image) |
4680 | - super(Rush_images,self).append(Image(image_path,True)) |
4681 | + |
4682 | + # if image list not empty generate images |
4683 | + if images_list != [] : |
4684 | + |
4685 | + self._progression = 1 |
4686 | + self._progression_ratio = 0.0 |
4687 | + self._cb_progress = cb_progress |
4688 | + |
4689 | + # the exection of pixbuf are threaded |
4690 | + # 1. create the image list |
4691 | + for image in images_list : |
4692 | + image_path = os.path.join(self._rush_folder,image) |
4693 | + super(Rush_images,self).append(Image(image_path,False)) |
4694 | + # launch threaded generation of pixbuf |
4695 | + # 2. launch the thread for pixbuf generation |
4696 | + t_thumb = MyThumbThread(self,self._cb_on_progress) |
4697 | + t_thumb.start() |
4698 | + |
4699 | + # 3 . Wait executiion of thread finished : means all the pixbuf where generated |
4700 | + while t_thumb.finish == False : |
4701 | + # the sleep can bemade because the executuiof rush_images is threaded |
4702 | + time.sleep(0.1) |
4703 | + else : |
4704 | + print _('rush folder not valid') |
4705 | + |
4706 | + def _cb_on_progress(self,num) : |
4707 | + """ update progression number """ |
4708 | + self._progression = num |
4709 | + self._progression_ratio = (self._progression*1.0)/len(self) |
4710 | + |
4711 | + # indicate progression to upper level |
4712 | + if self._cb_progress != None : self._cb_progress(self._progression_ratio) |
4713 | |
4714 | def get_image(self,image_name): |
4715 | """ return image object according image_name """ |
4716 | @@ -86,7 +212,24 @@ |
4717 | def append(self,image_name) : |
4718 | """ append an image name : generater pixbuf """ |
4719 | image_path = os.path.join(self._rush_folder,image_name) |
4720 | + |
4721 | + # the generation of pixbuf in not threaded and made imedialtely |
4722 | super(Rush_images,self).append(Image(image_path,True)) |
4723 | + |
4724 | + def append_threaded(self,image_name) : |
4725 | + """ append an image name : generater pixbuf for threaded calls |
4726 | + Manage the iddle_add stuff for pixbuf generation |
4727 | + """ |
4728 | + image_path = os.path.join(self._rush_folder,image_name) |
4729 | + |
4730 | + # the generation of pixbuf in not threaded and made imedialtely |
4731 | + image = Image(image_path,False) |
4732 | + super(Rush_images,self).append(image ) |
4733 | + image.generate_pixbuf_in_gui_thread() |
4734 | + |
4735 | + while image.generated == False : |
4736 | + time.sleep(0.05) |
4737 | + return image |
4738 | |
4739 | def dump_image_name(self) : |
4740 | """ test function display rush image """ |
4741 | |
4742 | === removed file 'lucioLib/luciole_import.py' |
4743 | --- lucioLib/luciole_import.py 2009-03-08 18:06:41 +0000 |
4744 | +++ lucioLib/luciole_import.py 1970-01-01 00:00:00 +0000 |
4745 | @@ -1,136 +0,0 @@ |
4746 | -#!/usr/bin/env python |
4747 | -# -*- coding: utf-8 -*- |
4748 | -# |
4749 | -# |
4750 | -# Copyright Nicolas Bertrand (nico@inattendu.org), 2009 |
4751 | -# |
4752 | -# This file is part of Luciole. |
4753 | -# |
4754 | -# Luciole is free software: you can redistribute it and/or modify |
4755 | -# it under the terms of the GNU General Public License as published by |
4756 | -# the Free Software Foundation, either version 3 of the License, or |
4757 | -# (at your option) any later version. |
4758 | -# |
4759 | -# Luciole is distributed in the hope that it will be useful, |
4760 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
4761 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4762 | -# GNU General Public License for more details. |
4763 | -# |
4764 | -# You should have received a copy of the GNU General Public License |
4765 | -# along with Luciole. If not, see <http://www.gnu.org/licenses/>. |
4766 | -# |
4767 | -# |
4768 | - |
4769 | -""" |
4770 | -luciole_import.py |
4771 | - |
4772 | -Started on ven 28 déc 2007 12:57:52 @USER-NAME@ |
4773 | -Last update ven 28 déc 2007 12:57:52 @USER-NAME@ |
4774 | - |
4775 | -@Author Nico |
4776 | -@version 1 |
4777 | - |
4778 | -COMMENT : only PNG and JPEG are supportted. |
4779 | -""" |
4780 | -import gtk |
4781 | -import gtk.glade |
4782 | -import os.path |
4783 | -import os |
4784 | -import luciole_global as MG |
4785 | -import luciole_file_in_out as MF |
4786 | -import luciole_constants as MCONST |
4787 | -import luciole_class as MC |
4788 | -import Image |
4789 | - |
4790 | -class luciole_import(object) : |
4791 | - """ Manage the import of images. COMMENT : only PNG and JPEG are supported. |
4792 | -""" |
4793 | - |
4794 | - def __init__(self,gladefile,windowname): |
4795 | - """ Init of module """ |
4796 | - self._gladefile=gladefile |
4797 | - self._windowname=windowname |
4798 | - self._tvCapture = MG.luciole_global.dico[MC.LucioleGtkTreeView.__name__] |
4799 | - |
4800 | - self._inputImageList =[] |
4801 | - self._outputImageList =[] |
4802 | - def gui_import(self) : |
4803 | - """ Import from gui. """ |
4804 | - if ( (MF.luciole_project_file.__name__ in MG.luciole_global.dico) |
4805 | - and |
4806 | - ( MG.luciole_global.dico[MF.luciole_project_file.__name__].ProjectLoaded) ) : |
4807 | - self._Project = MG.luciole_global.dico[MF.luciole_project_file.__name__] |
4808 | - # clear imageList when a project is Loaded |
4809 | - self._inputImageList =[] |
4810 | - self._outputImageList =[] |
4811 | - # a project exists and it loaded, the fileChosser Window can be opened |
4812 | - self.openFileWindow=gtk.glade.XML(self._gladefile,self._windowname) |
4813 | - dialog = self.openFileWindow.get_widget(self._windowname) |
4814 | - # set user dir as default dir |
4815 | - dialog.set_current_folder(os.path.expandvars('$HOME')) |
4816 | - |
4817 | - #set filters All files and all mime type images |
4818 | - # Image filter |
4819 | - filter = gtk.FileFilter() |
4820 | - filter.add_mime_type("image/jpeg") |
4821 | - filter.set_name("Images ( jpeg )") |
4822 | - dialog.add_filter(filter) |
4823 | - |
4824 | - # all files |
4825 | - filter = gtk.FileFilter() |
4826 | - filter.add_pattern("*") |
4827 | - filter.set_name("All files") |
4828 | - dialog.add_filter(filter) |
4829 | - |
4830 | - response=dialog.run() |
4831 | - # value 10 choosen in glade file th standard respone gtk.REPONSE_OK = -5 |
4832 | - # provides no result. It look like a bug in glade ... |
4833 | - if response == 10 : |
4834 | - print "Ok clicked files selected :" |
4835 | - self._inputImageList = dialog.get_filenames() |
4836 | - self.processImageList() |
4837 | - elif response == gtk.RESPONSE_CANCEL: |
4838 | - print 'Cancel clicked' |
4839 | - #on ferme la fenetre |
4840 | - dialog.destroy() |
4841 | - else : |
4842 | - # No Project Loaded send a message. |
4843 | - message = "Opération non permise quand un projet n'est pas chargé. Veuillez créer un nouveau porojet ou en charger un." |
4844 | - MG.luciole_global.dico['appgui'].ErrMessage(message) |
4845 | - |
4846 | - def processImageList(self) : |
4847 | - """ Process the Image list , transform and Append it in capture treeview""" |
4848 | - for image in self._inputImageList : |
4849 | - #transform image |
4850 | - imageTransformed = self.Transform(image) |
4851 | - #append image in treview |
4852 | - if imageTransformed : |
4853 | - self._tvCapture.AppendFromCapture(imageTransformed) |
4854 | - |
4855 | - def Transform(self,imagePath) : |
4856 | - """ Transform an image in jpeg format and defined size""" |
4857 | - #open file |
4858 | - print " Image Process : ",imagePath |
4859 | - im = Image.open(imagePath) |
4860 | - (base,ext) = os.path.splitext(imagePath) |
4861 | - (rep,base) = os.path.split(base) |
4862 | - print im.format, im.size, im.mode |
4863 | - if im.format == "JPEG" and im.size == MCONST.VIDEO_PAL_RES : |
4864 | - print " Nothing to do image ",imagePath," is in correct format" |
4865 | - IsImageTransformed =False |
4866 | - if im.size != MCONST.VIDEO_PAL_RES : |
4867 | - # image need to be rescaled |
4868 | - out = im.resize(MCONST.VIDEO_PAL_RES) |
4869 | - IsImageTransformed = True |
4870 | - # save image |
4871 | - dirOut = os.path.join(self._Project.project_dir,"work") |
4872 | - fileOut = base+".jpeg" |
4873 | - fileOut = os.path.join(dirOut,fileOut) |
4874 | - if IsImageTransformed : |
4875 | - out.save(fileOut) |
4876 | - else : |
4877 | - #image not transformed just copy it |
4878 | - MF.luciole_file_tools.copy(imagePath,fileOut) |
4879 | - return fileOut |
4880 | - |
4881 | - |
4882 | |
4883 | === modified file 'lucioLib/luciole_manage_recent.py' |
4884 | --- lucioLib/luciole_manage_recent.py 2009-03-08 18:06:41 +0000 |
4885 | +++ lucioLib/luciole_manage_recent.py 2009-04-11 16:57:27 +0000 |
4886 | @@ -1,4 +1,7 @@ |
4887 | -# |
4888 | +#!/usr/bin/env python |
4889 | +# -*- coding: utf-8 -*- |
4890 | +# -*- Mode: Python -*- |
4891 | +# vi:si:ai:et:sw=4:sts=4:ts=4 |
4892 | # |
4893 | # Copyright Nicolas Bertrand (nico@inattendu.org), 2009 |
4894 | # |
4895 | @@ -19,58 +22,53 @@ |
4896 | # |
4897 | # |
4898 | import gtk |
4899 | -import luciole_global as MG |
4900 | -import luciole_file_in_out as MF |
4901 | -import luciole_conf as MCONF |
4902 | |
4903 | class luciole_recent(object): |
4904 | """ Manage recent projects, display |
4905 | - 3 projects can be dsiplayed at max """ |
4906 | - |
4907 | - __MAX_PROJECT = 3 |
4908 | - |
4909 | - def __init__(self,ProjectList,MenuWidget) : |
4910 | - """ Init of module """ |
4911 | - #init du dictionnaire global d'objet |
4912 | - if not self.__class__.__name__ in MG.luciole_global.dico : |
4913 | - MG.luciole_global.dico[self.__class__.__name__] = self |
4914 | - else : |
4915 | - print "l objet",self.__class__.__name__," existe deja" |
4916 | - return None |
4917 | - |
4918 | - self.__ProjectList = list() |
4919 | - self.__MenuWidget=MenuWidget |
4920 | - if len(ProjectList) <= self.__MAX_PROJECT : self.__ProjectList.extend(ProjectList) |
4921 | - self._displayRecentProject() |
4922 | + 5 projects can be dsiplayed at max """ |
4923 | + |
4924 | + __MAX_PROJECT = 5 |
4925 | + __ui_recent_path = '/menubar1/menu_file/menu_file_open_recent' |
4926 | + |
4927 | + def __init__(self,ProjectList,uiManager,cb_open,conf) : |
4928 | + """ Init of module """ |
4929 | + self.__ProjectList = list() |
4930 | + self._uiManager = uiManager |
4931 | + self._cb_open = cb_open # callback for open project |
4932 | + self._conf = conf |
4933 | + if len(ProjectList) <= self.__MAX_PROJECT : self.__ProjectList.extend(ProjectList) |
4934 | + |
4935 | + self._displayRecentProject() |
4936 | |
4937 | |
4938 | def add_project(self,project) : |
4939 | - """ add a project ro recent used projects """ |
4940 | - # verify project is not yet present |
4941 | - # count shall return 0 |
4942 | - if self.__ProjectList.count(project) == 0 : |
4943 | - if len(self.__ProjectList) >= self.__MAX_PROJECT : |
4944 | - # remove older project |
4945 | - self.__ProjectList.pop() |
4946 | - #insert project |
4947 | - self.__ProjectList.insert(0,project) |
4948 | - self._displayRecentProject() |
4949 | - MG.luciole_global.dico[MCONF.LucioleConf.__name__].update_last_project(self.__ProjectList) |
4950 | + """ add a project ro recent used projects """ |
4951 | + # verify project is not yet present |
4952 | + # count shall return 0 |
4953 | + if self.__ProjectList.count(project) == 0 : |
4954 | + if len(self.__ProjectList) >= self.__MAX_PROJECT : |
4955 | + # remove older project |
4956 | + self.__ProjectList.pop() |
4957 | + #insert project |
4958 | + self.__ProjectList.insert(0,project) |
4959 | + self._displayRecentProject() |
4960 | + self._conf.update_last_project(self.__ProjectList) |
4961 | |
4962 | def _displayRecentProject(self) : |
4963 | - """ Update submenu widget with recently used projects """ |
4964 | - Menu = self.__MenuWidget.get_submenu() |
4965 | - MenuChilds = Menu.get_children() |
4966 | - # first clean menu by removing all menu childs |
4967 | - for child in MenuChilds : Menu.remove(child) |
4968 | - # then add menuItem for eachProject |
4969 | - for project in self.__ProjectList : |
4970 | - MenuItem = gtk.MenuItem(project) |
4971 | - MenuItem.connect("activate",self.menu_activate,project) |
4972 | - Menu.append(MenuItem) |
4973 | - MenuItem.show() |
4974 | + """ Update submenu widget with recently used projects """ |
4975 | + MenuW = self._uiManager.get_widget(self.__ui_recent_path) |
4976 | + Menu = MenuW.get_submenu() |
4977 | + MenuChilds = Menu.get_children() |
4978 | + # first clean menu by removing all menu childs |
4979 | + for child in MenuChilds : Menu.remove(child) |
4980 | + ## then add menuItem for eachProject |
4981 | + for project in self.__ProjectList : |
4982 | + MenuItem = gtk.MenuItem(project) |
4983 | + MenuItem.connect("activate",self.menu_activate,project) |
4984 | + Menu.append(MenuItem) |
4985 | + MenuItem.show() |
4986 | |
4987 | def menu_activate(self,widget,project): |
4988 | - """ Callback on menu activation. open selected project """ |
4989 | - projectObj = MG.luciole_global.dico[MF.luciole_project_file.__name__] |
4990 | - projectObj.load_from_file(project,True) |
4991 | + """ Callback on menu activation. open selected project """ |
4992 | + self._cb_open(project) |
4993 | + |
4994 | |
4995 | === removed file 'lucioLib/luciole_timer.py' |
4996 | --- lucioLib/luciole_timer.py 2009-03-29 21:48:15 +0000 |
4997 | +++ lucioLib/luciole_timer.py 1970-01-01 00:00:00 +0000 |
4998 | @@ -1,84 +0,0 @@ |
4999 | -#!/usr/bin/env python |
5000 | -# -*- coding: utf-8 -*- |
The diff has been truncated for viewing.
Merge proposal for first luciole alpha