mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
Fix the root cause of all the book list edit cell problems
The root cause was that Qt doesnt support sharing a delegate between multiple views. So give the main view and pin view their own delegate instances. Hopefully I didnt break anything else.
This commit is contained in:
parent
3a64034055
commit
773a5206b3
@ -93,15 +93,7 @@ class UpdateEditorGeometry:
|
||||
new_width += r.width()
|
||||
|
||||
# Compute the maximum we can show if we consume the entire viewport
|
||||
pin_view = self.table_widget.pin_view
|
||||
is_pin_view, p = False, editor.parent()
|
||||
while p is not None:
|
||||
if p is pin_view:
|
||||
is_pin_view = True
|
||||
break
|
||||
p = p.parent()
|
||||
|
||||
max_width = (pin_view if is_pin_view else self.table_widget).viewport().rect().width()
|
||||
max_width = self.parent().viewport().rect().width()
|
||||
# What we have to display might not fit. If so, adjust down
|
||||
new_width = new_width if new_width < max_width else max_width
|
||||
|
||||
@ -215,15 +207,6 @@ class StyledItemDelegate(QStyledItemDelegate):
|
||||
ignore_kb_mods_on_edit = False
|
||||
|
||||
def createEditor(self, parent, option, index):
|
||||
current_indices = [self.table_widget.currentIndex()]
|
||||
if hasattr(self.table_widget, 'pin_view'):
|
||||
current_indices.append(self.table_widget.pin_view.currentIndex())
|
||||
if index not in current_indices:
|
||||
idx = self.table_widget.currentIndex()
|
||||
print(f'createEditor idx err: delegate={self.__class__.__name__}. '
|
||||
f'cur idx=({idx.row()}, {idx.column()}), '
|
||||
f'given idx=({index.row()}, {index.column()})')
|
||||
return None
|
||||
e = self.create_editor(parent, option, index)
|
||||
return e
|
||||
|
||||
@ -249,7 +232,6 @@ class RatingDelegate(StyledItemDelegate, UpdateEditorGeometry): # {{{
|
||||
def __init__(self, *args, **kwargs):
|
||||
StyledItemDelegate.__init__(self, *args)
|
||||
self.is_half_star = kwargs.get('is_half_star', False)
|
||||
self.table_widget = args[0]
|
||||
self.rf = QFont(rating_font())
|
||||
self.em = Qt.TextElideMode.ElideMiddle
|
||||
delta = 0
|
||||
@ -295,7 +277,6 @@ class DateDelegate(StyledItemDelegate, UpdateEditorGeometry): # {{{
|
||||
def __init__(self, parent, tweak_name='gui_timestamp_display_format',
|
||||
default_format='dd MMM yyyy'):
|
||||
StyledItemDelegate.__init__(self, parent)
|
||||
self.table_widget = parent
|
||||
self.tweak_name = tweak_name
|
||||
self.format = tweaks[self.tweak_name]
|
||||
if self.format is None:
|
||||
@ -331,7 +312,6 @@ class PubDateDelegate(StyledItemDelegate, UpdateEditorGeometry): # {{{
|
||||
def __init__(self, *args, **kwargs):
|
||||
StyledItemDelegate.__init__(self, *args, **kwargs)
|
||||
self.format = tweaks['gui_pubdate_display_format']
|
||||
self.table_widget = args[0]
|
||||
if self.format is None:
|
||||
self.format = 'MMM yyyy'
|
||||
|
||||
@ -370,7 +350,6 @@ class TextDelegate(StyledItemDelegate, UpdateEditorGeometry, EditableTextDelegat
|
||||
auto-complete will be used.
|
||||
'''
|
||||
StyledItemDelegate.__init__(self, parent)
|
||||
self.table_widget = parent
|
||||
self.auto_complete_function = None
|
||||
|
||||
def set_auto_complete_function(self, f):
|
||||
@ -417,10 +396,10 @@ class CompleteDelegate(StyledItemDelegate, UpdateEditorGeometry, EditableTextDel
|
||||
self.sep = sep
|
||||
self.items_func_name = items_func_name
|
||||
self.space_before_sep = space_before_sep
|
||||
self.table_widget = parent
|
||||
|
||||
def set_database(self, db):
|
||||
self.db = db
|
||||
@property
|
||||
def db(self):
|
||||
return self.parent().model().db
|
||||
|
||||
def create_editor(self, parent, option, index):
|
||||
if self.db and hasattr(self.db, self.items_func_name):
|
||||
@ -464,7 +443,6 @@ class LanguagesDelegate(StyledItemDelegate, UpdateEditorGeometry): # {{{
|
||||
|
||||
def __init__(self, parent):
|
||||
StyledItemDelegate.__init__(self, parent)
|
||||
self.table_widget = parent
|
||||
|
||||
def create_editor(self, parent, option, index):
|
||||
editor = LanguagesEdit(parent=parent)
|
||||
@ -491,7 +469,6 @@ class CcDateDelegate(StyledItemDelegate, UpdateEditorGeometry): # {{{
|
||||
|
||||
def __init__(self, parent):
|
||||
StyledItemDelegate.__init__(self, parent)
|
||||
self.table_widget = parent
|
||||
|
||||
def set_format(self, _format):
|
||||
if not _format:
|
||||
@ -541,7 +518,6 @@ class CcTextDelegate(StyledItemDelegate, UpdateEditorGeometry, EditableTextDeleg
|
||||
|
||||
def __init__(self, parent):
|
||||
StyledItemDelegate.__init__(self, parent)
|
||||
self.table_widget = parent
|
||||
|
||||
def create_editor(self, parent, option, index):
|
||||
m = index.model()
|
||||
@ -589,7 +565,6 @@ class CcLongTextDelegate(StyledItemDelegate): # {{{
|
||||
|
||||
def __init__(self, parent):
|
||||
StyledItemDelegate.__init__(self, parent)
|
||||
self.table_widget = parent
|
||||
self.document = QTextDocument()
|
||||
self.is_editable_with_tab = False
|
||||
|
||||
@ -617,7 +592,6 @@ class CcMarkdownDelegate(StyledItemDelegate): # {{{
|
||||
|
||||
def __init__(self, parent):
|
||||
super().__init__(parent)
|
||||
self.table_widget = parent
|
||||
self.document = QTextDocument()
|
||||
self.is_editable_with_tab = False
|
||||
|
||||
@ -671,7 +645,6 @@ class CcNumberDelegate(StyledItemDelegate, UpdateEditorGeometry): # {{{
|
||||
|
||||
def __init__(self, parent):
|
||||
StyledItemDelegate.__init__(self, parent)
|
||||
self.table_widget = parent
|
||||
|
||||
def create_editor(self, parent, option, index):
|
||||
m = index.model()
|
||||
@ -722,7 +695,6 @@ class CcEnumDelegate(StyledItemDelegate, UpdateEditorGeometry): # {{{
|
||||
|
||||
def __init__(self, parent):
|
||||
StyledItemDelegate.__init__(self, parent)
|
||||
self.table_widget = parent
|
||||
self.longest_text = ''
|
||||
|
||||
def create_editor(self, parent, option, index):
|
||||
@ -770,7 +742,6 @@ class CcCommentsDelegate(StyledItemDelegate): # {{{
|
||||
|
||||
def __init__(self, parent):
|
||||
StyledItemDelegate.__init__(self, parent)
|
||||
self.table_widget = parent
|
||||
self.document = QTextDocument()
|
||||
self.is_editable_with_tab = False
|
||||
|
||||
@ -833,7 +804,6 @@ class CcBoolDelegate(StyledItemDelegate, UpdateEditorGeometry): # {{{
|
||||
'''
|
||||
self.nuke_option_data = False
|
||||
StyledItemDelegate.__init__(self, parent)
|
||||
self.table_widget = parent
|
||||
|
||||
def create_editor(self, parent, option, index):
|
||||
editor = DelegateCB(parent)
|
||||
@ -896,7 +866,6 @@ class CcTemplateDelegate(StyledItemDelegate): # {{{
|
||||
Delegate for composite custom_columns.
|
||||
'''
|
||||
StyledItemDelegate.__init__(self, parent)
|
||||
self.table_widget = parent
|
||||
self.disallow_edit = gprefs['edit_metadata_templates_only_F2_on_booklist']
|
||||
self.is_editable_with_tab = False
|
||||
|
||||
|
@ -11,7 +11,6 @@ from collections import OrderedDict
|
||||
from functools import partial
|
||||
|
||||
from qt.core import (
|
||||
QAbstractItemDelegate,
|
||||
QAbstractItemView,
|
||||
QDialog,
|
||||
QDialogButtonBox,
|
||||
@ -68,7 +67,7 @@ from calibre.gui2.library.delegates import (
|
||||
TextDelegate,
|
||||
)
|
||||
from calibre.gui2.library.models import BooksModel, DeviceBooksModel
|
||||
from calibre.gui2.pin_columns import PinTableView
|
||||
from calibre.gui2.pin_columns import CustomEditTabbingBehavior, PinTableView
|
||||
from calibre.gui2.preferences.create_custom_column import CreateNewCustomColumn
|
||||
from calibre.utils.config import prefs, tweaks
|
||||
from calibre.utils.icu import primary_sort_key
|
||||
@ -357,7 +356,7 @@ class AdjustColumnSize(QDialog): # {{{
|
||||
|
||||
|
||||
@setup_dnd_interface
|
||||
class BooksView(QTableView): # {{{
|
||||
class BooksView(QTableView, CustomEditTabbingBehavior): # {{{
|
||||
|
||||
files_dropped = pyqtSignal(object)
|
||||
books_dropped = pyqtSignal(object)
|
||||
@ -418,28 +417,30 @@ class BooksView(QTableView): # {{{
|
||||
wv.setWordWrap(False)
|
||||
self.refresh_grid()
|
||||
|
||||
self.rating_delegate = RatingDelegate(self)
|
||||
self.half_rating_delegate = RatingDelegate(self, is_half_star=True)
|
||||
self.timestamp_delegate = DateDelegate(self)
|
||||
self.pubdate_delegate = PubDateDelegate(self)
|
||||
self.last_modified_delegate = DateDelegate(self,
|
||||
tweak_name='gui_last_modified_display_format')
|
||||
self.languages_delegate = LanguagesDelegate(self)
|
||||
self.tags_delegate = CompleteDelegate(self, ',', 'all_tag_names')
|
||||
self.authors_delegate = CompleteDelegate(self, '&', 'all_author_names', True)
|
||||
self.cc_names_delegate = CompleteDelegate(self, '&', 'all_custom', True)
|
||||
self.series_delegate = SeriesDelegate(self)
|
||||
self.publisher_delegate = TextDelegate(self)
|
||||
self.text_delegate = TextDelegate(self)
|
||||
self.cc_text_delegate = CcTextDelegate(self)
|
||||
self.cc_series_delegate = CcSeriesDelegate(self)
|
||||
self.cc_longtext_delegate = CcLongTextDelegate(self)
|
||||
self.cc_markdown_delegate = CcMarkdownDelegate(self)
|
||||
self.cc_enum_delegate = CcEnumDelegate(self)
|
||||
self.cc_bool_delegate = CcBoolDelegate(self)
|
||||
self.cc_comments_delegate = CcCommentsDelegate(self)
|
||||
self.cc_template_delegate = CcTemplateDelegate(self)
|
||||
self.cc_number_delegate = CcNumberDelegate(self)
|
||||
def create_delegates(view):
|
||||
view.rating_delegate = RatingDelegate(view)
|
||||
view.half_rating_delegate = RatingDelegate(view, is_half_star=True)
|
||||
view.timestamp_delegate = DateDelegate(view)
|
||||
view.pubdate_delegate = PubDateDelegate(view)
|
||||
view.last_modified_delegate = DateDelegate(view, tweak_name='gui_last_modified_display_format')
|
||||
view.languages_delegate = LanguagesDelegate(view)
|
||||
view.tags_delegate = CompleteDelegate(view, ',', 'all_tag_names')
|
||||
view.authors_delegate = CompleteDelegate(view, '&', 'all_author_names', True)
|
||||
view.cc_names_delegate = CompleteDelegate(view, '&', 'all_custom', True)
|
||||
view.series_delegate = SeriesDelegate(view)
|
||||
view.publisher_delegate = TextDelegate(view)
|
||||
view.text_delegate = TextDelegate(view)
|
||||
view.cc_text_delegate = CcTextDelegate(view)
|
||||
view.cc_series_delegate = CcSeriesDelegate(view)
|
||||
view.cc_longtext_delegate = CcLongTextDelegate(view)
|
||||
view.cc_markdown_delegate = CcMarkdownDelegate(view)
|
||||
view.cc_enum_delegate = CcEnumDelegate(view)
|
||||
view.cc_bool_delegate = CcBoolDelegate(view)
|
||||
view.cc_comments_delegate = CcCommentsDelegate(view)
|
||||
view.cc_template_delegate = CcTemplateDelegate(view)
|
||||
view.cc_number_delegate = CcNumberDelegate(view)
|
||||
|
||||
create_delegates(self), create_delegates(self.pin_view)
|
||||
self.display_parent = parent
|
||||
self._model = modelcls(self)
|
||||
self.setModel(self._model)
|
||||
@ -1124,11 +1125,6 @@ class BooksView(QTableView): # {{{
|
||||
self.alternate_views.set_database(db)
|
||||
self.save_state()
|
||||
self._model.set_database(db)
|
||||
self.tags_delegate.set_database(db)
|
||||
self.cc_names_delegate.set_database(db)
|
||||
self.authors_delegate.set_database(db)
|
||||
self.series_delegate.set_auto_complete_function(db.all_series)
|
||||
self.publisher_delegate.set_auto_complete_function(db.all_publishers)
|
||||
self.alternate_views.set_database(db, stage=1)
|
||||
|
||||
def marked_changed(self, old_marked, current_marked):
|
||||
@ -1172,55 +1168,56 @@ class BooksView(QTableView): # {{{
|
||||
self.last_modified_delegate, self.languages_delegate, self.half_rating_delegate):
|
||||
vw.setItemDelegateForColumn(i, vw.itemDelegate())
|
||||
|
||||
cm = self.column_map
|
||||
def set_delegates(view):
|
||||
cm = view.column_map
|
||||
|
||||
def set_item_delegate(colhead, delegate):
|
||||
idx = cm.index(colhead)
|
||||
self.setItemDelegateForColumn(idx, delegate)
|
||||
self.pin_view.setItemDelegateForColumn(idx, delegate)
|
||||
def set_item_delegate(colhead, delegate):
|
||||
idx = view.column_map.index(colhead)
|
||||
view.setItemDelegateForColumn(idx, delegate)
|
||||
|
||||
for colhead in cm:
|
||||
if self._model.is_custom_column(colhead):
|
||||
cc = self._model.custom_columns[colhead]
|
||||
if cc['datatype'] == 'datetime':
|
||||
delegate = CcDateDelegate(self)
|
||||
delegate.set_format(cc['display'].get('date_format',''))
|
||||
set_item_delegate(colhead, delegate)
|
||||
elif cc['datatype'] == 'comments':
|
||||
ctype = cc['display'].get('interpret_as', 'html')
|
||||
if ctype == 'short-text':
|
||||
set_item_delegate(colhead, self.cc_text_delegate)
|
||||
elif ctype == 'long-text':
|
||||
set_item_delegate(colhead, self.cc_longtext_delegate)
|
||||
elif ctype == 'markdown':
|
||||
set_item_delegate(colhead, self.cc_markdown_delegate)
|
||||
else:
|
||||
set_item_delegate(colhead, self.cc_comments_delegate)
|
||||
elif cc['datatype'] == 'text':
|
||||
if cc['is_multiple']:
|
||||
if cc['display'].get('is_names', False):
|
||||
set_item_delegate(colhead, self.cc_names_delegate)
|
||||
for colhead in cm:
|
||||
if self._model.is_custom_column(colhead):
|
||||
cc = self._model.custom_columns[colhead]
|
||||
if cc['datatype'] == 'datetime':
|
||||
delegate = CcDateDelegate(view)
|
||||
delegate.set_format(cc['display'].get('date_format',''))
|
||||
set_item_delegate(colhead, delegate)
|
||||
elif cc['datatype'] == 'comments':
|
||||
ctype = cc['display'].get('interpret_as', 'html')
|
||||
if ctype == 'short-text':
|
||||
set_item_delegate(colhead, view.cc_text_delegate)
|
||||
elif ctype == 'long-text':
|
||||
set_item_delegate(colhead, view.cc_longtext_delegate)
|
||||
elif ctype == 'markdown':
|
||||
set_item_delegate(colhead, view.cc_markdown_delegate)
|
||||
else:
|
||||
set_item_delegate(colhead, self.tags_delegate)
|
||||
else:
|
||||
set_item_delegate(colhead, self.cc_text_delegate)
|
||||
elif cc['datatype'] == 'series':
|
||||
set_item_delegate(colhead, self.cc_series_delegate)
|
||||
elif cc['datatype'] in ('int', 'float'):
|
||||
set_item_delegate(colhead, self.cc_number_delegate)
|
||||
elif cc['datatype'] == 'bool':
|
||||
set_item_delegate(colhead, self.cc_bool_delegate)
|
||||
elif cc['datatype'] == 'rating':
|
||||
d = self.half_rating_delegate if cc['display'].get('allow_half_stars', False) else self.rating_delegate
|
||||
set_item_delegate(colhead, d)
|
||||
elif cc['datatype'] == 'composite':
|
||||
set_item_delegate(colhead, self.cc_template_delegate)
|
||||
elif cc['datatype'] == 'enumeration':
|
||||
set_item_delegate(colhead, self.cc_enum_delegate)
|
||||
else:
|
||||
dattr = colhead+'_delegate'
|
||||
delegate = colhead if hasattr(self, dattr) else 'text'
|
||||
set_item_delegate(colhead, getattr(self, delegate+'_delegate'))
|
||||
set_item_delegate(colhead, view.cc_comments_delegate)
|
||||
elif cc['datatype'] == 'text':
|
||||
if cc['is_multiple']:
|
||||
if cc['display'].get('is_names', False):
|
||||
set_item_delegate(colhead, view.cc_names_delegate)
|
||||
else:
|
||||
set_item_delegate(colhead, view.tags_delegate)
|
||||
else:
|
||||
set_item_delegate(colhead, view.cc_text_delegate)
|
||||
elif cc['datatype'] == 'series':
|
||||
set_item_delegate(colhead, view.cc_series_delegate)
|
||||
elif cc['datatype'] in ('int', 'float'):
|
||||
set_item_delegate(colhead, view.cc_number_delegate)
|
||||
elif cc['datatype'] == 'bool':
|
||||
set_item_delegate(colhead, view.cc_bool_delegate)
|
||||
elif cc['datatype'] == 'rating':
|
||||
d = view.half_rating_delegate if cc['display'].get('allow_half_stars', False) else view.rating_delegate
|
||||
set_item_delegate(colhead, d)
|
||||
elif cc['datatype'] == 'composite':
|
||||
set_item_delegate(colhead, view.cc_template_delegate)
|
||||
elif cc['datatype'] == 'enumeration':
|
||||
set_item_delegate(colhead, view.cc_enum_delegate)
|
||||
else:
|
||||
dattr = colhead+'_delegate'
|
||||
delegate = colhead if hasattr(view, dattr) else 'text'
|
||||
set_item_delegate(colhead, getattr(view, delegate+'_delegate'))
|
||||
set_delegates(self), set_delegates(self.pin_view)
|
||||
|
||||
self.restore_state()
|
||||
self.set_ondevice_column_visibility()
|
||||
@ -1637,77 +1634,9 @@ class BooksView(QTableView): # {{{
|
||||
def close(self):
|
||||
self._model.close()
|
||||
|
||||
def is_index_editable_with_tab(self, index) -> bool:
|
||||
if not index.isValid():
|
||||
return False
|
||||
col = self.column_map[index.column()]
|
||||
m = self.model()
|
||||
if m.is_custom_column(col):
|
||||
# Don't try to open editors implemented by dialogs such as
|
||||
# markdown, composites and comments
|
||||
return self.itemDelegateForIndex(index).is_editable_with_tab
|
||||
return bool(m.flags(index) & Qt.ItemFlag.ItemIsEditable)
|
||||
|
||||
def closeEditor(self, editor, hint):
|
||||
# We want to implement our own go to next/previous cell behavior
|
||||
orig = self.currentIndex()
|
||||
do_move = False
|
||||
delta = 1
|
||||
if hint is QAbstractItemDelegate.EndEditHint.EditNextItem:
|
||||
do_move = True
|
||||
elif hint is QAbstractItemDelegate.EndEditHint.EditPreviousItem:
|
||||
do_move = True
|
||||
delta = -1
|
||||
super().closeEditor(editor, QAbstractItemDelegate.EndEditHint.NoHint if do_move else hint)
|
||||
if do_move:
|
||||
# Need to invoke after event loop tick otherwise
|
||||
# mirror_selection_between_views causes issues
|
||||
QTimer.singleShot(0, lambda: self.edit_next_cell(orig, delta))
|
||||
|
||||
def on_current_row_change(self, current, previous):
|
||||
self._model.current_changed(current, previous)
|
||||
|
||||
def edit(self, index, trigger=QAbstractItemView.EditTrigger.AllEditTriggers, event=None):
|
||||
edited = super().edit(index, trigger, event)
|
||||
return edited
|
||||
|
||||
def edit_next_cell(self, current, delta=1):
|
||||
m = self.model()
|
||||
row = current.row()
|
||||
idx = m.index(row, current.column(), current.parent())
|
||||
while True:
|
||||
col = idx.column() + delta
|
||||
if col < 0:
|
||||
if row <= 0:
|
||||
return
|
||||
row -= 1
|
||||
col += len(self.column_map)
|
||||
if col >= len(self.column_map):
|
||||
if row >= len(self.column_map) - 1:
|
||||
return
|
||||
row += 1
|
||||
col -= len(self.column_map)
|
||||
if col < 0 or col >= len(self.column_map):
|
||||
return
|
||||
colname = self.column_map[col]
|
||||
idx = m.index(row, col, current.parent())
|
||||
if m.is_custom_column(colname):
|
||||
if self.itemDelegateForIndex(idx).is_editable_with_tab:
|
||||
# Don't try to open editors implemented by dialogs such as
|
||||
# markdown, composites and comments
|
||||
break
|
||||
elif m.flags(idx) & Qt.ItemFlag.ItemIsEditable:
|
||||
break
|
||||
|
||||
if idx.isValid():
|
||||
# Tell the delegate to ignore keyboard modifiers in case
|
||||
# Shift-Tab is being used to move the cell.
|
||||
d = self.itemDelegateForIndex(idx)
|
||||
if d is not None:
|
||||
d.ignore_kb_mods_on_edit = True
|
||||
self.setCurrentIndex(idx)
|
||||
self.edit(idx)
|
||||
|
||||
def set_editable(self, editable, supports_backloading):
|
||||
self._model.set_editable(editable)
|
||||
|
||||
@ -1853,4 +1782,7 @@ class DeviceBooksView(BooksView): # {{{
|
||||
h.setSortIndicator(
|
||||
h.sortIndicatorSection(), Qt.SortOrder.AscendingOrder if h.sortIndicatorOrder() == Qt.SortOrder.DescendingOrder else Qt.SortOrder.DescendingOrder)
|
||||
|
||||
def closeEditor(self, editor, hint):
|
||||
return super().closeEditor(editor, hint)
|
||||
|
||||
# }}}
|
||||
|
@ -2,25 +2,72 @@
|
||||
# License: GPLv3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
|
||||
from qt.core import QAbstractItemView, QSplitter, QTableView
|
||||
from qt.core import QAbstractItemDelegate, QSplitter, Qt, QTableView
|
||||
|
||||
from calibre.gui2 import gprefs
|
||||
from calibre.gui2.library import DEFAULT_SORT
|
||||
|
||||
|
||||
class PinTableView(QTableView):
|
||||
class CustomEditTabbingBehavior:
|
||||
|
||||
def closeEditor(self, editor, hint):
|
||||
# We want to implement our own go to next/previous cell behavior
|
||||
orig = self.currentIndex()
|
||||
delta = 0
|
||||
if hint is QAbstractItemDelegate.EndEditHint.EditNextItem:
|
||||
delta = 1
|
||||
elif hint is QAbstractItemDelegate.EndEditHint.EditPreviousItem:
|
||||
delta = -1
|
||||
QTableView.closeEditor(self, editor, QAbstractItemDelegate.EndEditHint.NoHint if delta else hint)
|
||||
if not delta:
|
||||
return
|
||||
current = self.currentIndex()
|
||||
m = self.model()
|
||||
row = current.row()
|
||||
idx = m.index(row, current.column(), current.parent())
|
||||
while True:
|
||||
col = idx.column() + delta
|
||||
if col < 0:
|
||||
if row <= 0:
|
||||
return
|
||||
row -= 1
|
||||
col += len(self.column_map)
|
||||
if col >= len(self.column_map):
|
||||
if row >= len(self.column_map) - 1:
|
||||
return
|
||||
row += 1
|
||||
col -= len(self.column_map)
|
||||
if col < 0 or col >= len(self.column_map):
|
||||
return
|
||||
colname = self.column_map[col]
|
||||
idx = m.index(row, col, current.parent())
|
||||
if m.is_custom_column(colname):
|
||||
if self.itemDelegateForIndex(idx).is_editable_with_tab:
|
||||
# Don't try to open editors implemented by dialogs such as
|
||||
# markdown, composites and comments
|
||||
break
|
||||
elif m.flags(idx) & Qt.ItemFlag.ItemIsEditable:
|
||||
break
|
||||
|
||||
if idx.isValid():
|
||||
# Tell the delegate to ignore keyboard modifiers in case
|
||||
# Shift-Tab is being used to move the cell.
|
||||
d = self.itemDelegateForIndex(idx)
|
||||
if d is not None:
|
||||
d.ignore_kb_mods_on_edit = True
|
||||
self.setCurrentIndex(idx)
|
||||
self.edit(idx)
|
||||
|
||||
|
||||
class PinTableView(QTableView, CustomEditTabbingBehavior):
|
||||
|
||||
disable_save_state = False
|
||||
|
||||
def __init__(self, books_view, parent=None):
|
||||
QTableView.__init__(self, parent)
|
||||
self.books_view = books_view
|
||||
self.verticalHeader().close()
|
||||
self.splitter = None
|
||||
self.disable_save_state = False
|
||||
|
||||
def edit(self, index, trigger=QAbstractItemView.EditTrigger.AllEditTriggers, event=None):
|
||||
if not self.isVisible():
|
||||
return False
|
||||
return super().edit(index, trigger, event)
|
||||
|
||||
@property
|
||||
def column_map(self):
|
||||
|
Loading…
x
Reference in New Issue
Block a user