예제 #1
0
    def on_recover_button_clicked(self, widget):
        iter = self.backup_combobox.get_active_iter()
        model = self.backup_combobox.get_model()
        directory = self.dir_label.get_text()
        path = model.get_value(iter, 1)

        if directory.count('/') == 2:
            message = _('Would you like to recover the backup: <b>%s/%s</b>?') % (
                        directory, os.path.basename(path)[:-4])
        else:
            message = _('Would you like to recover the backup of all'
                        '<b>%s</b> settings named <b>%s</b>?') % (
                        directory, os.path.basename(path)[:-4])

        addon_message = _('<b>NOTES</b>: While recovering, your desktop may be unresponsive for a moment.')

        dialog = QuestionDialog(message=message + '\n\n' + addon_message)
        response = dialog.run()
        dialog.destroy()

        if response == Gtk.ResponseType.YES:
            if directory.count('/') == 1:
                for line in open(path):
                    stdout, stderr = do_recover_task(line.strip())
            else:
                stdout, stderr = do_recover_task(path)

            if stderr:
                log.error(stderr)
                #TODO raise error or others
                return
            self._show_successful_dialog(title=_('Recovery Successful!'),
                 message=_('You may need to restart your desktop for changes to take effect'))
예제 #2
0
    def on_reset_button_clicked(self, widget):
        iter = self.backup_combobox.get_active_iter()
        model = self.backup_combobox.get_model()
        directory = self.dir_label.get_text()

        if directory.count('/') == 2:
            message = _('Would you like to reset settings for "<b>%s</b>"?'
                        ) % directory
        else:
            message = _(
                'Would you like to reset all settings under "<b>%s</b>"?'
            ) % directory

        addon_message = _(
            '<b>NOTES</b>: Whilst resetting, your desktop may be unresponsive for a moment.'
        )

        dialog = QuestionDialog(message=message + '\n\n' + addon_message)
        response = dialog.run()
        dialog.destroy()

        if response == Gtk.ResponseType.YES:
            stdout, stderr = do_reset_task(directory)

            if stderr:
                log.error(stderr)
                #TODO raise error or others
                return
            self._show_successful_dialog(
                title=_('Reset Successful!'),
                message=
                _('You may need to restart your desktop for changes to take effect'
                  ))
예제 #3
0
    def on_recover_button_clicked(self, widget):
        model, iter = self.list_selection.get_selected()

        if iter:
            list_path = model[iter][0]
            list_name = model[iter][1]

            backup_iter = self.backup_combobox.get_active_iter()

            if backup_iter:
                backup_path = self.backup_model[backup_iter][0]
                backup_name = self.backup_model[backup_iter][1]

                dialog = QuestionDialog(message=_('Would you like to recover the '
                                        'backup "<b>%(backup_name)s</b>" for "<b>%(list_name)s</b>"?') % \
                                                {'backup_name': backup_name,
                                                 'list_name': list_name})
                response = dialog.run()
                dialog.destroy()

                if response == Gtk.ResponseType.YES:
                    if proxy.restore_source(backup_path, list_path):
                        self.infobar.response(Gtk.ResponseType.CLOSE)
                    else:
                        ErrorDialog(title=_('Recovery Failed!'),
                                    message=_(
                                        'You may need to check the permission '
                                        'of source list.')).launch()
예제 #4
0
    def on_recover_button_clicked(self, widget):
        model, iter = self.list_selection.get_selected()

        if iter:
            list_path = model[iter][0]
            list_name = model[iter][1]

            backup_iter = self.backup_combobox.get_active_iter()

            if backup_iter:
                backup_path = self.backup_model[backup_iter][0]
                backup_name = self.backup_model[backup_iter][1]

                dialog = QuestionDialog(message=_('Would you like to recover the '
                                        'backup "<b>%s</b>" for "<b>%s</b>"?') % (
                                backup_name, list_name))
                response = dialog.run()
                dialog.destroy()

                if response == Gtk.ResponseType.YES:
                    if proxy.restore_source(backup_path, list_path):
                        self.infobar.response(Gtk.ResponseType.CLOSE)
                    else:
                        ErrorDialog(title=_('Recovery Failed!'),
                                   message=_('You may need to check the permission '
                                             'of source list.')).launch()
예제 #5
0
 def on_rebuild_clicked(self, widget):
     dialog = QuestionDialog(message=_('This will delete all disabled scripts.\nDo you wish to continue?'))
     if dialog.run() == Gtk.ResponseType.YES:
         self.default.remove()
         self.default.create()
         self.disable_scripts.update_model()
     dialog.destroy()
예제 #6
0
 def on_rebuild_clicked(self, widget):
     dialog = QuestionDialog(message=_('This will delete all disabled scripts.\nDo you wish to continue?'))
     if dialog.run() == Gtk.ResponseType.YES:
         self.default.remove()
         self.default.create()
         self.disable_scripts.update_model()
     dialog.destroy()
예제 #7
0
    def on_reset_button_clicked(self, widget):
        iter = self.backup_combobox.get_active_iter()
        model = self.backup_combobox.get_model()
        directory = self.dir_label.get_text()

        if directory.count('/') == 2:
            message = _('Would you like to reset settings for: <b>%s</b>?') % directory
        else:
            message = _('Would you like to reset all settings under: <b>%s</b>?') % directory

        addon_message = _('<b>NOTES</b>: Whilst resetting, your desktop may be unresponsive for a moment.')

        dialog = QuestionDialog(message=message + '\n\n' + addon_message)
        response = dialog.run()
        dialog.destroy()

        if response == Gtk.ResponseType.YES:
            stdout, stderr = do_reset_task(directory)

            if stderr:
                log.error(stderr)
                #TODO raise error or others
                return
            self._show_successful_dialog(title=_('Reset Successful!'),
                 message=_('You may need to restart your desktop for changes to take effect'))
예제 #8
0
    def on_icon_reset_button_clicked(self, widget):
        dialog = QuestionDialog(title=_("Would you like to reset the launcher items?"),
                                message=_('If you continue, launcher will be set to default and all your current items will be lost.'))
        response = dialog.run()
        dialog.destroy()

        if response == Gtk.ResponseType.YES:
            self.launcher_setting.set_value(self.launcher_setting.get_schema_value())
예제 #9
0
    def on_redo_button_clicked(self, widget):
        dialog = QuestionDialog(message=_('The current content will be lost after reloading!\nDo you wish to continue?'))
        if dialog.run() == Gtk.ResponseType.YES:
            self.textview.update_content()
            self.save_button.set_sensitive(False)
            self.redo_button.set_sensitive(False)

        dialog.destroy()
예제 #10
0
    def on_redo_button_clicked(self, widget):
        dialog = QuestionDialog(message=_(
            'The current content will be lost after reloading!\nDo you wish to continue?'
        ))
        if dialog.run() == Gtk.ResponseType.YES:
            self.textview.update_content()
            self.save_button.set_sensitive(False)
            self.redo_button.set_sensitive(False)

        dialog.destroy()
예제 #11
0
    def on_backup_delete_button_clicked(self, widget):
        iter = self.backup_combobox.get_active_iter()
        path = self.backup_model[iter][0]

        dialog = QuestionDialog(message=_("Would you like to delete the backup:" "<b>%s</b>?") % os.path.basename(path))
        response = dialog.run()
        dialog.destroy()

        if response == Gtk.ResponseType.YES:
            proxy.delete_source(path)
            self.update_backup_model()
예제 #12
0
    def on_backup_delete_button_clicked(self, widget):
        iter = self.backup_combobox.get_active_iter()
        path = self.backup_model[iter][0]

        dialog = QuestionDialog(
            message=_('Would you like to delete the backup '
                      '"<b>%s</b>"?') % os.path.basename(path))
        response = dialog.run()
        dialog.destroy()

        if response == Gtk.ResponseType.YES:
            proxy.delete_source(path)
            self.update_backup_model()
예제 #13
0
    def on_purge_ppa_button_clicked(self, widget):
        # name_list is to display the name of PPA
        # url_list is to identify the ppa
        set_busy(self)
        name_list = []
        url_list = []
        log.debug("self.sourceview.to_purge: %s" % self.sourceview.to_purge)
        for url in self.sourceview.to_purge:
            name_list.append(ppa.get_short_name(url))
            url_list.append(url)

        log.debug("PPAs to purge: url_list: %s" % url_list)

        package_view = DowngradeView(self)
        package_view.update_downgrade_model(url_list)
        sw = Gtk.ScrolledWindow(shadow_type=Gtk.ShadowType.IN)
        sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        select_pkgs = package_view.get_downgrade_packages()
        sw.add(package_view)

        #TODO the logic is a little ugly, need to improve the BaseMessageDialog
        if not select_pkgs:
            message = _("It's safe to purge the PPA, no packages need to be downgraded.")
            sw.hide()
        else:
            message = _("To safely purge the PPA, the following packages must be downgraded.")
            sw.show_all()
            sw.set_size_request(500, 100)

        dialog = QuestionDialog(title=_("You're going to purge \"%s\":") % ', '.join(name_list),
                                message=message)
        dialog.set_resizable(True)
        dialog.get_content_area().pack_start(sw, True, True, 0)
        dialog.show_all()

        response = dialog.run()
        dialog.destroy()
        # Workflow
        # 1. Downgrade all the PPA packages to offical packages
        #TODO Maybe not official? Because anther ppa which is enabled may have newer packages then offical
        # 2. If succeed, disable PPA, or keep it

        if response == Gtk.ResponseType.YES:
            log.debug("The select pkgs is: %s", str(select_pkgs))
            worker = AptWorker(widget.get_toplevel(),
                               finish_handler=self.on_package_work_finished,
                               data={'parent': self,
                                     'url_list': url_list})
            worker.downgrade_packages(select_pkgs)
        else:
            unset_busy(self)
예제 #14
0
 def upgrade_sources(self):
     dialog = QuestionDialog(_('After a successful distribution upgrade, '
         'any third-party sources you use will be disabled by default.\n'
         'Would you like to re-enable any sources disabled by Update Manager?'),
         title=_('Upgrade Third Party Sources'))
     response = dialog.run()
     dialog.destroy()
     if response == Gtk.ResponseType.YES:
         proxy.upgrade_sources(self.__get_disable_string(), UPGRADE_DICT)
         if not self.check_source_upgradable():
             InfoDialog(_('Upgrade Successful!')).launch()
         else:
             ErrorDialog(_('Upgrade Failed!')).launch()
         self.emit('call', 'ubuntutweak.modules.sourceeditor', 'update_source_combo', {})
         self.update_thirdparty()
예제 #15
0
    def on_delete_button_clicked(self, widget):
        if self.textview.get_path() ==  SOURCES_LIST:
            ErrorDialog(_('You can\'t delete sources.list!')).launch()
        else:
            dialog = QuestionDialog(message=_('The "%s" will be deleted!\nDo you wish to continue?') % self.textview.get_path())
            response = dialog.run()
            dialog.destroy()
            if response == Gtk.ResponseType.YES:
                model, iter = self.list_selection.get_selected()

                if iter:
                    list_path = model[iter][0]
                    proxy.delete_source(list_path)
                    self.update_source_model()
                    self.update_backup_model()
예제 #16
0
    def on_redo_action_button_clicked(self, widget):
        model, iter = self.icon_view.get_selection().get_selected()
        if iter:
            name = model[iter][self.DESKTOP_NAME]

            dialog = QuestionDialog(title=_('Would you like to reset "%s"?') % name,
                                    message=_('If you continue, the actions of %s will be set to default.') % name)
            response = dialog.run()
            dialog.destroy()

            if response == Gtk.ResponseType.YES:
                entry = model[iter][self.DESKTOP_ENTRY]
#                log.debug("Before reset the actions is: %s" % entry.get_actions())
                entry.reset()
                log.debug("After reset the actions is: %s" % entry.get_actions())
                self.on_icon_view_selection_changed(self.icon_view.get_selection())
예제 #17
0
    def on_delete_button_clicked(self, widget):
        if self.textview.get_path() == SOURCES_LIST:
            ErrorDialog(_('You can\'t delete sources.list!')).launch()
        else:
            dialog = QuestionDialog(message=_(
                'The "%s" will be deleted!\nDo you wish to continue?') %
                                    self.textview.get_path())
            response = dialog.run()
            dialog.destroy()
            if response == Gtk.ResponseType.YES:
                model, iter = self.list_selection.get_selected()

                if iter:
                    list_path = model[iter][0]
                    proxy.delete_source(list_path)
                    self.update_source_model()
                    self.update_backup_model()
예제 #18
0
    def on_delete_button_clicked(self, widget):
        def try_remove_record_in_root_backup(directory, path):
            rootpath = build_backup_prefix('/'.join(directory.split('/')[:2])) + \
                                           os.path.basename(path)
            if os.path.exists(rootpath):
                lines = open(rootpath).read().split()
                lines.remove(path)

                if len(lines) == 0:
                    os.remove(rootpath)
                else:
                    new = open(rootpath, 'w')
                    new.write('\n'.join(lines))
                    new.close()

        def try_remove_all_subback(path):
            for line in open(path):
                os.remove(line.strip())

        iter = self.backup_combobox.get_active_iter()
        model = self.backup_combobox.get_model()

        directory = self.dir_label.get_text()

        path = model.get_value(iter, 1)
        if directory.count('/') == 2:
            dialog = QuestionDialog(message=_('Would you like to delete the backup '
                                      '"<b>%s/%s</b>"?') %
                                      (directory, os.path.basename(path)[:-4]))
        else:
            dialog = QuestionDialog(message=_('Would you like to delete the backup of'
                                      ' all "<b>%(setting_name)s</b>" settings named "<b>%(backup_name)s</b>"?') % \
                                      {'setting_name': directory,
                                       'backup_name': os.path.basename(path)[:-4]})
        response = dialog.run()
        dialog.destroy()
        if response == Gtk.ResponseType.YES:
            if directory.count('/') == 2:
                try_remove_record_in_root_backup(directory, path)
            else:
                try_remove_all_subback(path)

            os.remove(path)
            self.update_backup_model(directory)
예제 #19
0
    def upgrade_sources(self):
        dialog = QuestionDialog(
            title=_('Upgrade Third Party Sources'),
            message=
            _('After a successful distribution upgrade, '
              'any third-party sources you use will be disabled by default.\n'
              'Would you like to re-enable any sources disabled by Update Manager?'
              ))

        response = dialog.run()
        dialog.destroy()
        if response == Gtk.ResponseType.YES:
            proxy.upgrade_sources(self.__get_disable_string(), UPGRADE_DICT)
            if not self.check_source_upgradable():
                InfoDialog(_('Upgrade Successful!')).launch()
            else:
                ErrorDialog(_('Upgrade Failed!')).launch()
            self.emit('call', 'ubuntutweak.modules.sourceeditor',
                      'update_source_combo', {})
            self.update_sourceview()
예제 #20
0
    def on_restore_directory(self, widget):
        model, iter = self.get_selection().get_selected()
        userdir = model.get_value(iter, self.COLUMN_DIR)

        dialog = QuestionDialog(message=_('Ubuntu Tweak will restore the selected '
            'directory to it\'s default location.\n'
            'However, you must move your files back into place manually.\n'
            'Do you wish to continue?'))

        if dialog.run() == Gtk.ResponseType.YES:
            newdir = os.path.join(os.getenv("HOME"), self.uf.get_restorename(userdir))
            self.uf.set_userdir(userdir, newdir)
            model.set_value(iter, self.COLUMN_PATH, newdir)

            if not os.path.exists(newdir):
                os.mkdir(newdir)
            elif os.path.isfile(newdir):
                os.remove(newdir)
                os.mkdir(newdir)

        dialog.destroy()
예제 #21
0
    def on_recover_button_clicked(self, widget):
        iter = self.backup_combobox.get_active_iter()
        model = self.backup_combobox.get_model()
        directory = self.dir_label.get_text()
        path = model.get_value(iter, 1)

        if directory.count('/') == 2:
            message = _('Would you like to recover the backup "<b>%s/%s</b>"?'
                        ) % (directory, os.path.basename(path)[:-4])
        else:
            message = _('Would you like to recover the backup of all '
                        '"<b>%(setting_name)s</b>" settings named "<b>%(backup_name)s</b>"?') % \
                        {'setting_name': directory,
                         'backup_name': os.path.basename(path)[:-4]}

        addon_message = _(
            '<b>NOTES</b>: While recovering, your desktop may be unresponsive for a moment.'
        )

        dialog = QuestionDialog(message=message + '\n\n' + addon_message)
        response = dialog.run()
        dialog.destroy()

        if response == Gtk.ResponseType.YES:
            if directory.count('/') == 1:
                for line in open(path):
                    stdout, stderr = do_recover_task(line.strip())
            else:
                stdout, stderr = do_recover_task(path)

            if stderr:
                log.error(stderr)
                #TODO raise error or others
                return
            self._show_successful_dialog(
                title=_('Recovery Successful!'),
                message=
                _('You may need to restart your desktop for changes to take effect'
                  ))
예제 #22
0
    def on_restore_directory(self, widget):
        model, iter = self.get_selection().get_selected()
        userdir = model.get_value(iter, self.COLUMN_DIR)

        dialog = QuestionDialog(message=_(
            'Ubuntu Tweak will restore the selected '
            'directory to it\'s default location.\n'
            'However, you must move your files back into place manually.\n'
            'Do you wish to continue?'))

        if dialog.run() == Gtk.ResponseType.YES:
            newdir = os.path.join(os.getenv("HOME"),
                                  self.uf.get_restorename(userdir))
            self.uf.set_userdir(userdir, newdir)
            model.set_value(iter, self.COLUMN_PATH, newdir)

            if not os.path.exists(newdir):
                os.mkdir(newdir)
            elif os.path.isfile(newdir):
                os.remove(newdir)
                os.mkdir(newdir)

        dialog.destroy()
예제 #23
0
 def on_sync_button_clicked(self, widget):
     dialog = CheckUpdateDialog(widget.get_toplevel(), self.url)
     dialog.run()
     dialog.destroy()
     if dialog.status == True:
         dialog = QuestionDialog(_("Update available, would you like to update?"))
         response = dialog.run()
         dialog.destroy()
         if response == Gtk.ResponseType.YES:
             dialog = FetchingDialog(get_app_data_url(), self.get_toplevel())
             dialog.connect('destroy', self.on_app_data_downloaded)
             dialog.run()
             dialog.destroy()
     elif dialog.error == True:
         ErrorDialog(_("Network Error, please check your network connection - or the remote server may be down.")).launch()
     else:
         utdata.save_synced_timestamp(APPCENTER_ROOT)
         self.update_timestamp()
         InfoDialog(_("No update available.")).launch()
예제 #24
0
    def on_delete_button_clicked(self, widget):
        def try_remove_record_in_root_backup(directory, path):
            rootpath = build_backup_prefix('/'.join(directory.split('/')[:2])) + \
                                           os.path.basename(path)
            if os.path.exists(rootpath):
                lines = open(rootpath).read().split()
                lines.remove(path)

                if len(lines) == 0:
                    os.remove(rootpath)
                else:
                    new = open(rootpath, 'w')
                    new.write('\n'.join(lines))
                    new.close()

        def try_remove_all_subback(path):
            for line in open(path):
                os.remove(line.strip())

        iter = self.backup_combobox.get_active_iter()
        model = self.backup_combobox.get_model()

        directory = self.dir_label.get_text()

        path = model.get_value(iter, 1)
        if directory.count('/') == 2:
            dialog = QuestionDialog(
                message=_('Would you like to delete the backup '
                          '"<b>%s/%s</b>"?') %
                (directory, os.path.basename(path)[:-4]))
        else:
            dialog = QuestionDialog(message=_('Would you like to delete the backup of'
                                      ' all "<b>%(setting_name)s</b>" settings named "<b>%(backup_name)s</b>"?') % \
                                      {'setting_name': directory,
                                       'backup_name': os.path.basename(path)[:-4]})
        response = dialog.run()
        dialog.destroy()
        if response == Gtk.ResponseType.YES:
            if directory.count('/') == 2:
                try_remove_record_in_root_backup(directory, path)
            else:
                try_remove_all_subback(path)

            os.remove(path)
            self.update_backup_model(directory)
예제 #25
0
    def on_have_update(self, *args):
        log.debug("on_have_update")
        if UPDATE_SETTING.get_value():
            dialog = QuestionDialog(
                _('New application data available, would you like to update?'))
            response = dialog.run()
            dialog.destroy()

            if response == Gtk.ResponseType.YES:
                dialog = FetchingDialog(get_app_data_url(),
                                        self.get_toplevel())
                dialog.connect('destroy', self.on_app_data_downloaded)
                dialog.run()
                dialog.destroy()
예제 #26
0
                        )

        self.add_start(theme_box, False, False, 0)

    def on_file_set(self, widget):
        try:
            tf = ThemeFile(widget.get_filename())
        except Exception, e:
            log.error(e)
            ErrorDialog(message=_('Theme file is invalid')).launch()
        else:
            if tf.install():
                log.debug("Theme installed! Now update the combox")
                valid_icon_themes = theme.get_valid_icon_themes()
                self.icon_theme.update_texts_values_pair(valid_icon_themes, valid_icon_themes)
                dialog = QuestionDialog(title=_('"%s" installed successfully' % tf.theme_name),
                               message=_('Would you like to set your icon theme to "%s" immediatelly?') % tf.theme_name)
                response = dialog.launch()
                if response == Gtk.ResponseType.YES:
                    self.icon_theme.get_setting().set_value(tf.install_name)

    def _get_valid_icon_themes(self):
        # This function is taken from gnome-tweak-tool
        dirs = ( '/usr/share/icons',
                 os.path.join(os.path.expanduser("~"), ".icons"))
        valid = walk_directories(dirs, lambda d:
                    os.path.isdir(d) and \
                        not os.path.exists(os.path.join(d, "cursors")))

        valid.sort()

        return valid
예제 #27
0
    def clean_cruft(self, parent, cruft_list):
        set_busy(parent)

        # name_list is to display the name of PPA
        # url_list is to identify the ppa
        name_list = []
        url_list = []
        for cruft in cruft_list:
            name_list.append(ppa.get_short_name(cruft.get_uri()))
            url_list.append(cruft.get_uri())

        package_view = DowngradeView(self)
        package_view.update_model(url_list)
        sw = Gtk.ScrolledWindow(shadow_type=Gtk.ShadowType.IN)
        sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        select_pkgs = package_view.get_downgrade_packages()
        sw.add(package_view)

        #TODO the logic is a little ugly, need to improve the BaseMessageDialog
        if not select_pkgs:
            message = _("It's safe to purge the PPA, no packages need to be downgraded.")
            sw.hide()
        else:
            message = _("To safely purge the PPA, the following packages must be downgraded.")
            sw.show_all()
            sw.set_size_request(500, 100)

        dialog = QuestionDialog(message=message,
                                title=_("You're going to purge: %s") % ', '.join(name_list))
        dialog.set_resizable(True)
        dialog.get_content_area().pack_start(sw, True, True, 0)
        dialog.show()

        response = dialog.run()
        dialog.destroy()
        # Workflow
        # 1. Downgrade all the PPA packages to offical packages
        #TODO Maybe not official? Because anther ppa which is enabled may have newer packages then offical
        # 2. If succeed, disable PPA, or keep it

        if response == Gtk.ResponseType.YES:
            log.debug("The select pkgs is: %s", str(select_pkgs))
            dialog = CleanPpaDialog(parent, select_pkgs, url_list)
            dialog.run()
            dialog.destroy()
            if dialog.error:
                log.error("Error: %s" % dialog.error)
                ErrorDialog(dialog.error).launch()
        # TODO refresh source?

        self.emit('cleaned', True)
        unset_busy(parent)
예제 #28
0
    def on_file_set(self, widget):
        try:
            tf = ThemeFile(widget.get_filename())
        except Exception, e:
            log.error(e)
            ErrorDialog(message=_('Theme file is invalid')).launch()
        else:
            if tf.install():
                log.debug("Theme installed! Now update the combox")
                valid_icon_themes = theme.get_valid_icon_themes()
                self.icon_theme.update_texts_values_pair(
                    valid_icon_themes, valid_icon_themes)
                dialog = QuestionDialog(
                    title=_('"%s" installed successfully' % tf.theme_name),
                    message=
                    _('Would you like to set your icon theme to "%s" immediatelly?'
                      ) % tf.theme_name)
                response = dialog.launch()
                if response == Gtk.ResponseType.YES:
                    self.icon_theme.get_setting().set_value(tf.install_name)

    def _get_valid_icon_themes(self):
        # This function is taken from gnome-tweak-tool
        dirs = ('/usr/share/icons',
                os.path.join(os.path.expanduser("~"), ".icons"))
        valid = walk_directories(dirs, lambda d:
                    os.path.isdir(d) and \
                        not os.path.exists(os.path.join(d, "cursors")))

        valid.sort()
예제 #29
0
    def on_install_extension(self, dialog_label, klass, feature,
                             setting, update_func, error_message):
        dialog = Gtk.FileChooserDialog(dialog_label,
                                       action=Gtk.FileChooserAction.OPEN,
                                       buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                                                Gtk.STOCK_OPEN, Gtk.ResponseType.ACCEPT))
        filter = Gtk.FileFilter()
        filter.set_name(_('Ubuntu Tweak Extension (*.py, *.tar.gz)'))
        filter.add_pattern('*.py')
        filter.add_pattern('*.tar.gz')
        dialog.add_filter(filter)
        dialog.set_current_folder(self.clips_location_setting.get_value() or
                                  GLib.get_home_dir())

        filename = ''
        install_done = False
        not_extension = False

        if dialog.run() == Gtk.ResponseType.ACCEPT:
            filename = dialog.get_filename()
        dialog.destroy()

        if filename:
            self.clips_location_setting.set_value(os.path.dirname(filename))

            log.debug("Start to check the class in %s" % filename)
            if filename.endswith('.tar.gz'):
                tar_file = TarFile(filename)
                if tar_file.is_valid():
                    tar_file.extract(TEMP_ROOT)
                    #TODO if multi-root
                    if tar_file.get_root_name():
                        temp_dir = os.path.join(TEMP_ROOT, tar_file.get_root_name())

                if ModuleLoader.is_target_class(temp_dir, klass):
                    target = os.path.join(ModuleLoader.get_user_extension_dir(feature), os.path.basename(temp_dir))
                    copy = True
                    if os.path.exists(target):
                        dialog = QuestionDialog(message=_("Would you like to remove it then install again?"),
                                                title=_('"%s" has already installed' % os.path.basename(target)))
                        response = dialog.run()
                        dialog.destroy()

                        if response == Gtk.ResponseType.YES:
                            shutil.rmtree(target)
                        else:
                            copy = False

                    if copy:
                        log.debug("Now copying tree...")
                        shutil.move(temp_dir, target)
                    else:
                        shutil.rmtree(temp_dir)
                else:
                    not_extension = True
            else:
                if ModuleLoader.is_target_class(filename, klass):
                    shutil.copy(filename, ModuleLoader.get_user_extension_dir(feature))
                    install_done = True
                else:
                    not_extension = True

        if install_done:
            update_func(feature)

            # To force empty the clips_setting to make load_cips
            value = setting.get_value()
            setting.set_value([''])
            setting.set_value(value)

        if not_extension:
            ErrorDialog(message=error_message % os.path.basename(filename)).launch()
예제 #30
0
    def on_install_extension(self, dialog_label, klass, feature, setting,
                             update_func, error_message):
        dialog = Gtk.FileChooserDialog(
            dialog_label,
            action=Gtk.FileChooserAction.OPEN,
            buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN,
                     Gtk.ResponseType.ACCEPT))
        filter = Gtk.FileFilter()
        filter.set_name(_('Ubuntu Tweak Extension (*.py, *.tar.gz)'))
        filter.add_pattern('*.py')
        filter.add_pattern('*.tar.gz')
        dialog.add_filter(filter)
        dialog.set_current_folder(self.clips_location_setting.get_value()
                                  or GLib.get_home_dir())

        filename = ''
        install_done = False
        not_extension = False

        if dialog.run() == Gtk.ResponseType.ACCEPT:
            filename = dialog.get_filename()
        dialog.destroy()

        if filename:
            self.clips_location_setting.set_value(os.path.dirname(filename))

            log.debug("Start to check the class in %s" % filename)
            if filename.endswith('.tar.gz'):
                tar_file = TarFile(filename)
                if tar_file.is_valid():
                    tar_file.extract(TEMP_ROOT)
                    #TODO if multi-root
                    if tar_file.get_root_name():
                        temp_dir = os.path.join(TEMP_ROOT,
                                                tar_file.get_root_name())

                if ModuleLoader.is_target_class(temp_dir, klass):
                    target = os.path.join(
                        ModuleLoader.get_user_extension_dir(feature),
                        os.path.basename(temp_dir))
                    copy = True
                    if os.path.exists(target):
                        dialog = QuestionDialog(message=_(
                            "Would you like to remove it then install again?"),
                                                title=_(
                                                    '"%s" has already installed'
                                                    %
                                                    os.path.basename(target)))
                        response = dialog.run()
                        dialog.destroy()

                        if response == Gtk.ResponseType.YES:
                            shutil.rmtree(target)
                        else:
                            copy = False

                    if copy:
                        log.debug("Now copying tree...")
                        shutil.move(temp_dir, target)
                    else:
                        shutil.rmtree(temp_dir)
                else:
                    not_extension = True
            else:
                if ModuleLoader.is_target_class(filename, klass):
                    shutil.copy(filename,
                                ModuleLoader.get_user_extension_dir(feature))
                    install_done = True
                else:
                    not_extension = True

        if install_done:
            update_func(feature)

            # To force empty the clips_setting to make load_cips
            value = setting.get_value()
            setting.set_value([''])
            setting.set_value(value)

        if not_extension:
            ErrorDialog(message=error_message %
                        os.path.basename(filename)).launch()
예제 #31
0
    def on_change_icon_clicked(self, widget):
        dialog = Gtk.FileChooserDialog(_('Choose a new logo image'),
                                       action=Gtk.FileChooserAction.OPEN,
                                       buttons=(Gtk.STOCK_REVERT_TO_SAVED, Gtk.ResponseType.DELETE_EVENT,
                                                Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                                                 Gtk.STOCK_OPEN, Gtk.ResponseType.ACCEPT))
        filter = Gtk.FileFilter()
        filter.set_name(_("PNG images with 24x24 size or SVG images"))
        filter.add_pattern('*.png')
        filter.add_pattern('*.svg')
        dialog.set_current_folder(os.path.expanduser('~'))
        dialog.add_filter(filter)

        icon_theme = GconfSetting('/desktop/gnome/interface/icon_theme').get_value()
        dest = os.path.expanduser('~/.icons/%s/apps/24/start-here' % icon_theme)

        revert_button = dialog.get_action_area().get_children()[-1]

        HAVE_ICON = os.path.exists(dest + '.png') or os.path.exists(dest + '.svg')

        if not HAVE_ICON:
            revert_button.set_sensitive(False)

        filename = ''
        response = dialog.run()

        if response == Gtk.ResponseType.ACCEPT:
            filename = dialog.get_filename()
            dialog.destroy()

            if filename:
                ext = os.path.splitext(filename)[1]
                log.debug('The select file name is: %s' % ext)
                pixbuf = GdkPixbuf.Pixbuf.new_from_file(filename)
                w, h = pixbuf.get_width(), pixbuf.get_height()
                dest = dest + ext

                if ext == '.png' and (w != 24 or h != 24):
                    ErrorDialog(message=_("This image size isn't suitable for the panel.\nIt should measure 24x24.")).launch()
                    return
                else:
                    os.system('mkdir -p %s' % os.path.dirname(dest))
                    os.system('cp %s %s' % (filename, dest))

                    if ext == '.svg':
                        pixbuf = pixbuf.scale_simple(24, 24, GdkPixbuf.InterpType.BILINEAR)
                    image = Gtk.Image.new_from_pixbuf(pixbuf)
                    widget.set_image(image)
        elif response == Gtk.ResponseType.DELETE_EVENT:
            dialog.destroy()
            for dest in glob.glob(dest + '*'):
                os.remove(dest)
            image = Gtk.Image.new_from_pixbuf(icon.get_from_name('start-here', force_reload=True))
            widget.set_image(image)
        else:
            dialog.destroy()
            return

        dialog = QuestionDialog(message=_('Do you want your changes to take effect immediately?'))
        if dialog.run() == Gtk.ResponseType.YES:
            os.system('killall gnome-panel')

        dialog.destroy()
예제 #32
0
    def on_enable_toggled(self, cell, path):
        model = self.get_model()
        iter = model.get_iter((int(path),))

        id = model.get_value(iter, self.COLUMN_ID)
        name = model.get_value(iter, self.COLUMN_NAME)
        enabled = model.get_value(iter, self.COLUMN_ENABLED)
        url = model.get_value(iter, self.COLUMN_URL)

        if self.view_mode == 'view':
            conflicts = SOURCE_PARSER.get_conflicts(id)
            dependencies = SOURCE_PARSER.get_dependencies(id)

            #Convert to real model, because will involke the set method
            if type(model) == Gtk.TreeModelFilter:
                iter = model.convert_iter_to_child_iter(iter)
                model = model.get_model()

            if not enabled and conflicts:
                conflict_list = []
                conflict_name_list = []
                for conflict_id in conflicts:
                    if self.get_source_enabled(conflict_id):
                        conflict_list.append(conflict_id)
                        name_list = [r[self.COLUMN_NAME] for r in model if r[self.COLUMN_ID] == conflict_id]
                        if name_list:
                                conflict_name_list.extend(name_list)

                if conflict_list and conflict_name_list:
                    full_name = ', '.join(conflict_name_list)
                    ErrorDialog(_('You can\'t enable this Source because'
                                  '<b>"%(SOURCE)s"</b> conflicts with it.\nTo '
                                  'continue you need to disable <b>"%(SOURCE)s"</b>' \
                                  'first.') % {'SOURCE': full_name}).launch()

                    model.set(iter, self.COLUMN_ENABLED, enabled)
                    return

            if enabled is False and dependencies:
                depend_list = []
                depend_name_list = []
                for depend_id in dependencies:
                    if self.get_source_enabled(depend_id) is False:
                        depend_list.append(depend_id)
                        name_list = [r[self.COLUMN_NAME] for r in model if r[self.COLUMN_ID] == depend_id]
                        if name_list:
                                depend_name_list.extend(name_list)

                if depend_list and depend_name_list:
                    full_name = ', '.join(depend_name_list)

                    dialog = QuestionDialog(title=_('Dependency Notice'),
                                            message= _('To enable this Source, You need to enable <b>"%s"</b> at first.\nDo you wish to continue?') \
                                % full_name)
                    if dialog.run() == Gtk.ResponseType.YES:
                        for depend_id in depend_list:
                            self.set_source_enabled(depend_id)
                        self.set_source_enabled(id)
                    else:
                        model.set(iter, self.COLUMN_ENABLED, enabled)

                    dialog.destroy()
                    return

            if enabled and SOURCE_PARSER.has_reverse_depends(id):
                depend_list = []
                depend_name_list = []
                for depend_id in SOURCE_PARSER.get_reverse_depends(id):
                    if self.get_source_enabled(depend_id):
                        depend_list.append(depend_id)
                        name_list = [r[self.COLUMN_NAME] for r in model if r[self.COLUMN_ID] == depend_id]
                        if name_list:
                                depend_name_list.extend(name_list)

                if depend_list and depend_name_list:
                    full_name = ', '.join(depend_name_list)

                    ErrorDialog(_('You can\'t disable this Source because '
                                '<b>"%(SOURCE)s"</b> depends on it.\nTo continue '
                                'you need to disable <b>"%(SOURCE)s"</b> first.') \
                                     % {'SOURCE': full_name}).launch()

                    model.set(iter, self.COLUMN_ENABLED, enabled)
                    return

            self.do_source_enable(iter, not enabled)
        else:
            #TODO purge dependencies
            status = not enabled
            model.set(iter, self.COLUMN_ENABLED, status)

            if status:
                self.to_purge.append(url)
            else:
                self.to_purge.remove(url)

            self.emit('new_purge', self.to_purge)
예제 #33
0
    def on_have_update(self, *args):
        if UPDATE_SETTING.get_value():
            dialog = QuestionDialog(_('New source data available, would you like to update?'))
            response = dialog.run()
            dialog.destroy()

            if response == Gtk.ResponseType.YES:
                dialog = FetchingDialog(get_source_data_url(),
                                        self.get_toplevel())
                dialog.connect('destroy', self.on_source_data_downloaded)
                dialog.run()
                dialog.destroy()
예제 #34
0
    def on_purge_ppa_button_clicked(self, widget):
        # name_list is to display the name of PPA
        # url_list is to identify the ppa
        set_busy(self)
        name_list = []
        url_list = []
        log.debug("self.sourceview.to_purge: %s" % self.sourceview.to_purge)
        for url in self.sourceview.to_purge:
            name_list.append(ppa.get_short_name(url))
            url_list.append(url)

        log.debug("PPAs to purge: url_list: %s" % url_list)

        package_view = DowngradeView(self)
        package_view.update_downgrade_model(url_list)
        sw = Gtk.ScrolledWindow(shadow_type=Gtk.ShadowType.IN)
        sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
        select_pkgs = package_view.get_downgrade_packages()
        sw.add(package_view)

        #TODO the logic is a little ugly, need to improve the BaseMessageDialog
        if not select_pkgs:
            message = _(
                "It's safe to purge the PPA, no packages need to be downgraded."
            )
            sw.hide()
        else:
            message = _(
                "To safely purge the PPA, the following packages must be downgraded."
            )
            sw.show_all()
            sw.set_size_request(500, 100)

        dialog = QuestionDialog(title=_("You're going to purge \"%s\":") %
                                ', '.join(name_list),
                                message=message)
        dialog.set_resizable(True)
        dialog.get_content_area().pack_start(sw, True, True, 0)
        dialog.show_all()

        response = dialog.run()
        dialog.destroy()
        # Workflow
        # 1. Downgrade all the PPA packages to offical packages
        #TODO Maybe not official? Because anther ppa which is enabled may have newer packages then offical
        # 2. If succeed, disable PPA, or keep it

        if response == Gtk.ResponseType.YES:
            log.debug("The select pkgs is: %s", str(select_pkgs))
            worker = AptWorker(widget.get_toplevel(),
                               finish_handler=self.on_package_work_finished,
                               data={
                                   'parent': self,
                                   'url_list': url_list
                               })
            worker.downgrade_packages(select_pkgs)
        else:
            unset_busy(self)
예제 #35
0
    def on_enable_toggled(self, cell, path):
        model = self.get_model()
        iter = model.get_iter((int(path), ))

        id = model.get_value(iter, self.COLUMN_ID)
        name = model.get_value(iter, self.COLUMN_NAME)
        enabled = model.get_value(iter, self.COLUMN_ENABLED)
        url = model.get_value(iter, self.COLUMN_URL)

        if self.view_mode == 'view':
            conflicts = SOURCE_PARSER.get_conflicts(id)
            dependencies = SOURCE_PARSER.get_dependencies(id)

            #Convert to real model, because will involke the set method
            if type(model) == Gtk.TreeModelFilter:
                iter = model.convert_iter_to_child_iter(iter)
                model = model.get_model()

            if not enabled and conflicts:
                conflict_list = []
                conflict_name_list = []
                for conflict_id in conflicts:
                    if self.get_source_enabled(conflict_id):
                        conflict_list.append(conflict_id)
                        name_list = [
                            r[self.COLUMN_NAME] for r in model
                            if r[self.COLUMN_ID] == conflict_id
                        ]
                        if name_list:
                            conflict_name_list.extend(name_list)

                if conflict_list and conflict_name_list:
                    full_name = ', '.join(conflict_name_list)
                    ErrorDialog(_('You can\'t enable this Source because'
                                  '<b>"%(SOURCE)s"</b> conflicts with it.\nTo '
                                  'continue you need to disable <b>"%(SOURCE)s"</b>' \
                                  'first.') % {'SOURCE': full_name}).launch()

                    model.set(iter, self.COLUMN_ENABLED, enabled)
                    return

            if enabled is False and dependencies:
                depend_list = []
                depend_name_list = []
                for depend_id in dependencies:
                    if self.get_source_enabled(depend_id) is False:
                        depend_list.append(depend_id)
                        name_list = [
                            r[self.COLUMN_NAME] for r in model
                            if r[self.COLUMN_ID] == depend_id
                        ]
                        if name_list:
                            depend_name_list.extend(name_list)

                if depend_list and depend_name_list:
                    full_name = ', '.join(depend_name_list)

                    dialog = QuestionDialog(title=_('Dependency Notice'),
                                            message= _('To enable this Source, You need to enable <b>"%s"</b> at first.\nDo you wish to continue?') \
                                % full_name)
                    if dialog.run() == Gtk.ResponseType.YES:
                        for depend_id in depend_list:
                            self.set_source_enabled(depend_id)
                        self.set_source_enabled(id)
                    else:
                        model.set(iter, self.COLUMN_ENABLED, enabled)

                    dialog.destroy()
                    return

            if enabled and SOURCE_PARSER.has_reverse_depends(id):
                depend_list = []
                depend_name_list = []
                for depend_id in SOURCE_PARSER.get_reverse_depends(id):
                    if self.get_source_enabled(depend_id):
                        depend_list.append(depend_id)
                        name_list = [
                            r[self.COLUMN_NAME] for r in model
                            if r[self.COLUMN_ID] == depend_id
                        ]
                        if name_list:
                            depend_name_list.extend(name_list)

                if depend_list and depend_name_list:
                    full_name = ', '.join(depend_name_list)

                    ErrorDialog(_('You can\'t disable this Source because '
                                '<b>"%(SOURCE)s"</b> depends on it.\nTo continue '
                                'you need to disable <b>"%(SOURCE)s"</b> first.') \
                                     % {'SOURCE': full_name}).launch()

                    model.set(iter, self.COLUMN_ENABLED, enabled)
                    return

            self.do_source_enable(iter, not enabled)
        else:
            #TODO purge dependencies
            status = not enabled
            model.set(iter, self.COLUMN_ENABLED, status)

            if status:
                self.to_purge.append(url)
            else:
                self.to_purge.remove(url)

            self.emit('new_purge', self.to_purge)