'
+__docformat__ = 'restructuredtext en'
+
+
+from PyQt4.Qt import QToolButton, QSize, QPropertyAnimation, Qt, \
+ QMetaObject
+
+from calibre.gui2 import config
+
+class ThrobbingButton(QToolButton):
+
+ def __init__(self, *args):
+ QToolButton.__init__(self, *args)
+ self.animation = QPropertyAnimation(self, 'iconSize', self)
+ self.animation.setDuration(60/72.*1000)
+ self.animation.setLoopCount(4)
+ self.normal_icon_size = QSize(64, 64)
+ self.animation.valueChanged.connect(self.value_changed)
+ self.setCursor(Qt.PointingHandCursor)
+ self.animation.finished.connect(self.animation_finished)
+
+ def set_normal_icon_size(self, w, h):
+ self.normal_icon_size = QSize(w, h)
+ self.setIconSize(self.normal_icon_size)
+ self.setMinimumSize(self.sizeHint())
+
+ def animation_finished(self):
+ self.setIconSize(self.normal_icon_size)
+
+ def enterEvent(self, ev):
+ self.start_animation()
+
+ def leaveEvent(self, ev):
+ self.stop_animation()
+
+ def value_changed(self, val):
+ self.update()
+
+ def start_animation(self):
+ if config['disable_animations']: return
+ if self.animation.state() != self.animation.Stopped or not self.isVisible():
+ return
+ size = self.normal_icon_size.width()
+ smaller = int(0.7 * size)
+ self.animation.setStartValue(QSize(smaller, smaller))
+ self.animation.setEndValue(self.normal_icon_size)
+ QMetaObject.invokeMethod(self.animation, 'start', Qt.QueuedConnection)
+
+ def stop_animation(self):
+ self.animation.stop()
+ self.animation_finished()
+
+
+if __name__ == '__main__':
+ from PyQt4.Qt import QApplication, QWidget, QHBoxLayout, QIcon
+ app = QApplication([])
+ w = QWidget()
+ w.setLayout(QHBoxLayout())
+ b = ThrobbingButton()
+ b.setIcon(QIcon(I('donate.svg')))
+ w.layout().addWidget(b)
+ w.show()
+ b.set_normal_icon_size(64, 64)
+ b.start_animation()
+
+ app.exec_()
diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py
index 756e375e23..709f91da25 100644
--- a/src/calibre/gui2/ui.py
+++ b/src/calibre/gui2/ui.py
@@ -19,7 +19,7 @@ from PyQt4.Qt import Qt, SIGNAL, QObject, QTimer, \
QMessageBox, QHelpEvent
from calibre import prints, patheq
-from calibre.constants import __version__, __appname__, isosx
+from calibre.constants import __appname__, isosx
from calibre.ptempfile import PersistentTemporaryFile
from calibre.utils.config import prefs, dynamic
from calibre.utils.ipc.server import Server
@@ -163,6 +163,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceMixin, ToolbarMixin, # {{{
self.donate_action = self.system_tray_menu.addAction(
QIcon(I('donate.svg')), _('&Donate to support calibre'))
self.donate_button.setDefaultAction(self.donate_action)
+ self.donate_button.setStatusTip(self.donate_button.toolTip())
self.eject_action = self.system_tray_menu.addAction(
QIcon(I('eject.svg')), _('&Eject connected device'))
self.eject_action.setEnabled(False)
@@ -202,18 +203,7 @@ class Main(MainWindow, Ui_MainWindow, DeviceMixin, ToolbarMixin, # {{{
self.device_manager.umount_device)
self.eject_action.triggered.connect(self.device_manager.umount_device)
- ####################### Vanity ########################
- self.vanity_template = _('For help see the: User Manual'
- '
')%'http://calibre-ebook.com/user_manual'
- dv = os.environ.get('CALIBRE_DEVELOP_FROM', None)
- v = __version__
- if getattr(sys, 'frozen', False) and dv and os.path.abspath(dv) in sys.path:
- v += '*'
- self.vanity_template += _('%s: %s by Kovid Goyal '
- '%%(version)s
%%(device)s
')%(__appname__, v)
- self.latest_version = ' '
- self.vanity.setText(self.vanity_template%dict(version=' ', device=' '))
- self.device_info = ' '
+ #################### Update notification ###################
UpdateMixin.__init__(self, opts)
####################### Setup Toolbar #####################
@@ -291,6 +281,8 @@ class Main(MainWindow, Ui_MainWindow, DeviceMixin, ToolbarMixin, # {{{
self.read_settings()
self.finalize_layout()
+ self.donate_button.set_normal_icon_size(64, 64)
+ self.donate_button.start_animation()
def resizeEvent(self, ev):
MainWindow.resizeEvent(self, ev)
diff --git a/src/calibre/gui2/update.py b/src/calibre/gui2/update.py
index 84168d17b5..38612c46f2 100644
--- a/src/calibre/gui2/update.py
+++ b/src/calibre/gui2/update.py
@@ -49,12 +49,8 @@ class UpdateMixin(object):
def update_found(self, version):
os = 'windows' if iswindows else 'osx' if isosx else 'linux'
url = 'http://calibre-ebook.com/download_%s'%os
- self.latest_version = '
' + _(''
- 'Latest version: %s')%(url, version)
- self.vanity.setText(self.vanity_template%\
- (dict(version=self.latest_version,
- device=self.device_info)))
- self.vanity.update()
+ self.status_bar.new_version_available(version, url)
+
if config.get('new_version_notification') and \
dynamic.get('update to version %s'%version, True):
if question_dialog(self, _('Update available'),
diff --git a/src/calibre/gui2/widgets.py b/src/calibre/gui2/widgets.py
index d46c020484..d94d8e7292 100644
--- a/src/calibre/gui2/widgets.py
+++ b/src/calibre/gui2/widgets.py
@@ -298,6 +298,14 @@ class LocationModel(QAbstractListModel):
row = 3
return row
+ def get_tooltip(self, row, drow):
+ ans = self.tooltips[row]
+ if row > 0:
+ fs = self.free[drow-1]
+ if fs > -1:
+ ans += '\n\n%s '%(human_readable(fs)) + _('free')
+ return ans
+
def data(self, index, role):
row = index.row()
drow = self.get_device_row(row)
@@ -308,12 +316,8 @@ class LocationModel(QAbstractListModel):
data = QVariant(text)
elif role == Qt.DecorationRole:
data = self.icons[drow]
- elif role == Qt.ToolTipRole:
- ans = self.tooltips[row]
- if row > 0:
- fs = self.free[drow-1]
- if fs > -1:
- ans += '\n\n%s '%(human_readable(fs)) + _('free')
+ elif role in (Qt.ToolTipRole, Qt.StatusTipRole):
+ ans = self.get_tooltip(row, drow)
data = QVariant(ans)
elif role == Qt.SizeHintRole:
data = QVariant(QSize(155, 90))
@@ -1011,12 +1015,14 @@ class LayoutButton(QToolButton):
label =_('Show')
self.setText(label + ' ' + self.label)
self.setToolTip(self.text())
+ self.setStatusTip(self.text())
def set_state_to_hide(self, *args):
self.setChecked(True)
label = _('Hide')
self.setText(label + ' ' + self.label)
self.setToolTip(self.text())
+ self.setStatusTip(self.text())
def update_state(self, *args):
if self.splitter.is_side_index_hidden: