Right click menu for hiding/showing/sorting columns

This commit is contained in:
Kovid Goyal 2010-05-17 20:51:46 -06:00
parent e4b0f51363
commit 61e78b6a17

View File

@ -6,6 +6,7 @@ __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import os import os
from functools import partial
from PyQt4.Qt import QTableView, Qt, QAbstractItemView, QMenu, pyqtSignal from PyQt4.Qt import QTableView, Qt, QAbstractItemView, QMenu, pyqtSignal
@ -40,7 +41,15 @@ class BooksView(QTableView): # {{{
self.setSelectionBehavior(QAbstractItemView.SelectRows) self.setSelectionBehavior(QAbstractItemView.SelectRows)
self.setSortingEnabled(True) self.setSortingEnabled(True)
self.selectionModel().currentRowChanged.connect(self._model.current_changed) self.selectionModel().currentRowChanged.connect(self._model.current_changed)
# {{{ Column Header setup
self.column_header = self.horizontalHeader() self.column_header = self.horizontalHeader()
self.column_header.setMovable(True)
self.column_header.sectionMoved.connect(self.save_state)
self.column_header.setContextMenuPolicy(Qt.CustomContextMenu)
self.column_header.customContextMenuRequested.connect(self.show_column_header_context_menu)
# }}}
self._model.database_changed.connect(self.database_changed) self._model.database_changed.connect(self.database_changed)
hv = self.verticalHeader() hv = self.verticalHeader()
hv.setClickable(True) hv.setClickable(True)
@ -49,6 +58,69 @@ class BooksView(QTableView): # {{{
self._model.about_to_be_sorted.connect(self.about_to_be_sorted) self._model.about_to_be_sorted.connect(self.about_to_be_sorted)
self._model.sorting_done.connect(self.sorting_done) self._model.sorting_done.connect(self.sorting_done)
def column_header_context_handler(self, action=None, column=None):
if not action or not column:
return
try:
idx = self.column_map.index(column)
except:
return
h = self.column_header
if action == 'hide':
h.setSectionHidden(idx, True)
elif action == 'show':
h.setSectionHidden(idx, False)
elif action == 'ascending':
self._model.sort(idx, Qt.AscendingOrder)
h.setSortIndicator(idx, Qt.AscendingOrder)
elif action == 'descending':
self._model.sort(idx, Qt.DescendingOrder)
h.setSortIndicator(idx, Qt.DescendingOrder)
self.save_state()
def show_column_header_context_menu(self, pos):
idx = self.column_header.logicalIndexAt(pos)
if idx > -1 and idx < len(self.column_map):
col = self.column_map[idx]
name = unicode(self.model().headerData(idx, Qt.Horizontal,
Qt.DisplayRole).toString())
self.column_header_context_menu = QMenu(self)
if col != 'ondevice':
self.column_header_context_menu.addAction(_('Hide column %s') %
name,
partial(self.column_header_context_handler, action='hide',
column=col))
self.column_header_context_menu.addAction(
_('Sort on column %s (ascending)') % name,
partial(self.column_header_context_handler,
action='ascending', column=col))
self.column_header_context_menu.addAction(
_('Sort on column %s (descending)') % name,
partial(self.column_header_context_handler,
action='descending', column=col))
hidden_cols = [self.column_map[i] for i in
range(self.column_header.count()) if
self.column_header.isSectionHidden(i)]
try:
hidden_cols.remove('ondevice')
except:
pass
if hidden_cols:
self.column_header_context_menu.addSeparator()
m = self.column_header_context_menu.addMenu(_('Show column'))
for col in hidden_cols:
hidx = self.column_map.index(col)
name = unicode(self.model().headerData(hidx, Qt.Horizontal,
Qt.DisplayRole).toString())
m.addAction(name,
partial(self.column_header_context_handler,
action='show', column=col))
self.column_header_context_menu.popup(self.column_header.mapToGlobal(pos))
def about_to_be_sorted(self, idc): def about_to_be_sorted(self, idc):
selected_rows = [r.row() for r in self.selectionModel().selectedRows()] selected_rows = [r.row() for r in self.selectionModel().selectedRows()]
self.selected_ids = [idc(r) for r in selected_rows] self.selected_ids = [idc(r) for r in selected_rows]
@ -71,14 +143,47 @@ class BooksView(QTableView): # {{{
self._model.set_device_connected(is_connected) self._model.set_device_connected(is_connected)
self.set_ondevice_column_visibility() self.set_ondevice_column_visibility()
def get_state(self):
h = self.column_header
cm = self.column_map
state = {}
state['hidden_columns'] = [cm[i] for i in range(h.count())
if h.isSectionHidden(i) and cm[i] != 'ondevice']
state['column_positions'] = {}
state['column_sizes'] = {}
for i in range(h.count()):
name = cm[i]
state['column_positions'][name] = h.visualIndex(i)
if name != 'ondevice':
state['column_sizes'][name] = h.sectionSize(i)
import pprint
pprint.pprint(state)
return state
def save_state(self):
# Only save if we have been initialized (set_database called)
if len(self.column_map) > 0:
state = self.get_state()
state
def apply_state(self, state):
pass
def restore_state(self):
pass
@property
def column_map(self):
return self._model.column_map
def database_changed(self, db): def database_changed(self, db):
for i in range(self.model().columnCount(None)): for i in range(self.model().columnCount(None)):
if self.itemDelegateForColumn(i) in (self.rating_delegate, if self.itemDelegateForColumn(i) in (self.rating_delegate,
self.timestamp_delegate, self.pubdate_delegate): self.timestamp_delegate, self.pubdate_delegate):
self.setItemDelegateForColumn(i, self.itemDelegate()) self.setItemDelegateForColumn(i, self.itemDelegate())
cm = self._model.column_map cm = self.column_map
self.set_ondevice_column_visibility()
for colhead in cm: for colhead in cm:
if self._model.is_custom_column(colhead): if self._model.is_custom_column(colhead):
@ -106,6 +211,9 @@ class BooksView(QTableView): # {{{
self.setItemDelegateForColumn(cm.index(colhead), getattr(self, self.setItemDelegateForColumn(cm.index(colhead), getattr(self,
delegate+'_delegate')) delegate+'_delegate'))
self.restore_state()
self.set_ondevice_column_visibility()
def set_context_menu(self, edit_metadata, send_to_device, convert, view, def set_context_menu(self, edit_metadata, send_to_device, convert, view,
save, open_folder, book_details, delete, similar_menu=None): save, open_folder, book_details, delete, similar_menu=None):
self.setContextMenuPolicy(Qt.DefaultContextMenu) self.setContextMenuPolicy(Qt.DefaultContextMenu)
@ -177,6 +285,7 @@ class BooksView(QTableView): # {{{
self.files_dropped.emit(paths) self.files_dropped.emit(paths)
def set_database(self, db): def set_database(self, db):
self.save_state()
self._model.set_database(db) self._model.set_database(db)
self.tags_delegate.set_database(db) self.tags_delegate.set_database(db)
self.authors_delegate.set_auto_complete_function(db.all_authors) self.authors_delegate.set_auto_complete_function(db.all_authors)