Source code for cgl.ui.widgets.containers.table
import logging
try:
from PySide6 import QtCore, QtWidgets
except ImportError:
from PySide6 import QtCore, QtWidgets
from cgl.ui.util import UISettings, widget_name
from cgl.ui.util import drop_handler
from cgl.ui.widgets.base import StateSavers
from cgl.ui.widgets.containers.menu import LJMenu
from cgl.ui.widgets.containers.proxy import LJTableSearchProxy
[docs]
class LJTableWidget(QtWidgets.QTableView):
selected = QtCore.Signal(object)
right_clicked = QtCore.Signal(object)
dropped = QtCore.Signal(object)
double_clicked = QtCore.Signal(object)
def __init__(self, parent, path_object=None):
QtWidgets.QTableView.__init__(self, parent)
self.verticalHeader().hide()
self.horizontalHeader().setStretchLastSection(True)
self.path_object = path_object
self.menu = None
self.search_wgt = None
self.alphabet_header = None
self.header_right_click_menu = LJMenu(self)
self.horizontalHeader().setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.setFocusPolicy(QtCore.Qt.NoFocus)
StateSavers.remember_me(self)
self.height_hint = 0
self.width_hint = 0
self.doubleClicked.connect(self.send_double_click_signal)
self.setAlternatingRowColors(True)
[docs]
def send_double_click_signal(self):
items = []
if self.selectionModel():
for each in self.selectionModel().selectedRows():
if isinstance(self.model(), QtCore.QAbstractProxyModel):
mdl_index = self.model().mapToSource(each)
mdl = self.model().sourceModel()
row = mdl_index.row()
else:
mdl = self.model()
row = each.row()
sel = mdl.data_[row]
items.append(sel)
else:
logging.info("No data to select")
try:
self.double_clicked.emit(items)
except IndexError:
logging.info("nothing selected")
self.nothing_selected.emit()
[docs]
def mouseReleaseEvent(self, e):
super(LJTableWidget, self).mouseReleaseEvent(e)
if e.button() == QtCore.Qt.LeftButton:
self.viewClicked()
[docs]
def mousePressEvent(self, e):
super(LJTableWidget, self).mousePressEvent(e)
if e.button() == QtCore.Qt.RightButton:
self.viewClicked()
# noinspection PyShadowingNames,PyPep8
[docs]
def set_item_model(self, mdl, proxy=None):
if not proxy:
proxy = LJTableSearchProxy()
self.setModel(proxy)
# if isinstance(mdl, )
proxy.setSourceModel(mdl)
self.setSortingEnabled(True)
# self.horizontalHeader().customContextMenuRequested.connect(
# self.header_right_click
# )
# settings = UISettings.settings()
# hheading = self.horizontalHeader()
# state = settings.value(widget_name(self) + ":hheading", None)
# if state:
# hheading.restoreState(state)
[docs]
def set_search_box(self, wgt):
self.search_wgt = wgt
self.model().set_search_widget(wgt)
try:
wgt.textChanged.connect(self.model().invalidateFilter)
except AttributeError:
pass
# Right Click Menu Function
[docs]
def header_right_click(self, position):
self.header_right_click_menu.exec(self.mapToGlobal(position))
# Unfinished deprecated feature for removing Alchemy columns
[docs]
def viewClicked(self):
items = []
if self.selectionModel():
for each in self.selectionModel().selectedRows():
try:
mdl_index = self.model().mapToSource(each)
mdl = self.model().sourceModel()
row = mdl_index.row()
sel = mdl.data_[row]
items.append(sel)
except AttributeError:
# TODO this seems so much simpler than the above, we should probably just use this
data = self.model().data(each, QtCore.Qt.DisplayRole)
items.append(data)
else:
logging.info("No data to select")
try:
self.selected.emit(items)
except IndexError:
logging.info("nothing selected")
self.nothing_selected.emit()
[docs]
def select_row_by_text(self, text, column=0):
# search all the items in the table view and select the one that has 'text' in it.
# .setSelection() is a massive part of figuring this out.
data = []
row_count = self.model().rowCount()
for row in range(0, row_count + 1):
src_index = self.model().index(row, column)
data = self.model().data(src_index, QtCore.Qt.DisplayRole)
if data == text:
self.selectRow(row)
self.selected.emit([data])
[docs]
def on_closing(self):
settings = UISettings.settings()
try:
hheading = self.horizontalHeader()
settings.setValue(widget_name(self) + ":hheading", hheading.saveState())
except RuntimeError:
# eek we were closing any way
print("some thing bad happened")
[docs]
def dragMoveEvent(self, e):
if e.mimeData().hasUrls:
e.setDropAction(QtCore.Qt.CopyAction)
e.accept()
else:
e.ignore()
[docs]
def dropEvent(self, e):
# this is set up specifically to handle files as that's the only use case
# we've encountered to date, i'm sure we can put options in as they arise.
drop_handler(self.dropped, e)
[docs]
def column_count(self):
if self.model() is not None:
return self.model().columnCount()
else:
return 0
[docs]
def resizeEvent(self, event):
# TODO - this doesn't work on mac, but does on windows
"""Resize all sections to content and user interactive"""
super(LJTableWidget, self).resizeEvent(event)
header = self.horizontalHeader()
v_header = self.verticalHeader()
total_height = 0
total_width = 0
for column in range(header.count()):
try:
width = header.sectionSize(column)
header.setSectionResizeMode(column, QtWidgets.QHeaderView.Interactive)
header.resizeSection(column, width)
total_width += width
except AttributeError:
logging.debug("PySide6 compatibility issue: setResizeMode")
logging.info("PySide6 compatibility issue: setSectionResizeMode")
for row in range(v_header.count()):
try:
height = v_header.sectionSize(row)
v_header.setSectionResizeMode(row, QtWidgets.QHeaderView.Interactive)
v_header.resizeSection(row, height)
total_height += height
except AttributeError:
logging.debug("PySide6 compatibility issue: setResizeMode")
self.height_hint = total_height
self.width_hint = total_width
self.sizeHint()