From b0c0d40e6ff57ebd5d15e2cf344c8aa4e8541d7f Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 18 May 2011 20:02:00 -0600 Subject: [PATCH] Fix #780484 (Intermittent crash when disconnect with dialog open) --- src/calibre/gui2/bars.py | 309 ++++++++++++++++++++++++ src/calibre/gui2/device.py | 2 + src/calibre/gui2/layout.py | 284 ++-------------------- src/calibre/gui2/preferences/main.py | 5 +- src/calibre/gui2/preferences/toolbar.py | 3 + src/calibre/gui2/ui.py | 6 +- 6 files changed, 336 insertions(+), 273 deletions(-) create mode 100644 src/calibre/gui2/bars.py diff --git a/src/calibre/gui2/bars.py b/src/calibre/gui2/bars.py new file mode 100644 index 0000000000..8bae9d65d1 --- /dev/null +++ b/src/calibre/gui2/bars.py @@ -0,0 +1,309 @@ +#!/usr/bin/env python +# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai +from __future__ import (unicode_literals, division, absolute_import, + print_function) + +__license__ = 'GPL v3' +__copyright__ = '2011, Kovid Goyal ' +__docformat__ = 'restructuredtext en' + + +from PyQt4.Qt import (QObject, QToolBar, Qt, QSize, QToolButton, QVBoxLayout, + QLabel, QWidget, QAction, QMenuBar, QMenu) + +from calibre.constants import isosx +from calibre.gui2 import gprefs + +class ToolBar(QToolBar): # {{{ + + def __init__(self, donate, location_manager, parent): + QToolBar.__init__(self, parent) + self.setContextMenuPolicy(Qt.PreventContextMenu) + self.setMovable(False) + self.setFloatable(False) + self.setOrientation(Qt.Horizontal) + self.setAllowedAreas(Qt.TopToolBarArea|Qt.BottomToolBarArea) + self.setStyleSheet('QToolButton:checked { font-weight: bold }') + self.preferred_width = self.sizeHint().width() + self.gui = parent + self.donate_button = donate + self.added_actions = [] + + self.location_manager = location_manager + donate.setAutoRaise(True) + donate.setCursor(Qt.PointingHandCursor) + self.setAcceptDrops(True) + self.showing_donate = False + + def resizeEvent(self, ev): + QToolBar.resizeEvent(self, ev) + style = self.get_text_style() + self.setToolButtonStyle(style) + if hasattr(self, 'd_widget') and hasattr(self.d_widget, 'filler'): + self.d_widget.filler.setVisible(style != Qt.ToolButtonIconOnly) + + def get_text_style(self): + style = Qt.ToolButtonTextUnderIcon + s = gprefs['toolbar_icon_size'] + if s != 'off': + p = gprefs['toolbar_text'] + if p == 'never': + style = Qt.ToolButtonIconOnly + elif p == 'auto' and self.preferred_width > self.width()+35: + style = Qt.ToolButtonIconOnly + return style + + def contextMenuEvent(self, *args): + pass + + def update_lm_actions(self): + for ac in self.added_actions: + if ac in self.location_manager.all_actions: + ac.setVisible(ac in self.location_manager.available_actions) + + def init_bar(self, actions): + self.showing_donate = False + for ac in self.added_actions: + m = ac.menu() + if m is not None: + m.setVisible(False) + + self.clear() + self.added_actions = [] + + bar = self + + for what in actions: + if what is None: + bar.addSeparator() + elif what == 'Location Manager': + for ac in self.location_manager.all_actions: + bar.addAction(ac) + bar.added_actions.append(ac) + bar.setup_tool_button(bar, ac, QToolButton.MenuButtonPopup) + ac.setVisible(False) + elif what == 'Donate': + self.d_widget = QWidget() + self.d_widget.setLayout(QVBoxLayout()) + self.d_widget.layout().addWidget(self.donate_button) + if isosx: + self.d_widget.setStyleSheet('QWidget, QToolButton {background-color: none; border: none; }') + self.d_widget.layout().setContentsMargins(0,0,0,0) + self.d_widget.setContentsMargins(0,0,0,0) + self.d_widget.filler = QLabel(u'\u00a0') + self.d_widget.layout().addWidget(self.d_widget.filler) + bar.addWidget(self.d_widget) + self.showing_donate = True + elif what in self.gui.iactions: + action = self.gui.iactions[what] + bar.addAction(action.qaction) + self.added_actions.append(action.qaction) + self.setup_tool_button(bar, action.qaction, action.popup_type) + self.preferred_width = self.sizeHint().width() + + def setup_tool_button(self, bar, ac, menu_mode=None): + ch = bar.widgetForAction(ac) + if ch is None: + ch = self.child_bar.widgetForAction(ac) + ch.setCursor(Qt.PointingHandCursor) + ch.setAutoRaise(True) + if ac.menu() is not None and menu_mode is not None: + ch.setPopupMode(menu_mode) + return ch + + #support drag&drop from/to library from/to reader/card + def dragEnterEvent(self, event): + md = event.mimeData() + if md.hasFormat("application/calibre+from_library") or \ + md.hasFormat("application/calibre+from_device"): + event.setDropAction(Qt.CopyAction) + event.accept() + else: + event.ignore() + + def dragMoveEvent(self, event): + allowed = False + md = event.mimeData() + #Drop is only allowed in the location manager widget's different from the selected one + for ac in self.location_manager.available_actions: + w = self.widgetForAction(ac) + if w is not None: + if ( md.hasFormat("application/calibre+from_library") or \ + md.hasFormat("application/calibre+from_device") ) and \ + w.geometry().contains(event.pos()) and \ + isinstance(w, QToolButton) and not w.isChecked(): + allowed = True + break + if allowed: + event.acceptProposedAction() + else: + event.ignore() + + def dropEvent(self, event): + data = event.mimeData() + + mime = 'application/calibre+from_library' + if data.hasFormat(mime): + ids = list(map(int, str(data.data(mime)).split())) + tgt = None + for ac in self.location_manager.available_actions: + w = self.widgetForAction(ac) + if w is not None and w.geometry().contains(event.pos()): + tgt = ac.calibre_name + if tgt is not None: + if tgt == 'main': + tgt = None + self.gui.sync_to_device(tgt, False, send_ids=ids) + event.accept() + + mime = 'application/calibre+from_device' + if data.hasFormat(mime): + paths = [unicode(u.toLocalFile()) for u in data.urls()] + if paths: + self.gui.iactions['Add Books'].add_books_from_device( + self.gui.current_view(), paths=paths) + event.accept() + +# }}} + +class MenuAction(QAction): # {{{ + + def __init__(self, clone, parent): + QAction.__init__(self, clone.text(), parent) + self.clone = clone + clone.changed.connect(self.clone_changed) + + def clone_changed(self): + self.setText(self.clone.text()) +# }}} + +class MenuBar(QMenuBar): # {{{ + + def __init__(self, location_manager, parent): + QMenuBar.__init__(self, parent) + self.gui = parent + self.setNativeMenuBar(True) + + self.location_manager = location_manager + self.added_actions = [] + + self.donate_action = QAction(_('Donate'), self) + self.donate_menu = QMenu() + self.donate_menu.addAction(self.gui.donate_action) + self.donate_action.setMenu(self.donate_menu) + + def update_lm_actions(self): + for ac in self.added_actions: + if ac in self.location_manager.all_actions: + ac.setVisible(ac in self.location_manager.available_actions) + + def init_bar(self, actions): + for ac in self.added_actions: + m = ac.menu() + if m is not None: + m.setVisible(False) + + self.clear() + self.added_actions = [] + + for what in actions: + if what is None: + continue + elif what == 'Location Manager': + for ac in self.location_manager.all_actions: + ac = self.build_menu(ac) + self.addAction(ac) + self.added_actions.append(ac) + ac.setVisible(False) + elif what == 'Donate': + self.addAction(self.donate_action) + elif what in self.gui.iactions: + action = self.gui.iactions[what] + ac = self.build_menu(action.qaction) + self.addAction(ac) + self.added_actions.append(ac) + + def build_menu(self, action): + m = action.menu() + ac = MenuAction(action, self) + if m is None: + m = QMenu() + m.addAction(action) + ac.setMenu(m) + return ac + +# }}} + +class BarsManager(QObject): + + def __init__(self, donate_button, location_manager, parent): + QObject.__init__(self, parent) + self.donate_button, self.location_manager = (donate_button, + location_manager) + + bars = [ToolBar(donate_button, location_manager, parent) for i in + range(3)] + self.main_bars = tuple(bars[:2]) + self.child_bars = tuple(bars[2:]) + + + self.apply_settings() + self.init_bars() + + def database_changed(self, db): + pass + + @property + def bars(self): + for x in self.main_bars + self.child_bars: + yield x + + @property + def showing_donate(self): + for b in self.bars: + if b.isVisible() and b.showing_donate: + return True + return False + + def init_bars(self): + self.bar_actions = tuple( + [gprefs['action-layout-toolbar'+x] for x in ('', '-device')] + + [gprefs['action-layout-toolbar-child']] + + [gprefs['action-layout-menubar']] + + [gprefs['action-layout-menubar-device']] + ) + + for bar, actions in zip(self.bars, self.bar_actions[:3]): + bar.init_bar(actions) + + def update_bars(self): + showing_device = self.location_manager.has_device + main_bar = self.main_bars[1 if showing_device else 0] + child_bar = self.child_bars[0] + for bar in self.bars: + bar.setVisible(False) + bar.update_lm_actions() + if main_bar.added_actions: + main_bar.setVisible(True) + if child_bar.added_actions: + child_bar.setVisible(True) + + self.menu_bar = MenuBar(self.location_manager, self.parent()) + self.menu_bar.init_bar(self.bar_actions[4 if showing_device else 3]) + self.menu_bar.update_lm_actions() + self.menu_bar.setVisible(bool(self.menu_bar.added_actions)) + self.parent().setMenuBar(self.menu_bar) + + def apply_settings(self): + sz = gprefs['toolbar_icon_size'] + sz = {'off':0, 'small':24, 'medium':48, 'large':64}[sz] + style = Qt.ToolButtonTextUnderIcon + if sz > 0 and gprefs['toolbar_text'] == 'never': + style = Qt.ToolButtonIconOnly + + for bar in self.bars: + bar.setIconSize(QSize(sz, sz)) + bar.setToolButtonStyle(style) + self.donate_button.set_normal_icon_size(sz, sz) + + diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py index 49542abdc1..02bce9e701 100644 --- a/src/calibre/gui2/device.py +++ b/src/calibre/gui2/device.py @@ -751,6 +751,7 @@ class DeviceMixin(object): # {{{ if self.current_view() != self.library_view: self.book_details.reset_info() self.location_manager.update_devices() + self.bars_manager.update_bars() self.library_view.set_device_connected(self.device_connected) self.refresh_ondevice() device_signals.device_connection_changed.emit(connected) @@ -1198,6 +1199,7 @@ class DeviceMixin(object): # {{{ cp, fs = job.result self.location_manager.update_devices(cp, fs, self.device_manager.device.icon) + self.bars_manager.update_bars() # reset the views so that up-to-date info is shown. These need to be # here because some drivers update collections in sync_booklists self.memory_view.reset() diff --git a/src/calibre/gui2/layout.py b/src/calibre/gui2/layout.py index b3c9bd3a02..46b6356a6e 100644 --- a/src/calibre/gui2/layout.py +++ b/src/calibre/gui2/layout.py @@ -7,15 +7,15 @@ __docformat__ = 'restructuredtext en' from functools import partial -from PyQt4.Qt import (QIcon, Qt, QWidget, QToolBar, QSize, - pyqtSignal, QToolButton, QMenu, QMenuBar, QAction, +from PyQt4.Qt import (QIcon, Qt, QWidget, QSize, + pyqtSignal, QToolButton, QMenu, QObject, QVBoxLayout, QSizePolicy, QLabel, QHBoxLayout, QActionGroup) -from calibre.constants import __appname__, isosx +from calibre.constants import __appname__ from calibre.gui2.search_box import SearchBox2, SavedSearchBox from calibre.gui2.throbber import ThrobbingButton -from calibre.gui2 import gprefs +from calibre.gui2.bars import BarsManager from calibre.gui2.widgets import ComboBoxWithHelp from calibre import human_readable @@ -35,6 +35,8 @@ class LocationManager(QObject): # {{{ self._mem = [] self.tooltips = {} + self.all_actions = [] + def ac(name, text, icon, tooltip): icon = QIcon(I(icon)) ac = self.location_actions.addAction(icon, text) @@ -44,7 +46,7 @@ class LocationManager(QObject): # {{{ receiver = partial(self._location_selected, name) ac.triggered.connect(receiver) self.tooltips[name] = tooltip - + m = QMenu(parent) self._mem.append(m) a = m.addAction(icon, tooltip) @@ -59,6 +61,7 @@ class LocationManager(QObject): # {{{ ac.setMenu(m) ac.calibre_name = name + self.all_actions.append(ac) return ac self.library_action = ac('library', _('Library'), 'lt.png', @@ -77,7 +80,7 @@ class LocationManager(QObject): # {{{ self.switch_menu.addSeparator() else: self.switch_menu = QMenu() - + self.switch_menu.addAction(choose_action) self.cs_menus = [] for t, acs in [(_('Quick switch'), quick_actions), @@ -91,7 +94,7 @@ class LocationManager(QObject): # {{{ self.switch_menu.addSeparator() for ac in switch_actions: self.switch_menu.addAction(ac) - + if self.switch_menu != self.library_action.menu(): self.library_action.setMenu(self.switch_menu) @@ -234,259 +237,6 @@ class Spacer(QWidget): # {{{ self.l.addStretch(10) # }}} -class MenuAction(QAction): # {{{ - - def __init__(self, clone, parent): - QAction.__init__(self, clone.text(), parent) - self.clone = clone - clone.changed.connect(self.clone_changed) - - def clone_changed(self): - self.setText(self.clone.text()) -# }}} - -class MenuBar(QMenuBar): # {{{ - - def __init__(self, location_manager, parent): - QMenuBar.__init__(self, parent) - self.gui = parent - self.setNativeMenuBar(True) - - self.location_manager = location_manager - self.location_manager.locations_changed.connect(self.build_bar) - self.added_actions = [] - - self.donate_action = QAction(_('Donate'), self) - self.donate_menu = QMenu() - self.donate_menu.addAction(self.gui.donate_action) - self.donate_action.setMenu(self.donate_menu) - self.build_bar() - - def build_bar(self, changed_action=None): - showing_device = self.location_manager.has_device - actions = '-device' if showing_device else '' - actions = gprefs['action-layout-menubar'+actions] - - show_main = len(actions) > 0 - self.setVisible(show_main) - - for ac in self.added_actions: - m = ac.menu() - if m is not None: - m.setVisible(False) - - self.clear() - self.added_actions = [] - self.action_map = {} - - for what in actions: - if what is None: - continue - elif what == 'Location Manager': - for ac in self.location_manager.available_actions: - ac = self.build_menu(ac) - self.addAction(ac) - self.added_actions.append(ac) - elif what == 'Donate': - self.addAction(self.donate_action) - elif what in self.gui.iactions: - action = self.gui.iactions[what] - ac = self.build_menu(action.qaction) - self.addAction(ac) - self.added_actions.append(ac) - - def build_menu(self, action): - m = action.menu() - ac = MenuAction(action, self) - if m is None: - m = QMenu() - m.addAction(action) - ac.setMenu(m) - return ac - -# }}} - -class BaseToolBar(QToolBar): # {{{ - - def __init__(self, parent): - QToolBar.__init__(self, parent) - self.setContextMenuPolicy(Qt.PreventContextMenu) - self.setMovable(False) - self.setFloatable(False) - self.setOrientation(Qt.Horizontal) - self.setAllowedAreas(Qt.TopToolBarArea|Qt.BottomToolBarArea) - self.setStyleSheet('QToolButton:checked { font-weight: bold }') - self.preferred_width = self.sizeHint().width() - - def resizeEvent(self, ev): - QToolBar.resizeEvent(self, ev) - style = self.get_text_style() - self.setToolButtonStyle(style) - if hasattr(self, 'd_widget') and hasattr(self.d_widget, 'filler'): - self.d_widget.filler.setVisible(style != Qt.ToolButtonIconOnly) - - def get_text_style(self): - style = Qt.ToolButtonTextUnderIcon - s = gprefs['toolbar_icon_size'] - if s != 'off': - p = gprefs['toolbar_text'] - if p == 'never': - style = Qt.ToolButtonIconOnly - elif p == 'auto' and self.preferred_width > self.width()+35: - style = Qt.ToolButtonIconOnly - return style - - def contextMenuEvent(self, *args): - pass - -# }}} - -class ToolBar(BaseToolBar): # {{{ - - def __init__(self, donate, location_manager, child_bar, parent): - BaseToolBar.__init__(self, parent) - self.gui = parent - self.child_bar = child_bar - self.donate_button = donate - self.apply_settings() - - self.location_manager = location_manager - self.location_manager.locations_changed.connect(self.build_bar) - donate.setAutoRaise(True) - donate.setCursor(Qt.PointingHandCursor) - self.added_actions = [] - self.build_bar() - self.setAcceptDrops(True) - - def apply_settings(self): - sz = gprefs['toolbar_icon_size'] - sz = {'off':0, 'small':24, 'medium':48, 'large':64}[sz] - self.setIconSize(QSize(sz, sz)) - self.child_bar.setIconSize(QSize(sz, sz)) - style = Qt.ToolButtonTextUnderIcon - if sz > 0 and gprefs['toolbar_text'] == 'never': - style = Qt.ToolButtonIconOnly - self.setToolButtonStyle(style) - self.child_bar.setToolButtonStyle(style) - self.donate_button.set_normal_icon_size(sz, sz) - - def build_bar(self): - self.showing_donate = False - showing_device = self.location_manager.has_device - mactions = '-device' if showing_device else '' - mactions = gprefs['action-layout-toolbar'+mactions] - cactions = gprefs['action-layout-toolbar-child'] - - show_main = len(mactions) > 0 - self.setVisible(show_main) - show_child = len(cactions) > 0 - self.child_bar.setVisible(show_child) - - for ac in self.added_actions: - m = ac.menu() - if m is not None: - m.setVisible(False) - - self.clear() - self.child_bar.clear() - self.added_actions = [] - - for bar, actions in ((self, mactions), (self.child_bar, cactions)): - for what in actions: - if what is None: - bar.addSeparator() - elif what == 'Location Manager': - for ac in self.location_manager.available_actions: - bar.addAction(ac) - bar.added_actions.append(ac) - bar.setup_tool_button(bar, ac, QToolButton.MenuButtonPopup) - elif what == 'Donate': - self.d_widget = QWidget() - self.d_widget.setLayout(QVBoxLayout()) - self.d_widget.layout().addWidget(self.donate_button) - if isosx: - self.d_widget.setStyleSheet('QWidget, QToolButton {background-color: none; border: none; }') - self.d_widget.layout().setContentsMargins(0,0,0,0) - self.d_widget.setContentsMargins(0,0,0,0) - self.d_widget.filler = QLabel(u'\u00a0') - self.d_widget.layout().addWidget(self.d_widget.filler) - bar.addWidget(self.d_widget) - self.showing_donate = True - elif what in self.gui.iactions: - action = self.gui.iactions[what] - bar.addAction(action.qaction) - self.added_actions.append(action.qaction) - self.setup_tool_button(bar, action.qaction, action.popup_type) - self.preferred_width = self.sizeHint().width() - self.child_bar.preferred_width = self.child_bar.sizeHint().width() - - def setup_tool_button(self, bar, ac, menu_mode=None): - ch = bar.widgetForAction(ac) - if ch is None: - ch = self.child_bar.widgetForAction(ac) - ch.setCursor(Qt.PointingHandCursor) - ch.setAutoRaise(True) - if ac.menu() is not None and menu_mode is not None: - ch.setPopupMode(menu_mode) - return ch - - def database_changed(self, db): - pass - - #support drag&drop from/to library from/to reader/card - def dragEnterEvent(self, event): - md = event.mimeData() - if md.hasFormat("application/calibre+from_library") or \ - md.hasFormat("application/calibre+from_device"): - event.setDropAction(Qt.CopyAction) - event.accept() - else: - event.ignore() - - def dragMoveEvent(self, event): - allowed = False - md = event.mimeData() - #Drop is only allowed in the location manager widget's different from the selected one - for ac in self.location_manager.available_actions: - w = self.widgetForAction(ac) - if w is not None: - if ( md.hasFormat("application/calibre+from_library") or \ - md.hasFormat("application/calibre+from_device") ) and \ - w.geometry().contains(event.pos()) and \ - isinstance(w, QToolButton) and not w.isChecked(): - allowed = True - break - if allowed: - event.acceptProposedAction() - else: - event.ignore() - - def dropEvent(self, event): - data = event.mimeData() - - mime = 'application/calibre+from_library' - if data.hasFormat(mime): - ids = list(map(int, str(data.data(mime)).split())) - tgt = None - for ac in self.location_manager.available_actions: - w = self.widgetForAction(ac) - if w is not None and w.geometry().contains(event.pos()): - tgt = ac.calibre_name - if tgt is not None: - if tgt == 'main': - tgt = None - self.gui.sync_to_device(tgt, False, send_ids=ids) - event.accept() - - mime = 'application/calibre+from_device' - if data.hasFormat(mime): - paths = [unicode(u.toLocalFile()) for u in data.urls()] - if paths: - self.gui.iactions['Add Books'].add_books_from_device( - self.gui.current_view(), paths=paths) - event.accept() - -# }}} class MainWindowMixin(object): # {{{ @@ -507,13 +257,13 @@ class MainWindowMixin(object): # {{{ self.iactions['Fetch News'].init_scheduler(db) self.search_bar = SearchBar(self) - self.child_bar = BaseToolBar(self) - self.tool_bar = ToolBar(self.donate_button, - self.location_manager, self.child_bar, self) - self.addToolBar(Qt.TopToolBarArea, self.tool_bar) - self.addToolBar(Qt.BottomToolBarArea, self.child_bar) - self.menu_bar = MenuBar(self.location_manager, self) - self.setMenuBar(self.menu_bar) + self.bars_manager = BarsManager(self.donate_button, + self.location_manager, self) + for bar in self.bars_manager.main_bars: + self.addToolBar(Qt.TopToolBarArea, bar) + for bar in self.bars_manager.child_bars: + self.addToolBar(Qt.BottomToolBarArea, bar) + self.bars_manager.update_bars() self.setUnifiedTitleAndToolBarOnMac(True) l = self.centralwidget.layout() diff --git a/src/calibre/gui2/preferences/main.py b/src/calibre/gui2/preferences/main.py index c5f9a11d16..85a5fc018c 100644 --- a/src/calibre/gui2/preferences/main.py +++ b/src/calibre/gui2/preferences/main.py @@ -361,10 +361,9 @@ class Preferences(QMainWindow): self.gui.tags_view.recount() self.gui.create_device_menu() self.gui.set_device_menu_items_state(bool(self.gui.device_connected)) - self.gui.tool_bar.build_bar() - self.gui.menu_bar.build_bar() + self.gui.bars_manager.apply_settings() + self.gui.bars_manager.update_bars() self.gui.build_context_menus() - self.gui.tool_bar.apply_settings() return QMainWindow.closeEvent(self, *args) diff --git a/src/calibre/gui2/preferences/toolbar.py b/src/calibre/gui2/preferences/toolbar.py index 7f5e0c4441..04ddb29170 100644 --- a/src/calibre/gui2/preferences/toolbar.py +++ b/src/calibre/gui2/preferences/toolbar.py @@ -317,6 +317,9 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): am.restore_defaults() self.changed_signal.emit() + def refresh_gui(self, gui): + gui.bars_manager.init_bars() + if __name__ == '__main__': from PyQt4.Qt import QApplication diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py index 435b9ebe78..122bfc81b4 100644 --- a/src/calibre/gui2/ui.py +++ b/src/calibre/gui2/ui.py @@ -288,8 +288,8 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{ self.db_images.reset() self.library_view.model().count_changed() - self.tool_bar.database_changed(self.library_view.model().db) - self.library_view.model().database_changed.connect(self.tool_bar.database_changed, + self.bars_manager.database_changed(self.library_view.model().db) + self.library_view.model().database_changed.connect(self.bars_manager.database_changed, type=Qt.QueuedConnection) ########################### Tags Browser ############################## @@ -324,7 +324,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{ self.read_settings() self.finalize_layout() - if self.tool_bar.showing_donate: + if self.bars_manager.showing_donate: self.donate_button.start_animation() self.set_window_title()