Example #1
0
def get_autostart_path():
    """Return the path of the BleachBit shortcut in the user's startup folder"""
    try:
        startupdir = shell.SHGetSpecialFolderPath(None, shellcon.CSIDL_STARTUP)
    except:
        # example of failure
        # https://www.bleachbit.org/forum/error-windows-7-x64-bleachbit-091
        logger = logging.getLogger(__name__)
        logger.exception('exception in get_autostart_path()')
        msg = 'Error finding user startup folder: %s ' % (str(
            sys.exc_info()[1]))
        import GuiBasic
        GuiBasic.message_dialog(None, msg)
        # as a fallback, guess
        # Windows XP: C:\Documents and Settings\(username)\Start Menu\Programs\Startup
        # Windows 7:
        # C:\Users\(username)\AppData\Roaming\Microsoft\Windows\Start
        # Menu\Programs\Startup
        startupdir = os.path.expandvars(
            '$USERPROFILE\\Start Menu\\Programs\\Startup')
        if not os.path.exists(startupdir):
            startupdir = os.path.expandvars(
                '$APPDATA\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup'
            )
    return os.path.join(startupdir, 'bleachbit.lnk')
Example #2
0
    def preview_or_run_operations(self, really_delete, operations=None):
        """Preview operations or run operations (delete files)"""
		
        assert(isinstance(really_delete, bool))
        import Worker
        self.start_time = None
        if None == operations:
            operations = {}
            for operation in self.get_selected_operations():
                operations[operation] = self.get_operation_options(operation)
        assert(isinstance(operations, dict))
        if 0 == len(operations):
            GuiBasic.message_dialog(self.window,
                                    _("You must select an operation"),
                                    gtk.MESSAGE_WARNING, gtk.BUTTONS_OK)
            return
        try:
            self.set_sensitive(True)
            self.textbuffer.set_text("")
            self.progressbar.show()
            print "STOP NOW"
            print self,stop_now
            self.worker = Worker.Worker(self, really_delete, operations, self.stop_now)
        except:
            traceback.print_exc()
            err = str(sys.exc_info()[1])
            self.append_text(err + "\n", 'error')
        else:
            self.start_time = time.time()
            worker = self.worker.run()
            gobject.idle_add(worker.next)
Example #3
0
def environ(varname, csidl):
    try:
        os.environ[varname] = shell.SHGetSpecialFolderPath(None, csidl)
    except:
        traceback.print_exc()
        msg = 'Error setting environemnt variable "%s": %s ' % (varname, str(sys.exc_info()[1]))
        import GuiBasic
        GuiBasic.message_dialog(None, msg)
Example #4
0
def environ(varname, csidl):
    try:
        os.environ[varname] = shell.SHGetSpecialFolderPath(None, csidl)
    except:
        traceback.print_exc()
        msg = 'Error setting environemnt variable "%s": %s ' % (
            varname, str(sys.exc_info()[1]))
        import GuiBasic
        GuiBasic.message_dialog(None, msg)
Example #5
0
    def create_menubar(self):
        """Create the menu bar (file, help)"""
        # Create a UIManager instance
        uimanager = gtk.UIManager()

        # Add the accelerator group to the top level window
        accelgroup = uimanager.get_accel_group()
        self.window.add_accel_group(accelgroup)

        # Create an ActionGroup
        actiongroup = gtk.ActionGroup('UIManagerExample')
        self.actiongroup = actiongroup

        # Create actions
        entries = (
            ('ShredFiles', None, _('_Shred Files'),
             None, None, self.cb_shred_file),
            ('ShredFolders', None, _('Sh_red Folders'),
             None, None, self.cb_shred_file),
            ('WipeFreeSpace', None, _('_Wipe Free Space'),
             None, None, self.cb_wipe_free_space),
            ('ShredQuit', None, _('S_hred Settings and Quit'),
             None, None, self.cb_shred_quit),
            ('Quit', gtk.STOCK_QUIT, _('_Quit'), None,
             None, lambda *dummy: gtk.main_quit()),
            ('File', None, _('_File')),
            ('Preferences', gtk.STOCK_PREFERENCES, _(
             "Preferences"), None, None, self.cb_preferences_dialog),
            ('Edit', None, _("_Edit")),
            ('HelpContents', gtk.STOCK_HELP, _('Help Contents'), 'F1', None,
             lambda link: GuiBasic.open_url(
             help_contents_url, self.window)),
            ('ReleaseNotes', gtk.STOCK_INFO, _('_Release Notes'), None, None,
             lambda link: GuiBasic.open_url(
             release_notes_url, self.window)),
            ('SystemInformation', None, _('_System Information'), None,
             None, lambda foo: self.diagnostic_dialog(self.window)),
            ('About', gtk.STOCK_ABOUT, _(
             '_About'), None, None, self.about),
            ('Help', None, _("_Help")))
        actiongroup.add_actions(entries)
        actiongroup.get_action('Quit').set_property('short-label', '_Quit')

        # Add the actiongroup to the uimanager
        uimanager.insert_action_group(actiongroup, 0)

        # Add a UI description
        uimanager.add_ui_from_string(self.ui)

        # Create a MenuBar
        menubar = uimanager.get_widget('/MenuBar')
        return menubar
Example #6
0
 def set_cleaner(self, path, model, parent_window, value=None):
     """Activate or deactive option of cleaner."""
     if None == value:
         # if not value given, toggle current value
         value = not model[path][1]
     assert(type(value) is types.BooleanType)
     assert(type(model) is gtk.TreeStore)
     cleaner_id = None
     i = path
     if type(i) is str:
         # type is either str or gtk.TreeIter
         i = model.get_iter(path)
     parent = model.iter_parent(i)
     if None != parent:
         # this is an option (child), not a cleaner (parent)
         cleaner_id = model[parent][2]
         option_id = model[path][2]
     if cleaner_id and value:
         # when toggling an option, present any warnings
         warning = backends[cleaner_id].get_warning(option_id)
         # TRANSLATORS: %(cleaner) may be Firefox, System, etc.
         # %(option) may be cache, logs, cookies, etc.
         # %(warning) may be 'This option is really slow'
         msg = _("Warning regarding %(cleaner)s - %(option)s:\n\n%(warning)s") % \
             {'cleaner': model[parent][0],
              'option': model[path][0],
              'warning': warning}
         if warning:
             resp = GuiBasic.message_dialog(parent_window,
                                            msg,
                                            gtk.MESSAGE_WARNING, gtk.BUTTONS_OK_CANCEL)
             if gtk.RESPONSE_OK != resp:
                 # user cancelled, so don't toggle option
                 return
     model[path][1] = value
Example #7
0
 def about(self, __event):
     """Create and show the about dialog"""
     if 'nt' != os.name and (2, 16, 6) != gtk.gtk_version:
         # workaround for broken GTK+
         # (https://bugs.launchpad.net/bleachbit/+bug/797012)
         gtk.about_dialog_set_url_hook(lambda dialog,
                                       link: GuiBasic.open_url(link, self.window, False))
     dialog = gtk.AboutDialog()
     dialog.set_comments(_("Program to clean unnecessary files"))
     dialog.set_copyright("Copyright (C) 2014 Andrew Ziem")
     try:
         dialog.set_license(open(license_filename).read())
     except:
         dialog.set_license(
             _("GNU General Public License version 3 or later.\nSee http://www.gnu.org/licenses/gpl-3.0.txt"))
     dialog.set_name(APP_NAME)
     # TRANSLATORS: Maintain the names of translators here.
     # Launchpad does this automatically for translations
     # typed in Launchpad. This is a special string shown
     # in the 'About' box.
     dialog.set_translator_credits(_("translator-credits"))
     dialog.set_version(APP_VERSION)
     dialog.set_website(APP_URL)
     dialog.set_transient_for(self.window)
     if appicon_path and os.path.exists(appicon_path):
         icon = gtk.gdk.pixbuf_new_from_file(appicon_path)
         dialog.set_logo(icon)
     dialog.run()
     dialog.hide()
Example #8
0
def get_autostart_path():
    """Return the path of the BleachBit shortcut in the user's startup folder"""
    try:
        startupdir = shell.SHGetSpecialFolderPath(None, shellcon.CSIDL_STARTUP)
    except:
        # example of failure http://bleachbit.sourceforge.net/forum/error-windows-7-x64-bleachbit-091
        traceback.print_exc()
        msg = 'Error finding user startup folder: %s ' % (str(sys.exc_info()[1]))
        import GuiBasic
        GuiBasic.message_dialog(None, msg)
        # as a fallback, guess
        # Windows XP: C:\Documents and Settings\(username)\Start Menu\Programs\Startup
        # Windows 7: C:\Users\(username)\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
        startupdir = os.path.expandvars('$USERPROFILE\\Start Menu\\Programs\\Startup')
        if not os.path.exists(startupdir):
            startupdir = os.path.expandvars('$APPDATA\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup')
    return os.path.join(startupdir, 'bleachbit.lnk')
Example #9
0
    def cb_shred_file(self, action):
        """Callback for shredding a file or folder"""

        # get list of files
        if "ShredFiles" == action.get_name():
            paths = GuiBasic.browse_files(self.window, _("Choose files to shred"))
        elif "ShredFolders" == action.get_name():
            paths = GuiBasic.browse_folder(
                self.window, _("Choose folder to shred"), multiple=True, stock_button=gtk.STOCK_DELETE
            )
        else:
            raise RuntimeError("Unexpected kind in cb_shred_file")

        if not paths:
            return

        self.shred_paths(paths)
Example #10
0
 def add_drive_cb(button):
     """Callback for adding a drive"""
     title = _("Choose a folder")
     pathname = GuiBasic.browse_folder(self.parent, title,
                                       multiple=False, stock_button=gtk.STOCK_ADD)
     if pathname:
         liststore.append([pathname])
         pathnames.append(pathname)
         options.set_list('shred_drives', pathnames)
Example #11
0
 def add_drive_cb(button):
     """Callback for adding a drive"""
     title = _("Choose a folder")
     pathname = GuiBasic.browse_folder(self.parent, title,
                                       multiple=False, stock_button=gtk.STOCK_ADD)
     if pathname:
         liststore.append([pathname])
         pathnames.append(pathname)
         options.set_list('shred_drives', pathnames)
Example #12
0
    def cb_shred_file(self, action):
        """Callback for shredding a file or folder"""

        # get list of files
        if 'ShredFiles' == action.get_name():
            paths = GuiBasic.browse_files(self.window,
                                          _("Choose files to shred"))
        elif 'ShredFolders' == action.get_name():
            paths = GuiBasic.browse_folder(self.window,
                                           _("Choose folder to shred"),
                                           multiple=True,
                                           stock_button=gtk.STOCK_DELETE)
        else:
            raise RuntimeError("Unexpected kind in cb_shred_file")

        if not paths:
            return

        self.shred_paths(paths)
Example #13
0
 def run_operations(self, __widget):
     """Event when the 'delete' toolbar button is clicked."""
     # fixme: should present this dialog after finding operations 
     # Disable delete confirmation message.
     # if the option is selected under preference.
     self.stop_now = False
     print "Cleane clicked" , self.stop_now
     if not options.get("no_popup"):
         if not GuiBasic.delete_confirmation_dialog(self.window, True):
             return
     self.preview_or_run_operations(True)
Example #14
0
    def cb_wipe_free_space(self, action):
        """callback to wipe free space in arbitrary folder"""
        path = GuiBasic.browse_folder(self.window, _("Choose a folder"), multiple=False, stock_button=gtk.STOCK_OK)
        if not path:
            # user cancelled
            return

        backends["_gui"] = Cleaner.create_wipe_cleaner(path)

        # execute
        operations = {"_gui": ["free_disk_space"]}
        self.preview_or_run_operations(True, operations)
Example #15
0
 def add_custom_file_cb(button):
     """Callback for adding a file"""
     title = _("Choose a file")
     pathname = GuiBasic.browse_file(self.parent, title)
     if pathname:
         for this_pathname in pathnames:
             if pathname == this_pathname[1]:
                 print "warning: '%s' already exists in whitelist" % pathname
                 return
         liststore.append([_('File'), pathname])
         pathnames.append(['file', pathname])
         options.set_custom_paths(pathnames)
Example #16
0
 def add_custom_file_cb(button):
     """Callback for adding a file"""
     title = _("Choose a file")
     pathname = GuiBasic.browse_file(self.parent, title)
     if pathname:
         for this_pathname in pathnames:
             if pathname == this_pathname[1]:
                 print "warning: '%s' already exists in whitelist" % pathname
                 return
         liststore.append([_('File'), pathname])
         pathnames.append(['file', pathname])
         options.set_custom_paths(pathnames)
Example #17
0
    def cb_run_option(self, widget, really_delete, cleaner_id, option_id):
        """Callback from context menu to delete/preview a single option"""
        operations = {cleaner_id: [option_id]}

        # preview
        if not really_delete:
            self.preview_or_run_operations(False, operations)
            return

        # delete
        if GuiBasic.delete_confirmation_dialog(self.window, mention_preview=False):
            self.preview_or_run_operations(True, operations)
            return
Example #18
0
 def add_custom_folder_cb(button):
     """Callback for adding a folder"""
     title = _("Choose a folder")
     pathname = GuiBasic.browse_folder(self.parent, title,
                                       multiple=False, stock_button=gtk.STOCK_ADD)
     if pathname:
         for this_pathname in pathnames:
             if pathname == this_pathname[1]:
                 print "warning: '%s' already exists in whitelist" % pathname
                 return
         liststore.append([_('Folder'), pathname])
         pathnames.append(['folder', pathname])
         options.set_custom_paths(pathnames)
Example #19
0
 def add_custom_folder_cb(button):
     """Callback for adding a folder"""
     title = _("Choose a folder")
     pathname = GuiBasic.browse_folder(self.parent, title,
                                       multiple=False, stock_button=gtk.STOCK_ADD)
     if pathname:
         for this_pathname in pathnames:
             if pathname == this_pathname[1]:
                 print "warning: '%s' already exists in whitelist" % pathname
                 return
         liststore.append([_('Folder'), pathname])
         pathnames.append(['folder', pathname])
         options.set_custom_paths(pathnames)
Example #20
0
    def cb_wipe_free_space(self, action):
        """callback to wipe free space in arbitrary folder"""
        path = GuiBasic.browse_folder(self.window,
                                      _("Choose a folder"),
                                      multiple=False, stock_button=gtk.STOCK_OK)
        if not path:
            # user cancelled
            return

        backends['_gui'] = Cleaner.create_wipe_cleaner(path)

        # execute
        operations = {'_gui': ['free_disk_space']}
        self.preview_or_run_operations(True, operations)
Example #21
0
    def shred_paths(self, paths):
        """Shred file or folders"""
        # create a temporary cleaner object
        backends['_gui'] = Cleaner.create_simple_cleaner(paths)

        # preview and confirm
        operations = {'_gui': ['files']}
        self.preview_or_run_operations(False, operations)

        if GuiBasic.delete_confirmation_dialog(self.window, mention_preview=False):
            # delete
            self.preview_or_run_operations(True, operations)
            return True
        return False
Example #22
0
    // dialog 실행
    dialog.show_all()
    while True:
        if gtk.RESPONSE_ACCEPT != dialog.run():
            sys.exit(0)
        delete = []
        for row in liststore:
            b = row[0]
            path = row[1]
            if b:
                delete.append(path)
        if 0 == len(delete):
            # no files selected to delete
            break
        import GuiBasic
        if not GuiBasic.delete_confirmation_dialog(parent, mention_preview=False):
            
            continue
        for path in delete:
            logger.info("deleting unrecognized CleanerML '%s'", path)
            os.remove(path)
        break
    dialog.destroy()

// 문자열에 대한 해시의 16진수 digest 반환
def hashdigest(string):
   

    
    return hashlib.sha512(string).hexdigest()
Example #23
0
    def create_menubar(self):
        """Create the menu bar (file, help)"""
        # Create a UIManager instance
        uimanager = gtk.UIManager()

        # Add the accelerator group to the top level window
        accelgroup = uimanager.get_accel_group()
        self.window.add_accel_group(accelgroup)

        # Create an ActionGroup
        actiongroup = gtk.ActionGroup("UIManagerExample")
        self.actiongroup = actiongroup

        # Create actions
        entries = (
            ("ShredFiles", None, _("_Shred Files"), None, None, self.cb_shred_file),
            ("ShredFolders", None, _("Sh_red Folders"), None, None, self.cb_shred_file),
            ("WipeFreeSpace", None, _("_Wipe Free Space"), None, None, self.cb_wipe_free_space),
            ("ShredQuit", None, _("S_hred Settings and Quit"), None, None, self.cb_shred_quit),
            ("Quit", gtk.STOCK_QUIT, _("_Quit"), None, None, lambda *dummy: gtk.main_quit()),
            ("File", None, _("_File")),
            ("Preferences", gtk.STOCK_PREFERENCES, _("Preferences"), None, None, self.cb_preferences_dialog),
            ("Edit", None, _("_Edit")),
            (
                "HelpContents",
                gtk.STOCK_HELP,
                _("Help Contents"),
                "F1",
                None,
                lambda link: GuiBasic.open_url(help_contents_url, self.window),
            ),
            (
                "ReleaseNotes",
                gtk.STOCK_INFO,
                _("_Release Notes"),
                None,
                None,
                lambda link: GuiBasic.open_url(release_notes_url, self.window),
            ),
            (
                "SystemInformation",
                None,
                _("_System Information"),
                None,
                None,
                lambda foo: self.diagnostic_dialog(self.window),
            ),
            ("About", gtk.STOCK_ABOUT, _("_About"), None, None, self.about),
            ("Help", None, _("_Help")),
        )
        actiongroup.add_actions(entries)
        actiongroup.get_action("Quit").set_property("short-label", "_Quit")

        # Add the actiongroup to the uimanager
        uimanager.insert_action_group(actiongroup, 0)

        # Add a UI description
        uimanager.add_ui_from_string(self.ui)

        # Create a MenuBar
        menubar = uimanager.get_widget("/MenuBar")
        return menubar
def cleaner_change_dialog(changes, parent):
    """Present a dialog regarding the change of cleaner definitions"""

    def toggled(cell, path, model):
        """Callback for clicking the checkbox"""
        __iter = model.get_iter_from_string(path)
        value = not model.get_value(__iter, 0)
        model.set(__iter, 0, value)

    import pygtk
    pygtk.require('2.0')
    import gtk

    dialog = gtk.Dialog(title=_("Security warning"),
                        parent=parent,
                        flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
    dialog.set_default_size(600, 500)

    # create warning
    warnbox = gtk.HBox()
    image = gtk.Image()
    image.set_from_stock(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_DIALOG)
    warnbox.pack_start(image, False)
    # TRANSLATORS: Cleaner definitions are XML data files that define
    # which files will be cleaned.
    label = gtk.Label(
        _("These cleaner definitions are new or have changed. Malicious definitions can damage your system. If you do not trust these changes, delete the files or quit."))
    label.set_line_wrap(True)
    warnbox.pack_start(label, True)
    dialog.vbox.pack_start(warnbox, False)

    # create tree view
    liststore = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING)
    treeview = gtk.TreeView(model=liststore)

    renderer0 = gtk.CellRendererToggle()
    renderer0.set_property('activatable', True)
    renderer0.connect('toggled', toggled, liststore)
    # TRANSLATORS: This is the column label (header) in the tree view for the
    # security dialog
    treeview.append_column(
        gtk.TreeViewColumn(_p('column_label', 'Delete'), renderer0, active=0))
    renderer1 = gtk.CellRendererText()
    # TRANSLATORS: This is the column label (header) in the tree view for the
    # security dialog
    treeview.append_column(
        gtk.TreeViewColumn(_p('column_label', 'Filename'), renderer1, text=1))

    # populate tree view
    for change in changes:
        liststore.append([False, change[0]])

    # populate dialog with widgets
    scrolled_window = gtk.ScrolledWindow()
    scrolled_window.add_with_viewport(treeview)
    dialog.vbox.pack_start(scrolled_window)

    dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)
    dialog.add_button(gtk.STOCK_QUIT, gtk.RESPONSE_CLOSE)

    # run dialog
    dialog.show_all()
    while True:
        if gtk.RESPONSE_ACCEPT != dialog.run():
            sys.exit(0)
        delete = []
        for row in liststore:
            b = row[0]
            path = row[1]
            if b:
                delete.append(path)
        if 0 == len(delete):
            # no files selected to delete
            break
        import GuiBasic
        if not GuiBasic.delete_confirmation_dialog(parent, mention_preview=False):
            # confirmation not accepted, so do not delete files
            continue
        for path in delete:
            print "info: deleting unrecognized CleanerML '%s'" % path
            os.remove(path)
        break
    dialog.destroy()
Example #25
0
def cleaner_change_dialog(changes, parent):
    """Present a dialog regarding the change of cleaner definitions"""

    def toggled(cell, path, model):
        """Callback for clicking the checkbox"""
        __iter = model.get_iter_from_string(path)
        value = not model.get_value(__iter, 0)
        model.set(__iter, 0, value)

    # TODO: move to GuiBasic
    from bleachbit.GuiBasic import Gtk
    from gi.repository import GObject

    dialog = Gtk.Dialog(title=_("Security warning"),
                        transient_for=parent,
                        modal=True, destroy_with_parent=True)
    dialog.set_default_size(600, 500)

    # create warning
    warnbox = Gtk.Box()
    image = Gtk.Image()
    image.set_from_icon_name("dialog-warning", Gtk.IconSize.DIALOG)
    warnbox.pack_start(image, False, True, 0)

    # TRANSLATORS: Cleaner definitions are XML data files that define
    # which files will be cleaned.
    label = Gtk.Label(
        label=_("These cleaner definitions are new or have changed. Malicious definitions can damage your system. If you do not trust these changes, delete the files or quit."))
    label.set_line_wrap(True)
    warnbox.pack_start(label, True, True, 0)
    dialog.vbox.pack_start(warnbox, False, True, 0)

    # create tree view
    liststore = Gtk.ListStore(GObject.TYPE_BOOLEAN, GObject.TYPE_STRING)
    treeview = Gtk.TreeView(model=liststore)

    renderer0 = Gtk.CellRendererToggle()
    renderer0.set_property('activatable', True)
    renderer0.connect('toggled', toggled, liststore)
    # TRANSLATORS: This is the column label (header) in the tree view for the
    # security dialog
    treeview.append_column(
        Gtk.TreeViewColumn(_p('column_label', 'Delete'), renderer0, active=0))
    renderer1 = Gtk.CellRendererText()
    # TRANSLATORS: This is the column label (header) in the tree view for the
    # security dialog
    treeview.append_column(
        Gtk.TreeViewColumn(_p('column_label', 'Filename'), renderer1, text=1))

    # populate tree view
    for change in changes:
        liststore.append([False, change[0]])

    # populate dialog with widgets
    scrolled_window = Gtk.ScrolledWindow()
    scrolled_window.add(treeview)
    dialog.vbox.pack_start(scrolled_window, True, True, 0)

    dialog.add_button(Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT)
    dialog.add_button(Gtk.STOCK_QUIT, Gtk.ResponseType.CLOSE)

    # run dialog
    dialog.show_all()
    while True:
        if Gtk.ResponseType.ACCEPT != dialog.run():
            sys.exit(0)
        delete = []
        for row in liststore:
            b = row[0]
            path = row[1]
            if b:
                delete.append(path)
        if 0 == len(delete):
            # no files selected to delete
            break
        import GuiBasic
        if not GuiBasic.delete_confirmation_dialog(parent, mention_preview=False):
            # confirmation not accepted, so do not delete files
            continue
        for path in delete:
            logger.info("deleting unrecognized CleanerML '%s'", path)
            os.remove(path)
        break
    dialog.destroy()
Example #26
0
 def run_operations(self, __widget):
     """Event when the 'delete' toolbar button is clicked."""
     # fixme: should present this dialog after finding operations
     if not GuiBasic.delete_confirmation_dialog(self.window, True):
         return
     self.preview_or_run_operations(True)
def cleaner_change_dialog(changes, parent):
    """Present a dialog regarding the change of cleaner definitions
       클리너 정의의 변경에 관한 다이얼로그 제시"""
    def toggled(cell, path, model):
        """Callback for clicking the checkbox
           체크박스를 클릭하기 위한 콜백함수"""
        __iter = model.get_iter_from_string(path)
        # path_sring으로 표시되는 경로를 가리키는 gtk.TreeIter를 추출
        value = not model.get_value(__iter, 0)
        # ???
        model.set(__iter, 0, value)
        # ???

    import pygtk
    pygtk.require('2.0')
    import gtk

    dialog = gtk.Dialog(title=_("Security warning"),
                        parent=parent,
                        flags=gtk.DIALOG_MODAL
                        | gtk.DIALOG_DESTROY_WITH_PARENT)
    dialog.set_default_size(600, 500)

    # create warning
    warnbox = gtk.HBox()
    image = gtk.Image()
    image.set_from_stock(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_DIALOG)
    warnbox.pack_start(image, False)
    # TRANSLATORS: Cleaner definitions are XML data files that define
    # which files will be cleaned.
    label = gtk.Label(
        _("These cleaner definitions are new or have changed. Malicious definitions can damage your system. If you do not trust these changes, delete the files or quit."
          ))
    label.set_line_wrap(True)
    warnbox.pack_start(label, True)
    dialog.vbox.pack_start(warnbox, False)

    # create tree view
    import gobject
    liststore = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING)
    treeview = gtk.TreeView(model=liststore)

    renderer0 = gtk.CellRendererToggle()
    renderer0.set_property('activatable', True)
    renderer0.connect('toggled', toggled, liststore)
    # TRANSLATORS: This is the column label (header) in the tree view for the
    # security dialog
    treeview.append_column(
        gtk.TreeViewColumn(_p('column_label', 'Delete'), renderer0, active=0))
    renderer1 = gtk.CellRendererText()
    # TRANSLATORS: This is the column label (header) in the tree view for the
    # security dialog
    treeview.append_column(
        gtk.TreeViewColumn(_p('column_label', 'Filename'), renderer1, text=1))

    # populate tree view
    for change in changes:
        liststore.append([False, change[0]])

    # populate dialog with widgets
    scrolled_window = gtk.ScrolledWindow()
    scrolled_window.add_with_viewport(treeview)
    dialog.vbox.pack_start(scrolled_window)

    dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)
    dialog.add_button(gtk.STOCK_QUIT, gtk.RESPONSE_CLOSE)

    # run dialog
    dialog.show_all()
    while True:
        if gtk.RESPONSE_ACCEPT != dialog.run():
            sys.exit(0)
        delete = []
        for row in liststore:
            b = row[0]
            path = row[1]
            if b:
                delete.append(path)
        if 0 == len(delete):
            # no files selected to delete
            break
        import GuiBasic
        if not GuiBasic.delete_confirmation_dialog(parent,
                                                   mention_preview=False):
            # confirmation not accepted, so do not delete files
            continue
        for path in delete:
            logger.info("deleting unrecognized CleanerML '%s'", path)
            os.remove(path)
        break
    dialog.destroy()
def cleaner_change_dialog(changes, parent):
    """Present a dialog regarding the change of cleaner definitions"""
    def toggled(cell, path, model):
        """Callback for clicking the checkbox"""
        __iter = model.get_iter_from_string(path)
        value = not model.get_value(__iter, 0)
        model.set(__iter, 0, value)

    # TODO: move to GuiBasic
    from bleachbit.GuiBasic import Gtk
    from gi.repository import GObject

    dialog = Gtk.Dialog(title=_("Security warning"),
                        transient_for=parent,
                        modal=True,
                        destroy_with_parent=True)
    dialog.set_default_size(600, 500)

    # create warning
    warnbox = Gtk.Box()
    image = Gtk.Image()
    image.set_from_icon_name("dialog-warning", Gtk.IconSize.DIALOG)
    warnbox.pack_start(image, False, True, 0)

    # TRANSLATORS: Cleaner definitions are XML data files that define
    # which files will be cleaned.
    label = Gtk.Label(label=_(
        "These cleaner definitions are new or have changed. Malicious definitions can damage your system. If you do not trust these changes, delete the files or quit."
    ))
    label.set_line_wrap(True)
    warnbox.pack_start(label, True, True, 0)
    dialog.vbox.pack_start(warnbox, False, True, 0)

    # create tree view
    liststore = Gtk.ListStore(GObject.TYPE_BOOLEAN, GObject.TYPE_STRING)
    treeview = Gtk.TreeView(model=liststore)

    renderer0 = Gtk.CellRendererToggle()
    renderer0.set_property('activatable', True)
    renderer0.connect('toggled', toggled, liststore)
    # TRANSLATORS: This is the column label (header) in the tree view for the
    # security dialog
    treeview.append_column(
        Gtk.TreeViewColumn(_p('column_label', 'Delete'), renderer0, active=0))
    renderer1 = Gtk.CellRendererText()
    # TRANSLATORS: This is the column label (header) in the tree view for the
    # security dialog
    treeview.append_column(
        Gtk.TreeViewColumn(_p('column_label', 'Filename'), renderer1, text=1))

    # populate tree view
    for change in changes:
        liststore.append([False, change[0]])

    # populate dialog with widgets
    scrolled_window = Gtk.ScrolledWindow()
    scrolled_window.add(treeview)
    dialog.vbox.pack_start(scrolled_window, True, True, 0)

    dialog.add_button(Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT)
    dialog.add_button(Gtk.STOCK_QUIT, Gtk.ResponseType.CLOSE)

    # run dialog
    dialog.show_all()
    while True:
        if Gtk.ResponseType.ACCEPT != dialog.run():
            sys.exit(0)
        delete = []
        for row in liststore:
            b = row[0]
            path = row[1]
            if b:
                delete.append(path)
        if 0 == len(delete):
            # no files selected to delete
            break
        import GuiBasic
        if not GuiBasic.delete_confirmation_dialog(parent,
                                                   mention_preview=False):
            # confirmation not accepted, so do not delete files
            continue
        for path in delete:
            logger.info("deleting unrecognized CleanerML '%s'", path)
            os.remove(path)
        break
    dialog.destroy()