-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFieldTable.py
233 lines (171 loc) · 7.71 KB
/
FieldTable.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
#Import basic modules
import os
import re
#Import the main window object (mw) from aqt
from aqt import mw
#Import the "show info" tool from utils.py
from aqt.utils import showInfo
#Import all of the Qt GUI library
from aqt.qt import *
#Import local .py modules
from . import Utils
echo = Utils.echo
from . import CustomQt
#Class to instantiate a GroupWindow object
class FieldTable(QTableWidget):
#Setup signals for when a row is added / removed
rowAdded = pyqtSignal(int)
rowRemoved = pyqtSignal(int)
def __init__(self, group, *args, **kwargs):
super().__init__(*args, **kwargs)
#Config variables
self.tableClearable = True
self.triggers = True
#Set arguments to local properties
self.group = group
#Set the default table
self.setColumnCount(3)
self.hideColumn(1)
self.setHorizontalHeaderLabels(['Fields', 'RegEx', 'Delete'] )
self.addFieldRow()
#Resize the columns
self.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch)
self.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch)
self.horizontalHeader().setSectionResizeMode(2, QHeaderView.Fixed)
self.horizontalHeader().resizeSection(2, 65)
#Method trigger to update the field in the Comparer object and also adds a new row if the index = row count - 1
def selectField(self, fieldRow):
if not self.triggers:
return
self.triggers = False
#Get the row index
rowIndex = fieldRow.rowIndex
#Get the selected field index (which is the field index - 1, since the first row is a placeholder)
selectedIndex = fieldRow.currentIndex() - 1
#If this is the first placeholder field, remove the field row
#and return
if selectedIndex == -1:
self.remFieldRow(rowIndex)
self.triggers = True
return
#Add or update the field in the Group object
self.group.addUpdateFieldRow(rowIndex, selectedIndex)
#Set the tableClearable attribute to true if the number of rows is > 0
if len(self.group.fields) > 0:
self.tableClearable = True
#Check the number of rows, if it's the last one, add a new row to the table
if rowIndex == self.rowCount() - 1:
self.addFieldRow(update = True)
self.triggers = True
#Method trigger to delete a row when selecting the delete button of a row
def selectDelete(self, fieldRow):
#If there is only one row left or it's the last row, don't delete it
rowCount = self.rowCount()
if rowCount <= 1 or rowCount - 1 == fieldRow.rowIndex:
return
#Delete the row
self.remFieldRow(fieldRow.rowIndex)
#Method trigger to save en entered regex
def enterRegex(self, regexRow):
if self.triggers == False:
return
self.triggers = False
#Retrieve the added field row
addedField = self.group.getFieldRow(regexRow.rowIndex)
#Only continue to save it if the text is different
if addedField != None and regexRow.text() != addedField['regex']:
addedField['regex'] = regexRow.text()
self.triggers = True
#Method to add a new row to the field table
def addFieldRow(self, update = False):
#Increase the number of rows in the table by 1
currentRowCount = self.rowCount() or 0
self.setRowCount(currentRowCount+1)
#Emit signal, except if it is the first row
if currentRowCount > 0:
self.rowAdded.emit(currentRowCount)
#Create a combobox to be added to the table, add the row index to it,
#disable the wheel event and link an lambda function to it
fieldRow = QComboBox(self)
fieldRow.rowIndex = currentRowCount
fieldRow.addItems(['None'])
fieldRow.wheelEvent = lambda event: None
fieldRow.currentIndexChanged.connect(lambda: self.selectField(fieldRow))
#Create a new QTableWidgetItem(), add the combobox to an attribute of it
#and add it to the field table.
self.addTableWidget(currentRowCount, 0, fieldRow)
#Place a regex line edit at the second column
regexRow = QLineEdit(self)
regexRow.rowIndex = currentRowCount
regexRow.textChanged.connect(lambda: self.enterRegex(regexRow))
self.addTableWidget(currentRowCount, 1, regexRow)
#Add a delete button to the third column
delButton = QPushButton('🗑', self)
delButton.clicked.connect(lambda: self.selectDelete(fieldRow))
self.addTableWidget(currentRowCount, 2, delButton)
#Update all the regex line edit and delete button states
self.updateRowStates()
#Add the vertical header item
item = QTableWidgetItem(f'F{currentRowCount+1}')
self.setVerticalHeaderItem(currentRowCount, item)
#Update the fields of the row if necessary
if update:
self.updateFieldRow(currentRowCount)
#Return the index of the added row
return currentRowCount
#Method to update the fields of the indicated the row based on the selected name and type
def updateFieldRow(self, rowIndex):
self.triggers = False
#Retrieve the field names to be set
fieldNames = [f"{f['name']}\n({f['noteType']['name']})\n" for f in self.group.getPossibleFields()]
#Update row fields
self.item(rowIndex, 0).widget.clear()
self.item(rowIndex, 0).widget.addItems(['None'] + fieldNames)
self.triggers = True
#Method to remove the indicated row from the field table
def remFieldRow(self, rowIndex):
#Emit signal
self.rowRemoved.emit(rowIndex)
#Remove the row
self.group.removeFieldRow(rowIndex)
self.removeRow(rowIndex)
#Update all of the indices of the field rows in the table after the indiciated index
for i in range(rowIndex, self.rowCount()):
self.item(i, 0).widget.rowIndex -= 1
#Update the vertical header items following it
for i in range(rowIndex, self.rowCount()):
self.verticalHeaderItem(i).setText(f'F{i+1}')
#Update the RegEx line edits and delete buttons
self.updateRowStates()
#Method to clear all the field rows
def clearFieldRows(self):
self.setRowCount(0)
self.group.clearFieldRows()
#Method to add an widget to an table cell
def addTableWidget(self, rowIndex, columnIndex, widget):
item = QTableWidgetItem()
item.widget = widget
self.setItem(rowIndex, columnIndex, item)
self.setCellWidget(rowIndex, columnIndex, widget)
#Method to update the RegEx line edit and delete button active states
def updateRowStates(self):
rowCount = self.rowCount()
#When the row count is 1 disable the first line edit and button
if rowCount == 1:
self.item(0, 1).widget.setEnabled(False)
self.item(0, 2).widget.setEnabled(False)
#When the row count is greater than 1, disable the last button
#and enable all other buttons
elif rowCount > 1:
self.item(rowCount-1, 1).widget.setEnabled(False)
self.item(rowCount-1, 2).widget.setEnabled(False)
for i in range(rowCount-1):
self.item(i, 1).widget.setEnabled(True)
self.item(i, 2).widget.setEnabled(True)
def setEnabledAll(self, boolean):
for i in range(self.rowCount()):
self.item(i, 0).widget.setEnabled(boolean)
self.item(i, 1).widget.setEnabled(boolean)
self.item(i, 2).widget.setEnabled(boolean)
if boolean == True:
self.updateRowStates()