summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjvoisin2013-04-27 16:39:45 +0200
committerjvoisin2013-04-27 16:39:45 +0200
commitdf3a1b246031fa06adecf7dbf6e54600b20b10ba (patch)
tree4697db0080ef9a72b8506579e8440d8bb332c36c
parent3e2670ea9a87ce55f5308b0d5343bd49aab25c0b (diff)
The GUI now use glade !
Warning: this is a pretty huge commit Not everything is ported now, but this is already a big step.
-rw-r--r--MAT/mat.py15
-rw-r--r--data/mat.ui625
-rwxr-xr-xmat3
-rwxr-xr-xmat-gui573
4 files changed, 845 insertions, 371 deletions
diff --git a/MAT/mat.py b/MAT/mat.py
index 3a0938a..0da5c3b 100644
--- a/MAT/mat.py
+++ b/MAT/mat.py
@@ -39,14 +39,13 @@ def get_logo():
39 elif os.path.isfile('/usr/local/share/pixmaps/mat.png'): 39 elif os.path.isfile('/usr/local/share/pixmaps/mat.png'):
40 return '/usr/local/share/pixmaps/mat.png' 40 return '/usr/local/share/pixmaps/mat.png'
41 41
42def get_formats(): 42def get_datadir():
43 if os.path.isfile('./data/FORMATS'): 43 if os.path.isdir('./data/'):
44 return './data/FORMATS' 44 return './data/'
45 elif os.path.isfile('/usr/share/mat/FORMATS'): 45 elif os.path.isdir('/usr/share/mat/'):
46 return '/usr/share/mat/FORMATS' 46 return '/usr/share/mat/'
47 elif os.path.isfile('/usr/local/share/mat/FORMATS'): 47 elif os.path.isdir('/usr/local/share/mat/'):
48 return '/usr/local/share/mat/FORMATS' 48 return '/usr/local/share/mat/'
49
50 49
51class XMLParser(xml.sax.handler.ContentHandler): 50class XMLParser(xml.sax.handler.ContentHandler):
52 ''' 51 '''
diff --git a/data/mat.ui b/data/mat.ui
new file mode 100644
index 0000000..83d1702
--- /dev/null
+++ b/data/mat.ui
@@ -0,0 +1,625 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<interface>
3 <!-- interface-requires gtk+ 3.0 -->
4 <object class="GtkListStore" id="Liststore">
5 <columns>
6 <!-- column-name Obj -->
7 <column type="PyObject"/>
8 <!-- column-name Path -->
9 <column type="gchararray"/>
10 <!-- column-name Filename -->
11 <column type="gchararray"/>
12 <!-- column-name Mimetype -->
13 <column type="gchararray"/>
14 <!-- column-name State(str) -->
15 <column type="gchararray"/>
16 <!-- column-name Cleaned -->
17 <column type="gchararray"/>
18 <!-- column-name State -->
19 <column type="gint"/>
20 </columns>
21 </object>
22 <object class="GtkWindow" id="MainWindow">
23 <property name="visible">True</property>
24 <property name="can_focus">False</property>
25 <property name="title" translatable="yes">Metadata Anonymisation Toolkit</property>
26 <property name="window_position">center</property>
27 <property name="default_width">400</property>
28 <property name="default_height">400</property>
29 <signal name="destroy" handler="cb_close_application" swapped="no"/>
30 <child>
31 <object class="GtkBox" id="MainVBox">
32 <property name="visible">True</property>
33 <property name="can_focus">False</property>
34 <property name="orientation">vertical</property>
35 <child>
36 <object class="GtkMenuBar" id="Menubar">
37 <property name="visible">True</property>
38 <property name="can_focus">False</property>
39 <child>
40 <object class="GtkMenuItem" id="File">
41 <property name="visible">True</property>
42 <property name="can_focus">False</property>
43 <property name="label" translatable="yes">_File</property>
44 <property name="use_underline">True</property>
45 <child type="submenu">
46 <object class="GtkMenu" id="File_menu">
47 <property name="visible">True</property>
48 <property name="can_focus">False</property>
49 <child>
50 <object class="GtkImageMenuItem" id="Menu_add">
51 <property name="label">gtk-add</property>
52 <property name="visible">True</property>
53 <property name="can_focus">False</property>
54 <property name="use_underline">True</property>
55 <property name="use_stock">True</property>
56 <accelerator key="o" signal="activate" modifiers="GDK_CONTROL_MASK"/>
57 <signal name="activate" handler="cb_add_files" swapped="no"/>
58 </object>
59 </child>
60 <child>
61 <object class="GtkImageMenuItem" id="Menu_quit">
62 <property name="label">gtk-quit</property>
63 <property name="visible">True</property>
64 <property name="can_focus">False</property>
65 <property name="use_underline">True</property>
66 <property name="use_stock">True</property>
67 <accelerator key="q" signal="activate" modifiers="GDK_CONTROL_MASK"/>
68 <signal name="activate" handler="cb_close_application" swapped="no"/>
69 </object>
70 </child>
71 </object>
72 </child>
73 </object>
74 </child>
75 <child>
76 <object class="GtkMenuItem" id="Edit">
77 <property name="visible">True</property>
78 <property name="can_focus">False</property>
79 <property name="label" translatable="yes">_Edit</property>
80 <property name="use_underline">True</property>
81 <child type="submenu">
82 <object class="GtkMenu" id="Edit_menu">
83 <property name="visible">True</property>
84 <property name="can_focus">False</property>
85 <child>
86 <object class="GtkImageMenuItem" id="menu_preferences">
87 <property name="label" translatable="yes">Preferences</property>
88 <property name="visible">True</property>
89 <property name="can_focus">False</property>
90 <property name="image">image2</property>
91 <property name="use_stock">False</property>
92 <accelerator key="p" signal="activate" modifiers="GDK_CONTROL_MASK"/>
93 <signal name="activate" handler="cb_preferences_popup" swapped="no"/>
94 </object>
95 </child>
96 <child>
97 <object class="GtkImageMenuItem" id="menu_clear">
98 <property name="label" translatable="yes">Clear</property>
99 <property name="visible">True</property>
100 <property name="can_focus">False</property>
101 <property name="image">image1</property>
102 <property name="use_stock">False</property>
103 </object>
104 </child>
105 </object>
106 </child>
107 </object>
108 </child>
109 <child>
110 <object class="GtkMenuItem" id="Process">
111 <property name="visible">True</property>
112 <property name="can_focus">False</property>
113 <property name="label" translatable="yes">_Process</property>
114 <property name="use_underline">True</property>
115 <child type="submenu">
116 <object class="GtkMenu" id="Process_menu">
117 <property name="visible">True</property>
118 <property name="can_focus">False</property>
119 <child>
120 <object class="GtkImageMenuItem" id="clean_menuitem">
121 <property name="label">Clean</property>
122 <property name="visible">True</property>
123 <property name="can_focus">False</property>
124 <property name="image">image3</property>
125 <property name="use_stock">False</property>
126 <signal name="activate" handler="cb_mat_clean" swapped="no"/>
127 </object>
128 </child>
129 <child>
130 <object class="GtkImageMenuItem" id="check_menuitem">
131 <property name="label">Check</property>
132 <property name="visible">True</property>
133 <property name="can_focus">False</property>
134 <property name="image">image4</property>
135 <property name="use_stock">False</property>
136 <signal name="activate" handler="cb_mat_check" swapped="no"/>
137 </object>
138 </child>
139 </object>
140 </child>
141 </object>
142 </child>
143 <child>
144 <object class="GtkMenuItem" id="Help">
145 <property name="visible">True</property>
146 <property name="can_focus">False</property>
147 <property name="label" translatable="yes">_Help</property>
148 <property name="use_underline">True</property>
149 <child type="submenu">
150 <object class="GtkMenu" id="Help_menu">
151 <property name="visible">True</property>
152 <property name="can_focus">False</property>
153 <child>
154 <object class="GtkImageMenuItem" id="supported_menuitem">
155 <property name="label">Supported formats</property>
156 <property name="visible">True</property>
157 <property name="can_focus">False</property>
158 <property name="image">image5</property>
159 <property name="use_stock">False</property>
160 <signal name="activate" handler="cb_supported_popup" swapped="no"/>
161 </object>
162 </child>
163 <child>
164 <object class="GtkImageMenuItem" id="about_menuitem">
165 <property name="label">About</property>
166 <property name="visible">True</property>
167 <property name="can_focus">False</property>
168 <property name="image">image6</property>
169 <property name="use_stock">False</property>
170 <signal name="activate" handler="cb_about_popup" swapped="no"/>
171 </object>
172 </child>
173 </object>
174 </child>
175 </object>
176 </child>
177 </object>
178 <packing>
179 <property name="expand">False</property>
180 <property name="fill">True</property>
181 <property name="position">0</property>
182 </packing>
183 </child>
184 <child>
185 <object class="GtkToolbar" id="Toolbar">
186 <property name="visible">True</property>
187 <property name="can_focus">False</property>
188 <child>
189 <object class="GtkToolButton" id="add">
190 <property name="visible">True</property>
191 <property name="can_focus">False</property>
192 <property name="label" translatable="yes">Add</property>
193 <property name="stock_id">gtk-add</property>
194 <signal name="clicked" handler="cb_add_files" swapped="no"/>
195 </object>
196 <packing>
197 <property name="expand">False</property>
198 <property name="homogeneous">True</property>
199 </packing>
200 </child>
201 <child>
202 <object class="GtkToolButton" id="clean">
203 <property name="visible">True</property>
204 <property name="can_focus">False</property>
205 <property name="label" translatable="yes">Clean</property>
206 <property name="stock_id">gtk-clear</property>
207 <signal name="clicked" handler="cb_mat_clean" swapped="no"/>
208 </object>
209 <packing>
210 <property name="expand">False</property>
211 <property name="homogeneous">True</property>
212 </packing>
213 </child>
214 <child>
215 <object class="GtkToolButton" id="check">
216 <property name="visible">True</property>
217 <property name="can_focus">False</property>
218 <property name="label" translatable="yes">Check</property>
219 <property name="stock_id">gtk-find</property>
220 <signal name="clicked" handler="cb_mat_check" swapped="no"/>
221 </object>
222 <packing>
223 <property name="expand">False</property>
224 <property name="homogeneous">True</property>
225 </packing>
226 </child>
227 <child>
228 <object class="GtkToolButton" id="clear">
229 <property name="visible">True</property>
230 <property name="can_focus">False</property>
231 <property name="label" translatable="yes">Clear</property>
232 <property name="stock_id">gtk-remove</property>
233 <signal name="clicked" handler="cb_clear_list" swapped="no"/>
234 </object>
235 <packing>
236 <property name="expand">False</property>
237 <property name="homogeneous">True</property>
238 </packing>
239 </child>
240 <child>
241 <object class="GtkToolButton" id="quit">
242 <property name="visible">True</property>
243 <property name="can_focus">False</property>
244 <property name="label" translatable="yes">Quit</property>
245 <property name="stock_id">gtk-quit</property>
246 <signal name="clicked" handler="cb_close_application" swapped="no"/>
247 </object>
248 <packing>
249 <property name="expand">False</property>
250 <property name="homogeneous">True</property>
251 </packing>
252 </child>
253 </object>
254 <packing>
255 <property name="expand">False</property>
256 <property name="fill">True</property>
257 <property name="position">1</property>
258 </packing>
259 </child>
260 <child>
261 <object class="GtkScrolledWindow" id="ScrolledWindow">
262 <property name="visible">True</property>
263 <property name="can_focus">False</property>
264 <child>
265 <object class="GtkTreeView" id="Treeview">
266 <property name="visible">True</property>
267 <property name="can_focus">False</property>
268 <property name="hexpand">True</property>
269 <property name="model">Liststore</property>
270 <property name="rules_hint">True</property>
271 <property name="search_column">2</property>
272 <property name="fixed_height_mode">True</property>
273 <property name="rubber_banding">True</property>
274 <signal name="drag-data-received" handler="cb_drag_data_received" swapped="no"/>
275 <signal name="row-activated" handler="cb_popup_metadata" swapped="no"/>
276 <signal name="key-press-event" handler="cb_treeview_keyboard_event" swapped="no"/>
277 <child internal-child="selection">
278 <object class="GtkTreeSelection" id="treeview-selection1">
279 <property name="mode">multiple</property>
280 </object>
281 </child>
282 <child>
283 <object class="GtkTreeViewColumn" id="tvc_path">
284 <property name="resizable">True</property>
285 <property name="sizing">fixed</property>
286 <property name="title" translatable="yes">Path</property>
287 <property name="expand">True</property>
288 <property name="clickable">True</property>
289 <property name="sort_indicator">True</property>
290 <property name="sort_column_id">1</property>
291 <child>
292 <object class="GtkCellRendererText" id="cellrenderertext_path"/>
293 <attributes>
294 <attribute name="text">1</attribute>
295 </attributes>
296 </child>
297 </object>
298 </child>
299 <child>
300 <object class="GtkTreeViewColumn" id="tvc-filename">
301 <property name="resizable">True</property>
302 <property name="sizing">fixed</property>
303 <property name="title" translatable="yes">Filename</property>
304 <property name="expand">True</property>
305 <property name="clickable">True</property>
306 <property name="sort_indicator">True</property>
307 <property name="sort_column_id">2</property>
308 <child>
309 <object class="GtkCellRendererText" id="cellrenderertext_filename"/>
310 <attributes>
311 <attribute name="text">2</attribute>
312 </attributes>
313 </child>
314 </object>
315 </child>
316 <child>
317 <object class="GtkTreeViewColumn" id="tvc_mimetype">
318 <property name="resizable">True</property>
319 <property name="sizing">fixed</property>
320 <property name="title" translatable="yes">Mimetype</property>
321 <property name="expand">True</property>
322 <property name="clickable">True</property>
323 <property name="sort_indicator">True</property>
324 <property name="sort_column_id">3</property>
325 <child>
326 <object class="GtkCellRendererText" id="cellrenderertext_mimetype"/>
327 <attributes>
328 <attribute name="text">3</attribute>
329 </attributes>
330 </child>
331 </object>
332 </child>
333 <child>
334 <object class="GtkTreeViewColumn" id="tvc_state">
335 <property name="resizable">True</property>
336 <property name="sizing">fixed</property>
337 <property name="title" translatable="yes">State</property>
338 <property name="expand">True</property>
339 <property name="clickable">True</property>
340 <property name="sort_indicator">True</property>
341 <property name="sort_column_id">4</property>
342 <child>
343 <object class="GtkCellRendererText" id="cellrenderertext_state"/>
344 <attributes>
345 <attribute name="text">4</attribute>
346 </attributes>
347 </child>
348 </object>
349 </child>
350 <child>
351 <object class="GtkTreeViewColumn" id="tvc_cleanedcopy">
352 <property name="resizable">True</property>
353 <property name="sizing">fixed</property>
354 <property name="title" translatable="yes">Cleaned copy</property>
355 <property name="expand">True</property>
356 <property name="clickable">True</property>
357 <property name="sort_indicator">True</property>
358 <property name="sort_column_id">5</property>
359 <child>
360 <object class="GtkCellRendererText" id="cellrenderertext_cleanedcopy"/>
361 <attributes>
362 <attribute name="text">5</attribute>
363 </attributes>
364 </child>
365 </object>
366 </child>
367 </object>
368 </child>
369 </object>
370 <packing>
371 <property name="expand">True</property>
372 <property name="fill">True</property>
373 <property name="position">3</property>
374 </packing>
375 </child>
376 <child>
377 <object class="GtkStatusbar" id="Statusbar">
378 <property name="visible">True</property>
379 <property name="can_focus">False</property>
380 </object>
381 <packing>
382 <property name="expand">False</property>
383 <property name="fill">True</property>
384 <property name="position">4</property>
385 </packing>
386 </child>
387 </object>
388 </child>
389 </object>
390 <object class="GtkDialog" id="SupportedWindow">
391 <property name="can_focus">False</property>
392 <property name="title" translatable="yes">Supported formats</property>
393 <property name="resizable">False</property>
394 <property name="modal">True</property>
395 <property name="destroy_with_parent">True</property>
396 <property name="type_hint">dialog</property>
397 <property name="skip_taskbar_hint">True</property>
398 <property name="skip_pager_hint">True</property>
399 <property name="deletable">False</property>
400 <property name="has_resize_grip">False</property>
401 <child internal-child="vbox">
402 <object class="GtkBox" id="supported_vbox">
403 <property name="can_focus">False</property>
404 <property name="orientation">vertical</property>
405 <property name="spacing">10</property>
406 <child>
407 <object class="GtkGrid" id="supported_grid">
408 <property name="visible">True</property>
409 <property name="can_focus">False</property>
410 <property name="halign">center</property>
411 <property name="valign">center</property>
412 <property name="hexpand">True</property>
413 <property name="vexpand">True</property>
414 <property name="row_spacing">5</property>
415 <property name="column_spacing">5</property>
416 <child>
417 <object class="GtkEntry" id="supported_support">
418 <property name="visible">True</property>
419 <property name="can_focus">False</property>
420 <property name="editable">False</property>
421 <property name="has_frame">False</property>
422 <property name="invisible_char">●</property>
423 </object>
424 <packing>
425 <property name="left_attach">1</property>
426 <property name="top_attach">1</property>
427 <property name="width">1</property>
428 <property name="height">1</property>
429 </packing>
430 </child>
431 <child>
432 <object class="GtkLabel" id="supported_label_support">
433 <property name="visible">True</property>
434 <property name="can_focus">False</property>
435 <property name="label" translatable="yes">Support</property>
436 </object>
437 <packing>
438 <property name="left_attach">0</property>
439 <property name="top_attach">1</property>
440 <property name="width">1</property>
441 <property name="height">1</property>
442 </packing>
443 </child>
444 <child>
445 <object class="GtkLabel" id="supported_label_metadata">
446 <property name="visible">True</property>
447 <property name="can_focus">False</property>
448 <property name="label" translatable="yes">Metadata</property>
449 </object>
450 <packing>
451 <property name="left_attach">0</property>
452 <property name="top_attach">2</property>
453 <property name="width">1</property>
454 <property name="height">1</property>
455 </packing>
456 </child>
457 <child>
458 <object class="GtkLabel" id="supported_label_method">
459 <property name="visible">True</property>
460 <property name="can_focus">False</property>
461 <property name="label" translatable="yes">Method</property>
462 </object>
463 <packing>
464 <property name="left_attach">0</property>
465 <property name="top_attach">3</property>
466 <property name="width">1</property>
467 <property name="height">1</property>
468 </packing>
469 </child>
470 <child>
471 <object class="GtkLabel" id="supported_label_remaining">
472 <property name="visible">True</property>
473 <property name="can_focus">False</property>
474 <property name="label" translatable="yes">Remaining</property>
475 </object>
476 <packing>
477 <property name="left_attach">0</property>
478 <property name="top_attach">4</property>
479 <property name="width">1</property>
480 <property name="height">1</property>
481 </packing>
482 </child>
483 <child>
484 <object class="GtkComboBoxText" id="supported_cbox">
485 <property name="visible">True</property>
486 <property name="can_focus">False</property>
487 <property name="hexpand">True</property>
488 <property name="border_width">5</property>
489 <property name="has_entry">True</property>
490 <property name="entry_text_column">1</property>
491 <property name="id_column">1</property>
492 <signal name="changed" handler="cb_update_supported_popup" swapped="no"/>
493 </object>
494 <packing>
495 <property name="left_attach">1</property>
496 <property name="top_attach">0</property>
497 <property name="width">1</property>
498 <property name="height">1</property>
499 </packing>
500 </child>
501 <child>
502 <object class="GtkLabel" id="supported_label_format">
503 <property name="visible">True</property>
504 <property name="can_focus">False</property>
505 <property name="xpad">39</property>
506 <property name="label" translatable="yes">Fileformat</property>
507 </object>
508 <packing>
509 <property name="left_attach">0</property>
510 <property name="top_attach">0</property>
511 <property name="width">1</property>
512 <property name="height">1</property>
513 </packing>
514 </child>
515 <child>
516 <object class="GtkTextView" id="supported_metadata">
517 <property name="visible">True</property>
518 <property name="can_focus">False</property>
519 <property name="hscroll_policy">natural</property>
520 <property name="editable">False</property>
521 <property name="wrap_mode">word</property>
522 </object>
523 <packing>
524 <property name="left_attach">1</property>
525 <property name="top_attach">2</property>
526 <property name="width">1</property>
527 <property name="height">1</property>
528 </packing>
529 </child>
530 <child>
531 <object class="GtkTextView" id="supported_remaining">
532 <property name="visible">True</property>
533 <property name="can_focus">False</property>
534 <property name="wrap_mode">word</property>
535 </object>
536 <packing>
537 <property name="left_attach">1</property>
538 <property name="top_attach">4</property>
539 <property name="width">1</property>
540 <property name="height">1</property>
541 </packing>
542 </child>
543 <child>
544 <object class="GtkTextView" id="supported_method">
545 <property name="visible">True</property>
546 <property name="can_focus">False</property>
547 <property name="wrap_mode">word</property>
548 </object>
549 <packing>
550 <property name="left_attach">1</property>
551 <property name="top_attach">3</property>
552 <property name="width">1</property>
553 <property name="height">1</property>
554 </packing>
555 </child>
556 </object>
557 <packing>
558 <property name="expand">False</property>
559 <property name="fill">True</property>
560 <property name="position">0</property>
561 </packing>
562 </child>
563 <child internal-child="action_area">
564 <object class="GtkButtonBox" id="supported_action_area">
565 <property name="can_focus">False</property>
566 <child>
567 <object class="GtkButton" id="supported_OK">
568 <property name="label">gtk-ok</property>
569 <property name="visible">True</property>
570 <property name="can_focus">False</property>
571 <property name="receives_default">True</property>
572 <property name="use_stock">True</property>
573 </object>
574 <packing>
575 <property name="expand">False</property>
576 <property name="fill">True</property>
577 <property name="position">1</property>
578 </packing>
579 </child>
580 </object>
581 <packing>
582 <property name="expand">False</property>
583 <property name="fill">True</property>
584 <property name="pack_type">end</property>
585 <property name="position">1</property>
586 </packing>
587 </child>
588 </object>
589 </child>
590 <action-widgets>
591 <action-widget response="0">supported_OK</action-widget>
592 </action-widgets>
593 </object>
594 <object class="GtkImage" id="image1">
595 <property name="visible">True</property>
596 <property name="can_focus">False</property>
597 <property name="xpad">1</property>
598 <property name="stock">gtk-remove</property>
599 </object>
600 <object class="GtkImage" id="image2">
601 <property name="visible">True</property>
602 <property name="can_focus">False</property>
603 <property name="stock">gtk-properties</property>
604 </object>
605 <object class="GtkImage" id="image3">
606 <property name="visible">True</property>
607 <property name="can_focus">False</property>
608 <property name="stock">gtk-clear</property>
609 </object>
610 <object class="GtkImage" id="image4">
611 <property name="visible">True</property>
612 <property name="can_focus">False</property>
613 <property name="stock">gtk-find</property>
614 </object>
615 <object class="GtkImage" id="image5">
616 <property name="visible">True</property>
617 <property name="can_focus">False</property>
618 <property name="stock">gtk-info</property>
619 </object>
620 <object class="GtkImage" id="image6">
621 <property name="visible">True</property>
622 <property name="can_focus">False</property>
623 <property name="stock">gtk-about</property>
624 </object>
625</interface>
diff --git a/mat b/mat
index da43198..c0b5ee3 100755
--- a/mat
+++ b/mat
@@ -6,6 +6,7 @@
6import sys 6import sys
7import xml.sax 7import xml.sax
8import optparse 8import optparse
9import os
9 10
10import hachoir_core 11import hachoir_core
11 12
@@ -104,7 +105,7 @@ def list_supported():
104 handler = mat.XMLParser() 105 handler = mat.XMLParser()
105 parser = xml.sax.make_parser() 106 parser = xml.sax.make_parser()
106 parser.setContentHandler(handler) 107 parser.setContentHandler(handler)
107 path = mat.get_formats() 108 path = os.path.join(mat.get_formats(), 'FORMATS')
108 with open(path, 'r') as xmlfile: 109 with open(path, 'r') as xmlfile:
109 parser.parse(xmlfile) 110 parser.parse(xmlfile)
110 111
diff --git a/mat-gui b/mat-gui
index 57d04d9..74e8959 100755
--- a/mat-gui
+++ b/mat-gui
@@ -5,12 +5,10 @@
5 Metadata anonymisation toolkit - GUI edition 5 Metadata anonymisation toolkit - GUI edition
6''' 6'''
7 7
8import gi 8from gi.repository import GObject, Gtk
9from gi.repository import GObject 9from gi.repository import Gdk, GdkPixbuf
10from gi.repository import Gtk, Gdk, GdkPixbuf
11 10
12import gettext 11import gettext
13#import locale
14import logging 12import logging
15import os 13import os
16import sys 14import sys
@@ -21,24 +19,21 @@ import urllib2
21from MAT import mat 19from MAT import mat
22from MAT import strippers 20from MAT import strippers
23 21
24
25logging.basicConfig(level=mat.LOGGING_LEVEL) 22logging.basicConfig(level=mat.LOGGING_LEVEL)
26 23
27 24
28class CFile(object): 25class CFile(GObject.Object):
29 ''' 26 '''
30 Contain the "parser" class of the file "filename" 27 Contain the "parser" class of the file "filename"
31 This class exist just to be "around" my parser.Generic_parser class, 28 This class exist just to be "around" my parser.Generic_parser class,
32 since the Gtk.ListStore does not accept it. 29 since the Gtk.ListStore does not accept it because it does not
30 extends Gobject.Object
33 ''' 31 '''
34 def __init__(self, filename, backup, **kwargs): 32 def __init__(self, filename, backup, **kwargs):
35 try: 33 self.file = mat.create_class_file(filename, backup, **kwargs)
36 self.file = mat.create_class_file(filename, backup, **kwargs)
37 except:
38 self.file = None
39 34
40 35
41class GUI: 36class GUI(object):
42 ''' 37 '''
43 Main GUI class 38 Main GUI class
44 ''' 39 '''
@@ -50,204 +45,101 @@ class GUI:
50 self.pdf_quality = False 45 self.pdf_quality = False
51 46
52 # Main window 47 # Main window
53 self.window = Gtk.Window() 48 self.builder = Gtk.Builder()
54 self.window.set_title('Metadata Anonymisation Toolkit') 49 self.builder.add_from_file(os.path.join(mat.get_datadir(), 'mat.ui'))
55 self.window.connect('destroy', Gtk.main_quit) 50 self.builder.connect_signals(self)
56 self.window.set_default_size(800, 600) 51
57 self.logo = mat.get_logo() 52 self.logo = mat.get_logo()
58 icon = GdkPixbuf.Pixbuf.new_from_file_at_size(self.logo, 50, 50) 53 icon = GdkPixbuf.Pixbuf.new_from_file_at_size(self.logo, 50, 50)
59 self.window.set_icon(icon)
60
61 self.accelerator = Gtk.AccelGroup()
62 self.window.add_accel_group(self.accelerator)
63
64 vbox = Gtk.VBox()
65 self.window.add(vbox)
66
67 menubar = self.__create_menu()
68 toolbar = self.__create_toolbar()
69 content = Gtk.ScrolledWindow()
70 content.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
71 vbox.pack_start(menubar, False, True, 0)
72 vbox.pack_start(toolbar, False, True, 0)
73 vbox.pack_start(content, True, True, 0)
74
75 # parser.class - name - path - type - cleaned
76 self.liststore = Gtk.ListStore(object, str, str, str, str, str)
77
78 self.treeview = Gtk.TreeView(model=self.liststore)
79 self.treeview.set_search_column(1) # filename column is searchable
80 self.treeview.set_rules_hint(True) # alternate colors for rows
81 self.treeview.set_rubber_banding(True) # mouse selection
82 self.treeview.connect("key_press_event", self.treeview_keyboard_event)
83 self.treeview.connect('row-activated', self.__popup_metadata)
84 self.treeview.connect('drag_data_received',
85 self.__on_drag_data_received)
86 self.treeview.drag_dest_set(Gtk.DestDefaults.MOTION |
87 Gtk.DestDefaults.HIGHLIGHT | Gtk.DestDefaults.DROP,
88 [], Gdk.DragAction.COPY)
89 targets = Gtk.TargetList.new([])
90 targets.add_uri_targets(80)
91 self.treeview.drag_dest_set_target_list(targets)
92 self.__add_columns()
93 self.selection = self.treeview.get_selection()
94 self.selection.set_mode(Gtk.SelectionMode.MULTIPLE)
95
96 content.add(self.treeview)
97
98 self.statusbar = Gtk.Statusbar()
99 self.statusbar.push(1, _('Ready'))
100 vbox.pack_start(self.statusbar, False, False, 0)
101 54
102 self.window.show_all() 55 self.window = self.builder.get_object('MainWindow')
103 56 self.window.set_icon(icon)
104 def __create_toolbar(self): 57 self.liststore = self.builder.get_object('Liststore')
105 ''' 58 ''' The liststore contains:
106 Returns a vbox object, which contains a toolbar with buttons 59 0: a CFile instance which represent the file
60 1: the file's path
61 2: the file's name
62 3: the file's mimetype
63 4: the file's state (translated string)
64 5: the cleaned copy's path
65 6: the file's state (-1: unknown, 0: clean, 1: dirty)
107 ''' 66 '''
108 toolbar = Gtk.Toolbar()
109 67
110 toolbutton = Gtk.ToolButton(Gtk.STOCK_ADD) 68 self.treeview = self.builder.get_object('Treeview')
111 toolbutton.set_label(_('Add')) 69 self.treeview.get_column(4).set_visible(self.backup)
112 toolbutton.connect('clicked', self.__add_files)
113 toolbutton.set_tooltip_text(_('Add files'))
114 toolbar.add(toolbutton)
115 70
116 toolbutton = Gtk.ToolButton(Gtk.STOCK_CLEAR) 71 self.statusbar = self.builder.get_object('Statusbar')
117 toolbutton.set_label(_('Clean')) 72 self.statusbar.push(1, _('Ready'))
118 toolbutton.connect('clicked', self.__process_files, self.__mat_clean)
119 toolbutton.set_tooltip_text(_('Clean selected files'))
120 toolbar.add(toolbutton)
121
122 toolbutton = Gtk.ToolButton(Gtk.STOCK_FIND)
123 toolbutton.set_label(_('Check'))
124 toolbutton.connect('clicked', self.__process_files, self.__mat_check)
125 toolbutton.set_tooltip_text(_('Check selected files for harmful meta'))
126 toolbar.add(toolbutton)
127 73
128 toolbutton = Gtk.ToolButton(stock_id=Gtk.STOCK_REMOVE) 74 self.__init_supported_popup()
129 toolbutton.set_label(_('Clear the filelist')) 75 self.__set_drag_treeview()
130 toolbutton.connect('clicked', lambda x: self.liststore.clear())
131 toolbutton.set_tooltip_text(_('Clear the filelist'))
132 toolbar.add(toolbutton)
133 76
134 toolbutton = Gtk.ToolButton(stock_id=Gtk.STOCK_QUIT) 77 self.window.show_all()
135 toolbutton.set_label(_('Quit'))
136 toolbutton.connect('clicked', Gtk.main_quit)
137 toolbar.add(toolbutton)
138 78
139 vbox = Gtk.VBox(spacing=3) 79 def __init_supported_popup(self):
140 vbox.pack_start(toolbar, False, False, 0) 80 ''' Initialize the "supported formats" popup '''
141 return vbox 81 self.supported_dict = mat.XMLParser()
82 parser = xml.sax.make_parser()
83 parser.setContentHandler(self.supported_dict)
84 path = os.path.join(mat.get_datadir(), 'FORMATS')
85 with open(path, 'r') as xmlfile:
86 parser.parse(xmlfile)
142 87
143 def __add_columns(self): 88 supported_cbox = self.builder.get_object('supported_cbox')
144 ''' 89 store = Gtk.ListStore(int, str)
145 Create the columns, and add them to the treeview 90 for i, j in enumerate(self.supported_dict.list):
146 ''' 91 store.append([i, j['name']])
147 colname = [_('Path'), _('Filename'), _('Mimetype'), _('State'), 92 supported_cbox.set_model(store)
148 _('Cleaned file')] 93 supported_cbox.set_active(0)
149 94
150 for i, j in enumerate(colname, 1): 95 self.builder.get_object('supported_metadata').set_buffer(Gtk.TextBuffer())
151 filename_column = Gtk.CellRendererText() 96 self.builder.get_object('supported_remaining').set_buffer(Gtk.TextBuffer())
152 column = Gtk.TreeViewColumn(j, filename_column, text=i) 97 self.builder.get_object('supported_method').set_buffer(Gtk.TextBuffer())
153 column.set_sort_column_id(i)
154 column.set_resizable(True) # column is resizeable
155 self.treeview.append_column(column)
156 98
157 def __create_menu_item(self, name, func, menu, pix, shortcut): 99 self.cb_update_supported_popup(supported_cbox) # to initially fill the dialog
158 '''
159 Create a MenuItem() like Preferences, Quit, Add, Clean, ...
160 '''
161 item = Gtk.ImageMenuItem()
162 if shortcut:
163 key, mod = Gtk.accelerator_parse(shortcut)
164 item.add_accelerator('activate', self.accelerator,
165 key, mod, Gtk.AccelFlags.VISIBLE)
166 picture = Gtk.Image()
167 picture.set_from_stock(pix, Gtk.IconSize.MENU)
168 item.set_image(picture)
169 item.set_label('_' + name)
170 item.set_use_underline(True)
171 item.connect('activate', func)
172 menu.append(item)
173 100
174 def __create_sub_menu(self, name, menubar): 101 def __set_drag_treeview(self):
175 ''' 102 ''' Setup the drag'n'drop handling by the treeview '''
176 Create a submenu like File, Edit, Clean, ... 103 self.treeview.drag_dest_set(Gtk.DestDefaults.MOTION |
177 ''' 104 Gtk.DestDefaults.HIGHLIGHT | Gtk.DestDefaults.DROP,
178 submenu = Gtk.Menu() 105 [], Gdk.DragAction.COPY)
179 menuitem = Gtk.MenuItem() 106 targets = Gtk.TargetList.new([])
180 menuitem.set_submenu(submenu) 107 targets.add_uri_targets(80)
181 menuitem.set_label('_' + name) 108 self.treeview.drag_dest_set_target_list(targets)
182 menuitem.set_use_underline(True)
183 menubar.append(menuitem)
184 return submenu
185 109
186 def __create_menu(self): 110 def cb_update_supported_popup(self, w):
187 ''' 111 '''
188 Return a MenuBar 112 Fill GtkEntries of the supported_format_popups
113 with corresponding data.
189 ''' 114 '''
190 menubar = Gtk.MenuBar() 115 i = w.get_active_iter()
191 116 index, _ = w.get_model()[i]
192 file_menu = self.__create_sub_menu(_('Files'), menubar) 117 support = self.builder.get_object('supported_support')
193 self.__create_menu_item(_('Add files'), self.__add_files, file_menu, 118 support.set_text(self.supported_dict.list[index]['support'])
194 Gtk.STOCK_ADD, '<Control>O') 119 metadata = self.builder.get_object('supported_metadata').get_buffer()
195 self.__create_menu_item(_('Quit'), Gtk.main_quit, file_menu, 120 metadata.set_text(self.supported_dict.list[index]['metadata'])
196 Gtk.STOCK_QUIT, '<Control>Q') 121 method = self.builder.get_object('supported_method').get_buffer()
122 method.set_text(self.supported_dict.list[index]['method'])
123 remaining = self.builder.get_object('supported_remaining').get_buffer()
124 remaining.set_text(self.supported_dict.list[index]['remaining'])
197 125
198 edit_menu = self.__create_sub_menu(_('Edit'), menubar) 126 def cb_treeview_keyboard_event(self, widget, event):
199 self.__create_menu_item(_('Clear the filelist'),
200 lambda x: self.liststore.clear(), edit_menu, Gtk.STOCK_REMOVE,
201 None)
202 self.__create_menu_item(_('Preferences'), self.__preferences,
203 edit_menu, Gtk.STOCK_PREFERENCES, '<Control>P')
204
205 process_menu = self.__create_sub_menu(_('Process'), menubar)
206 item = Gtk.ImageMenuItem()
207 key, mod = Gtk.accelerator_parse('<Control>L')
208 item.add_accelerator('activate', self.accelerator,
209 key, mod, Gtk.AccelFlags.VISIBLE)
210 picture = Gtk.Image()
211 picture.set_from_stock(Gtk.STOCK_CLEAR, Gtk.IconSize.MENU)
212 item.set_image(picture)
213 item.set_label(_('Clean'))
214 item.connect('activate', self.__process_files, self.__mat_clean)
215 process_menu.append(item)
216
217 item = Gtk.ImageMenuItem()
218 key, mod = Gtk.accelerator_parse('<Control>h')
219 item.add_accelerator('activate', self.accelerator,
220 key, mod, Gtk.AccelFlags.VISIBLE)
221 picture = Gtk.Image()
222 picture.set_from_stock(Gtk.STOCK_FIND, Gtk.IconSize.MENU)
223 item.set_image(picture)
224 item.set_label(_('Check'))
225 item.connect('activate', self.__process_files, self.__mat_check)
226 process_menu.append(item)
227
228 help_menu = self.__create_sub_menu(_('Help'), menubar)
229 self.__create_menu_item(_('Supported formats'), self.__supported,
230 help_menu, Gtk.STOCK_INFO, False)
231 self.__create_menu_item(_('About'), self.__about, help_menu,
232 Gtk.STOCK_ABOUT, False)
233
234 return menubar
235
236 def treeview_keyboard_event(self, widget, event):
237 ''' 127 '''
238 Remove selected files from the treeview 128 Remove selected files from the treeview
239 when the use hit the 'suppr' key 129 when the use hit the 'suppr' key
240 ''' 130 '''
241 if Gdk.keyval_name(event.keyval) == "Delete": 131 if Gdk.keyval_name(event.keyval) == "Delete":
242 rows = [] 132 rows = []
243 self.selection.selected_foreach( 133 self.treeview.get_selection().selected_foreach(
244 lambda model, path, iter: rows.append(iter)) 134 lambda model, path, iter: rows.append(iter))
245 [self.liststore.remove(i) for i in rows] 135 [self.liststore.remove(i) for i in rows]
246 136
247 def __add_files(self, button): 137 def cb_close_application(self, _):
248 ''' 138 ''' Close the application '''
249 Add the files chosed by the filechoser ("Add" button) 139 Gtk.main_quit()
250 ''' 140
141 def cb_add_files(self, button):
142 ''' Add the files chosed by the filechoser ("Add" button) '''
251 chooser = Gtk.FileChooserDialog(title=_('Choose files'), 143 chooser = Gtk.FileChooserDialog(title=_('Choose files'),
252 parent=self.window, action=Gtk.FileChooserAction.OPEN, 144 parent=self.window, action=Gtk.FileChooserAction.OPEN,
253 buttons=(Gtk.STOCK_OK, 0, Gtk.STOCK_CANCEL, 1)) 145 buttons=(Gtk.STOCK_OK, 0, Gtk.STOCK_CANCEL, 1))
@@ -259,8 +151,8 @@ class GUI:
259 all_filter.add_pattern('*') 151 all_filter.add_pattern('*')
260 chooser.add_filter(all_filter) 152 chooser.add_filter(all_filter)
261 153
262 supported_filter = Gtk.FileFilter()
263 # filter that shows only supported formats 154 # filter that shows only supported formats
155 supported_filter = Gtk.FileFilter()
264 [supported_filter.add_mime_type(i) for i in strippers.STRIPPERS.keys()] 156 [supported_filter.add_mime_type(i) for i in strippers.STRIPPERS.keys()]
265 supported_filter.set_name(_('Supported files')) 157 supported_filter.set_name(_('Supported files'))
266 chooser.add_filter(supported_filter) 158 chooser.add_filter(supported_filter)
@@ -269,58 +161,24 @@ class GUI:
269 161
270 if not response: # Gtk.STOCK_OK 162 if not response: # Gtk.STOCK_OK
271 filenames = chooser.get_filenames() 163 filenames = chooser.get_filenames()
272 task = self.populate(filenames) 164 GObject.idle_add(self.populate(filenames).next) # asynchrone processing
273 GObject.idle_add(task.next) # asynchrone processing
274 chooser.destroy() 165 chooser.destroy()
275 166
276 def populate(self, filenames): 167 def cb_popup_metadata(self, widget, row, col):
277 '''
278 Append selected files by add_file to the self.liststore
279 '''
280 not_supported = []
281 for filename in filenames: # filenames : all selected files/folders
282 if os.path.isdir(filename): # if "filename" is a directory
283 for root, dirs, files in os.walk(filename):
284 for item in files:
285 path_to_file = os.path.join(root, item)
286 if self.__add_file_to_treeview(path_to_file):
287 not_supported.append(item)
288 else: # filename is a regular file
289 if self.__add_file_to_treeview(filename):
290 not_supported.append(filename)
291 yield True
292 if not_supported:
293 self.__popup_non_supported(not_supported)
294 yield False
295
296 def __add_file_to_treeview(self, filename):
297 '''
298 Add a file to the list if it's format is supported
299 '''
300 if not os.path.isfile(filename):
301 # if filename does not exist
302 return False
303
304 cf = CFile(filename, self.backup, add2archive=self.add2archive, low_pdf_quality=self.pdf_quality)
305 if cf.file: # if the file is supported by the mat
306 self.liststore.append([cf, os.path.dirname(cf.file.filename) + os.path.sep,
307 cf.file.basename, cf.file.mime, _('unknow'), 'None'])
308 return False
309 return True
310
311 def __popup_metadata(self, widget, row, col):
312 ''' 168 '''
313 Popup that display on double-clic 169 Popup that display on double-clic
314 metadata from a file 170 metadata from a file
171
172 FIXME: use a prettier GUI ?
315 ''' 173 '''
316 label = '<b>%s</b>\'s metadatas:\n' % self.liststore[row][1] 174 label = '<b>%s</b>\'s metadatas:\n' % self.liststore[row][1]
317 meta = '' 175 meta = ''
318 if self.liststore[row][4] == _('Clean') or\ 176 if not self.liststore[row][6] or self.liststore[row][0].file.is_clean():
319 self.liststore[row][0].file.is_clean():
320 meta = 'No metadata found' 177 meta = 'No metadata found'
321 self.liststore[row][4] = _('Clean') 178 self.liststore[row][4] = _('Clean')
322 else: 179 else:
323 self.liststore[row][4] = _('Dirty') 180 self.liststore[row][4] = _('Dirty')
181 self.liststore[row][6] = 1
324 iterator = self.liststore[row][0].file.get_meta().iteritems() 182 iterator = self.liststore[row][0].file.get_meta().iteritems()
325 for i, j in iterator: 183 for i, j in iterator:
326 name = '-<b>' + str(i) + '</b> : ' 184 name = '-<b>' + str(i) + '</b> : '
@@ -345,45 +203,8 @@ class GUI:
345 if click: 203 if click:
346 w.destroy() 204 w.destroy()
347 205
348 def __popup_non_supported(self, filelist): 206 def cb_about_popup(self, button):
349 ''' 207 ''' About popup '''
350 Popup that warn the user about the unsupported files
351 that he want to process
352 '''
353 dialog = Gtk.Dialog(title=_('Not-supported'), parent=self.window,
354 flags=0, buttons=(Gtk.STOCK_OK, 0))
355 vbox = Gtk.VBox(spacing=5)
356 dialog.get_content_area().pack_start(vbox, True, True, 0)
357 store = Gtk.ListStore(str, str)
358
359 # append filename - mimetype to the store
360 #FIXME : I'm ugly
361 for item in filelist:
362 mime = mimetypes.guess_type(item)[0]
363 if mime:
364 store.append([item, mime])
365 else:
366 store.append([item, 'unknown'])
367
368 treeview = Gtk.TreeView(store)
369 vbox.pack_start(treeview, True, True, 0)
370
371 #create column
372 rendererText = Gtk.CellRendererText()
373 column = Gtk.TreeViewColumn(_('Filename'), rendererText, text=0)
374 treeview.append_column(column)
375 column = Gtk.TreeViewColumn(_('Mimetype'), rendererText, text=1)
376 treeview.append_column(column)
377
378 dialog.show_all()
379 click = dialog.run()
380 if not click: # Ok button
381 dialog.destroy()
382
383 def __about(self, button):
384 '''
385 About popup
386 '''
387 w = Gtk.AboutDialog() 208 w = Gtk.AboutDialog()
388 w.set_authors(['Julien (jvoisin) Voisin', ]) 209 w.set_authors(['Julien (jvoisin) Voisin', ])
389 w.set_artists(['Marine Benoît', ]) 210 w.set_artists(['Marine Benoît', ])
@@ -398,63 +219,28 @@ class GUI:
398 w.run() 219 w.run()
399 w.destroy() 220 w.destroy()
400 221
401 def __supported(self, button): 222 def cb_supported_popup(self, w):
402 ''' 223 ''' Show the "supported formats" popup'''
403 List the supported formats 224 dialog = self.builder.get_object('SupportedWindow')
404 '''
405 dialog = Gtk.Dialog(_('Supported formats'), self.window, 0,
406 (Gtk.STOCK_CLOSE, 0))
407 vbox = Gtk.VBox(spacing=5)
408 dialog.get_content_area().pack_start(vbox, True, True, 0)
409
410 label = Gtk.Label()
411 label.set_markup('<big><u>Supported fileformats</u></big>')
412 vbox.pack_start(label, True, True, 0)
413
414 #parsing xml
415 handler = mat.XMLParser()
416 parser = xml.sax.make_parser()
417 parser.setContentHandler(handler)
418 path = mat.get_formats()
419 with open(path, 'r') as xmlfile:
420 parser.parse(xmlfile)
421
422 def expander_callback(current):
423 ''' Close every expander except the current one '''
424 for i in vbox.get_children()[1:]: # first child is a Gtk.Label
425 if i != current:
426 i.set_expanded(False)
427
428 for item in handler.list: # list of dict : one dict per format
429 # create one expander per format
430 # only if the format is supported
431 if item['mimetype'].split(',')[0] in strippers.STRIPPERS:
432 # some format have more than one mimetype
433 title = '%s (%s)' % (item['name'], item['extension'])
434 support = ('\t<b>%s</b> : %s' % ('support', item['support']))
435 metadata = '\n\t<b>metadata</b> : ' + item['metadata']
436 method = '\n\t<b>method</b> : ' + item['method']
437 content = support + metadata + method
438 if item['support'] == 'partial':
439 content += '\n\t<b>remaining</b> : ' + item['remaining']
440
441 expander = Gtk.Expander()
442 expander.set_label(title)
443 vbox.pack_start(expander, False, False, 0)
444 label = Gtk.Label()
445 label.set_markup(content)
446 expander.add(label)
447 expander.connect('activate', expander_callback)
448
449 dialog.show_all() 225 dialog.show_all()
450 click = dialog.run() 226 click = dialog.run()
451 if not click: # Close 227 if not click: # Close
452 dialog.destroy() 228 dialog.hide()
453 229
454 def __preferences(self, button): 230 def cb_clear_list(self, _):
455 ''' 231 ''' Clear the file list '''
456 Preferences popup 232 self.liststore.clear()
457 ''' 233
234 def cb_mat_check(self, button):
235 ''' Callback for checking files '''
236 self.__process_files(self.mat_check)
237
238 def cb_mat_clean(self, button):
239 ''' Callback for cleaning files '''
240 self.__process_files(self.mat_clean)
241
242 def cb_preferences_popup(self, button):
243 ''' Preferences popup '''
458 dialog = Gtk.Dialog(_('Preferences'), self.window, 0, 244 dialog = Gtk.Dialog(_('Preferences'), self.window, 0,
459 (Gtk.STOCK_OK, 0)) 245 (Gtk.STOCK_OK, 0))
460 dialog.set_resizable(False) 246 dialog.set_resizable(False)
@@ -472,8 +258,7 @@ class GUI:
472 force = Gtk.CheckButton(_('Force Clean'), False) 258 force = Gtk.CheckButton(_('Force Clean'), False)
473 force.set_active(self.force) 259 force.set_active(self.force)
474 force.connect('toggled', self.__invert, 'force') 260 force.connect('toggled', self.__invert, 'force')
475 force.set_tooltip_text(_('Do not check if already clean before \ 261 force.set_tooltip_text(_('Do not check if already clean before cleaning'))
476cleaning'))
477 table.attach(force, 0, 1, 0, 1) 262 table.attach(force, 0, 1, 0, 1)
478 263
479 backup = Gtk.CheckButton(_('Backup'), False) 264 backup = Gtk.CheckButton(_('Backup'), False)
@@ -498,31 +283,14 @@ non-anonymised) file to output archive'))
498 283
499 hbox.show_all() 284 hbox.show_all()
500 if not dialog.run(): # Gtk.STOCK_OK 285 if not dialog.run(): # Gtk.STOCK_OK
501 for i in self.liststore: # update preferences 286 for file in self.liststore: # update preferences
502 i[0].backup = self.backup 287 file[0].backup = self.backup
503 i[0].add2archive = self.add2archive 288 file[0].add2archive = self.add2archive
504 if i[2].startswith('pdf'): 289 if file[2].startswith('pdf'):
505 i[0].pdf_quality = self.pdf_quality 290 file[0].pdf_quality = self.pdf_quality
506 dialog.destroy() 291 dialog.destroy()
507 292
508 def __invert(self, button, name): 293 def cb_drag_data_received(self, widget, context,
509 '''
510 Invert a preference state
511 '''
512 if name == 'force':
513 self.force = not self.force
514 elif name == 'backup':
515 self.backup = not self.backup
516 for line in xrange(len(self.liststore)):
517 # change the "backup" property of all files
518 self.liststore[line][0].file.backup = self.backup
519 self.treeview.get_column(4).set_visible(self.backup)
520 elif name == 'pdf_quality':
521 self.pdf_quality = not self.pdf_quality
522 elif name == 'add2archive':
523 self.add2archive = not self.add2archive
524
525 def __on_drag_data_received(self, widget, context,
526 x, y, selection, target_type, timestamp): 294 x, y, selection, target_type, timestamp):
527 ''' 295 '''
528 This function is called when something is 296 This function is called when something is
@@ -530,7 +298,6 @@ non-anonymised) file to output archive'))
530 It basically add files. 298 It basically add files.
531 ''' 299 '''
532 300
533
534 def clean_path(url): 301 def clean_path(url):
535 ''' 302 '''
536 Since the dragged urls are ugly, 303 Since the dragged urls are ugly,
@@ -551,43 +318,126 @@ non-anonymised) file to output archive'))
551 task = self.populate(urls) 318 task = self.populate(urls)
552 GObject.idle_add(task.next) # asynchrone processing 319 GObject.idle_add(task.next) # asynchrone processing
553 320
554 def __process_files(self, button, func): 321 def __add_file_to_treeview(self, filename):
322 '''
323 Add a file to the list if its format is supported
324 '''
325 cf = CFile(filename, self.backup, add2archive=self.add2archive,
326 low_pdf_quality=self.pdf_quality)
327 if cf.file: # if the file is supported by the mat
328 self.liststore.append([cf, os.path.dirname(cf.file.filename) + os.path.sep,
329 cf.file.basename, cf.file.mime, _('unknow'), 'None', -1])
330 return False
331 return True
332
333 def __process_files(self, func):
555 ''' 334 '''
556 Launch the function "func" in a asynchrone way 335 Launch the function "func" in a asynchrone way
557 ''' 336 '''
558 iterator = self.selection.get_selected_rows()[1] 337 iterator = self.treeview.get_selection().get_selected_rows()[1]
559 if not iterator: # if nothing is selected : select everything 338 if not iterator: # if nothing is selected : select everything
560 iterator = xrange(len(self.liststore)) 339 iterator = xrange(len(self.liststore))
561 task = func(iterator) # launch func() in an asynchrone way 340 task = func(iterator) # launch func() in an asynchrone way
562 GObject.idle_add(task.next) 341 GObject.idle_add(task.next)
563 342
564 def __mat_check(self, iterator): 343 def __invert(self, button, name):
344 ''' Invert a preference state '''
345 if name == 'force':
346 self.force = not self.force
347 elif name == 'pdf_quality':
348 self.pdf_quality = not self.pdf_quality
349 elif name == 'add2archive':
350 self.add2archive = not self.add2archive
351 elif name == 'backup':
352 self.backup = not self.backup
353 for line in xrange(len(self.liststore)):
354 # change the "backup" property of all files
355 self.liststore[line][0].file.backup = self.backup
356 self.treeview.get_column(4).set_visible(self.backup)
357
358 def populate(self, filenames):
359 '''
360 Append selected files by add_file to the self.liststore
361 '''
362 not_supported = []
363 for filename in filenames: # filenames : all selected files/folders
364 if os.path.isdir(filename): # if "filename" is a directory
365 for root, dirs, files in os.walk(filename):
366 for item in files:
367 path_to_file = os.path.join(root, item)
368 if self.__add_file_to_treeview(path_to_file):
369 not_supported.append(item)
370 yield True
371 else: # filename is a regular file
372 if self.__add_file_to_treeview(filename):
373 not_supported.append(filename)
374 yield True
375 if not_supported:
376 self.__popup_non_supported(not_supported)
377 yield False
378
379 def __popup_non_supported(self, filelist):
565 ''' 380 '''
566 Check if selected elements are clean 381 Popup that warn the user about the unsupported files
382 that he want to process
567 ''' 383 '''
384 dialog = Gtk.Dialog(title=_('Not-supported'), parent=self.window,
385 flags=0, buttons=(Gtk.STOCK_OK, 0))
386 vbox = Gtk.VBox(spacing=5)
387 dialog.get_content_area().pack_start(vbox, True, True, 0)
388 store = Gtk.ListStore(str, str)
389
390 # append filename - mimetype to the store
391 for item in filelist:
392 mime = mimetypes.guess_type(item)[0]
393 if mime:
394 store.append([item, mime])
395 else:
396 store.append([item, 'unknown'])
397
398 treeview = Gtk.TreeView(store)
399 vbox.pack_start(treeview, True, True, 0)
400
401 #create column
402 rendererText = Gtk.CellRendererText()
403 column = Gtk.TreeViewColumn(_('Filename'), rendererText, text=0)
404 treeview.append_column(column)
405 column = Gtk.TreeViewColumn(_('Mimetype'), rendererText, text=1)
406 treeview.append_column(column)
407
408 dialog.show_all()
409 click = dialog.run()
410 if not click: # Ok button
411 dialog.destroy()
412
413 def mat_check(self, iterator):
414 ''' Check elements in iterator are clean '''
568 for line in iterator: # for each file in selection 415 for line in iterator: # for each file in selection
569 self.statusbar.push(0, _('Checking %s...') % self.liststore[line][1]) 416 print self.liststore[line][0].file
570 if self.force or self.liststore[line][4] != _('Clean'): 417 logging.info('Checking %s' % self.liststore[line][2])
418 self.statusbar.push(0, _('Checking %s...') % self.liststore[line][2])
419
420 if self.force or self.liststore[line][6]:
571 if self.liststore[line][0].file.is_clean(): 421 if self.liststore[line][0].file.is_clean():
572 string = _('Clean') 422 self.liststore[line][4] = _('Clean')
423 self.liststore[line][6] = 0
573 else: 424 else:
574 string = _('Dirty') 425 self.liststore[line][4] = _('Dirty')
575 logging.info('%s is %s' % (self.liststore[line][1], string)) 426 self.liststore[line][6] = 1
576 self.liststore[line][4] = string 427 logging.info('%s is %s' % (self.liststore[line][1], self.liststore[line][4]))
577 yield True 428 yield True
578 self.statusbar.push(0, _('Ready')) 429 self.statusbar.push(0, _('Ready'))
579 yield False 430 yield False
580 431
581 def __mat_clean(self, iterator): 432 def mat_clean(self, iterator):
582 ''' 433 ''' Clean elements in iterator '''
583 Clean selected elements
584 '''
585 for line in iterator: # for each file in selection 434 for line in iterator: # for each file in selection
586 logging.info('Cleaning %s' % self.liststore[line][1]) 435 logging.info('Cleaning %s' % self.liststore[line][2])
587 self.statusbar.push(0, _('Cleaning %s...') % self.liststore[line][1]) 436 self.statusbar.push(0, _('Cleaning %s...') % self.liststore[line][2])
588 if self.force or self.liststore[line][4] != _('Clean'): 437 if self.force or self.liststore[line][6]:
589 if self.liststore[line][0].file.remove_all(): 438 if self.liststore[line][0].file.remove_all():
590 self.liststore[line][4] = _('Clean') 439 self.liststore[line][4] = _('Clean')
440 self.liststore[line][6] = 0
591 if self.backup: # the backup copy state 441 if self.backup: # the backup copy state
592 self.liststore[line][5] = os.path.basename(self.liststore[line][0].file.output) 442 self.liststore[line][5] = os.path.basename(self.liststore[line][0].file.output)
593 yield True 443 yield True
@@ -597,7 +447,6 @@ non-anonymised) file to output archive'))
597if __name__ == '__main__': 447if __name__ == '__main__':
598 gettext.install('MAT', unicode=True) 448 gettext.install('MAT', unicode=True)
599 449
600 #Main
601 gui = GUI() 450 gui = GUI()
602 451
603 #Add files from command line 452 #Add files from command line