diff --git a/CHANGELOG.md b/CHANGELOG.md
index 021936db..85cf0745 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,9 +5,22 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [0.9.2] 2020
+### Features
+- UI
+ - it is possible to view details of some initialization tasks by clicking on their icons
+
+
+
+
+
+
+
### Improvements
- Backup
- new **type** field on settings to specify the Timeshift backup mode: **RSYNC** or **BTRFS**
+
+
+
- Trim
- the dialog is now displayed before the upgrading process (but the operation is only executed after a successful upgrade)
- Settings
diff --git a/bauh/api/abstract/handler.py b/bauh/api/abstract/handler.py
index b1249191..d4c9f4ed 100644
--- a/bauh/api/abstract/handler.py
+++ b/bauh/api/abstract/handler.py
@@ -102,6 +102,15 @@ class TaskManager:
"""
pass
+ def update_output(self, task_id: str, output: str):
+ """
+ updates the task output
+ :param task_id:
+ :param output:
+ :return:
+ """
+ pass
+
def finish_task(self, task_id: str):
"""
marks a task as finished
diff --git a/bauh/gems/arch/pacman.py b/bauh/gems/arch/pacman.py
index 1399e853..e253e340 100644
--- a/bauh/gems/arch/pacman.py
+++ b/bauh/gems/arch/pacman.py
@@ -500,8 +500,7 @@ def get_current_mirror_countries() -> List[str]:
def is_mirrors_available() -> bool:
- res = run_cmd('which pacman-mirrors', print_error=False)
- return res and not res.strip().startswith('which ')
+ return bool(run_cmd('which pacman-mirrors', print_error=False))
def get_update_size(pkgs: List[str]) -> Dict[str, int]: # bytes:
diff --git a/bauh/gems/arch/resources/locale/ca b/bauh/gems/arch/resources/locale/ca
index 2de00529..57b78ef1 100644
--- a/bauh/gems/arch/resources/locale/ca
+++ b/bauh/gems/arch/resources/locale/ca
@@ -168,7 +168,7 @@ arch.task.disk_cache.prepared=Llegits
arch.task.disk_cache.reading=Determinant els paquets instal·lats
arch.task.mirrors=Refreshing mirrors
arch.task.optimizing=Optimizing {}
-arch.task.sync_databases.waiting=Waiting for mirrors refreshing
+arch.task.sync_databases.waiting=Waiting for {}
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
diff --git a/bauh/gems/arch/resources/locale/de b/bauh/gems/arch/resources/locale/de
index c513c70b..fbfde2f1 100644
--- a/bauh/gems/arch/resources/locale/de
+++ b/bauh/gems/arch/resources/locale/de
@@ -168,7 +168,7 @@ arch.task.disk_cache.prepared=Read
arch.task.disk_cache.reading=Determining installed packages
arch.task.mirrors=Refreshing mirrors
arch.task.optimizing=Optimizing {}
-arch.task.sync_databases.waiting=Waiting for mirrors refreshing
+arch.task.sync_databases.waiting=Waiting for {}
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
diff --git a/bauh/gems/arch/resources/locale/en b/bauh/gems/arch/resources/locale/en
index 6c9fbcbf..00a28ba4 100644
--- a/bauh/gems/arch/resources/locale/en
+++ b/bauh/gems/arch/resources/locale/en
@@ -168,7 +168,7 @@ arch.task.disk_cache.prepared=Read
arch.task.disk_cache.reading=Determining installed packages
arch.task.mirrors=Refreshing mirrors
arch.task.optimizing=Optimizing {}
-arch.task.sync_databases.waiting=Waiting for mirrors refreshing
+arch.task.sync_databases.waiting=Waiting for {}
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
diff --git a/bauh/gems/arch/resources/locale/es b/bauh/gems/arch/resources/locale/es
index 81e1bf6a..d0d47b55 100644
--- a/bauh/gems/arch/resources/locale/es
+++ b/bauh/gems/arch/resources/locale/es
@@ -168,7 +168,7 @@ arch.task.disk_cache.prepared=Lidos
arch.task.disk_cache.reading=Determinando los paquetes instalados
arch.task.mirrors=Actualizando espejos
arch.task.optimizing=Optimizando {}
-arch.task.sync_databases.waiting=Esperando por actualización de espejos
+arch.task.sync_databases.waiting=Esperando por {}
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
diff --git a/bauh/gems/arch/resources/locale/it b/bauh/gems/arch/resources/locale/it
index a9596784..fdcba133 100644
--- a/bauh/gems/arch/resources/locale/it
+++ b/bauh/gems/arch/resources/locale/it
@@ -168,7 +168,7 @@ arch.task.disk_cache.prepared=Letti
arch.task.disk_cache.reading=Determinando i pacchetti installati
arch.task.mirrors=Aggiornando i mirror
arch.task.optimizing=Ottimizzando {}
-arch.task.sync_databases.waiting=In attesa dell'aggiornamento dei mirror
+arch.task.sync_databases.waiting=Waiting for {}
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
diff --git a/bauh/gems/arch/resources/locale/pt b/bauh/gems/arch/resources/locale/pt
index 6a740b45..cee36abe 100644
--- a/bauh/gems/arch/resources/locale/pt
+++ b/bauh/gems/arch/resources/locale/pt
@@ -168,7 +168,7 @@ arch.task.disk_cache.prepared=Lidos
arch.task.disk_cache.reading=Determinando pacotes instalados
arch.task.mirrors=Atualizando espelhos
arch.task.optimizing=Otimizando {}
-arch.task.sync_databases.waiting=Aguardando atualização de espelhos
+arch.task.sync_databases.waiting=Aguardando por {}
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
diff --git a/bauh/gems/arch/resources/locale/ru b/bauh/gems/arch/resources/locale/ru
index 042ea5bd..0b51d6e5 100644
--- a/bauh/gems/arch/resources/locale/ru
+++ b/bauh/gems/arch/resources/locale/ru
@@ -168,7 +168,7 @@ arch.task.disk_cache.prepared=Read
arch.task.disk_cache.reading=Determining installed packages
arch.task.mirrors=Обновление зеркал
arch.task.optimizing=Optimizing {}
-arch.task.sync_databases.waiting=Ожидание обновления зеркал
+arch.task.sync_databases.waiting=Waiting for {}
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
diff --git a/bauh/gems/arch/resources/locale/tr b/bauh/gems/arch/resources/locale/tr
index 2234d951..d2a8f2bd 100644
--- a/bauh/gems/arch/resources/locale/tr
+++ b/bauh/gems/arch/resources/locale/tr
@@ -168,7 +168,7 @@ arch.task.disk_cache.prepared=oku
arch.task.disk_cache.reading=Kurulu paketler belirleniyor
arch.task.mirrors=Yansılar yenileniyor
arch.task.optimizing=Uygun hale getiriliyor {}
-arch.task.sync_databases.waiting=Yansıların yenilenmesi bekleniyor
+arch.task.sync_databases.waiting=Waiting for {}
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ı
diff --git a/bauh/gems/arch/worker.py b/bauh/gems/arch/worker.py
index 558f7269..bc39fdd9 100644
--- a/bauh/gems/arch/worker.py
+++ b/bauh/gems/arch/worker.py
@@ -292,21 +292,24 @@ class RefreshMirrors(Thread):
self.task_id = "arch_mirrors"
self.sort_limit = sort_limit
+ def _notify_output(self, output: str):
+ self.taskman.update_output(self.task_id, output)
+
def run(self):
- self.logger.info("Refreshing mirrors")
self.taskman.register_task(self.task_id, self.i18n['arch.task.mirrors'], get_icon_path())
+ self.logger.info("Refreshing mirrors")
handler = ProcessHandler()
try:
self.taskman.update_progress(self.task_id, 10, '')
- success, output = handler.handle_simple(pacman.refresh_mirrors(self.root_password))
+ success, output = handler.handle_simple(pacman.refresh_mirrors(self.root_password), output_handler=self._notify_output)
if success:
if self.sort_limit is not None and self.sort_limit >= 0:
self.taskman.update_progress(self.task_id, 50, self.i18n['arch.custom_action.refresh_mirrors.status.updating'])
try:
- handler.handle_simple(pacman.sort_fastest_mirrors(self.root_password, self.sort_limit))
+ handler.handle_simple(pacman.sort_fastest_mirrors(self.root_password, self.sort_limit), output_handler=self._notify_output)
except:
self.logger.error("Could not sort mirrors by speed")
traceback.print_exc()
@@ -340,7 +343,7 @@ class SyncDatabases(Thread):
self.taskman.register_task(self.task_id, self.i18n['arch.sync_databases.substatus'], get_icon_path())
if self.refresh_mirrors and self.refresh_mirrors.is_alive():
- self.taskman.update_progress(self.task_id, 0, self.i18n['arch.task.sync_databases.waiting'])
+ self.taskman.update_progress(self.task_id, 0, self.i18n['arch.task.sync_databases.waiting'].format('"{}"'.format(self.i18n['arch.task.mirrors'])))
self.refresh_mirrors.join()
progress = 10
@@ -357,20 +360,25 @@ class SyncDatabases(Thread):
for o in p.stdout:
line = o.decode().strip()
- if line and line.startswith('downloading'):
- db = line.split(' ')[1].strip()
+ if line:
+ self.task_man.update_output(self.task_id, line)
+ if line.startswith('downloading'):
+ db = line.split(' ')[1].strip()
- if last_db is None or last_db != db:
- last_db = db
- dbs_read += 1
- progress = dbs_read * inc
- else:
- progress += 0.25
+ if last_db is None or last_db != db:
+ last_db = db
+ dbs_read += 1
+ progress = dbs_read * inc
+ else:
+ progress += 0.25
- self.taskman.update_progress(self.task_id, progress, self.i18n['arch.task.sync_sb.status'].format(db))
+ self.taskman.update_progress(self.task_id, progress, self.i18n['arch.task.sync_sb.status'].format(db))
for o in p.stderr:
- o.decode()
+ line = o.decode().strip()
+
+ if line:
+ self.task_man.update_output(self.task_id, line)
p.wait()
diff --git a/bauh/view/qt/prepare.py b/bauh/view/qt/prepare.py
index 6eaee648..257474be 100644
--- a/bauh/view/qt/prepare.py
+++ b/bauh/view/qt/prepare.py
@@ -5,9 +5,9 @@ from functools import reduce
from typing import Tuple
from PyQt5.QtCore import QSize, Qt, QThread, pyqtSignal, QCoreApplication
-from PyQt5.QtGui import QIcon
+from PyQt5.QtGui import QIcon, QCursor
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QSizePolicy, QTableWidget, QHeaderView, QPushButton, QToolBar, \
- QProgressBar, QApplication
+ QProgressBar, QApplication, QPlainTextEdit, QToolButton, QHBoxLayout
from bauh import __app_name__
from bauh.api.abstract.context import ApplicationContext
@@ -27,6 +27,7 @@ class Prepare(QThread, TaskManager):
signal_finished = pyqtSignal(str)
signal_started = pyqtSignal()
signal_ask_password = pyqtSignal()
+ signal_output = pyqtSignal(str, str)
def __init__(self, context: ApplicationContext, manager: SoftwareManager, i18n: I18n):
super(Prepare, self).__init__()
@@ -63,6 +64,9 @@ class Prepare(QThread, TaskManager):
def update_progress(self, task_id: str, progress: float, substatus: str):
self.signal_update.emit(task_id, progress, substatus)
+ def update_output(self, task_id: str, output: str):
+ self.signal_output.emit(task_id, output)
+
def register_task(self, id_: str, label: str, icon_path: str):
self.signal_register.emit(id_, label, icon_path)
@@ -79,6 +83,7 @@ class CheckFinished(QThread):
self.finished = None
def run(self):
+ time.sleep(3)
while True:
if self.total is not None and self.finished is not None:
if self.total == self.finished:
@@ -117,8 +122,7 @@ class PreparePanel(QWidget, TaskManager):
signal_password_response = pyqtSignal(str, bool)
def __init__(self, context: ApplicationContext, manager: SoftwareManager, screen_size: QSize, i18n: I18n, manage_window: QWidget):
- super(PreparePanel, self).__init__()
- self.setWindowFlag(Qt.WindowCloseButtonHint, False)
+ super(PreparePanel, self).__init__(flags=Qt.CustomizeWindowHint | Qt.WindowTitleHint)
self.i18n = i18n
self.context = context
self.manage_window = manage_window
@@ -130,6 +134,7 @@ class PreparePanel(QWidget, TaskManager):
self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
self.manager = manager
self.tasks = {}
+ self.output = {}
self.ntasks = 0
self.ftasks = 0
self.self_close = False
@@ -140,6 +145,7 @@ class PreparePanel(QWidget, TaskManager):
self.prepare_thread.signal_finished.connect(self.finish_task)
self.prepare_thread.signal_started.connect(self.start)
self.prepare_thread.signal_ask_password.connect(self.ask_root_password)
+ self.prepare_thread.signal_output.connect(self.update_output)
self.signal_password_response.connect(self.prepare_thread.set_password_reply)
self.check_thread = CheckFinished()
@@ -170,27 +176,60 @@ class PreparePanel(QWidget, TaskManager):
self.table.setHorizontalHeaderLabels(['' for _ in range(4)])
self.layout().addWidget(self.table)
- toolbar = QToolBar()
+ self.textarea_output = QPlainTextEdit(self)
+ self.textarea_output.resize(self.table.size())
+ self.textarea_output.setStyleSheet("background: black; color: white;")
+ self.layout().addWidget(self.textarea_output)
+ self.textarea_output.setVisible(False)
+ self.textarea_output.setReadOnly(True)
+ self.textarea_output.setMaximumHeight(100)
+ self.current_output_task = None
+
+ self.bottom_widget = QWidget()
+ self.bottom_widget.setLayout(QHBoxLayout())
+ self.bottom_widget.layout().addStretch()
+ bt_hide_output = QPushButton('Hide details')
+ bt_hide_output.setStyleSheet('QPushButton { text-decoration: underline; border: 0px; background: none } ')
+ bt_hide_output.clicked.connect(self.hide_output)
+ bt_hide_output.setCursor(QCursor(Qt.PointingHandCursor))
+ self.bottom_widget.layout().addWidget(bt_hide_output)
+ self.bottom_widget.layout().addStretch()
+ self.layout().addWidget(self.bottom_widget)
+ self.bottom_widget.setVisible(False)
+
+ self.bt_bar = QToolBar()
self.bt_close = QPushButton(self.i18n['close'].capitalize())
+ self.bt_close.setCursor(QCursor(Qt.PointingHandCursor))
self.bt_close.clicked.connect(self.close)
self.bt_close.setVisible(False)
- self.ref_bt_close = toolbar.addWidget(self.bt_close)
+ self.ref_bt_close = self.bt_bar.addWidget(self.bt_close)
- toolbar.addWidget(new_spacer())
+ self.bt_bar.addWidget(new_spacer())
self.progress_bar = QProgressBar()
self.progress_bar.setStyleSheet(styles.PROGRESS_BAR)
self.progress_bar.setMaximumHeight(10 if QApplication.instance().style().objectName().lower() == 'windows' else 4)
self.progress_bar.setTextVisible(False)
self.progress_bar.setVisible(False)
- self.ref_progress_bar = toolbar.addWidget(self.progress_bar)
- toolbar.addWidget(new_spacer())
+ self.ref_progress_bar = self.bt_bar.addWidget(self.progress_bar)
+ self.bt_bar.addWidget(new_spacer())
self.bt_skip = QPushButton(self.i18n['prepare_panel.bt_skip.label'].capitalize())
self.bt_skip.clicked.connect(self.finish)
self.bt_skip.setEnabled(False)
- toolbar.addWidget(self.bt_skip)
+ self.bt_bar.addWidget(self.bt_skip)
- self.layout().addWidget(toolbar)
+ self.layout().addWidget(self.bt_bar)
+
+ def hide_output(self):
+ self.current_output_task = None
+ self.textarea_output.setVisible(False)
+ self.textarea_output.clear()
+ self.bottom_widget.setVisible(False)
+ self._resize_columns()
+ self.setFocus(Qt.NoFocusReason)
+
+ if not self.bt_bar.isVisible():
+ self.bt_bar.setVisible(True)
def ask_root_password(self):
root_pwd, ok = root.ask_root_password(self.context, self.i18n)
@@ -198,6 +237,7 @@ class PreparePanel(QWidget, TaskManager):
def _enable_skip_button(self):
self.bt_skip.setEnabled(True)
+ self.bt_skip.setCursor(QCursor(Qt.PointingHandCursor))
def _change_progress(self, value: int):
self.progress_bar.setValue(value)
@@ -235,14 +275,40 @@ class PreparePanel(QWidget, TaskManager):
task_row = self.ntasks - 1
- lb_icon = QLabel()
- lb_icon.setContentsMargins(10, 0, 10, 0)
- lb_icon.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
+ icon_widget = QWidget()
+ icon_widget.setLayout(QHBoxLayout())
+ icon_widget.layout().setContentsMargins(10, 0, 10, 0)
+ bt_icon = QToolButton()
+ bt_icon.setEnabled(False)
+ bt_icon.setToolTip(self.i18n['prepare.bt_icon.no_output'])
+ bt_icon.setFixedSize(QSize(24, 24))
+ bt_icon.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
if icon_path:
- lb_icon.setPixmap(QIcon(icon_path).pixmap(14, 14))
+ bt_icon.setIcon(QIcon(icon_path))
- self.table.setCellWidget(task_row, 0, lb_icon)
+ def _show_output():
+ lines = self.output[id_]
+
+ if lines:
+ self.current_output_task = id_
+ self.textarea_output.clear()
+ self.textarea_output.setVisible(True)
+
+ for l in lines:
+ self.textarea_output.appendPlainText(l)
+
+ self.bottom_widget.setVisible(True)
+
+ self.setFocus(Qt.NoFocusReason)
+
+ if self.bt_bar.isVisible():
+ self.bt_bar.setVisible(False)
+
+ bt_icon.clicked.connect(_show_output)
+ icon_widget.layout().addWidget(bt_icon)
+
+ self.table.setCellWidget(task_row, 0, icon_widget)
lb_status = QLabel(label)
lb_status.setMinimumWidth(50)
@@ -263,7 +329,8 @@ class PreparePanel(QWidget, TaskManager):
self.table.setCellWidget(task_row, 3, lb_progress)
- self.tasks[id_] = {'lb_status': lb_status,
+ self.tasks[id_] = {'bt_icon': bt_icon,
+ 'lb_status': lb_status,
'lb_prog': lb_progress,
'progress': 0,
'lb_sub': lb_sub,
@@ -285,6 +352,22 @@ class PreparePanel(QWidget, TaskManager):
self._resize_columns()
+ def update_output(self, task_id: str, output: str):
+ full_output = self.output.get(task_id)
+
+ if full_output is None:
+ full_output = []
+ self.output[task_id] = full_output
+ task = self.tasks[task_id]
+ task['bt_icon'].setEnabled(True)
+ task['bt_icon'].setCursor(QCursor(Qt.PointingHandCursor))
+ task['bt_icon'].setToolTip(self.i18n['prepare.bt_icon.output'])
+
+ full_output.append(output)
+
+ if self.current_output_task == task_id:
+ self.textarea_output.appendPlainText(output)
+
def finish_task(self, task_id: str):
task = self.tasks[task_id]
task['lb_sub'].setText('')
diff --git a/bauh/view/qt/root.py b/bauh/view/qt/root.py
index be75eae9..d35a8ff0 100644
--- a/bauh/view/qt/root.py
+++ b/bauh/view/qt/root.py
@@ -1,14 +1,16 @@
import os
from typing import Tuple
-from PyQt5.QtWidgets import QInputDialog, QLineEdit
+from PyQt5.QtCore import Qt
+from PyQt5.QtGui import QCursor, QIcon
+from PyQt5.QtWidgets import QInputDialog, QLineEdit, QDialogButtonBox
from bauh.api.abstract.context import ApplicationContext
from bauh.api.abstract.view import MessageType
from bauh.commons.system import new_subprocess
from bauh.view.core.config import read_config
+from bauh.view.qt import css
from bauh.view.qt.dialog import show_message
-from bauh.view.qt.view_utils import load_resource_icon
from bauh.view.util import util
from bauh.view.util.translation import I18n
@@ -25,7 +27,7 @@ def ask_root_password(context: ApplicationContext, i18n: I18n, app_config: dict
if store_password and context.root_password and validate_password(context.root_password):
return context.root_password, True
- diag = QInputDialog()
+ diag = QInputDialog(flags=Qt.CustomizeWindowHint | Qt.WindowTitleHint)
diag.setStyleSheet("""QLineEdit { border-radius: 5px; font-size: 16px; border: 1px solid lightblue }""")
diag.setInputMode(QInputDialog.TextInput)
diag.setTextEchoMode(QLineEdit.Password)
@@ -34,6 +36,16 @@ def ask_root_password(context: ApplicationContext, i18n: I18n, app_config: dict
diag.setLabelText('')
diag.setOkButtonText(i18n['popup.root.continue'].capitalize())
diag.setCancelButtonText(i18n['popup.button.cancel'].capitalize())
+
+ bt_box = [c for c in diag.children() if isinstance(c, QDialogButtonBox)][0]
+
+ for bt in bt_box.buttons():
+ if bt_box.buttonRole(bt) == QDialogButtonBox.AcceptRole:
+ bt.setStyleSheet(css.OK_BUTTON)
+
+ bt.setCursor(QCursor(Qt.PointingHandCursor))
+ bt.setIcon(QIcon())
+
diag.resize(400, 200)
for attempt in range(3):
diff --git a/bauh/view/resources/locale/ca b/bauh/view/resources/locale/ca
index ec9edcd9..6d210ddf 100644
--- a/bauh/view/resources/locale/ca
+++ b/bauh/view/resources/locale/ca
@@ -334,6 +334,8 @@ popup.root.bad_password.title=Error
popup.root.continue=continuar
popup.root.title=Requireix la vostra contrasenya per a continuar
popup.screenshots.no_screenshot.body=no s’han pogut recuperar captures de pantalla del {}
+prepare.bt_icon.no_output=There are no progress details for this task to be displayed
+prepare.bt_icon.output=Click here to display the progress details of this task
prepare_panel.bt_skip.label=saltar
prepare_panel.title.finish=Llest
prepare_panel.title.start=Iniciando
diff --git a/bauh/view/resources/locale/de b/bauh/view/resources/locale/de
index 0a2306ff..2138baba 100644
--- a/bauh/view/resources/locale/de
+++ b/bauh/view/resources/locale/de
@@ -333,6 +333,8 @@ popup.root.bad_password.title=Fehler
popup.root.continue=Fortfahren
popup.root.title=Zum Fortfahren wird das Passwort benötigt.
popup.screenshots.no_screenshot.body={} Screenshots konnten nicht heruntergeladen werden.
+prepare.bt_icon.no_output=There are no progress details for this task to be displayed
+prepare.bt_icon.output=Click here to display the progress details of this task
prepare_panel.bt_skip.label=skip
prepare_panel.title.finish=Bereit
prepare_panel.title.start=Initialisierung
diff --git a/bauh/view/resources/locale/en b/bauh/view/resources/locale/en
index 404372f1..058cbe36 100644
--- a/bauh/view/resources/locale/en
+++ b/bauh/view/resources/locale/en
@@ -333,6 +333,8 @@ popup.root.bad_password.title=Error
popup.root.continue=continue
popup.root.title=Requires your password to continue
popup.screenshots.no_screenshot.body=it was not possible to retrieve {} screenshots
+prepare.bt_icon.no_output=There are no progress details for this task to be displayed
+prepare.bt_icon.output=Click here to display the progress details of this task
prepare_panel.bt_skip.label=skip
prepare_panel.title.finish=Ready
prepare_panel.title.start=Initializing
diff --git a/bauh/view/resources/locale/es b/bauh/view/resources/locale/es
index 76fb99b0..1b96957b 100644
--- a/bauh/view/resources/locale/es
+++ b/bauh/view/resources/locale/es
@@ -334,6 +334,8 @@ popup.root.bad_password.title=Error
popup.root.continue=continuar
popup.root.title=Proporcione su contraseña para continuar
popup.screenshots.no_screenshot.body=No fue posible recuperar las fotos de {}
+prepare.bt_icon.no_output=No hay detalles del progreso de esta tarea para mostrar
+prepare.bt_icon.output=Haga clic aquí para mostrar los detalles del progreso de esta tarea
prepare_panel.bt_skip.label=omitir
prepare_panel.title.finish=Listo
prepare_panel.title.start=Inicializando
diff --git a/bauh/view/resources/locale/it b/bauh/view/resources/locale/it
index def0b8db..e5cf47fc 100644
--- a/bauh/view/resources/locale/it
+++ b/bauh/view/resources/locale/it
@@ -336,6 +336,8 @@ popup.root.continue=continuare
popup.root.title=Richiede la tua password per continuare
popup.screenshots.no_screenshot.body=non è stato possibile recuperare {} schermate
prepar_panel.bt_skip.label=saltare
+prepare.bt_icon.no_output=There are no progress details for this task to be displayed
+prepare.bt_icon.output=Click here to display the progress details of this task
prepare_panel.bt_skip.label=skip
prepare_panel.title.finish=Pronto
prepare_panel.title.start=Inizializzazione
diff --git a/bauh/view/resources/locale/pt b/bauh/view/resources/locale/pt
index 0ecf7902..f64a1926 100644
--- a/bauh/view/resources/locale/pt
+++ b/bauh/view/resources/locale/pt
@@ -333,6 +333,8 @@ popup.root.bad_password.title=Erro
popup.root.continue=prosseguir
popup.root.title=Requer sua senha para prosseguir
popup.screenshots.no_screenshot.body=Não foi possível obter as fotos de {}
+prepare.bt_icon.no_output=Não existe detalhes do progresso dessa tarefa para ser exibido
+prepare.bt_icon.output=Clique aqui para exibir detalhes do progresso dessa tarefa
prepare_panel.bt_skip.label=Pular
prepare_panel.title.finish=Pronto
prepare_panel.title.start=Iniciando
diff --git a/bauh/view/resources/locale/ru b/bauh/view/resources/locale/ru
index 311da13c..16684f12 100644
--- a/bauh/view/resources/locale/ru
+++ b/bauh/view/resources/locale/ru
@@ -333,6 +333,8 @@ popup.root.bad_password.title=Ошибка
popup.root.continue=Продолжить
popup.root.title=Требуется ваш пароль, чтобы продолжить
popup.screenshots.no_screenshot.body=не удалось получить скриншоты {}
+prepare.bt_icon.no_output=There are no progress details for this task to be displayed
+prepare.bt_icon.output=Click here to display the progress details of this task
prepare_panel.bt_skip.label=Пропустить
prepare_panel.title.finish=Ready
prepare_panel.title.start=Initializing
diff --git a/bauh/view/resources/locale/tr b/bauh/view/resources/locale/tr
index a3178561..f1116006 100644
--- a/bauh/view/resources/locale/tr
+++ b/bauh/view/resources/locale/tr
@@ -333,6 +333,8 @@ popup.root.bad_password.title=Hata
popup.root.continue=devam
popup.root.title=Devam etmek için şifre girmelisiniz
popup.screenshots.no_screenshot.body={} ekran görüntüsünü almak mümkün değildi
+prepare.bt_icon.no_output=There are no progress details for this task to be displayed
+prepare.bt_icon.output=Click here to display the progress details of this task
prepare_panel.bt_skip.label=atla
prepare_panel.title.finish=Hazır
prepare_panel.title.start=Başlatılıyor
diff --git a/pictures/releases/0.9.2/backup_mode.png b/pictures/releases/0.9.2/backup_mode.png
new file mode 100644
index 00000000..35c9bec9
Binary files /dev/null and b/pictures/releases/0.9.2/backup_mode.png differ
diff --git a/pictures/releases/0.9.2/prepare_icon.png b/pictures/releases/0.9.2/prepare_icon.png
new file mode 100644
index 00000000..3155caf6
Binary files /dev/null and b/pictures/releases/0.9.2/prepare_icon.png differ
diff --git a/pictures/releases/0.9.2/prepare_output.png b/pictures/releases/0.9.2/prepare_output.png
new file mode 100644
index 00000000..7cecf1d2
Binary files /dev/null and b/pictures/releases/0.9.2/prepare_output.png differ