mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Allow auto hiding popup questions
This commit is contained in:
parent
7fe6b7dfe5
commit
019e9435fb
@ -6,11 +6,12 @@ __copyright__ = '2012, Kovid Goyal <kovid@kovidgoyal.net>'
|
|||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
from qt.core import (
|
from qt.core import (
|
||||||
QWidget, Qt, QLabel, QVBoxLayout, QDialogButtonBox, QApplication, QTimer, QPixmap, QEvent,
|
QApplication, QCheckBox, QDialogButtonBox, QEasingCurve, QEvent, QFontMetrics,
|
||||||
QSize, pyqtSignal, QIcon, QPlainTextEdit, QCheckBox, QPainter, QHBoxLayout, QFontMetrics,
|
QHBoxLayout, QIcon, QImage, QLabel, QPainter, QPainterPath, QPalette, QPixmap,
|
||||||
QPainterPath, QRectF, pyqtProperty, QPropertyAnimation, QEasingCurve, QSizePolicy, QImage, QPalette)
|
QPlainTextEdit, QPropertyAnimation, QRectF, QSize, QSizePolicy, Qt, QTimer,
|
||||||
|
QVBoxLayout, QWidget, pyqtProperty, pyqtSignal, sip,
|
||||||
|
)
|
||||||
|
|
||||||
from calibre.constants import __version__
|
from calibre.constants import __version__
|
||||||
from calibre.gui2.dialogs.message_box import ViewLog
|
from calibre.gui2.dialogs.message_box import ViewLog
|
||||||
@ -19,7 +20,7 @@ Question = namedtuple('Question', 'payload callback cancel_callback '
|
|||||||
'title msg html_log log_viewer_title log_is_file det_msg '
|
'title msg html_log log_viewer_title log_is_file det_msg '
|
||||||
'show_copy_button checkbox_msg checkbox_checked action_callback '
|
'show_copy_button checkbox_msg checkbox_checked action_callback '
|
||||||
'action_label action_icon focus_action show_det show_ok icon '
|
'action_label action_icon focus_action show_det show_ok icon '
|
||||||
'log_viewer_unique_name')
|
'log_viewer_unique_name auto_hide_after')
|
||||||
|
|
||||||
|
|
||||||
class Icon(QWidget):
|
class Icon(QWidget):
|
||||||
@ -95,6 +96,7 @@ class ProceedQuestion(QWidget):
|
|||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
QWidget.__init__(self, parent)
|
QWidget.__init__(self, parent)
|
||||||
self.setVisible(False)
|
self.setVisible(False)
|
||||||
|
self.auto_hide_timer = None
|
||||||
parent.installEventFilter(self)
|
parent.installEventFilter(self)
|
||||||
|
|
||||||
self._show_fraction = 0.0
|
self._show_fraction = 0.0
|
||||||
@ -181,6 +183,7 @@ class ProceedQuestion(QWidget):
|
|||||||
self.accept()
|
self.accept()
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
|
self.cancel_auto_hide()
|
||||||
if self.questions:
|
if self.questions:
|
||||||
payload, callback, cancel_callback = self.questions[0][:3]
|
payload, callback, cancel_callback = self.questions[0][:3]
|
||||||
self.questions = self.questions[1:]
|
self.questions = self.questions[1:]
|
||||||
@ -191,6 +194,7 @@ class ProceedQuestion(QWidget):
|
|||||||
self.hide()
|
self.hide()
|
||||||
|
|
||||||
def reject(self):
|
def reject(self):
|
||||||
|
self.cancel_auto_hide()
|
||||||
if self.questions:
|
if self.questions:
|
||||||
payload, callback, cancel_callback = self.questions[0][:3]
|
payload, callback, cancel_callback = self.questions[0][:3]
|
||||||
self.questions = self.questions[1:]
|
self.questions = self.questions[1:]
|
||||||
@ -223,10 +227,16 @@ class ProceedQuestion(QWidget):
|
|||||||
self.resize(sz)
|
self.resize(sz)
|
||||||
self.position_widget()
|
self.position_widget()
|
||||||
|
|
||||||
|
def cancel_auto_hide(self):
|
||||||
|
if self.auto_hide_timer is not None:
|
||||||
|
self.auto_hide_timer.stop()
|
||||||
|
self.auto_hide_timer = None
|
||||||
|
|
||||||
def show_question(self):
|
def show_question(self):
|
||||||
if not self.questions:
|
if not self.questions:
|
||||||
return
|
return
|
||||||
if not self.isVisible():
|
if not self.isVisible():
|
||||||
|
self.cancel_auto_hide()
|
||||||
question = self.questions[0]
|
question = self.questions[0]
|
||||||
self.msg_label.setText(question.msg)
|
self.msg_label.setText(question.msg)
|
||||||
self.icon.set_icon(question.icon)
|
self.icon.set_icon(question.icon)
|
||||||
@ -260,6 +270,16 @@ class ProceedQuestion(QWidget):
|
|||||||
button.setDefault(True)
|
button.setDefault(True)
|
||||||
self.raise_()
|
self.raise_()
|
||||||
self.start_show_animation()
|
self.start_show_animation()
|
||||||
|
if question.auto_hide_after > 0:
|
||||||
|
self.auto_hide_timer = t = QTimer(self)
|
||||||
|
t.setSingleShot(True)
|
||||||
|
t.timeout.connect(self.auto_hide)
|
||||||
|
t.start(1000 * question.auto_hide_after)
|
||||||
|
|
||||||
|
def auto_hide(self):
|
||||||
|
self.auto_hide_timer = None
|
||||||
|
if not sip.isdeleted(self) and self.isVisible():
|
||||||
|
self.reject()
|
||||||
|
|
||||||
def start_show_animation(self):
|
def start_show_animation(self):
|
||||||
if self.rendered_pixmap is not None:
|
if self.rendered_pixmap is not None:
|
||||||
@ -307,18 +327,21 @@ class ProceedQuestion(QWidget):
|
|||||||
self.show()
|
self.show()
|
||||||
self.position_widget()
|
self.position_widget()
|
||||||
|
|
||||||
def dummy_question(self, action_label=None):
|
def dummy_question(self, action_label=None, auto_hide_after=0):
|
||||||
self(lambda *args:args, (), 'dummy log', 'Log Viewer', 'A Dummy Popup',
|
self(lambda *args:args, (), 'dummy log', 'Log Viewer', 'A Dummy Popup',
|
||||||
'This is a dummy popup to easily test things, with a long line of text that should wrap. '
|
'This is a dummy popup to easily test things, with a long line of text that should wrap. '
|
||||||
'This is a dummy popup to easily test things, with a long line of text that should wrap',
|
'This is a dummy popup to easily test things, with a long line of text that should wrap',
|
||||||
checkbox_msg='A dummy checkbox',
|
checkbox_msg='A dummy checkbox', auto_hide_after=auto_hide_after,
|
||||||
action_callback=lambda *args: args, action_label=action_label or 'An action')
|
action_callback=lambda *args: args, action_label=action_label or 'An action')
|
||||||
|
|
||||||
def __call__(self, callback, payload, html_log, log_viewer_title, title,
|
def __call__(
|
||||||
msg, det_msg='', show_copy_button=False, cancel_callback=None,
|
self, callback, payload, html_log, log_viewer_title, title,
|
||||||
log_is_file=False, checkbox_msg=None, checkbox_checked=False,
|
msg, det_msg='', show_copy_button=False, cancel_callback=None,
|
||||||
action_callback=None, action_label=None, action_icon=None, focus_action=False,
|
log_is_file=False, checkbox_msg=None, checkbox_checked=False, auto_hide_after=0,
|
||||||
show_det=False, show_ok=False, icon=None, log_viewer_unique_name=None, **kw):
|
action_callback=None, action_label=None, action_icon=None, focus_action=False,
|
||||||
|
show_det=False, show_ok=False, icon=None, log_viewer_unique_name=None,
|
||||||
|
**kw
|
||||||
|
):
|
||||||
'''
|
'''
|
||||||
A non modal popup that notifies the user that a background task has
|
A non modal popup that notifies the user that a background task has
|
||||||
been completed. This class guarantees that only a single popup is
|
been completed. This class guarantees that only a single popup is
|
||||||
@ -343,6 +366,7 @@ class ProceedQuestion(QWidget):
|
|||||||
called with both the payload and the state of the
|
called with both the payload and the state of the
|
||||||
checkbox as arguments.
|
checkbox as arguments.
|
||||||
:param checkbox_checked: If True the checkbox is checked by default.
|
:param checkbox_checked: If True the checkbox is checked by default.
|
||||||
|
:param auto_hide_after: Number of seconds to automatically cancel this question after. Zero or less for no auto hide.
|
||||||
:param action_callback: If not None, an extra button is added, which
|
:param action_callback: If not None, an extra button is added, which
|
||||||
when clicked will cause action_callback to be called
|
when clicked will cause action_callback to be called
|
||||||
instead of callback. action_callback is called in
|
instead of callback. action_callback is called in
|
||||||
@ -359,7 +383,7 @@ class ProceedQuestion(QWidget):
|
|||||||
payload, callback, cancel_callback, title, msg, html_log,
|
payload, callback, cancel_callback, title, msg, html_log,
|
||||||
log_viewer_title, log_is_file, det_msg, show_copy_button,
|
log_viewer_title, log_is_file, det_msg, show_copy_button,
|
||||||
checkbox_msg, checkbox_checked, action_callback, action_label,
|
checkbox_msg, checkbox_checked, action_callback, action_label,
|
||||||
action_icon, focus_action, show_det, show_ok, icon, log_viewer_unique_name)
|
action_icon, focus_action, show_det, show_ok, icon, log_viewer_unique_name, auto_hide_after)
|
||||||
self.questions.append(question)
|
self.questions.append(question)
|
||||||
self.show_question()
|
self.show_question()
|
||||||
|
|
||||||
@ -403,8 +427,9 @@ class ProceedQuestion(QWidget):
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
from calibre.gui2 import Application
|
|
||||||
from qt.core import QMainWindow, QStatusBar, QTimer
|
from qt.core import QMainWindow, QStatusBar, QTimer
|
||||||
|
|
||||||
|
from calibre.gui2 import Application
|
||||||
app = Application([])
|
app = Application([])
|
||||||
w = QMainWindow()
|
w = QMainWindow()
|
||||||
s = QStatusBar(w)
|
s = QStatusBar(w)
|
||||||
@ -414,6 +439,10 @@ def main():
|
|||||||
p = ProceedQuestion(w)
|
p = ProceedQuestion(w)
|
||||||
|
|
||||||
def doit():
|
def doit():
|
||||||
|
p(
|
||||||
|
lambda p:None, None, 'ass2', 'ass2', 'testing auto hide', 'this popup will auto hide after 2 seconds',
|
||||||
|
auto_hide_after=2,
|
||||||
|
)
|
||||||
p.dummy_question()
|
p.dummy_question()
|
||||||
p.dummy_question(action_label='A very long button for testing relayout (indeed)')
|
p.dummy_question(action_label='A very long button for testing relayout (indeed)')
|
||||||
p(
|
p(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user