diff options
| author | jvoisin | 2012-02-21 14:54:00 +0100 |
|---|---|---|
| committer | jvoisin | 2012-02-21 14:54:00 +0100 |
| commit | f12a3732fc4c12462179910b2804524fc1ea5c41 (patch) | |
| tree | a529924a5912407a14da1514014db754e8d552f7 /mat-gui | |
| parent | 396b9d99d4d100cb4a40a9ad86d1cb7f87bc094b (diff) | |
Remove tooltip for a "path" column
Diffstat (limited to 'mat-gui')
| -rwxr-xr-x | mat-gui | 177 |
1 files changed, 21 insertions, 156 deletions
| @@ -53,7 +53,8 @@ class GUI: | |||
| 53 | self.window.set_title('Metadata Anonymisation Toolkit') | 53 | self.window.set_title('Metadata Anonymisation Toolkit') |
| 54 | self.window.connect('destroy', gtk.main_quit) | 54 | self.window.connect('destroy', gtk.main_quit) |
| 55 | self.window.set_default_size(800, 600) | 55 | self.window.set_default_size(800, 600) |
| 56 | self.window.set_icon(gtk.gdk.pixbuf_new_from_file_at_size("logo.png", 50, 50)) | 56 | icon = gtk.gdk.pixbuf_new_from_file_at_size("logo.png", 50, 50) |
| 57 | self.window.set_icon(icon) | ||
| 57 | 58 | ||
| 58 | self.accelerator = gtk.AccelGroup() | 59 | self.accelerator = gtk.AccelGroup() |
| 59 | self.window.add_accel_group(self.accelerator) | 60 | self.window.add_accel_group(self.accelerator) |
| @@ -69,8 +70,8 @@ class GUI: | |||
| 69 | vbox.pack_start(toolbar, False, True, 0) | 70 | vbox.pack_start(toolbar, False, True, 0) |
| 70 | vbox.pack_start(content, True, True, 0) | 71 | vbox.pack_start(content, True, True, 0) |
| 71 | 72 | ||
| 72 | # parser.class - name - type - cleaned | 73 | # parser.class - name - path - type - cleaned |
| 73 | self.liststore = gtk.ListStore(object, str, str, str, str) | 74 | self.liststore = gtk.ListStore(object, str, str, str, str, str) |
| 74 | 75 | ||
| 75 | self.treeview = gtk.TreeView(model=self.liststore) | 76 | self.treeview = gtk.TreeView(model=self.liststore) |
| 76 | self.treeview.set_search_column(1) # filename column is searchable | 77 | self.treeview.set_search_column(1) # filename column is searchable |
| @@ -82,7 +83,7 @@ class GUI: | |||
| 82 | self.__on_drag_data_received) | 83 | self.__on_drag_data_received) |
| 83 | self.treeview.drag_dest_set(gtk.DEST_DEFAULT_MOTION | | 84 | self.treeview.drag_dest_set(gtk.DEST_DEFAULT_MOTION | |
| 84 | gtk.DEST_DEFAULT_HIGHLIGHT | gtk.DEST_DEFAULT_DROP, | 85 | gtk.DEST_DEFAULT_HIGHLIGHT | gtk.DEST_DEFAULT_DROP, |
| 85 | [('text/uri-list', 0, 80)], gtk.gdk.ACTION_COPY) | 86 | [('text/uri-list', 0, 80), ], gtk.gdk.ACTION_COPY) |
| 86 | self.__add_columns() | 87 | self.__add_columns() |
| 87 | self.selection = self.treeview.get_selection() | 88 | self.selection = self.treeview.get_selection() |
| 88 | self.selection.set_mode(gtk.SELECTION_MULTIPLE) | 89 | self.selection.set_mode(gtk.SELECTION_MULTIPLE) |
| @@ -132,17 +133,14 @@ class GUI: | |||
| 132 | ''' | 133 | ''' |
| 133 | Create the columns, and add them to the treeview | 134 | Create the columns, and add them to the treeview |
| 134 | ''' | 135 | ''' |
| 135 | colname = [_('Filename'), _('Mimetype'), _('State'), | 136 | colname = [_('Path'), _('Filename'), _('Mimetype'), _('State'), |
| 136 | _('Cleaned file')] | 137 | _('Cleaned file')] |
| 137 | 138 | ||
| 138 | for i, j in enumerate(colname): | 139 | for i, j in enumerate(colname, 1): |
| 139 | filename_column = gtk.CellRendererText() | 140 | filename_column = gtk.CellRendererText() |
| 140 | column = gtk.TreeViewColumn(j, filename_column, text=i + 1) | 141 | column = gtk.TreeViewColumn(j, filename_column, text=i) |
| 141 | column.set_sort_column_id(i + 1) | 142 | column.set_sort_column_id(i) |
| 142 | column.set_resizable(True) # column is resizeable | 143 | column.set_resizable(True) # column is resizeable |
| 143 | if i is 0: # place cell-specific tooltip on this column | ||
| 144 | tips = TreeViewTooltips(column) | ||
| 145 | tips.add_view(self.treeview) | ||
| 146 | self.treeview.append_column(column) | 144 | self.treeview.append_column(column) |
| 147 | 145 | ||
| 148 | def __create_menu_item(self, name, func, menu, pix, shortcut): | 146 | def __create_menu_item(self, name, func, menu, pix, shortcut): |
| @@ -294,8 +292,8 @@ class GUI: | |||
| 294 | 292 | ||
| 295 | cf = CFile(filename, self.backup, self.add2archive) | 293 | cf = CFile(filename, self.backup, self.add2archive) |
| 296 | if cf.file is not None: # if the file is supported by the mat | 294 | if cf.file is not None: # if the file is supported by the mat |
| 297 | self.liststore.append([cf, cf.file.basename, | 295 | self.liststore.append([cf, os.path.dirname(cf.file.filename), |
| 298 | cf.file.mime, _('unknow'), 'None']) | 296 | cf.file.basename, cf.file.mime, _('unknow'), 'None']) |
| 299 | return False | 297 | return False |
| 300 | else: | 298 | else: |
| 301 | return True | 299 | return True |
| @@ -307,11 +305,12 @@ class GUI: | |||
| 307 | ''' | 305 | ''' |
| 308 | label = '<b>%s</b>\'s metadatas:\n' % self.liststore[row][1] | 306 | label = '<b>%s</b>\'s metadatas:\n' % self.liststore[row][1] |
| 309 | meta = '' | 307 | meta = '' |
| 310 | if self.liststore[row][0].file.is_clean(): | 308 | if self.liststore[row][4] == _('Clean') or\ |
| 309 | self.liststore[row][0].file.is_clean(): | ||
| 311 | meta = 'No metadata found' | 310 | meta = 'No metadata found' |
| 312 | self.liststore[row][3] = _('Clean') | 311 | self.liststore[row][4] = _('Clean') |
| 313 | else: | 312 | else: |
| 314 | self.liststore[row][3] = _('Dirty') | 313 | self.liststore[row][4] = _('Dirty') |
| 315 | iterator = self.liststore[row][0].file.get_meta().iteritems() | 314 | iterator = self.liststore[row][0].file.get_meta().iteritems() |
| 316 | for i, j in iterator: | 315 | for i, j in iterator: |
| 317 | name = '-<b>' + str(i) + '</b> : ' | 316 | name = '-<b>' + str(i) + '</b> : ' |
| @@ -386,7 +385,7 @@ class GUI: | |||
| 386 | w.set_website('https://mat.boum.org') | 385 | w.set_website('https://mat.boum.org') |
| 387 | w.set_website_label(_('Website')) | 386 | w.set_website_label(_('Website')) |
| 388 | w.set_position(gtk.WIN_POS_CENTER) | 387 | w.set_position(gtk.WIN_POS_CENTER) |
| 389 | click = w.run() | 388 | w.run() |
| 390 | w.destroy() | 389 | w.destroy() |
| 391 | 390 | ||
| 392 | def __supported(self, button): | 391 | def __supported(self, button): |
| @@ -539,13 +538,13 @@ non-anonymised) file to output archive')) | |||
| 539 | ''' | 538 | ''' |
| 540 | for line in iterator: # for each file in selection | 539 | for line in iterator: # for each file in selection |
| 541 | self.statusbar.push(0, _('Checking %s...') % self.liststore[line][1]) | 540 | self.statusbar.push(0, _('Checking %s...') % self.liststore[line][1]) |
| 542 | if self.force is True or self.liststore[line][3] != _('Clean'): | 541 | if self.force is True or self.liststore[line][4] != _('Clean'): |
| 543 | if self.liststore[line][0].file.is_clean(): | 542 | if self.liststore[line][0].file.is_clean(): |
| 544 | string = _('Clean') | 543 | string = _('Clean') |
| 545 | else: | 544 | else: |
| 546 | string = _('Dirty') | 545 | string = _('Dirty') |
| 547 | logging.info('%s is %s' % (self.liststore[line][1], string)) | 546 | logging.info('%s is %s' % (self.liststore[line][1], string)) |
| 548 | self.liststore[line][3] = string | 547 | self.liststore[line][4] = string |
| 549 | yield True | 548 | yield True |
| 550 | self.statusbar.push(0, _('Ready')) | 549 | self.statusbar.push(0, _('Ready')) |
| 551 | yield False | 550 | yield False |
| @@ -557,150 +556,16 @@ non-anonymised) file to output archive')) | |||
| 557 | for line in iterator: # for each file in selection | 556 | for line in iterator: # for each file in selection |
| 558 | logging.info('Cleaning %s' % self.liststore[line][1]) | 557 | logging.info('Cleaning %s' % self.liststore[line][1]) |
| 559 | self.statusbar.push(0, _('Cleaning %s...') % self.liststore[line][1]) | 558 | self.statusbar.push(0, _('Cleaning %s...') % self.liststore[line][1]) |
| 560 | if self.force is True or self.liststore[line][3] != _('Clean'): | 559 | if self.force is True or self.liststore[line][4] != _('Clean'): |
| 561 | if self.liststore[line][0].file.remove_all(): | 560 | if self.liststore[line][0].file.remove_all(): |
| 562 | self.liststore[line][3] = _('Clean') | 561 | self.liststore[line][4] = _('Clean') |
| 563 | if self.backup: # the backup copy state | 562 | if self.backup: # the backup copy state |
| 564 | self.liststore[line][4] = self.liststore[line][0].file.output | 563 | self.liststore[line][5] = os.path.basename(self.liststore[line][0].file.output) |
| 565 | yield True | 564 | yield True |
| 566 | self.statusbar.push(0, _('Ready')) | 565 | self.statusbar.push(0, _('Ready')) |
| 567 | yield False | 566 | yield False |
| 568 | 567 | ||
| 569 | 568 | ||
| 570 | class TreeViewTooltips(object): | ||
| 571 | ''' | ||
| 572 | A dirty hack losely based on treeviewtooltip from Daniel J. Popowich | ||
| 573 | (dpopowich AT astro dot umass dot edu), to display differents tooltips | ||
| 574 | for each cell of the first row of the GUI. | ||
| 575 | ''' | ||
| 576 | # Copyright (c) 2006, Daniel J. Popowich | ||
| 577 | # | ||
| 578 | # Permission is hereby granted, free of charge, to any person | ||
| 579 | # obtaining a copy of this software and associated documentation files | ||
| 580 | # (the "Software"), to deal in the Software without restriction, | ||
| 581 | # including without limitation the rights to use, copy, modify, merge, | ||
| 582 | # publish, distribute, sublicense, and/or sell copies of the Software, | ||
| 583 | # and to permit persons to whom the Software is furnished to do so, | ||
| 584 | # subject to the following conditions: | ||
| 585 | # | ||
| 586 | # The above copyright notice and this permission notice shall be | ||
| 587 | # included in all copies or substantial portions of the Software. | ||
| 588 | def __init__(self, namecol): | ||
| 589 | ''' | ||
| 590 | Initialize the tooltip. | ||
| 591 | window: the popup window that holds the tooltip text, an | ||
| 592 | instance of gtk.Window. | ||
| 593 | label: a gtk.Label that is packed into the window. The | ||
| 594 | tooltip text is set in the label with the | ||
| 595 | set_label() method, so the text can be plain or | ||
| 596 | markup text. | ||
| 597 | ''' | ||
| 598 | # create the window | ||
| 599 | self.window = window = gtk.Window(gtk.WINDOW_POPUP) | ||
| 600 | window.set_name('gtk-tooltips') | ||
| 601 | window.set_resizable(False) | ||
| 602 | window.set_border_width(4) | ||
| 603 | window.set_app_paintable(True) | ||
| 604 | window.connect("expose-event", self.__on_expose_event) | ||
| 605 | |||
| 606 | # create the label | ||
| 607 | self.label = label = gtk.Label() | ||
| 608 | label.set_line_wrap(True) | ||
| 609 | label.set_alignment(0.5, 0.5) | ||
| 610 | label.show() | ||
| 611 | window.add(label) | ||
| 612 | |||
| 613 | self.namecol = namecol | ||
| 614 | self.__save = None # saves the current cell | ||
| 615 | self.__next = None # the timer id for the next tooltip to be shown | ||
| 616 | self.__shown = False # flag on whether the tooltip window is shown | ||
| 617 | |||
| 618 | def __show(self, tooltip, x, y): | ||
| 619 | ''' | ||
| 620 | show the tooltip | ||
| 621 | ''' | ||
| 622 | self.label.set_label(tooltip) # set label | ||
| 623 | self.window.move(x, y) # move the window | ||
| 624 | self.window.show() # show it | ||
| 625 | self.__shown = True | ||
| 626 | |||
| 627 | def __hide(self): | ||
| 628 | ''' | ||
| 629 | hide the tooltip | ||
| 630 | ''' | ||
| 631 | self.__queue_next() | ||
| 632 | self.window.hide() | ||
| 633 | self.__shown = False | ||
| 634 | |||
| 635 | def __motion_handler(self, view, event): | ||
| 636 | ''' | ||
| 637 | as the pointer moves across the view, show a tooltip | ||
| 638 | ''' | ||
| 639 | path_at_pos = view.get_path_at_pos(int(event.x), int(event.y)) | ||
| 640 | if path_at_pos: | ||
| 641 | path, col, x, y = path_at_pos | ||
| 642 | tooltip = self.get_tooltip(view, col, path) | ||
| 643 | if tooltip: | ||
| 644 | tooltip = str(tooltip).strip() | ||
| 645 | self.__queue_next((path, col), tooltip, int(event.x_root), | ||
| 646 | int(event.y_root)) | ||
| 647 | return | ||
| 648 | self.__hide() | ||
| 649 | |||
| 650 | def __queue_next(self, *args): | ||
| 651 | ''' | ||
| 652 | queue next request to show a tooltip | ||
| 653 | if args is non-empty it means a request was made to show a | ||
| 654 | tooltip. if empty, no request is being made, but any | ||
| 655 | pending requests should be cancelled anyway | ||
| 656 | ''' | ||
| 657 | cell = None | ||
| 658 | |||
| 659 | if args: # if called with args, break them out | ||
| 660 | cell, tooltip, x, y = args | ||
| 661 | |||
| 662 | # if it's the same cell as previously shown, just return | ||
| 663 | if self.__save == cell: | ||
| 664 | return | ||
| 665 | |||
| 666 | if self.__next: # if we have something queued up, cancel it | ||
| 667 | gobject.source_remove(self.__next) | ||
| 668 | self.__next = None | ||
| 669 | |||
| 670 | if cell: # if there was a request | ||
| 671 | if self.__shown: # if tooltip is already shown show the new one | ||
| 672 | self.__show(tooltip, x, y) | ||
| 673 | else: # else queue it up in 1/2 second | ||
| 674 | self.__next = gobject.timeout_add(500, self.__show, | ||
| 675 | tooltip, x, y) | ||
| 676 | self.__save = cell # save this cell | ||
| 677 | |||
| 678 | def __on_expose_event(self, window, event): | ||
| 679 | ''' | ||
| 680 | this magic is required so the window appears with a 1-pixel | ||
| 681 | black border (default gtk Style). | ||
| 682 | ''' | ||
| 683 | w, h = window.size_request() | ||
| 684 | window.style.paint_flat_box(window.window, gtk.STATE_NORMAL, | ||
| 685 | gtk.SHADOW_OUT, None, window, 'tooltip', 0, 0, w, h) | ||
| 686 | |||
| 687 | def add_view(self, view): | ||
| 688 | ''' | ||
| 689 | add a gtk.TreeView to the tooltip | ||
| 690 | ''' | ||
| 691 | view.connect('motion-notify-event', self.__motion_handler) | ||
| 692 | view.connect('leave-notify-event', lambda i, j: self.__hide()) | ||
| 693 | |||
| 694 | def get_tooltip(self, view, column, path): | ||
| 695 | ''' | ||
| 696 | See the module doc string for a description of this method | ||
| 697 | ''' | ||
| 698 | if column is self.namecol: | ||
| 699 | model = view.get_model() | ||
| 700 | name = model[path][0] | ||
| 701 | return name.file.filename | ||
| 702 | |||
| 703 | |||
| 704 | def translate(): | 569 | def translate(): |
| 705 | '''' | 570 | '''' |
| 706 | Handle L10N of mat-gui | 571 | Handle L10N of mat-gui |
