Worklog GUI somewhat complete

This commit is contained in:
Fabian 2021-11-27 17:25:53 +01:00
parent 35a884ea1e
commit d953cdd5ed
5 changed files with 251 additions and 76 deletions

View File

@ -9,6 +9,48 @@ except ImportError:
from PySide2 import QtCore from PySide2 import QtCore
qt_resource_data = b"\ qt_resource_data = b"\
\x00\x00\x02x\
<\
svg xmlns=\x22http:\
//www.w3.org/200\
0/svg\x22 viewBox=\x22\
0 0 24 24\x22 width\
=\x2224\x22 height=\x2224\
\x22>\x0a <defs id=\x22d\
efs3051\x22>\x0a <s\
tyle type=\x22text/\
css\x22 id=\x22current\
-color-scheme\x22>\x0a\
.ColorSche\
me-Text {\x0a \
color:#232629;\
\x0a }\x0a <\
/style>\x0a </defs\
>\x0a <g transform\
=\x22translate(1,1)\
\x22>\x0a <path sty\
le=\x22fill:current\
Color;fill-opaci\
ty:1;stroke:none\
\x22 d=\x22M 4 3 L 4 5\
L 5 5 L 5 4 L 1\
7 4 L 17 5 L 18 \
5 L 18 3 L 17 3 \
L 5 3 L 4 3 z M \
11 5 L 5 11.1835\
94 L 5.7929688 1\
2 L 11 6.6328125\
L 16.207031 12 \
L 17 11.183594 L\
11 5 z M 8 13 L\
8 19 L 9 19 L 1\
3 19 L 14 19 L 1\
4 13 L 13 13 L 1\
3 18 L 9 18 L 9 \
13 L 8 13 z \x22 cl\
ass=\x22ColorScheme\
-Text\x22/>\x0a </g>\x0a\
</svg>\x0a\
\x00\x00\x02\xdd\ \x00\x00\x02\xdd\
<\ <\
svg xmlns=\x22http:\ svg xmlns=\x22http:\
@ -120,6 +162,47 @@ Scheme-Text {\x0a \
rScheme-Text\x22 fi\ rScheme-Text\x22 fi\
ll=\x22currentColor\ ll=\x22currentColor\
\x22/>\x0a</svg>\x0a\ \x22/>\x0a</svg>\x0a\
\x00\x00\x02g\
<\
svg xmlns=\x22http:\
//www.w3.org/200\
0/svg\x22 version=\x22\
1.1\x22 viewBox=\x220 \
0 24 24\x22 width=\x22\
24\x22 height=\x2224\x22>\
\x0a <style type=\x22\
text/css\x22 id=\x22cu\
rrent-color-sche\
me\x22>\x0a .Co\
lorScheme-Negati\
veText {\x0a \
color:#da44\
53;\x0a }\x0a \
</style>\x0a <g \
transform=\x22trans\
late(1,1)\x22>\x0a \
<path class=\x22Col\
orScheme-Negativ\
eText\x22 d=\x22M 3.69\
92188 3 L 3 3.69\
92188 L 10.30078\
1 11 L 3 18.3007\
81 C 3 18.300781\
3.7112147 18.99\
3333 3.6992188 1\
9 L 11 11.699219\
L 18.300781 19 \
C 18.288781 18.9\
933 19 18.300781\
19 18.300781 L \
11.699219 11.001\
953 L 19 3.69921\
88 L 18.300781 3\
L 11 10.300781 \
L 3.6992188 3 z \
\x22 fill=\x22currentC\
olor\x22/>\x0a </g>\x0a<\
/svg>\x0a\
\x00\x00\x01K\ \x00\x00\x01K\
<\ <\
svg viewBox=\x220 0\ svg viewBox=\x220 0\
@ -300,6 +383,10 @@ qt_resource_name = b"\
\x00o\xa6S\ \x00o\xa6S\
\x00i\ \x00i\
\x00c\x00o\x00n\x00s\ \x00c\x00o\x00n\x00s\
\x00\x10\
\x03\x84Y\x07\
\x00c\
\x00l\x00o\x00u\x00d\x00-\x00u\x00p\x00l\x00o\x00a\x00d\x00.\x00s\x00v\x00g\
\x00\x11\ \x00\x11\
\x03S\x8a\x87\ \x03S\x8a\x87\
\x00d\ \x00d\
@ -314,6 +401,11 @@ qt_resource_name = b"\
\x0f\x22iG\ \x0f\x22iG\
\x00a\ \x00a\
\x00r\x00r\x00o\x00w\x00-\x00r\x00i\x00g\x00h\x00t\x00.\x00s\x00v\x00g\ \x00r\x00r\x00o\x00w\x00-\x00r\x00i\x00g\x00h\x00t\x00.\x00s\x00v\x00g\
\x00\x16\
\x0e\x92\x91G\
\x00e\
\x00d\x00i\x00t\x00-\x00d\x00e\x00l\x00e\x00t\x00e\x00-\x00r\x00e\x00m\x00o\x00v\
\x00e\x00.\x00s\x00v\x00g\
\x00\x0e\ \x00\x0e\
\x08\xfa8\xa7\ \x08\xfa8\xa7\
\x00a\ \x00a\
@ -344,25 +436,29 @@ qt_resource_name = b"\
qt_resource_struct = b"\ qt_resource_struct = b"\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
\x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x09\x00\x00\x00\x02\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x0b\x00\x00\x00\x02\
\x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x01<\x00\x00\x00\x00\x00\x01\x00\x00\x0e\xe9\ \x00\x00\x01\x94\x00\x00\x00\x00\x00\x01\x00\x00\x13\xd0\
\x00\x00\x01}.b\xfd-\ \x00\x00\x01}.b\xfd-\
\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ \x00\x00\x006\x00\x00\x00\x00\x00\x01\x00\x00\x02|\
\x00\x00\x01}.a\xe4+\ \x00\x00\x01}.a\xe4+\
\x00\x00\x008\x00\x00\x00\x00\x00\x01\x00\x00\x02\xe1\ \x00\x00\x00^\x00\x00\x00\x00\x00\x01\x00\x00\x05]\
\x00\x00\x01}.\x1a\xb9\xf9\ \x00\x00\x01}.\x1a\xb9\xf9\
\x00\x00\x00\x88\x00\x00\x00\x00\x00\x01\x00\x00\x06\x95\ \x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
\x00\x00\x01}b-h:\
\x00\x00\x00\xe0\x00\x00\x00\x00\x00\x01\x00\x00\x0b|\
\x00\x00\x01}.b $\ \x00\x00\x01}.b $\
\x00\x00\x01\x1c\x00\x00\x00\x00\x00\x01\x00\x00\x0d\x82\ \x00\x00\x01t\x00\x00\x00\x00\x00\x01\x00\x00\x12i\
\x00\x00\x01}.a\xce_\ \x00\x00\x01}.a\xce_\
\x00\x00\x00\xaa\x00\x00\x00\x00\x00\x01\x00\x00\x07\xe4\ \x00\x00\x01\x02\x00\x00\x00\x00\x00\x01\x00\x00\x0c\xcb\
\x00\x00\x01}.b\xe1.\ \x00\x00\x01}.b\xe1.\
\x00\x00\x00\xc8\x00\x00\x00\x00\x00\x01\x00\x00\x09\xce\ \x00\x00\x01 \x00\x00\x00\x00\x00\x01\x00\x00\x0e\xb5\
\x00\x00\x01}/\x83\xea~\ \x00\x00\x01}/\x83\xea~\
\x00\x00\x01\x00\x00\x00\x00\x00\x00\x01\x00\x00\x0c2\ \x00\x00\x01X\x00\x00\x00\x00\x00\x01\x00\x00\x11\x19\
\x00\x00\x01}.b\x05\xfc\ \x00\x00\x01}.b\x05\xfc\
\x00\x00\x00d\x00\x00\x00\x00\x00\x01\x00\x00\x05E\ \x00\x00\x00\xae\x00\x00\x00\x00\x00\x01\x00\x00\x09\x11\
\x00\x00\x01}a\xb5\x12\xd7\
\x00\x00\x00\x8a\x00\x00\x00\x00\x00\x01\x00\x00\x07\xc1\
\x00\x00\x01}.b1)\ \x00\x00\x01}.b1)\
" "

View File

@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<defs id="defs3051">
<style type="text/css" id="current-color-scheme">
.ColorScheme-Text {
color:#232629;
}
</style>
</defs>
<g transform="translate(1,1)">
<path style="fill:currentColor;fill-opacity:1;stroke:none" d="M 4 3 L 4 5 L 5 5 L 5 4 L 17 4 L 17 5 L 18 5 L 18 3 L 17 3 L 5 3 L 4 3 z M 11 5 L 5 11.183594 L 5.7929688 12 L 11 6.6328125 L 16.207031 12 L 17 11.183594 L 11 5 z M 8 13 L 8 19 L 9 19 L 13 19 L 14 19 L 14 13 L 13 13 L 13 18 L 9 18 L 9 13 L 8 13 z " class="ColorScheme-Text"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 632 B

View File

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 24 24" width="24" height="24">
<style type="text/css" id="current-color-scheme">
.ColorScheme-NegativeText {
color:#da4453;
}
</style>
<g transform="translate(1,1)">
<path class="ColorScheme-NegativeText" d="M 3.6992188 3 L 3 3.6992188 L 10.300781 11 L 3 18.300781 C 3 18.300781 3.7112147 18.993333 3.6992188 19 L 11 11.699219 L 18.300781 19 C 18.288781 18.9933 19 18.300781 19 18.300781 L 11.699219 11.001953 L 19 3.6992188 L 18.300781 3 L 11 10.300781 L 3.6992188 3 z " fill="currentColor"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 615 B

View File

@ -5,8 +5,10 @@
<file>appointment-new-light.svg</file> <file>appointment-new-light.svg</file>
<file>arrow-left.svg</file> <file>arrow-left.svg</file>
<file>arrow-right.svg</file> <file>arrow-right.svg</file>
<file>cloud-upload.svg</file>
<file>dialog-cancel.svg</file> <file>dialog-cancel.svg</file>
<file>dialog-ok.svg</file> <file>dialog-ok.svg</file>
<file>edit-delete-remove.svg</file>
<file>go-next.svg</file> <file>go-next.svg</file>
<file>list-add.svg</file> <file>list-add.svg</file>
<file>list-remove.svg</file> <file>list-remove.svg</file>

View File

@ -1,4 +1,7 @@
import enum
from fime.progressindicator import ProgressIndicator from fime.progressindicator import ProgressIndicator
from fime.util import get_icon, get_screen_height
try: try:
from PySide6 import QtCore, QtGui, QtWidgets from PySide6 import QtCore, QtGui, QtWidgets
@ -37,35 +40,12 @@ class Worklog(QtWidgets.QDialog):
editor = self.table.cellWidget(self.table.currentRow(), self.table.currentColumn()) editor = self.table.cellWidget(self.table.currentRow(), self.table.currentColumn())
editor.setFocus() editor.setFocus()
def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
self.setWindowTitle("Worklog")
self._changing_items = False
self.tableWidget = Worklog.TabTable(self)
self.tableWidget.setColumnCount(3)
self.tableWidget.setHorizontalHeaderLabels(["Task", "Comment", "Duration"])
self.tableWidget.cellChanged.connect(self.cell_changed)
self.hheader = QtWidgets.QHeaderView(QtCore.Qt.Orientation.Horizontal)
self.hheader.setMinimumSectionSize(1)
self.hheader.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
self.tableWidget.setHorizontalHeader(self.hheader)
self.hheader.setSectionResizeMode(self.hheader.logicalIndex(1), QtWidgets.QHeaderView.Stretch)
self.vheader = QtWidgets.QHeaderView(QtCore.Qt.Orientation.Vertical)
self.vheader.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
self.vheader.hide()
self.tableWidget.setVerticalHeader(self.vheader)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.tableWidget)
self.setLayout(layout)
self.refresh_table()
class TableTextEdit(QtWidgets.QTextEdit): class TableTextEdit(QtWidgets.QTextEdit):
def __init__(self, text, parent, *args, **kwargs): text_changed = QtCore.Signal(str, int)
def __init__(self, text, row, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs) super().__init__(parent, *args, **kwargs)
self.row = row
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setLineWrapMode(QtWidgets.QTextEdit.WidgetWidth) self.setLineWrapMode(QtWidgets.QTextEdit.WidgetWidth)
self.setAcceptRichText(False) self.setAcceptRichText(False)
@ -79,61 +59,131 @@ class Worklog(QtWidgets.QDialog):
@QtCore.Slot() @QtCore.Slot()
def on_text_changed(self): def on_text_changed(self):
self.setFixedHeight(self.document().size().toSize().height()) self.setFixedHeight(self.document().size().toSize().height())
self.text_changed.emit(self.document().toPlainText(), self.row)
class Status(enum.Enum):
PROGRESS = enum.auto()
OK = enum.auto()
ERROR = enum.auto()
def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
self.setWindowTitle("Worklog")
self._changing_items = False
self._report_data = []
self._status = []
self.row_height = None
self.tableWidget = Worklog.TabTable(self)
self.tableWidget.setColumnCount(3)
self.tableWidget.setHorizontalHeaderLabels(["Task", "Comment", "Duration"])
self.tableWidget.cellChanged.connect(self.cell_changed)
self.hheader = QtWidgets.QHeaderView(QtCore.Qt.Orientation.Horizontal)
self.hheader.setMinimumSectionSize(10)
self.tableWidget.setHorizontalHeader(self.hheader)
self.hheader.setSectionResizeMode(self.hheader.logicalIndex(0), QtWidgets.QHeaderView.Stretch)
self.hheader.setSectionResizeMode(self.hheader.logicalIndex(1), QtWidgets.QHeaderView.Fixed)
self.hheader.resizeSection(self.hheader.logicalIndex(1), get_screen_width(self) * 0.2)
self.hheader.setSectionResizeMode(self.hheader.logicalIndex(2), QtWidgets.QHeaderView.ResizeToContents)
self.vheader = QtWidgets.QHeaderView(QtCore.Qt.Orientation.Vertical)
self.vheader.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
self.vheader.hide()
self.tableWidget.setVerticalHeader(self.vheader)
self.tableWidget.setMaximumWidth(get_screen_width(self) * 0.8)
self.upload_button = QtWidgets.QPushButton()
self.upload_button.setText("Upload")
self.upload_button.setIcon(get_icon("cloud-upload"))
#self.upload_button.pressed.connect(self.del_log)
self.upload_button.setAutoDefault(False)
self.upload_button.setMinimumWidth(self.upload_button.minimumSizeHint().width() * 1.33)
self.ok_button = QtWidgets.QPushButton()
self.ok_button.setText("OK")
self.ok_button.setIcon(get_icon("dialog-ok"))
#self.ok_button.pressed.connect(self._accept)
self.ok_button.setAutoDefault(True)
alayout = QtWidgets.QHBoxLayout()
alayout.addSpacerItem(QtWidgets.QSpacerItem(1, 1, QtWidgets.QSizePolicy.Expanding))
alayout.addWidget(self.upload_button)
alayout.addWidget(self.ok_button)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.tableWidget)
layout.addLayout(alayout)
self.setLayout(layout)
def set_data(self, data):
self._report_data = data
for i, _ in enumerate(self._report_data):
self._status.append(
(Worklog.Status.PROGRESS, "Fetching")
)
self.refresh_table()
def update_status(self, row, new_status, status_text="Could not find specified issue"):
self._status[row] = (new_status, status_text)
self.update_status_view(row)
def refresh_table(self): def refresh_table(self):
self._changing_items = True self._changing_items = True
self._report_data = [ if not self.row_height:
["ASG-8690 Ansible - Debian 11 Support", "Impl\nMore impl", "01:23"], self.tableWidget.setRowCount(1)
["ASG-8342 Ansible - MariaDB Rolle überarbeiten ", "Test", "03:57"], item = QtWidgets.QTableWidgetItem("test")
["ASG-8685 CATS Testsystem: Debian Upgrades Server mit Version kleiner 10 ", "Doing", "02:12"], self.tableWidget.setItem(0, 0, item)
] self.row_height = self.tableWidget.rowHeight(0)
self.tableWidget.setRowCount(len(self._report_data)) self.tableWidget.setRowCount(len(self._report_data))
for row, _ in enumerate(self._report_data): for row, _ in enumerate(self._report_data):
item0 = QtWidgets.QTableWidgetItem(self._report_data[row][0]) item0 = QtWidgets.QTableWidgetItem(self._report_data[row][0])
self.tableWidget.setItem(row, 0, item0) self.tableWidget.setItem(row, 0, item0)
size = self.tableWidget.rowHeight(row) self.update_status_view(row)
if row == 1: text_edit = Worklog.TableTextEdit(self._report_data[row][1], row, self)
icon = ProgressIndicator(self)
icon.setMaximumSize(QtCore.QSize(size * 0.75, size * 0.75))
icon.setAnimationDelay(70)
icon.startAnimation()
else:
if row == 0:
item_name = "dialog-ok"
elif row == 2:
item_name = "edit-delete-remove"
icon = QtWidgets.QLabel()
icon.setPixmap(QtGui.QIcon.fromTheme(item_name).pixmap(size * 0.75, size * 0.75))
icon.setToolTip("something has gone wrong")
layout = QtWidgets.QHBoxLayout()
layout.addWidget(icon, alignment=QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
layout.setContentsMargins(size * 0.1, size * 0.1, size * 0.1, size * 0.1)
wdgt = Worklog.ClickWidget(item0, self.tableWidget, self)
wdgt.setLayout(layout)
self.tableWidget.setCellWidget(row, 0, wdgt)
#item1 = QtWidgets.QTableWidgetItem(self._report_data[row][1])
#self.tableWidget.setItem(row, 1, item1)
#print(self.tableWidget.cellWidget(0, 0).height())
text_edit = Worklog.TableTextEdit(self._report_data[row][1], self)
text_edit.textChanged.connect(self.on_resize) text_edit.textChanged.connect(self.on_resize)
text_edit.setFrameStyle(QtWidgets.QFrame.NoFrame) text_edit.setFrameStyle(QtWidgets.QFrame.NoFrame)
text_edit.text_changed.connect(self.text_edit_changed)
self.tableWidget.setCellWidget(row, 1, text_edit) self.tableWidget.setCellWidget(row, 1, text_edit)
if row == 0: if row == 0:
text_edit.setFocus() text_edit.setFocus()
item2 = QtWidgets.QTableWidgetItem(self._report_data[row][2]) item2 = QtWidgets.QTableWidgetItem(self._report_data[row][2])
self.tableWidget.setItem(row, 2, item2) self.tableWidget.setItem(row, 2, item2)
item2.setFlags(item2.flags() & QtCore.Qt.ItemIsEnabled) item2.setFlags(item2.flags() & QtCore.Qt.ItemIsEnabled)
self.tableWidget.resizeColumnToContents(0)
# TODO integrate entered text and max screen width
comment_width = get_screen_width(self) * 0.2
self.tableWidget.setMinimumWidth(self.tableWidget.columnWidth(0) + comment_width + self.tableWidget.columnWidth(2))
self.tableWidget.setColumnWidth(0, self.tableWidget.columnWidth(0) * 1.05)
# broken
#self.tableWidget.setTabOrder(self.tableWidget.cellWidget(0, 1), self.tableWidget.cellWidget(1, 1))
QtWidgets.QWidget.setTabOrder(self.tableWidget.cellWidget(0, 1), self.tableWidget.cellWidget(1, 1))
self._changing_items = False self._changing_items = False
self.tableWidget.resizeColumnToContents(0)
desired_width = self.tableWidget.columnWidth(0) + self.tableWidget.columnWidth(1) + self.tableWidget.columnWidth(2)
self.tableWidget.setMinimumWidth(min(desired_width, self.tableWidget.maximumWidth()))
screen = QtGui.QGuiApplication.screenAt(self.pos())
x = ((screen.size().width() - self.tableWidget.width()) // 2) + screen.geometry().left()
y = ((screen.size().height() - self.height()) // 2) + screen.geometry().top()
self.move(x, y)
def update_status_view(self, row):
if self._status[row][0] is Worklog.Status.PROGRESS:
icon = ProgressIndicator(self)
icon.setMaximumSize(QtCore.QSize(self.row_height * 0.75, self.row_height * 0.75))
icon.setAnimationDelay(70)
icon.startAnimation()
else:
if self._status[row][0] is Worklog.Status.OK:
item_name = "dialog-ok"
elif self._status[row][0] is Worklog.Status.ERROR:
item_name = "edit-delete-remove"
icon = QtWidgets.QLabel()
icon.setPixmap(get_icon(item_name).pixmap(self.row_height * 0.75, self.row_height * 0.75))
icon.setToolTip(self._status[row][1])
layout = QtWidgets.QHBoxLayout()
layout.addWidget(icon, alignment=QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
layout.setContentsMargins(self.row_height * 0.1, self.row_height * 0.1,
self.row_height * 0.1, self.row_height * 0.1)
wdgt = Worklog.ClickWidget(self.tableWidget.item(row, 0), self.tableWidget, self)
wdgt.setLayout(layout)
self.tableWidget.setCellWidget(row, 0, wdgt)
@QtCore.Slot() @QtCore.Slot()
def on_resize(self): def on_resize(self):
self.tableWidget.resizeRowsToContents() self.tableWidget.resizeRowsToContents()
@ -147,8 +197,13 @@ class Worklog(QtWidgets.QDialog):
pass pass
@QtCore.Slot() @QtCore.Slot()
def cell_changed(self, row, column): def cell_changed(self, row, _):
if self._changing_items: if self._changing_items:
return return
print(f"cell changed: {row}, {column}") self._report_data[row][0] = self.tableWidget.item(row, 0).text()
self.update_status(row, Worklog.Status.PROGRESS, "Fetching")
self.refresh_table() self.refresh_table()
@QtCore.Slot()
def text_edit_changed(self, text, row):
self._report_data[row][1] = text