Jobs list: Add the ability to hide jobs, useful if you have run a lot of jobs and the list is getting crowded. Fixes #883734 (Clear Jobs)

This commit is contained in:
Kovid Goyal 2011-11-15 11:25:00 +05:30
parent 1d23886c12
commit efd0209ce6
2 changed files with 83 additions and 14 deletions

View File

@ -17,8 +17,8 @@
<iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/jobs.png</normaloff>:/images/jobs.png</iconset>
</property>
<layout class="QVBoxLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QTableView" name="jobs_view">
<property name="contextMenuPolicy">
<enum>Qt::NoContextMenu</enum>
@ -40,27 +40,48 @@
</property>
</widget>
</item>
<item>
<item row="1" column="0">
<widget class="QPushButton" name="kill_button">
<property name="text">
<string>&amp;Stop selected jobs</string>
</property>
</widget>
</item>
<item>
<item row="1" column="1">
<widget class="QPushButton" name="hide_button">
<property name="text">
<string>&amp;Hide selected jobs</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="details_button">
<property name="text">
<string>Show job &amp;details</string>
</property>
</widget>
</item>
<item>
<item row="2" column="1">
<widget class="QPushButton" name="show_button">
<property name="text">
<string>Show &amp;all jobs</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QPushButton" name="stop_all_jobs_button">
<property name="text">
<string>Stop &amp;all non device jobs</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QPushButton" name="hide_all_button">
<property name="text">
<string>&amp;Hide all jobs</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources>

View File

@ -14,7 +14,7 @@ from PyQt4.Qt import (QAbstractTableModel, QVariant, QModelIndex, Qt,
QTimer, pyqtSignal, QIcon, QDialog, QAbstractItemDelegate, QApplication,
QSize, QStyleOptionProgressBarV2, QString, QStyle, QToolTip, QFrame,
QHBoxLayout, QVBoxLayout, QSizePolicy, QLabel, QCoreApplication, QAction,
QByteArray)
QByteArray, QSortFilterProxyModel)
from calibre.utils.ipc.server import Server
from calibre.utils.ipc.job import ParallelJob
@ -26,6 +26,8 @@ from calibre.gui2.dialogs.job_view_ui import Ui_Dialog
from calibre.gui2.progress_indicator import ProgressIndicator
from calibre.gui2.threaded_jobs import ThreadedJobServer, ThreadedJob
HIDE_ROLE = Qt.UserRole + 1
class JobManager(QAbstractTableModel): # {{{
job_added = pyqtSignal(int)
@ -91,7 +93,7 @@ class JobManager(QAbstractTableModel): # {{{
def data(self, index, role):
try:
if role not in (Qt.DisplayRole, Qt.DecorationRole):
if role not in (Qt.DisplayRole, Qt.DecorationRole, HIDE_ROLE):
return NONE
row, col = index.row(), index.column()
job = self.jobs[row]
@ -121,6 +123,9 @@ class JobManager(QAbstractTableModel): # {{{
if job.killed or job.failed:
return self.error_icon
return self.done_icon
if role == HIDE_ROLE:
return QVariant('h' if getattr(job, 'hidden_in_gui', False)
else 's')
except:
import traceback
traceback.print_exc()
@ -251,6 +256,18 @@ class JobManager(QAbstractTableModel): # {{{
else:
job.kill_on_start = True
def hide_jobs(self, rows):
for r in rows:
self.jobs[r].hidden_in_gui = True
for r in rows:
self.dataChanged.emit(self.index(r, 0), self.index(r, 0))
def show_hidden_jobs(self):
for j in self.jobs:
j.hidden_in_gui = False
for r in xrange(len(self.jobs)):
self.dataChanged.emit(self.index(r, 0), self.index(r, 0))
def kill_job(self, row, view):
job = self.jobs[row]
if isinstance(job, DeviceJob):
@ -450,8 +467,12 @@ class JobsDialog(QDialog, Ui_JobsDialog):
QDialog.__init__(self, window)
Ui_JobsDialog.__init__(self)
self.setupUi(self)
self.jobs_view.setModel(model)
self.model = model
self.proxy_model = QSortFilterProxyModel(self)
self.proxy_model.setSourceModel(self.model)
self.proxy_model.setFilterRole(HIDE_ROLE)
self.proxy_model.setFilterFixedString('s')
self.jobs_view.setModel(self.proxy_model)
self.setWindowModality(Qt.NonModal)
self.setWindowTitle(__appname__ + _(' - Jobs'))
self.details_button.clicked.connect(self.show_details)
@ -461,6 +482,9 @@ class JobsDialog(QDialog, Ui_JobsDialog):
self.jobs_view.setItemDelegateForColumn(2, self.pb_delegate)
self.jobs_view.doubleClicked.connect(self.show_job_details)
self.jobs_view.horizontalHeader().setMovable(True)
self.hide_button.clicked.connect(self.hide_selected)
self.hide_all_button.clicked.connect(self.hide_all)
self.show_button.clicked.connect(self.show_hidden)
self.restore_state()
def restore_state(self):
@ -486,8 +510,10 @@ class JobsDialog(QDialog, Ui_JobsDialog):
pass
def show_job_details(self, index):
index = self.proxy_model.mapToSource(index)
if index.isValid():
row = index.row()
job = self.jobs_view.model().row_to_job(row)
job = self.model.row_to_job(row)
d = DetailView(self, job)
d.exec_()
d.timer.stop()
@ -498,8 +524,10 @@ class JobsDialog(QDialog, Ui_JobsDialog):
self.show_job_details(index)
def kill_job(self, *args):
rows = [index.row() for index in
indices = [self.proxy_model.mapToSource(index) for index in
self.jobs_view.selectionModel().selectedRows()]
indices = [i for i in indices if i.isValid()]
rows = [index.row() for index in indices]
if not rows:
return error_dialog(self, _('No job'),
_('No job selected'), show=True)
@ -517,6 +545,26 @@ class JobsDialog(QDialog, Ui_JobsDialog):
_('Do you really want to stop all non-device jobs?')):
self.model.kill_all_jobs()
def hide_selected(self, *args):
indices = [self.proxy_model.mapToSource(index) for index in
self.jobs_view.selectionModel().selectedRows()]
indices = [i for i in indices if i.isValid()]
rows = [index.row() for index in indices]
if not rows:
return error_dialog(self, _('No job'),
_('No job selected'), show=True)
self.model.hide_jobs(rows)
self.proxy_model.reset()
def hide_all(self, *args):
self.model.hide_jobs(list(xrange(0,
self.model.rowCount(QModelIndex()))))
self.proxy_model.reset()
def show_hidden(self, *args):
self.model.show_hidden_jobs()
self.proxy_model.reset()
def closeEvent(self, e):
self.save_state()
return QDialog.closeEvent(self, e)