Fix #6540 (Requesting metadata download while one is already ongoing causes pop-up spam)

This commit is contained in:
Kovid Goyal 2010-08-17 16:55:52 -06:00
parent 7692482955
commit 47fa5382b6
4 changed files with 258 additions and 221 deletions

View File

@ -16,6 +16,7 @@ from calibre.gui2.dialogs.metadata_bulk import MetadataBulkDialog
from calibre.gui2.dialogs.confirm_delete import confirm from calibre.gui2.dialogs.confirm_delete import confirm
from calibre.gui2.dialogs.tag_list_editor import TagListEditor from calibre.gui2.dialogs.tag_list_editor import TagListEditor
from calibre.gui2.actions import InterfaceAction from calibre.gui2.actions import InterfaceAction
from calibre.gui2.dialogs.progress import BlockingBusy
class EditMetadataAction(InterfaceAction): class EditMetadataAction(InterfaceAction):
@ -95,18 +96,19 @@ class EditMetadataAction(InterfaceAction):
x = _('social metadata') x = _('social metadata')
else: else:
x = _('covers') if covers and not set_metadata else _('metadata') x = _('covers') if covers and not set_metadata else _('metadata')
self.gui.progress_indicator.start(
_('Downloading %s for %d book(s)')%(x, len(ids)))
self._book_metadata_download_check = QTimer(self.gui) self._book_metadata_download_check = QTimer(self.gui)
self._book_metadata_download_check.timeout.connect(self.book_metadata_download_check, self._book_metadata_download_check.timeout.connect(self.book_metadata_download_check,
type=Qt.QueuedConnection) type=Qt.QueuedConnection)
self._book_metadata_download_check.start(100) self._book_metadata_download_check.start(100)
self._bb_dialog = BlockingBusy(_('Downloading %s for %d book(s)')%(x,
len(ids)), parent=self.gui)
self._bb_dialog.exec_()
def book_metadata_download_check(self): def book_metadata_download_check(self):
if self._download_book_metadata.is_alive(): if self._download_book_metadata.is_alive():
return return
self._book_metadata_download_check.stop() self._book_metadata_download_check.stop()
self.gui.progress_indicator.stop() self._bb_dialog.accept()
cr = self.gui.library_view.currentIndex().row() cr = self.gui.library_view.currentIndex().row()
x = self._download_book_metadata x = self._download_book_metadata
self._download_book_metadata = None self._download_book_metadata = None

View File

@ -5,9 +5,10 @@ __docformat__ = 'restructuredtext en'
'''''' ''''''
from PyQt4.Qt import QDialog, pyqtSignal, Qt from PyQt4.Qt import QDialog, pyqtSignal, Qt, QVBoxLayout, QLabel, QFont
from calibre.gui2.dialogs.progress_ui import Ui_Dialog from calibre.gui2.dialogs.progress_ui import Ui_Dialog
from calibre.gui2.progress_indicator import ProgressIndicator
class ProgressDialog(QDialog, Ui_Dialog): class ProgressDialog(QDialog, Ui_Dialog):
@ -69,3 +70,37 @@ class ProgressDialog(QDialog, Ui_Dialog):
self._canceled() self._canceled()
else: else:
QDialog.keyPressEvent(self, ev) QDialog.keyPressEvent(self, ev)
class BlockingBusy(QDialog):
def __init__(self, msg, parent=None, window_title=_('Working')):
QDialog.__init__(self, parent)
self._layout = QVBoxLayout()
self.setLayout(self._layout)
self.msg = QLabel(msg)
#self.msg.setWordWrap(True)
self.font = QFont()
self.font.setPointSize(self.font.pointSize() + 8)
self.msg.setFont(self.font)
self.pi = ProgressIndicator(self)
self.pi.setDisplaySize(100)
self._layout.addWidget(self.pi, 0, Qt.AlignHCenter)
self._layout.addSpacing(15)
self._layout.addWidget(self.msg, 0, Qt.AlignHCenter)
self.start()
self.setWindowTitle(window_title)
self.resize(self.sizeHint())
def start(self):
self.pi.startAnimation()
def stop(self):
self.pi.stopAnimation()
def accept(self):
self.stop()
return QDialog.accept(self)
def reject(self):
pass # Cannot cancel this dialog

View File

@ -1,124 +1,124 @@
#include "QProgressIndicator.h" #include "QProgressIndicator.h"
#include <QPainter> #include <QPainter>
QProgressIndicator::QProgressIndicator(QWidget* parent, int size) QProgressIndicator::QProgressIndicator(QWidget* parent, int size)
: QWidget(parent), : QWidget(parent),
m_angle(0), m_angle(0),
m_timerId(-1), m_timerId(-1),
m_delay(80), m_delay(80),
m_displayedWhenStopped(true), m_displayedWhenStopped(true),
m_displaySize(size), m_displaySize(size),
m_color(Qt::black) m_color(Qt::black)
{ {
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
setFocusPolicy(Qt::NoFocus); setFocusPolicy(Qt::NoFocus);
} }
bool QProgressIndicator::isAnimated () const bool QProgressIndicator::isAnimated () const
{ {
return (m_timerId != -1); return (m_timerId != -1);
} }
void QProgressIndicator::setDisplayedWhenStopped(bool state) void QProgressIndicator::setDisplayedWhenStopped(bool state)
{ {
m_displayedWhenStopped = state; m_displayedWhenStopped = state;
update(); update();
} }
void QProgressIndicator::setDisplaySize(int size) void QProgressIndicator::setDisplaySize(int size)
{ {
m_displaySize = size; m_displaySize = size;
update(); update();
} }
bool QProgressIndicator::isDisplayedWhenStopped() const bool QProgressIndicator::isDisplayedWhenStopped() const
{ {
return m_displayedWhenStopped; return m_displayedWhenStopped;
} }
void QProgressIndicator::startAnimation() void QProgressIndicator::startAnimation()
{ {
m_angle = 0; m_angle = 0;
if (m_timerId == -1) if (m_timerId == -1)
m_timerId = startTimer(m_delay); m_timerId = startTimer(m_delay);
} }
void QProgressIndicator::stopAnimation() void QProgressIndicator::stopAnimation()
{ {
if (m_timerId != -1) if (m_timerId != -1)
killTimer(m_timerId); killTimer(m_timerId);
m_timerId = -1; m_timerId = -1;
update(); update();
} }
void QProgressIndicator::setAnimationDelay(int delay) void QProgressIndicator::setAnimationDelay(int delay)
{ {
if (m_timerId != -1) if (m_timerId != -1)
killTimer(m_timerId); killTimer(m_timerId);
m_delay = delay; m_delay = delay;
if (m_timerId != -1) if (m_timerId != -1)
m_timerId = startTimer(m_delay); m_timerId = startTimer(m_delay);
} }
void QProgressIndicator::setColor(const QColor & color) void QProgressIndicator::setColor(const QColor & color)
{ {
m_color = color; m_color = color;
update(); update();
} }
QSize QProgressIndicator::sizeHint() const QSize QProgressIndicator::sizeHint() const
{ {
return QSize(m_displaySize, m_displaySize); return QSize(m_displaySize, m_displaySize);
} }
int QProgressIndicator::heightForWidth(int w) const int QProgressIndicator::heightForWidth(int w) const
{ {
return w; return w;
} }
void QProgressIndicator::timerEvent(QTimerEvent * /*event*/) void QProgressIndicator::timerEvent(QTimerEvent * /*event*/)
{ {
m_angle = (m_angle+30)%360; m_angle = (m_angle+30)%360;
update(); update();
} }
void QProgressIndicator::paintEvent(QPaintEvent * /*event*/) void QProgressIndicator::paintEvent(QPaintEvent * /*event*/)
{ {
if (!m_displayedWhenStopped && !isAnimated()) if (!m_displayedWhenStopped && !isAnimated())
return; return;
int width = qMin(this->width(), this->height()); int width = qMin(this->width(), this->height());
QPainter p(this); QPainter p(this);
p.setRenderHint(QPainter::Antialiasing); p.setRenderHint(QPainter::Antialiasing);
int outerRadius = (width-1)*0.5; int outerRadius = (width-1)*0.5;
int innerRadius = (width-1)*0.5*0.38; int innerRadius = (width-1)*0.5*0.38;
int capsuleHeight = outerRadius - innerRadius; int capsuleHeight = outerRadius - innerRadius;
int capsuleWidth = (width > 32 ) ? capsuleHeight *.23 : capsuleHeight *.35; int capsuleWidth = (width > 32 ) ? capsuleHeight *.23 : capsuleHeight *.35;
int capsuleRadius = capsuleWidth/2; int capsuleRadius = capsuleWidth/2;
for (int i=0; i<12; i++) for (int i=0; i<12; i++)
{ {
QColor color = m_color; QColor color = m_color;
color.setAlphaF(1.0f - (i/12.0f)); color.setAlphaF(1.0f - (i/12.0f));
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
p.setBrush(color); p.setBrush(color);
p.save(); p.save();
p.translate(rect().center()); p.translate(rect().center());
p.rotate(m_angle - i*30.0f); p.rotate(m_angle - i*30.0f);
p.drawRoundedRect(-capsuleWidth*0.5, -(innerRadius+capsuleHeight), capsuleWidth, capsuleHeight, capsuleRadius, capsuleRadius); p.drawRoundedRect(-capsuleWidth*0.5, -(innerRadius+capsuleHeight), capsuleWidth, capsuleHeight, capsuleRadius, capsuleRadius);
p.restore(); p.restore();
} }
} }

View File

@ -1,93 +1,93 @@
#pragma once #pragma once
#include <QWidget> #include <QWidget>
#include <QColor> #include <QColor>
/*! /*!
\class QProgressIndicator \class QProgressIndicator
\brief The QProgressIndicator class lets an application display a progress indicator to show that a lengthy task is under way. \brief The QProgressIndicator class lets an application display a progress indicator to show that a lengthy task is under way.
Progress indicators are indeterminate and do nothing more than spin to show that the application is busy. Progress indicators are indeterminate and do nothing more than spin to show that the application is busy.
\sa QProgressBar \sa QProgressBar
*/ */
class QProgressIndicator : public QWidget class QProgressIndicator : public QWidget
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(int delay READ animationDelay WRITE setAnimationDelay) Q_PROPERTY(int delay READ animationDelay WRITE setAnimationDelay)
Q_PROPERTY(bool displayedWhenStopped READ isDisplayedWhenStopped WRITE setDisplayedWhenStopped) Q_PROPERTY(bool displayedWhenStopped READ isDisplayedWhenStopped WRITE setDisplayedWhenStopped)
Q_PROPERTY(QColor color READ color WRITE setColor) Q_PROPERTY(QColor color READ color WRITE setColor)
Q_PROPERTY(int displaySize READ displaySize WRITE setDisplaySize) Q_PROPERTY(int displaySize READ displaySize WRITE setDisplaySize)
public: public:
QProgressIndicator(QWidget* parent = 0, int size = 64); QProgressIndicator(QWidget* parent = 0, int size = 64);
/*! Returns the delay between animation steps. /*! Returns the delay between animation steps.
\return The number of milliseconds between animation steps. By default, the animation delay is set to 80 milliseconds. \return The number of milliseconds between animation steps. By default, the animation delay is set to 80 milliseconds.
\sa setAnimationDelay \sa setAnimationDelay
*/ */
int animationDelay() const { return m_delay; } int animationDelay() const { return m_delay; }
/*! Returns a Boolean value indicating whether the component is currently animated. /*! Returns a Boolean value indicating whether the component is currently animated.
\return Animation state. \return Animation state.
\sa startAnimation stopAnimation \sa startAnimation stopAnimation
*/ */
bool isAnimated () const; bool isAnimated () const;
/*! Returns a Boolean value indicating whether the receiver shows itself even when it is not animating. /*! Returns a Boolean value indicating whether the receiver shows itself even when it is not animating.
\return Return true if the progress indicator shows itself even when it is not animating. By default, it returns false. \return Return true if the progress indicator shows itself even when it is not animating. By default, it returns false.
\sa setDisplayedWhenStopped \sa setDisplayedWhenStopped
*/ */
bool isDisplayedWhenStopped() const; bool isDisplayedWhenStopped() const;
/*! Returns the color of the component. /*! Returns the color of the component.
\sa setColor \sa setColor
*/ */
const QColor & color() const { return m_color; } const QColor & color() const { return m_color; }
virtual QSize sizeHint() const; virtual QSize sizeHint() const;
int heightForWidth(int w) const; int heightForWidth(int w) const;
int displaySize() const { return m_displaySize; } int displaySize() const { return m_displaySize; }
public slots: public slots:
/*! Starts the spin animation. /*! Starts the spin animation.
\sa stopAnimation isAnimated \sa stopAnimation isAnimated
*/ */
void startAnimation(); void startAnimation();
/*! Stops the spin animation. /*! Stops the spin animation.
\sa startAnimation isAnimated \sa startAnimation isAnimated
*/ */
void stopAnimation(); void stopAnimation();
/*! Sets the delay between animation steps. /*! Sets the delay between animation steps.
Setting the \a delay to a value larger than 40 slows the animation, while setting the \a delay to a smaller value speeds it up. Setting the \a delay to a value larger than 40 slows the animation, while setting the \a delay to a smaller value speeds it up.
\param delay The delay, in milliseconds. \param delay The delay, in milliseconds.
\sa animationDelay \sa animationDelay
*/ */
void setAnimationDelay(int delay); void setAnimationDelay(int delay);
/*! Sets whether the component hides itself when it is not animating. /*! Sets whether the component hides itself when it is not animating.
\param state The animation state. Set false to hide the progress indicator when it is not animating; otherwise true. \param state The animation state. Set false to hide the progress indicator when it is not animating; otherwise true.
\sa isDisplayedWhenStopped \sa isDisplayedWhenStopped
*/ */
void setDisplayedWhenStopped(bool state); void setDisplayedWhenStopped(bool state);
/*! Sets the color of the components to the given color. /*! Sets the color of the components to the given color.
\sa color \sa color
*/ */
void setColor(const QColor & color); void setColor(const QColor & color);
/*! Set the size of this widget (used by sizeHint) /*! Set the size of this widget (used by sizeHint)
* \sa displaySize * \sa displaySize
*/ */
void setDisplaySize(int size); void setDisplaySize(int size);
protected: protected:
virtual void timerEvent(QTimerEvent * event); virtual void timerEvent(QTimerEvent * event);
virtual void paintEvent(QPaintEvent * event); virtual void paintEvent(QPaintEvent * event);
private: private:
int m_angle; int m_angle;
int m_timerId; int m_timerId;
int m_delay; int m_delay;
int m_displaySize; int m_displaySize;
bool m_displayedWhenStopped; bool m_displayedWhenStopped;
QColor m_color; QColor m_color;
}; };