From 129ede9c6c07d0eb51311cbfa1c38a055067b5b1 Mon Sep 17 00:00:00 2001 From: Vinicius Moreira Date: Thu, 3 Sep 2020 18:06:43 -0300 Subject: [PATCH] [arch] fixes -> not displaying and uninstalling dependent packages during conflict resolutions | not retrieving all packages that would break if a given package is uninstalled --- CHANGELOG.md | 2 + bauh/api/abstract/controller.py | 2 +- bauh/gems/arch/controller.py | 130 ++++++++++++++--------------- bauh/gems/arch/resources/locale/ca | 12 +-- bauh/gems/arch/resources/locale/de | 12 +-- bauh/gems/arch/resources/locale/en | 12 +-- bauh/gems/arch/resources/locale/es | 12 +-- bauh/gems/arch/resources/locale/it | 12 +-- bauh/gems/arch/resources/locale/pt | 12 +-- bauh/gems/arch/resources/locale/ru | 12 +-- bauh/gems/arch/resources/locale/tr | 12 +-- bauh/view/qt/components.py | 2 + 12 files changed, 118 insertions(+), 114 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e22b5ed6..90d440ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -91,6 +91,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - some conflict resolution scenarios when upgrading several packages - not handling conflicting files errors during the installation process - some environment variables are not available during the common operations (install, upgrade, downgrade, uninstall, makepkg, launch) + - not displaying and uninstalling dependent packages during conflict resolutions + - not retrieving all packages that would break if a given package is uninstalled - AUR - info dialog of installed packages displays the latest PKGBUILD file instead of the one used for installation/upgrade/downgrade (the fix will only work for new installed packages) - multi-threaded download: not retrieving correctly some source files URLs (e.g: linux-xanmod-lts) diff --git a/bauh/api/abstract/controller.py b/bauh/api/abstract/controller.py index cf496949..67a61d29 100644 --- a/bauh/api/abstract/controller.py +++ b/bauh/api/abstract/controller.py @@ -72,7 +72,7 @@ class TransactionResult: The result of a given operation """ - def __init__(self, success: bool, installed: List[SoftwarePackage], removed: List[SoftwarePackage]): + def __init__(self, success: bool, installed: Optional[List[SoftwarePackage]], removed: Optional[List[SoftwarePackage]]): self.success = success self.installed = installed self.removed = removed diff --git a/bauh/gems/arch/controller.py b/bauh/gems/arch/controller.py index f60f6fc8..ba0a0d05 100644 --- a/bauh/gems/arch/controller.py +++ b/bauh/gems/arch/controller.py @@ -102,6 +102,7 @@ class TransactionContext: self.new_pkg = new_pkg self.custom_pkgbuild_path = custom_pkgbuild_path self.pkgs_to_build = pkgs_to_build + self.previous_change_progress = change_progress @classmethod def gen_context_from(cls, pkg: ArchPackage, arch_config: dict, root_password: str, handler: ProcessHandler) -> "TransactionContext": @@ -169,6 +170,17 @@ class TransactionContext: return self.remote_repo_map + def disable_progress_if_changing(self): + if self.change_progress: + self.previous_change_progress = True + self.change_progress = False + + def restabilish_progress(self): + if self.previous_change_progress is not None: + self.change_progress = self.previous_change_progress + + self.previous_change_progress = self.change_progress + class ArchManager(SoftwareManager): @@ -1093,37 +1105,34 @@ class ArchManager(SoftwareManager): return all_uninstalled - def _request_uninstall_confirmation(self, pkgs: Iterable[str], context: TransactionContext) -> bool: - reqs = [InputOption(label=p, value=p, icon_path=get_icon_path(), read_only=True) for p in pkgs] - reqs_select = MultipleSelectComponent(options=reqs, default_options=set(reqs), label="", max_per_line=3) + def _request_uninstall_confirmation(self, to_uninstall: Iterable[str], required: Iterable[str], watcher: ProcessWatcher) -> bool: + reqs = [InputOption(label=p, value=p, icon_path=get_icon_path(), read_only=True) for p in required] + reqs_select = MultipleSelectComponent(options=reqs, default_options=set(reqs), label="", max_per_line=1 if len(reqs) < 4 else 3) - msg = '

{}

{}

'.format(self.i18n['arch.uninstall.required_by'].format(bold(context.name), bold(str(len(reqs)))), - self.i18n['arch.uninstall.required_by.advice']) + msg = '

{}

{}

'.format(self.i18n['arch.uninstall.required_by'].format(bold(str(len(required))), ', '.join(bold(n)for n in to_uninstall)) + '.', + self.i18n['arch.uninstall.required_by.advice'] + '.') - if not context.watcher.request_confirmation(title=self.i18n['confirmation'].capitalize(), - body=msg, - components=[reqs_select], - confirmation_label=self.i18n['proceed'].capitalize(), - deny_label=self.i18n['cancel'].capitalize(), - window_cancel=False): - context.watcher.print("Aborted") + if not watcher.request_confirmation(title=self.i18n['warning'].capitalize(), + body=msg, + components=[reqs_select], + confirmation_label=self.i18n['proceed'].capitalize(), + deny_label=self.i18n['cancel'].capitalize(), + window_cancel=False): + watcher.print("Aborted") return False return True - def _request_unncessary_uninstall_confirmation(self, pkgs: Iterable[str], context: TransactionContext) -> List[str]: - reqs = [InputOption(label=p, value=p, icon_path=get_icon_path(), read_only=False) for p in pkgs] + def _request_unncessary_uninstall_confirmation(self, uninstalled: Iterable[str], unnecessary: Iterable[str], watcher: ProcessWatcher) -> Optional[List[str]]: + reqs = [InputOption(label=p, value=p, icon_path=get_icon_path(), read_only=False) for p in unnecessary] reqs_select = MultipleSelectComponent(options=reqs, default_options=set(reqs), label="", max_per_line=3) - msg = '

{}

{}:

'.format(self.i18n['arch.uninstall.unnecessary.l1'].format(bold(context.name)), - self.i18n['arch.uninstall.unnecessary.l2']) - - if not context.watcher.request_confirmation(title=self.i18n['confirmation'].capitalize(), - body=msg, - components=[reqs_select], - confirmation_label=self.i18n['arch.uninstall.unnecessary.proceed'].capitalize(), - deny_label=self.i18n['arch.uninstall.unnecessary.cancel'].capitalize(), - window_cancel=False): + if not watcher.request_confirmation(title=self.i18n['arch.uninstall.unnecessary.l1'].capitalize(), + body='

{}

'.format(self.i18n['arch.uninstall.unnecessary.l2']), + components=[reqs_select], + confirmation_label=self.i18n['arch.uninstall.unnecessary.proceed'].capitalize(), + deny_label=self.i18n['arch.uninstall.unnecessary.cancel'].capitalize(), + window_cancel=False): return return reqs_select.get_selected_values() @@ -1143,15 +1152,15 @@ class ArchManager(SoftwareManager): return True - def _uninstall(self, context: TransactionContext, remove_unneeded: bool = False, disk_loader: DiskCacheLoader = None): + def _uninstall(self, context: TransactionContext, names: Set[str], remove_unneeded: bool = False, disk_loader: DiskCacheLoader = None): self._update_progress(context, 10) net_available = internet.is_available() if disk_loader else True - required_by = self.deps_analyser.map_all_required_by({context.name}, set()) + required_by = self.deps_analyser.map_all_required_by(names, set()) if required_by: - target_provided = pacman.map_provided(pkgs={context.name}).keys() + target_provided = pacman.map_provided(pkgs={*names, *required_by}).keys() if target_provided: required_by_deps = pacman.map_all_deps(required_by, only_installed=True) @@ -1163,7 +1172,7 @@ class ArchManager(SoftwareManager): target_required_by = 0 for dep in deps: dep_split = pacman.RE_DEP_OPERATORS.split(dep) - if dep_split[0] in target_provided: + if dep_split[0] in target_provided or dep_split[0] in required_by: dep_providers = all_provided.get(dep_split[0]) if dep_providers: @@ -1175,12 +1184,14 @@ class ArchManager(SoftwareManager): self._update_progress(context, 50) to_uninstall = set() - to_uninstall.add(context.name) + to_uninstall.update(names) if required_by: to_uninstall.update(required_by) - if not self._request_uninstall_confirmation(required_by, context): + if not self._request_uninstall_confirmation(to_uninstall=names, + required=required_by, + watcher=context.watcher): return False if remove_unneeded: @@ -1188,12 +1199,12 @@ class ArchManager(SoftwareManager): else: all_deps_map = None - if disk_loader and len(to_uninstall) > 1: # loading package instances in case the uninstall succeeds + if disk_loader and to_uninstall: # loading package instances in case the uninstall succeeds instances = self.read_installed(disk_loader=disk_loader, - names={n for n in to_uninstall if n != context.name}, + names={n for n in to_uninstall}, internet_available=net_available).installed - if len(instances) + 1 < len(to_uninstall): + if len(instances) != len(to_uninstall): self.logger.warning("Not all packages to be uninstalled could be read") else: instances = None @@ -1202,8 +1213,6 @@ class ArchManager(SoftwareManager): if uninstalled: if disk_loader: # loading package instances in case the uninstall succeeds - context.removed[context.pkg.name] = context.pkg - if instances: for p in instances: context.removed[p.name] = p @@ -1234,7 +1243,9 @@ class ArchManager(SoftwareManager): if no_longer_needed: self.logger.info("{} packages no longer needed found".format(len(no_longer_needed))) - unnecessary_to_uninstall = self._request_unncessary_uninstall_confirmation(no_longer_needed, context) + unnecessary_to_uninstall = self._request_unncessary_uninstall_confirmation(uninstalled=to_uninstall, + unnecessary=no_longer_needed, + watcher=context.watcher) if unnecessary_to_uninstall: unnecessary_to_uninstall_deps = pacman.list_unnecessary_deps(unnecessary_to_uninstall, all_provided) @@ -1289,15 +1300,14 @@ class ArchManager(SoftwareManager): return TransactionResult.fail() removed = {} - success = self._uninstall(TransactionContext(name=pkg.name, - pkg=pkg, - change_progress=True, + success = self._uninstall(TransactionContext(change_progress=True, arch_config=read_config(), watcher=watcher, root_password=root_password, handler=handler, removed=removed), remove_unneeded=True, + names={pkg.name}, disk_loader=disk_loader) # to be able to return all uninstalled packages if success: return TransactionResult(success=True, installed=None, removed=[*removed.values()] if removed else []) @@ -1515,17 +1525,14 @@ class ArchManager(SoftwareManager): return False else: context.watcher.change_substatus(self.i18n['arch.uninstalling.conflict'].format(bold(conflicting_pkg))) - conflict_context = context.clone_base() - conflict_context.change_progress = False - conflict_context.name = conflicting_pkg + context.disable_progress_if_changing() - if not self._uninstall(conflict_context): - context.watcher.show_message(title=self.i18n['error'], - body=self.i18n['arch.uninstalling.conflict.fail'].format(bold(conflicting_pkg)), - type_=MessageType.ERROR) - return False + if context.removed is None: + context.removed = {} - return True + res = self._uninstall(context=context, names={conflicting_pkg}, disk_loader=context.disk_loader) + context.restabilish_progress() + return res def _install_deps(self, context: TransactionContext, deps: List[Tuple[str, str]]) -> Iterable[str]: """ @@ -2059,10 +2066,6 @@ class ArchManager(SoftwareManager): file=bool(context.install_files), simulate=True), notify_watcher=False) - # for check_out in SimpleProcess(cmd=['pacman', '-U' if context.install_files else '-S', pkgpath], - # root_password=context.root_password, - # cwd=context.project_dir or '.').instance.stdout: - # check_install_output.append(check_out.decode()) self._update_progress(context, 70) @@ -2078,27 +2081,24 @@ class ArchManager(SoftwareManager): else: # uninstall conflicts self._update_progress(context, 75) names_to_install = context.get_package_names() - to_uninstall = [conflict for conflict in conflicting_apps if conflict not in names_to_install] + to_uninstall = {conflict for conflict in conflicting_apps if conflict not in names_to_install} - self.logger.info("Preparing to uninstall conflicting packages: {}".format(to_uninstall)) + if to_uninstall: + self.logger.info("Preparing to uninstall conflicting packages: {}".format(to_uninstall)) + context.watcher.change_substatus(self.i18n['arch.uninstalling.conflict']) - pkgs_to_uninstall = self.read_installed(disk_loader=context.disk_loader, names=to_uninstall, internet_available=True).installed + if context.removed is None: + context.removed = {} - if not pkgs_to_uninstall: - self.logger.warning("Could not load packages to uninstall") - - for conflict in to_uninstall: - context.watcher.change_substatus(self.i18n['arch.uninstalling.conflict'].format(bold(conflict))) - - if not self._uninstall_pkgs(pkgs={conflict}, root_password=context.root_password, handler=context.handler): + context.disable_progress_if_changing() + if not self._uninstall(names=to_uninstall, context=context, remove_unneeded=False, disk_loader=context.disk_loader): context.watcher.show_message(title=self.i18n['error'], - body=self.i18n['arch.uninstalling.conflict.fail'].format(bold(conflict)), + body=self.i18n['arch.uninstalling.conflict.fail'].format(', '.join((bold(p) for p in to_uninstall))), type_=MessageType.ERROR) return False else: - uninstalled = [p for p in pkgs_to_uninstall if p.name == conflict] - if uninstalled: - context.removed[conflict] = uninstalled[0] + context.restabilish_progress() + else: self.logger.info("No conflict detected for '{}'".format(context.name)) diff --git a/bauh/gems/arch/resources/locale/ca b/bauh/gems/arch/resources/locale/ca index a5521e78..811413e5 100644 --- a/bauh/gems/arch/resources/locale/ca +++ b/bauh/gems/arch/resources/locale/ca @@ -213,15 +213,15 @@ arch.task.sync_sb.status=Actualitzen {} arch.uncompressing.package=S’està descomprimint el paquet arch.uninstall.clean_cached.error=No s'ha pogut eliminar {} versions antigues que es troba al disc arch.uninstall.clean_cached.substatus=Eliminació de versions antigues del disc -arch.uninstall.required_by=No es pot desinstal·lar {} perquè és necessari per al funcionament dels paquets següents. -arch.uninstall.required_by.advice=It is necessary to uninstall them as well to proceed. +arch.uninstall.required_by=The {} packages listed below depend on {} to work properly +arch.uninstall.required_by.advice=It is necessary to uninstall them as well to proceed arch.uninstall.unnecessary.all=The following {} packages will be uninstalled arch.uninstall.unnecessary.cancel=Keep -arch.uninstall.unnecessary.l1={} was successfully uninstalled. The packages below that it depended on are no longer needed. -arch.uninstall.unnecessary.l2=Check those you want to uninstall +arch.uninstall.unnecessary.l1=Packages successfully uninstalled! +arch.uninstall.unnecessary.l2=The packages below seem to be no longer necessary. Select those you want to uninstall arch.uninstall.unnecessary.proceed=Uninstall -arch.uninstalling.conflict=S’està suprimint el paquet conflictiu {} -arch.uninstalling.conflict.fail=No s’ha pogut desinstal·lar el paquet conflictiu {} +arch.uninstalling.conflict=Uninstalling conflicting packages +arch.uninstalling.conflict.fail=It was not possible to uninstall the conflicting packages: {} arch.update.disabled.tooltip=This package can oly be upgrade through the action "Quick system upgrade" arch.update_summary.conflict_between=Conflict between {} and {} arch.update_summary.to_install.dep_conflict=Conflict between the dependencies {} and {} diff --git a/bauh/gems/arch/resources/locale/de b/bauh/gems/arch/resources/locale/de index a0f8a813..76d49c5f 100644 --- a/bauh/gems/arch/resources/locale/de +++ b/bauh/gems/arch/resources/locale/de @@ -213,15 +213,15 @@ arch.task.sync_sb.status=Updating {} arch.uncompressing.package=Paket entpacken arch.uninstall.clean_cached.error=It was not possible to remove old {} versions found on disk arch.uninstall.clean_cached.substatus=Removing old versions from disk -arch.uninstall.required_by={} konnte nicht deinstalliert werden, da es für die folgenden Pakete benötigt wird. -arch.uninstall.required_by.advice=It is necessary to uninstall them as well to proceed. +arch.uninstall.required_by=The {} packages listed below depend on {} to work properly +arch.uninstall.required_by.advice=It is necessary to uninstall them as well to proceed arch.uninstall.unnecessary.all=The following {} packages will be uninstalled arch.uninstall.unnecessary.cancel=Keep -arch.uninstall.unnecessary.l1={} was successfully uninstalled. The packages below that it depended on are no longer needed. -arch.uninstall.unnecessary.l2=Check those you want to uninstall +arch.uninstall.unnecessary.l1=Packages successfully uninstalled! +arch.uninstall.unnecessary.l2=The packages below seem to be no longer necessary. Select those you want to uninstall arch.uninstall.unnecessary.proceed=Uninstall -arch.uninstalling.conflict={} deinstallieren -arch.uninstalling.conflict.fail=Deinstallation von {} fehlgeschlagen +arch.uninstalling.conflict=Uninstalling conflicting packages +arch.uninstalling.conflict.fail=It was not possible to uninstall the conflicting packages: {} arch.update.disabled.tooltip=This package can oly be upgrade through the action "Quick system upgrade" arch.update_summary.conflict_between=Conflict between {} and {} arch.update_summary.to_install.dep_conflict=Conflict between the dependencies {} and {} diff --git a/bauh/gems/arch/resources/locale/en b/bauh/gems/arch/resources/locale/en index c58dc999..c31b46d5 100644 --- a/bauh/gems/arch/resources/locale/en +++ b/bauh/gems/arch/resources/locale/en @@ -214,15 +214,15 @@ arch.task.sync_sb.status=Updating {} arch.uncompressing.package=Uncompressing the package arch.uninstall.clean_cached.error=It was not possible to remove old {} versions found on disk arch.uninstall.clean_cached.substatus=Removing old versions from disk -arch.uninstall.required_by={} cannot be uninstalled because it is required for the packages listed below to work. -arch.uninstall.required_by.advice=It is necessary to uninstall them as well to proceed. +arch.uninstall.required_by=The {} packages listed below depend on {} to work properly +arch.uninstall.required_by.advice=It is necessary to uninstall them as well to proceed arch.uninstall.unnecessary.all=The following {} packages will be uninstalled arch.uninstall.unnecessary.cancel=Keep -arch.uninstall.unnecessary.l1={} was successfully uninstalled. The packages below that it depended on are no longer needed. -arch.uninstall.unnecessary.l2=Check those you want to uninstall +arch.uninstall.unnecessary.l1=Packages successfully uninstalled! +arch.uninstall.unnecessary.l2=The packages below seem to be no longer necessary. Select those you want to uninstall arch.uninstall.unnecessary.proceed=Uninstall -arch.uninstalling.conflict=Uninstalling conflicting package {} -arch.uninstalling.conflict.fail=It was not possible to uninstall the conflicting package {} +arch.uninstalling.conflict=Uninstalling conflicting packages +arch.uninstalling.conflict.fail=It was not possible to uninstall the conflicting packages: {} arch.update.disabled.tooltip=This package can oly be upgrade through the action "Quick system upgrade" arch.update_summary.conflict_between=Conflict between {} and {} arch.update_summary.to_install.dep_conflict=Conflict between the dependencies {} and {} diff --git a/bauh/gems/arch/resources/locale/es b/bauh/gems/arch/resources/locale/es index 98c81add..64f5865e 100644 --- a/bauh/gems/arch/resources/locale/es +++ b/bauh/gems/arch/resources/locale/es @@ -213,15 +213,15 @@ arch.task.sync_sb.status=Actualizando {} arch.uncompressing.package=Descomprimindo el paquete arch.uninstall.clean_cached.error=No fue posible eliminar versiones antiguas de {} encontradas en disco arch.uninstall.clean_cached.substatus=Eliminando versiones antiguas del disco -arch.uninstall.required_by=No se puede desinstalar {} porque es necesario para que los paquetes enumerados abajo funcionen. -arch.uninstall.required_by.advice=Es necesario desinstalarlos también para continuar. +arch.uninstall.required_by=Los {} paquetes enumerados abajo dependen de {} para funcionar correctamente +arch.uninstall.required_by.advice=Es necesario desinstalarlos también para continuar arch.uninstall.unnecessary.all=Los {} seguintes paquetes serán desinstalados arch.uninstall.unnecessary.cancel=Mantener -arch.uninstall.unnecessary.l1={} se desinstaló correctamente. Los paquetes abajo de los que dependía ya no son necesarios -arch.uninstall.unnecessary.l2=Seleccione aquellos que desea desinstalar +arch.uninstall.unnecessary.l1=¡Paquetes desinstalados con éxito! +arch.uninstall.unnecessary.l2=Parece que los paquetes abajo ya no son necesarios. Seleccione los que desea desinstalar arch.uninstall.unnecessary.proceed=Desinstalar -arch.uninstalling.conflict=Eliminando el paquete conflictivo {} -arch.uninstalling.conflict.fail=No fue posible desinstalar el paquete conflictivo {} +arch.uninstalling.conflict=Eliminando paquetes conflictivos +arch.uninstalling.conflict.fail=No fue posible desinstalar los paquetes conflictivos: {} arch.update.disabled.tooltip=Solo es posible actualizar este paquete a través de la acción "Actualización rápida de sistema" arch.update_summary.conflict_between=Conflicto entre {} y {} arch.update_summary.to_install.dep_conflict=Conflicto entre las dependencias {} y {} diff --git a/bauh/gems/arch/resources/locale/it b/bauh/gems/arch/resources/locale/it index 488db7aa..3011a2a1 100644 --- a/bauh/gems/arch/resources/locale/it +++ b/bauh/gems/arch/resources/locale/it @@ -213,15 +213,15 @@ arch.task.sync_sb.status=Aggiornando {} arch.uncompressing.package=Non comprimere il pacchetto arch.uninstall.clean_cached.error=Non è stato possibile rimuovere le vecchie {} versioni trovate sul disco arch.uninstall.clean_cached.substatus=Rimozione di versioni precedenti dal disco -arch.uninstall.required_by={} non può essere disinstallato perché è necessario che i seguenti pacchetti funzionino. -arch.uninstall.required_by.advice=It is necessary to uninstall them as well to proceed. +arch.uninstall.required_by=The {} packages listed below depend on {} to work properly +arch.uninstall.required_by.advice=It is necessary to uninstall them as well to proceed arch.uninstall.unnecessary.all=The following {} packages will be uninstalled arch.uninstall.unnecessary.cancel=Keep -arch.uninstall.unnecessary.l1={} was successfully uninstalled. The packages below that it depended on are no longer needed. -arch.uninstall.unnecessary.l2=Check those you want to uninstall: +arch.uninstall.unnecessary.l1=Packages successfully uninstalled! +arch.uninstall.unnecessary.l2=The packages below seem to be no longer necessary. Select those you want to uninstall arch.uninstall.unnecessary.proceed=Uninstall -arch.uninstalling.conflict=Disinstallazione del pacchetto in conflitto {} -arch.uninstalling.conflict.fail=Non è stato possibile disinstallare il pacchetto in conflitto {} +arch.uninstalling.conflict=Uninstalling conflicting packages +arch.uninstalling.conflict.fail=It was not possible to uninstall the conflicting packages: {} arch.update.disabled.tooltip=This package can oly be upgrade through the action "Quick system upgrade" arch.update_summary.conflict_between=Conflict between {} and {} arch.update_summary.to_install.dep_conflict=Conflict between the dependencies {} and {} diff --git a/bauh/gems/arch/resources/locale/pt b/bauh/gems/arch/resources/locale/pt index bf148f0c..77706226 100644 --- a/bauh/gems/arch/resources/locale/pt +++ b/bauh/gems/arch/resources/locale/pt @@ -213,15 +213,15 @@ arch.task.sync_sb.status=Atualizando {} arch.uncompressing.package=Descompactando o pacote arch.uninstall.clean_cached.error=Não foi possível remover versões antigas de {} encontradas em disco arch.uninstall.clean_cached.substatus=Removendo versões antigas do disco -arch.uninstall.required_by={} não pode ser desinstalado porque ele é necessário para o funcionamento dos pacotes listados abaixo. -arch.uninstall.required_by.advice=Para prosseguir será necessário desinstá-los também. +arch.uninstall.required_by=Os {} pacotes listados abaixo dependem de {} para funcionar corretamente +arch.uninstall.required_by.advice=Para prosseguir será necessário desinstá-los também arch.uninstall.unnecessary.all=Os seguintes {} pacotes serão desinstalados arch.uninstall.unnecessary.cancel=Manter -arch.uninstall.unnecessary.l1={} foi desinstalado com sucesso ! Os pacotes abaixo que ele dependia já não são mais necessários. -arch.uninstall.unnecessary.l2=Selecione os desejados para desinstalação +arch.uninstall.unnecessary.l1=Pacotes desinstalados com sucesso! +arch.uninstall.unnecessary.l2=Os pacotes abaixo parecem não ser mais necessários. Selecione os desejados para desinstalação arch.uninstall.unnecessary.proceed=Desinstalar -arch.uninstalling.conflict=Desinstalando o pacote conflitante {} -arch.uninstalling.conflict.fail=Não foi possível desinstalar o pacote conflitante {} +arch.uninstalling.conflict=Desinstalando pacotes conflitante +arch.uninstalling.conflict.fail=Não foi possível desinstalar os pacotes conflitantes: {} arch.update.disabled.tooltip=Este pacote só pode ser atualizado através da ação "Atualização rápida de sistema" arch.update_summary.conflict_between=Conflito entre {} e {} arch.update_summary.to_install.dep_conflict=Conflito entre as dependências {} e {} diff --git a/bauh/gems/arch/resources/locale/ru b/bauh/gems/arch/resources/locale/ru index 9a848975..c43bc763 100644 --- a/bauh/gems/arch/resources/locale/ru +++ b/bauh/gems/arch/resources/locale/ru @@ -213,15 +213,15 @@ arch.task.sync_sb.status=Updating {} arch.uncompressing.package=Распаковка пакета arch.uninstall.clean_cached.error=It was not possible to remove old {} versions found on disk arch.uninstall.clean_cached.substatus=Removing old versions from disk -arch.uninstall.required_by={} не может быть удален, так как это необходимо для работы следующих пакетов -arch.uninstall.required_by.advice=It is necessary to uninstall them as well to proceed. +arch.uninstall.required_by=The {} packages listed below depend on {} to work properly +arch.uninstall.required_by.advice=It is necessary to uninstall them as well to proceed arch.uninstall.unnecessary.all=The following {} packages will be uninstalled arch.uninstall.unnecessary.cancel=Keep -arch.uninstall.unnecessary.l1={} was successfully uninstalled. The packages below that it depended on are no longer needed. -arch.uninstall.unnecessary.l2=Check those you want to uninstall +arch.uninstall.unnecessary.l1=Packages successfully uninstalled! +arch.uninstall.unnecessary.l2=The packages below seem to be no longer necessary. Select those you want to uninstall arch.uninstall.unnecessary.proceed=Uninstall -arch.uninstalling.conflict=Удаление конфликтующего пакета {} -arch.uninstalling.conflict.fail=Не удалось удалить конфликтующий пакет {} +arch.uninstalling.conflict=Uninstalling conflicting packages +arch.uninstalling.conflict.fail=It was not possible to uninstall the conflicting packages: {} arch.update.disabled.tooltip=Этот пакет может быть обновлен только через действие "обновить систему" arch.update_summary.conflict_between=Конфликт между {} и {} arch.update_summary.to_install.dep_conflict=Конфликт между зависимостями {} и {} diff --git a/bauh/gems/arch/resources/locale/tr b/bauh/gems/arch/resources/locale/tr index 8e867b99..baeab0f8 100644 --- a/bauh/gems/arch/resources/locale/tr +++ b/bauh/gems/arch/resources/locale/tr @@ -213,15 +213,15 @@ arch.task.sync_sb.status={} güncelleniyor arch.uncompressing.package=Paket arşivden çıkarılıyor arch.uninstall.clean_cached.error=Diskte bulunan eski {} sürümleri kaldırılamadı arch.uninstall.clean_cached.substatus=Eski sürümler diskten kaldırılıyor -arch.uninstall.required_by={} kaldırılamıyor çünkü aşağıda listelenen paketlerin çalışması için gerekli. -arch.uninstall.required_by.advice=Devam etmek için bunları da kaldırmak gerekir. +arch.uninstall.required_by=The {} packages listed below depend on {} to work properly +arch.uninstall.required_by.advice=Devam etmek için bunları da kaldırmak gerekir arch.uninstall.unnecessary.all=Aşağıdaki {} paketler kaldırılacak arch.uninstall.unnecessary.cancel=Tut -arch.uninstall.unnecessary.l1={} başarıyla kaldırıldı. Aşağıda bağlı olduğu paketlere artık gerek kalmadı. -arch.uninstall.unnecessary.l2=Kaldırmak istediklerinizi kontrol edin +arch.uninstall.unnecessary.l1=Packages successfully uninstalled! +arch.uninstall.unnecessary.l2=The packages below seem to be no longer necessary. Select those you want to uninstall arch.uninstall.unnecessary.proceed=Kaldır -arch.uninstalling.conflict=Çakışan paketin kaldırılması {} -arch.uninstalling.conflict.fail=Çakışan {} paketini kaldırmak mümkün olmadı +arch.uninstalling.conflict=Uninstalling conflicting packages +arch.uninstalling.conflict.fail=It was not possible to uninstall the conflicting packages: {} arch.update.disabled.tooltip=Bu paket yalnızca "Hızlı sistem yükseltme" işlemi ile yükseltilebilir arch.update_summary.conflict_between={} Ve {} arasında çakışma arch.update_summary.to_install.dep_conflict={} ve {} bağımlılıkları arasındaki çakışma diff --git a/bauh/view/qt/components.py b/bauh/view/qt/components.py index 41ed76e0..e247b12a 100644 --- a/bauh/view/qt/components.py +++ b/bauh/view/qt/components.py @@ -302,6 +302,8 @@ class CheckboxQt(QCheckBox): if model.read_only: self.setAttribute(Qt.WA_TransparentForMouseEvents) self.setFocusPolicy(Qt.NoFocus) + else: + self.setCursor(QCursor(Qt.PointingHandCursor)) def _set_checked(self, state): checked = state == 2