mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fix #780484 (Intermittent crash when disconnect with dialog open)
This commit is contained in:
parent
5317f8bb9c
commit
b0c0d40e6f
309
src/calibre/gui2/bars.py
Normal file
309
src/calibre/gui2/bars.py
Normal file
@ -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 <kovid@kovidgoyal.net>'
|
||||||
|
__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)
|
||||||
|
|
||||||
|
|
@ -751,6 +751,7 @@ class DeviceMixin(object): # {{{
|
|||||||
if self.current_view() != self.library_view:
|
if self.current_view() != self.library_view:
|
||||||
self.book_details.reset_info()
|
self.book_details.reset_info()
|
||||||
self.location_manager.update_devices()
|
self.location_manager.update_devices()
|
||||||
|
self.bars_manager.update_bars()
|
||||||
self.library_view.set_device_connected(self.device_connected)
|
self.library_view.set_device_connected(self.device_connected)
|
||||||
self.refresh_ondevice()
|
self.refresh_ondevice()
|
||||||
device_signals.device_connection_changed.emit(connected)
|
device_signals.device_connection_changed.emit(connected)
|
||||||
@ -1198,6 +1199,7 @@ class DeviceMixin(object): # {{{
|
|||||||
cp, fs = job.result
|
cp, fs = job.result
|
||||||
self.location_manager.update_devices(cp, fs,
|
self.location_manager.update_devices(cp, fs,
|
||||||
self.device_manager.device.icon)
|
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
|
# reset the views so that up-to-date info is shown. These need to be
|
||||||
# here because some drivers update collections in sync_booklists
|
# here because some drivers update collections in sync_booklists
|
||||||
self.memory_view.reset()
|
self.memory_view.reset()
|
||||||
|
@ -7,15 +7,15 @@ __docformat__ = 'restructuredtext en'
|
|||||||
|
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from PyQt4.Qt import (QIcon, Qt, QWidget, QToolBar, QSize,
|
from PyQt4.Qt import (QIcon, Qt, QWidget, QSize,
|
||||||
pyqtSignal, QToolButton, QMenu, QMenuBar, QAction,
|
pyqtSignal, QToolButton, QMenu,
|
||||||
QObject, QVBoxLayout, QSizePolicy, QLabel, QHBoxLayout, QActionGroup)
|
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.search_box import SearchBox2, SavedSearchBox
|
||||||
from calibre.gui2.throbber import ThrobbingButton
|
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.gui2.widgets import ComboBoxWithHelp
|
||||||
from calibre import human_readable
|
from calibre import human_readable
|
||||||
|
|
||||||
@ -35,6 +35,8 @@ class LocationManager(QObject): # {{{
|
|||||||
self._mem = []
|
self._mem = []
|
||||||
self.tooltips = {}
|
self.tooltips = {}
|
||||||
|
|
||||||
|
self.all_actions = []
|
||||||
|
|
||||||
def ac(name, text, icon, tooltip):
|
def ac(name, text, icon, tooltip):
|
||||||
icon = QIcon(I(icon))
|
icon = QIcon(I(icon))
|
||||||
ac = self.location_actions.addAction(icon, text)
|
ac = self.location_actions.addAction(icon, text)
|
||||||
@ -59,6 +61,7 @@ class LocationManager(QObject): # {{{
|
|||||||
ac.setMenu(m)
|
ac.setMenu(m)
|
||||||
ac.calibre_name = name
|
ac.calibre_name = name
|
||||||
|
|
||||||
|
self.all_actions.append(ac)
|
||||||
return ac
|
return ac
|
||||||
|
|
||||||
self.library_action = ac('library', _('Library'), 'lt.png',
|
self.library_action = ac('library', _('Library'), 'lt.png',
|
||||||
@ -234,259 +237,6 @@ class Spacer(QWidget): # {{{
|
|||||||
self.l.addStretch(10)
|
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): # {{{
|
class MainWindowMixin(object): # {{{
|
||||||
|
|
||||||
@ -507,13 +257,13 @@ class MainWindowMixin(object): # {{{
|
|||||||
self.iactions['Fetch News'].init_scheduler(db)
|
self.iactions['Fetch News'].init_scheduler(db)
|
||||||
|
|
||||||
self.search_bar = SearchBar(self)
|
self.search_bar = SearchBar(self)
|
||||||
self.child_bar = BaseToolBar(self)
|
self.bars_manager = BarsManager(self.donate_button,
|
||||||
self.tool_bar = ToolBar(self.donate_button,
|
self.location_manager, self)
|
||||||
self.location_manager, self.child_bar, self)
|
for bar in self.bars_manager.main_bars:
|
||||||
self.addToolBar(Qt.TopToolBarArea, self.tool_bar)
|
self.addToolBar(Qt.TopToolBarArea, bar)
|
||||||
self.addToolBar(Qt.BottomToolBarArea, self.child_bar)
|
for bar in self.bars_manager.child_bars:
|
||||||
self.menu_bar = MenuBar(self.location_manager, self)
|
self.addToolBar(Qt.BottomToolBarArea, bar)
|
||||||
self.setMenuBar(self.menu_bar)
|
self.bars_manager.update_bars()
|
||||||
self.setUnifiedTitleAndToolBarOnMac(True)
|
self.setUnifiedTitleAndToolBarOnMac(True)
|
||||||
|
|
||||||
l = self.centralwidget.layout()
|
l = self.centralwidget.layout()
|
||||||
|
@ -361,10 +361,9 @@ class Preferences(QMainWindow):
|
|||||||
self.gui.tags_view.recount()
|
self.gui.tags_view.recount()
|
||||||
self.gui.create_device_menu()
|
self.gui.create_device_menu()
|
||||||
self.gui.set_device_menu_items_state(bool(self.gui.device_connected))
|
self.gui.set_device_menu_items_state(bool(self.gui.device_connected))
|
||||||
self.gui.tool_bar.build_bar()
|
self.gui.bars_manager.apply_settings()
|
||||||
self.gui.menu_bar.build_bar()
|
self.gui.bars_manager.update_bars()
|
||||||
self.gui.build_context_menus()
|
self.gui.build_context_menus()
|
||||||
self.gui.tool_bar.apply_settings()
|
|
||||||
|
|
||||||
return QMainWindow.closeEvent(self, *args)
|
return QMainWindow.closeEvent(self, *args)
|
||||||
|
|
||||||
|
@ -317,6 +317,9 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
am.restore_defaults()
|
am.restore_defaults()
|
||||||
self.changed_signal.emit()
|
self.changed_signal.emit()
|
||||||
|
|
||||||
|
def refresh_gui(self, gui):
|
||||||
|
gui.bars_manager.init_bars()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from PyQt4.Qt import QApplication
|
from PyQt4.Qt import QApplication
|
||||||
|
@ -288,8 +288,8 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
|
|||||||
self.db_images.reset()
|
self.db_images.reset()
|
||||||
|
|
||||||
self.library_view.model().count_changed()
|
self.library_view.model().count_changed()
|
||||||
self.tool_bar.database_changed(self.library_view.model().db)
|
self.bars_manager.database_changed(self.library_view.model().db)
|
||||||
self.library_view.model().database_changed.connect(self.tool_bar.database_changed,
|
self.library_view.model().database_changed.connect(self.bars_manager.database_changed,
|
||||||
type=Qt.QueuedConnection)
|
type=Qt.QueuedConnection)
|
||||||
|
|
||||||
########################### Tags Browser ##############################
|
########################### Tags Browser ##############################
|
||||||
@ -324,7 +324,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
|
|||||||
|
|
||||||
self.read_settings()
|
self.read_settings()
|
||||||
self.finalize_layout()
|
self.finalize_layout()
|
||||||
if self.tool_bar.showing_donate:
|
if self.bars_manager.showing_donate:
|
||||||
self.donate_button.start_animation()
|
self.donate_button.start_animation()
|
||||||
self.set_window_title()
|
self.set_window_title()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user