Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/main/python/constant.py
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,22 @@ class UserDefinedRoles(dict):

})

PARTS_OF_SPEECH = {
"Noun": 0,
"Verb": 1,
"Adjective": 2,
"Adverb": 3,
"Adposition": 4,
"Conjunction": 5,
"Interjection": 6,
"Numeral": 7,
"Pronoun": 8,
"Determiner": 9,
"Article": 10,
"Phrase": 11,
"Unique": 12,
"Other": 13
}

# TODO KV - define here or in module_classes? or user-defined in global settings? or maybe even in the module window(s)?
treepathdelimiter = ">"
Expand Down
81 changes: 75 additions & 6 deletions src/main/python/gui/signlevelinfospecification_view.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
from datetime import datetime

from PyQt5.QtWidgets import (
QGroupBox,
QSpacerItem,
QLineEdit,
QDialog,
QFrame,
QHBoxLayout,
QFormLayout,
QRadioButton,
QVBoxLayout,
QFormLayout,
QDialogButtonBox,
QSizePolicy,
QPlainTextEdit,
QButtonGroup,
QCheckBox,
QLabel,
QListView,
QMessageBox
QGridLayout
)

from PyQt5.QtCore import (
Expand All @@ -28,7 +31,7 @@
from lexicon.module_classes import EntryID
from gui.decorator import check_duplicated_lemma, check_empty_glosslemmaIDgloss, check_duplicated_idgloss
from gui.link_help import show_help

from constant import PARTS_OF_SPEECH

class SignLevelDateDisplay(QLabel):
def __init__(self, thedatetime=None, **kwargs):
Expand Down Expand Up @@ -125,6 +128,48 @@ def __init__(self, signlevelinfo, **kwargs):

self.signlevelinfo = signlevelinfo
self.create_and_set_layout()

def create_and_set_pos_layout(self):
# parts of speech grid layout
layout = QGridLayout()
self.pos_buttongrp = QButtonGroup()
self.pos_buttongrp.setExclusive(False)
buttons_per_row = 4
curr_row = 0
for label in PARTS_OF_SPEECH:
i = PARTS_OF_SPEECH[label]
curr_col = i % buttons_per_row
pos_cb = QCheckBox(label)
self.pos_buttongrp.addButton(pos_cb, id=i)
if label == "Other":
break
else:
layout.addWidget(pos_cb, curr_row, curr_col)
if curr_col == buttons_per_row - 1:
curr_row += 1

self.other_pos_lineedit = QLineEdit("Specify")
self.other_pos_lineedit.setMaximumHeight(25)
thisbtn = self.pos_buttongrp.button(PARTS_OF_SPEECH["Other"])

self.other_pos_lineedit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
thisbtn.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)

self.other_pos_lineedit.textEdited.connect(self.handle_othertext_edited)
other_pos_layout = QHBoxLayout()
other_pos_layout.addWidget(self.pos_buttongrp.button(PARTS_OF_SPEECH["Other"]))
other_pos_layout.addWidget(self.other_pos_lineedit)
layout.addLayout(other_pos_layout, curr_row, curr_col, 1, 2, Qt.AlignmentFlag(0)) # span one row and two columns; default alignment
return layout

# if user specifies text for an "other" selection, ensure the parent ("other") radio button is checked
def handle_othertext_edited(self, txt):
if txt == "":
# don't need to do anything special
return

# ensure the parent is checked
self.pos_buttongrp.button(PARTS_OF_SPEECH["Other"]).setChecked(True)

def create_and_set_layout(self):

Expand Down Expand Up @@ -161,10 +206,17 @@ def create_and_set_layout(self):
self.modified_display = SignLevelDateDisplay()
note_label = QLabel('Notes:')
self.note_edit = QPlainTextEdit()
self.note_edit.setMaximumHeight(50)
fingerspelled_label = QLabel('Fingerspelled:')
self.fingerspelled_cb = QCheckBox()
compoundsign_label = QLabel('Compound sign:')
self.compoundsign_cb = QCheckBox()
pos_label = QLabel('Part(s) of speech:')
self.pos_layout = self.create_and_set_pos_layout()
pos_widget = QGroupBox()
pos_widget.setMinimumHeight(110)
pos_widget.setMaximumHeight(150)
pos_widget.setLayout(self.pos_layout)

handdominance_label = QLabel("Hand dominance:")
self.handdominance_buttongroup = QButtonGroup()
Expand Down Expand Up @@ -196,11 +248,11 @@ def create_and_set_layout(self):
main_layout.addRow(fingerspelled_label, self.fingerspelled_cb)
main_layout.addRow(compoundsign_label, self.compoundsign_cb)
main_layout.addRow(handdominance_label, self.handdominance_layout)

main_layout.addRow(pos_label, pos_widget)
self.set_value()

self.setLayout(main_layout)


def entryid_counter(self):
if self.signlevelinfo is not None:
return self.signlevelinfo.entryid.counter
Expand Down Expand Up @@ -234,6 +286,7 @@ def set_value(self, signlevelinfo=None):
self.fingerspelled_cb.setChecked(signlevelinfo.fingerspelled)
self.compoundsign_cb.setChecked(signlevelinfo.compoundsign)
self.set_handdominance(signlevelinfo.handdominance)
self.set_partsofspeech(signlevelinfo.partsofspeech)

def clear(self):
self.restore_defaults()
Expand All @@ -253,13 +306,23 @@ def restore_defaults(self):
self.fingerspelled_cb.setChecked(False)
self.compoundsign_cb.setChecked(False)
self.set_handdominance(self.defaulthand)
for cb in self.pos_buttongrp.buttons():
cb.setChecked(False)
self.other_pos_lineedit.setText("")

def set_handdominance(self, handdominance):
if handdominance == 'R':
self.handdominance_r_radio.setChecked(True)
elif handdominance == 'L':
self.handdominance_l_radio.setChecked(True)

def set_partsofspeech(self, partsofspeech):
(checked_list, other_text) = partsofspeech
for label in checked_list:
self.pos_buttongrp.button(PARTS_OF_SPEECH[label]).setChecked(True)
self.other_pos_lineedit.setText(other_text)


def get_handdominance(self):
return 'R' if self.handdominance_r_radio.isChecked() else 'L'

Expand All @@ -285,7 +348,8 @@ def get_value(self):
'note': self.note_edit.toPlainText(),
'fingerspelled': self.fingerspelled_cb.isChecked(),
'compoundsign': self.compoundsign_cb.isChecked(),
'handdominance': self.get_handdominance()
'handdominance': self.get_handdominance(),
'partsofspeech': self.get_partsofspeech()
}

def get_glosses(self):
Expand All @@ -296,6 +360,11 @@ def get_lemma(self):

def get_idgloss(self):
return self.idgloss_edit.text().strip()

def get_partsofspeech(self):
checked_btns = [btn.text() for btn in self.pos_buttongrp.buttons() if btn.isChecked()]
other_label = self.other_pos_lineedit.text()
return (checked_btns, other_label)

@check_empty_glosslemmaIDgloss
@check_duplicated_idgloss
Expand Down
18 changes: 17 additions & 1 deletion src/main/python/lexicon/module_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,8 @@ def __init__(self, signlevel_info=None, serializedsignlevelinfo=None, parentsign
self._fingerspelled = 'fingerspelled' in serializedsignlevelinfo.keys() and serializedsignlevelinfo['fingerspelled']
self._compoundsign = 'compoundsign' in serializedsignlevelinfo.keys() and serializedsignlevelinfo['compoundsign']
self._handdominance = serializedsignlevelinfo['handdominance']
# backward compatibility for attribute added 20250713
self._partsofspeech = serializedsignlevelinfo['partsofspeech'] if 'partsofspeech' in serializedsignlevelinfo else ([], "")
elif signlevel_info is not None:
self._entryid = EntryID(counter=signlevel_info['entryid'], parentsign=parentsign)
self._gloss = signlevel_info['gloss']
Expand All @@ -272,6 +274,8 @@ def __init__(self, signlevel_info=None, serializedsignlevelinfo=None, parentsign
self._fingerspelled = 'fingerspelled' in signlevel_info.keys() and signlevel_info['fingerspelled']
self._compoundsign = 'compoundsign' in signlevel_info.keys() and signlevel_info['compoundsign']
self._handdominance = signlevel_info['handdominance']
# backward compatibility for attribute added 20250713
self._partsofspeech = signlevel_info['partsofspeech'] if 'partsofspeech' in signlevel_info else ([], "")

def __eq__(self, other):
if isinstance(other, SignLevelInformation):
Expand All @@ -298,7 +302,8 @@ def serialize(self):
'note': self._note,
'fingerspelled': self._fingerspelled,
'compoundsign': self._compoundsign,
'handdominance': self._handdominance
'handdominance': self._handdominance,
'partsofspeech': self._partsofspeech
}

@property
Expand Down Expand Up @@ -437,6 +442,17 @@ def handdominance(self):
def handdominance(self, new_handdominance):
self._handdominance = new_handdominance

@property
def partsofspeech(self):
if not hasattr(self, '_partsofspeech'):
# backward compatibility for attribute added 20250713
self._partsofspeech = ([], "") # default value
return self._partsofspeech

@partsofspeech.setter
def partsofspeech(self, pos):
self._partsofspeech = pos


# This module stores the movement information for a particular articulator/s.
# It also stores "Added Info" (estimated, uncertain, etc) characteristics for each selected movement
Expand Down