Example #1
0
    def __init__(self, corpus):
        super().__init__()
        self.setWindowTitle('Search by gloss')

        layout = QVBoxLayout()

        searchLayout = QHBoxLayout()

        searchLabel = QLabel('Enter gloss to search for: ')
        searchLayout.addWidget(searchLabel)

        self.searchEdit = QLineEdit()
        completer = QCompleter()
        model = QStringListModel()
        model.setStringList([word.gloss for word in corpus])
        completer.setModel(model)
        completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.searchEdit.setCompleter(completer)
        searchLayout.addWidget(self.searchEdit)

        buttonLayout = QHBoxLayout()
        ok = QPushButton('OK')
        ok.clicked.connect(self.accept)
        buttonLayout.addWidget(ok)
        cancel = QPushButton('Cancel')
        cancel.clicked.connect(self.reject)
        buttonLayout.addWidget(cancel)

        layout.addLayout(searchLayout)
        layout.addLayout(buttonLayout)

        self.setLayout(layout)
Example #2
0
    def __init__(self, coderName, parent=None):
        super().__init__(parent=parent)
        self.setWindowTitle('Edit default coder name')

        self._coderName = coderName

        layout = QVBoxLayout()
        self.setLayout(layout)

        inputLayout = QHBoxLayout()
        layout.addLayout(inputLayout)

        self.coderNameLineEdit = QLineEdit(self._coderName)
        inputLayout.addWidget(QLabel('Default coder:'))
        inputLayout.addWidget(self.coderNameLineEdit)

        buttonLayout = QHBoxLayout()
        layout.addLayout(buttonLayout)

        okButton = QPushButton('Ok')
        buttonLayout.addWidget(okButton)
        okButton.clicked.connect(self.accept)

        cancelButton = QPushButton('Cancel')
        buttonLayout.addWidget(cancelButton)
        cancelButton.clicked.connect(self.reject)
Example #3
0
    def __init__(self, blankOptionSelection=None, wildcard=None):
        super().__init__()

        self.blankOptionSelection = blankOptionSelection
        self.wildcard = wildcard

        self.setWindowTitle('Search Options')
        layout = QVBoxLayout()

        blankOptionsLabel = QLabel(
            'How should blank spaces be interpreted in your search?')
        layout.addWidget(blankOptionsLabel)

        blankOptionsLayout = QVBoxLayout()
        self.blankOptionsGroup = QButtonGroup()

        asBlankOption = QRadioButton(
            'Interpret as literal blanks, and only match blank slots')
        blankOptionsLayout.addWidget(asBlankOption)
        self.blankOptionsGroup.addButton(asBlankOption)
        self.blankOptionsGroup.setId(asBlankOption, 0)
        if self.blankOptionSelection == 'literal':
            asBlankOption.setChecked(True)

        asWildcardOption = QRadioButton(
            'Interpret as wildcards, and match anything')
        blankOptionsLayout.addWidget(asWildcardOption)
        self.blankOptionsGroup.addButton(asWildcardOption)
        self.blankOptionsGroup.setId(asWildcardOption, 1)
        if self.blankOptionSelection == 'wildcard' or self.blankOptionSelection is None:
            asWildcardOption.setChecked(True)

        miniLayout = QHBoxLayout()
        asBlankWithWildcard = QRadioButton(
            'Interpret as literal blanks, and use this character for wildcards: '
        )
        self.wildcardLineEdit = QLineEdit()
        self.wildcardLineEdit.setMaxLength(1)
        self.wildcardLineEdit.setMaximumWidth(30)
        self.blankOptionsGroup.addButton(asBlankWithWildcard)
        self.blankOptionsGroup.setId(asBlankWithWildcard, 2)
        if self.blankOptionSelection == 'both':
            asBlankWithWildcard.setChecked(True)
            self.wildcardLineEdit.setText(self.wildcard)
        miniLayout.addWidget(asBlankWithWildcard)
        miniLayout.addWidget(self.wildcardLineEdit)
        blankOptionsLayout.addLayout(miniLayout)

        layout.addLayout(blankOptionsLayout)

        buttonLayout = QHBoxLayout()
        ok = QPushButton('OK')
        ok.clicked.connect(self.accept)
        buttonLayout.addWidget(ok)
        cancel = QPushButton('Cancel')
        cancel.clicked.connect(self.reject)
        buttonLayout.addWidget(cancel)
        layout.addLayout(buttonLayout)

        self.setLayout(layout)
Example #4
0
    def __init__(self):
        super().__init__()

        style = 'QTabWidget::pane { /* The tab widget frame */' \
                'border: 5px solid #9B9B9B;' \
                'top: -0.75em;}'

        self.c1h1Tab = AdvancedFingerTab()
        self.c1h2Tab = AdvancedFingerTab()
        self.c2h1Tab = AdvancedFingerTab()
        self.c2h2Tab = AdvancedFingerTab()

        handTab = QTabWidget()
        handTab.setStyleSheet(style)
        handTab.addTab(self.c1h1Tab, 'Config1Hand1')
        handTab.addTab(self.c1h2Tab, 'Config1Hand2')
        handTab.addTab(self.c2h1Tab, 'Config2Hand1')
        handTab.addTab(self.c2h2Tab, 'Config2Hand2')

        self.logicPanel = LogicRadioButtonGroup('horizontal', 'all', 'Signs should contain',
                                                all='All four hand/configuration specifications',
                                                any='Any of the four hand/configuration specifications')

        self.searchModePanel = LogicRadioButtonGroup('horizontal', 'pos', 'Global search mode',
                                                     pos='Positive search',
                                                     neg='Negative search')

        #self.signTypePanel = LogicRadioButtonGroup('horizontal',
        #                                           'e',
        #                                           title='Sign type',
        #                                           sg='Only one-hand signs',
        #                                           db='Only two-hand signs',
        #                                           e='Either')

        self.handCheckboxGroup = QGroupBox('Hand')
        self.box1 = QCheckBox('One-hand signs')
        self.box2 = QCheckBox('Two-hand signs (H1 == H2)')
        self.box3 = QCheckBox('Two-hand signs (H1 != H2)')

        self.box1.setChecked(True)
        self.box2.setChecked(True)
        self.box3.setChecked(True)

        hBox = QHBoxLayout()
        hBox.addWidget(self.box1)
        hBox.addWidget(self.box2)
        hBox.addWidget(self.box3)
        self.handCheckboxGroup.setLayout(hBox)

        self.notePanel = QLineEdit()
        self.notePanel.setPlaceholderText('Enter notes here...')

        mainLayout = QVBoxLayout()
        self.setLayout(mainLayout)
        mainLayout.addWidget(handTab)
        mainLayout.addWidget(self.logicPanel)
        mainLayout.addWidget(self.searchModePanel)
        #mainLayout.addWidget(self.signTypePanel)
        mainLayout.addWidget(self.handCheckboxGroup)
        mainLayout.addWidget(self.notePanel)
Example #5
0
    def __init__(self, corpus, parent, settings, recent):
        super().__init__(parent, settings, HSWorker())

        self.corpus = corpus
        self.recent = recent

        # container widget for scroll
        container = QWidget()

        scroll = QScrollArea()
        scroll.setWidgetResizable(True)
        scroll.setWidget(container)

        globalFrame = QGroupBox('Global options')
        globalLayout = QHBoxLayout()
        globalFrame.setLayout(globalLayout)

        self.forearmLogic = LogicRadioButtonGroup('vertical', 'e',
                                                  title='Forearm',
                                                  y='Yes', n='No', e='Either')

        self.estimateLogic = LogicRadioButtonGroup('vertical', 'e',
                                                   title='Estimated',
                                                   y='Yes', n='No', e='Either')

        self.uncertainLogic = LogicRadioButtonGroup('vertical', 'e',
                                                    title='Uncertain',
                                                    y='Yes', n='No', e='Either')

        self.incompleteLogic = LogicRadioButtonGroup('vertical', 'e',
                                                     title='Incomplete',
                                                     y='Yes', n='No', e='Either')
        globalLayout.addWidget(self.forearmLogic)
        globalLayout.addWidget(self.estimateLogic)
        globalLayout.addWidget(self.uncertainLogic)
        globalLayout.addWidget(self.incompleteLogic)

        self.configLogic = LogicRadioButtonGroup('vertical', 'e',
                                                 title='Configuration',
                                                 one='One-config signs', two='Two-config signs', e='Either')
        self.configLogic.chosen.connect(self.handleConfigChange)

        #self.handLogic = LogicRadioButtonGroup('vertical', 'e',
        #                                       title='Hand',
        #                                       one='One-hand signs', two='Two-hand signs', e='Either')
        #self.handLogic.chosen.connect(self.handleHandChange)

        self.handCheckboxGroup = QGroupBox('Hand')
        self.box1 = QCheckBox('One-hand signs')
        self.box2 = QCheckBox('Two-hand signs (H1 == H2)')
        self.box3 = QCheckBox('Two-hand signs (H1 != H2)')

        self.box1.setChecked(True)
        self.box2.setChecked(True)
        self.box3.setChecked(True)

        self.box1.stateChanged.connect(self.handCheckboxGroupChange)
        self.box2.stateChanged.connect(self.handCheckboxGroupChange)
        self.box3.stateChanged.connect(self.handCheckboxGroupChange)

        vBox = QVBoxLayout()
        vBox.addWidget(self.box1)
        vBox.addWidget(self.box2)
        vBox.addWidget(self.box3)
        self.handCheckboxGroup.setLayout(vBox)

        self.createConfigHand()
        self.createHandshapes()

        self.logicPanel = LogicRadioButtonGroup('vertical',
                                                'all',
                                                title='Signs should contain...',
                                                all='All of the above configurations',
                                                any='Any of the above configurations')

        self.searchModePanel = LogicRadioButtonGroup('vertical', 'pos', 'Global search mode',
                                                     pos='Positive search',
                                                     neg='Negative search')

        self.notePanel = QLineEdit()
        self.notePanel.setPlaceholderText('Enter notes here...')

        mainLayout = QGridLayout()
        mainLayout.addWidget(globalFrame, 0, 0, 1, 2)
        mainLayout.addWidget(self.configLogic, 0, 2, 1, 1)
        #mainLayout.addWidget(self.handLogic, 0, 3, 1, 1)
        mainLayout.addWidget(self.handCheckboxGroup, 0, 3, 1, 1)
        mainLayout.addWidget(self.c1h1Group, 1, 0, 1, 1)
        mainLayout.addWidget(self.c1h2Group, 1, 1, 1, 1)
        mainLayout.addWidget(self.c2h1Group, 1, 2, 1, 1)
        mainLayout.addWidget(self.c2h2Group, 1, 3, 1, 1)
        mainLayout.addWidget(self.logicPanel, 2, 0, 1, 1)
        mainLayout.addWidget(self.searchModePanel, 2, 1, 1, 1)
        mainLayout.addWidget(self.otherGroup, 2, 2, 1, 2)
        mainLayout.addWidget(self.unmarkedGroup, 3, 0, 1, 4)
        mainLayout.addWidget(self.markedGroup, 4, 0, 1, 4)
        mainLayout.addWidget(self.notePanel, 5, 0, 1, 4)
        container.setLayout(mainLayout)

        #####This part should be removed later#####
        #self.testButton = QPushButton('test')
        #mainLayout.addWidget(self.testButton, 6, 0, 1, 1)
        #self.testButton.clicked.connect(self.test)
        #####This part should be removed later#####
        self.layout().insertWidget(0, scroll)
Example #6
0
class HandshapeSearchDialog(FunctionDialog):
    header = ['Corpus', 'Sign', 'Token frequency', 'Note']
    about = 'Handshape search'
    name = 'handshape search'

    def __init__(self, corpus, parent, settings, recent):
        super().__init__(parent, settings, HSWorker())

        self.corpus = corpus
        self.recent = recent

        # container widget for scroll
        container = QWidget()

        scroll = QScrollArea()
        scroll.setWidgetResizable(True)
        scroll.setWidget(container)

        globalFrame = QGroupBox('Global options')
        globalLayout = QHBoxLayout()
        globalFrame.setLayout(globalLayout)

        self.forearmLogic = LogicRadioButtonGroup('vertical', 'e',
                                                  title='Forearm',
                                                  y='Yes', n='No', e='Either')

        self.estimateLogic = LogicRadioButtonGroup('vertical', 'e',
                                                   title='Estimated',
                                                   y='Yes', n='No', e='Either')

        self.uncertainLogic = LogicRadioButtonGroup('vertical', 'e',
                                                    title='Uncertain',
                                                    y='Yes', n='No', e='Either')

        self.incompleteLogic = LogicRadioButtonGroup('vertical', 'e',
                                                     title='Incomplete',
                                                     y='Yes', n='No', e='Either')
        globalLayout.addWidget(self.forearmLogic)
        globalLayout.addWidget(self.estimateLogic)
        globalLayout.addWidget(self.uncertainLogic)
        globalLayout.addWidget(self.incompleteLogic)

        self.configLogic = LogicRadioButtonGroup('vertical', 'e',
                                                 title='Configuration',
                                                 one='One-config signs', two='Two-config signs', e='Either')
        self.configLogic.chosen.connect(self.handleConfigChange)

        #self.handLogic = LogicRadioButtonGroup('vertical', 'e',
        #                                       title='Hand',
        #                                       one='One-hand signs', two='Two-hand signs', e='Either')
        #self.handLogic.chosen.connect(self.handleHandChange)

        self.handCheckboxGroup = QGroupBox('Hand')
        self.box1 = QCheckBox('One-hand signs')
        self.box2 = QCheckBox('Two-hand signs (H1 == H2)')
        self.box3 = QCheckBox('Two-hand signs (H1 != H2)')

        self.box1.setChecked(True)
        self.box2.setChecked(True)
        self.box3.setChecked(True)

        self.box1.stateChanged.connect(self.handCheckboxGroupChange)
        self.box2.stateChanged.connect(self.handCheckboxGroupChange)
        self.box3.stateChanged.connect(self.handCheckboxGroupChange)

        vBox = QVBoxLayout()
        vBox.addWidget(self.box1)
        vBox.addWidget(self.box2)
        vBox.addWidget(self.box3)
        self.handCheckboxGroup.setLayout(vBox)

        self.createConfigHand()
        self.createHandshapes()

        self.logicPanel = LogicRadioButtonGroup('vertical',
                                                'all',
                                                title='Signs should contain...',
                                                all='All of the above configurations',
                                                any='Any of the above configurations')

        self.searchModePanel = LogicRadioButtonGroup('vertical', 'pos', 'Global search mode',
                                                     pos='Positive search',
                                                     neg='Negative search')

        self.notePanel = QLineEdit()
        self.notePanel.setPlaceholderText('Enter notes here...')

        mainLayout = QGridLayout()
        mainLayout.addWidget(globalFrame, 0, 0, 1, 2)
        mainLayout.addWidget(self.configLogic, 0, 2, 1, 1)
        #mainLayout.addWidget(self.handLogic, 0, 3, 1, 1)
        mainLayout.addWidget(self.handCheckboxGroup, 0, 3, 1, 1)
        mainLayout.addWidget(self.c1h1Group, 1, 0, 1, 1)
        mainLayout.addWidget(self.c1h2Group, 1, 1, 1, 1)
        mainLayout.addWidget(self.c2h1Group, 1, 2, 1, 1)
        mainLayout.addWidget(self.c2h2Group, 1, 3, 1, 1)
        mainLayout.addWidget(self.logicPanel, 2, 0, 1, 1)
        mainLayout.addWidget(self.searchModePanel, 2, 1, 1, 1)
        mainLayout.addWidget(self.otherGroup, 2, 2, 1, 2)
        mainLayout.addWidget(self.unmarkedGroup, 3, 0, 1, 4)
        mainLayout.addWidget(self.markedGroup, 4, 0, 1, 4)
        mainLayout.addWidget(self.notePanel, 5, 0, 1, 4)
        container.setLayout(mainLayout)

        #####This part should be removed later#####
        #self.testButton = QPushButton('test')
        #mainLayout.addWidget(self.testButton, 6, 0, 1, 1)
        #self.testButton.clicked.connect(self.test)
        #####This part should be removed later#####
        self.layout().insertWidget(0, scroll)

    def handCheckboxGroupChange(self):
        # TODO: implement function to handle the hand widget
        print('==========')
        print(self.box1.isChecked())
        print(self.box2.isChecked())
        print(self.box3.isChecked())

    def handleConfigChange(self, option):
        if option == 'One-config signs':
            self.c2h1Group.selectionList.setToSpecified('empty')
            self.c2h2Group.selectionList.setToSpecified('empty')
            #self.c2h1Group.selectionList.setEnabled(False)
            #self.c2h2Group.selectionList.setEnabled(False)
            self.c2h1Group.setEnabled(False)
            self.c2h2Group.setEnabled(False)
        else:
            if self.handLogic.value() == 'One-hand signs':
                #self.c2h1Group.selectionList.setEnabled(True)
                self.c2h1Group.setEnabled(True)
            else:
                #self.c2h1Group.selectionList.setEnabled(True)
                #self.c2h2Group.selectionList.setEnabled(True)
                self.c2h1Group.setEnabled(True)
                self.c2h2Group.setEnabled(True)


    def handleHandChange(self, option):
        if option == 'One-hand signs':
            self.c1h2Group.selectionList.setToSpecified('empty')
            self.c2h2Group.selectionList.setToSpecified('empty')
            #self.c1h2Group.selectionList.setEnabled(False)
            #self.c2h2Group.selectionList.setEnabled(False)
            self.c1h2Group.setEnabled(False)
            self.c2h2Group.setEnabled(False)
        else:
            if self.configLogic.value() == 'One-config signs':
                #self.c1h2Group.selectionList.setEnabled(True)
                self.c1h2Group.setEnabled(True)
            else:
                #self.c1h2Group.selectionList.setEnabled(True)
                #self.c2h2Group.selectionList.setEnabled(True)
                self.c1h2Group.setEnabled(True)
                self.c2h2Group.setEnabled(True)

    #def test(self):
    #    res = self.generateKwargs()
        #ret = extended_finger_search(self.corpus, res['c1h1'], res['c1h2'], res['c2h1'], res['c2h2'], res['logic'])
    #    pprint(res)

    def createConfigHand(self):
        self.c1h1Group = ConfigHandPanel('Config1Hand1')
        self.c1h2Group = ConfigHandPanel('Config1Hand2')
        self.c2h1Group = ConfigHandPanel('Config2Hand1')
        self.c2h2Group = ConfigHandPanel('Config2Hand2')

    def createHandshapes(self):
        # unmarked handshapes
        self.unmarkedGroup = HandshapePanel('Unmarked handshapes')
        self.unmarkedGroup.addHandshape('A')
        self.unmarkedGroup.addHandshape('B1')
        self.unmarkedGroup.addHandshape('B2')
        self.unmarkedGroup.addHandshape('C')
        self.unmarkedGroup.addHandshape('O')
        self.unmarkedGroup.addHandshape('S')
        self.unmarkedGroup.addHandshape('1')
        self.unmarkedGroup.addHandshape('5')

        # marked handshapes
        self.markedGroup = HandshapePanel('Marked handshapes')
        self.markedGroup.addHandshape('g')
        self.markedGroup.addHandshape('7')

        # other
        self.otherGroup = HandshapePanel('Others')
        self.otherGroup.addHandshape('any')
        self.otherGroup.addHandshape('empty')

    def generateKwargs(self):
        kwargs = dict()

        kwargs['corpus'] = self.corpus
        kwargs['forearm'] = self.forearmLogic.value()
        kwargs['estimated'] = self.estimateLogic.value()
        kwargs['uncertain'] = self.uncertainLogic.value()
        kwargs['incomplete'] = self.incompleteLogic.value()
        kwargs['configuration'] = self.configLogic.value()
        kwargs['hand'] = self.handLogic.value()
        kwargs['logic'] = self.logicPanel.value()
        kwargs['config1hand1'] = self.c1h1Group.value()
        kwargs['config1hand2'] = self.c1h2Group.value()
        kwargs['config2hand1'] = self.c2h1Group.value()
        kwargs['config2hand2'] = self.c2h2Group.value()
        self.note = self.notePanel.text()

        return kwargs

    @Slot(object)
    def setResults(self, results):
        #TODO: need to modify token frequency when implemented (right not there is not frquency info)
        #TODO: double check thread method to properly place accept()
        self.results = list()
        for sign in results:
            self.results.append({'Corpus': self.corpus.name,
                                 'Sign': sign.gloss,
                                 'Token frequency': 1,
                                 'Note': self.notePanel.text()})
        self.accept()

#app = QApplication(sys.argv)
#main = HandshapeSearchDialog(None, None, None, None)
#main.show()
#sys.exit(app.exec_())
Example #7
0
    def __init__(self, corpus, parent, settings, recent):
        super().__init__(parent, settings, TSWorker())

        self.corpus = corpus
        self.recent = recent

        globalFrame = QGroupBox('Global options')
        globalFrame.setFixedWidth(500)
        globalLayout = QHBoxLayout()
        globalFrame.setLayout(globalLayout)

        self.forearmLogic = LogicRadioButtonGroup('vertical',
                                                  'e',
                                                  title='Forearm',
                                                  y='Yes',
                                                  n='No',
                                                  e='Either')
        self.estimateLogic = LogicRadioButtonGroup('vertical',
                                                   'e',
                                                   title='Estimated',
                                                   y='Yes',
                                                   n='No',
                                                   e='Either')
        self.uncertainLogic = LogicRadioButtonGroup('vertical',
                                                    'e',
                                                    title='Uncertain',
                                                    y='Yes',
                                                    n='No',
                                                    e='Either')
        self.incompleteLogic = LogicRadioButtonGroup('vertical',
                                                     'e',
                                                     title='Incomplete',
                                                     y='Yes',
                                                     n='No',
                                                     e='Either')

        self.configLogic = LogicRadioButtonGroup('vertical',
                                                 'e',
                                                 title='Configuration',
                                                 one='One-config signs',
                                                 two='Two-config signs',
                                                 e='Either')
        #self.configLogic.setFixedWidth(150)

        self.handCheckboxGroup = QGroupBox('Hand')
        self.box1 = QCheckBox('One-hand signs')
        self.box2 = QCheckBox('Two-hand signs (H1 == H2)')
        self.box3 = QCheckBox('Two-hand signs (H1 != H2)')

        self.box1.setChecked(True)
        self.box2.setChecked(True)
        self.box3.setChecked(True)

        vBox = QVBoxLayout()
        vBox.addWidget(self.box1)
        vBox.addWidget(self.box2)
        vBox.addWidget(self.box3)
        self.handCheckboxGroup.setLayout(vBox)
        # TODO: implement function to handle the hand widget
        #self.handCheckboxGroup.setFixedWidth(150)

        #self.handLogic = LogicRadioButtonGroup('vertical', 'e', title='Hand', one='One-hand signs', two='Two-hand signs', e='Either')
        #self.handLogic.setFixedWidth(150)

        frequencyGroup = QGroupBox('Frequency')
        frequencyGroup.setFixedWidth(100)
        freqeuncyLayout = QVBoxLayout()
        frequencyGroup.setLayout(freqeuncyLayout)
        self.minLineEdit = QLineEdit(str(self.corpus.getFrequencyRange()[0]))
        self.maxLineEdit = QLineEdit(str(self.corpus.getFrequencyRange()[1]))
        freqeuncyLayout.addWidget(QLabel('From:'))
        freqeuncyLayout.addWidget(self.minLineEdit)
        freqeuncyLayout.addWidget(QLabel('To:'))
        freqeuncyLayout.addWidget(self.maxLineEdit)

        globalLayout.addWidget(self.forearmLogic)
        globalLayout.addWidget(self.estimateLogic)
        globalLayout.addWidget(self.uncertainLogic)
        globalLayout.addWidget(self.incompleteLogic)

        config1Frame = QGroupBox('Config 1')
        config1Layout = QVBoxLayout()
        config1Frame.setLayout(config1Layout)

        self.config1 = TransConfigTab()
        self.config1.setFixedWidth(1250)
        config1Layout.addWidget(self.config1)

        config2Frame = QGroupBox('Config 2')
        config2Layout = QVBoxLayout()
        config2Frame.setLayout(config2Layout)

        self.config2 = TransConfigTab()
        self.config2.setFixedWidth(1250)
        config2Layout.addWidget(self.config2)

        self.notePanel = QLineEdit()
        self.notePanel.setPlaceholderText('Enter notes here...')

        metaInfoGroup = QGroupBox()
        metaInfoLayout = QHBoxLayout()
        metaInfoGroup.setLayout(metaInfoLayout)
        self.coderSlot = CoderSlot(self.corpus)
        self.lastUpdatedSlot = LastUpdateSlot(self.corpus)
        metaInfoLayout.addWidget(QLabel('Coder:'))
        metaInfoLayout.addWidget(self.coderSlot)
        metaInfoLayout.addWidget(QLabel('Last updated:'))
        metaInfoLayout.addWidget(self.lastUpdatedSlot)

        mainLayout = QGridLayout()
        #self.setLayout(mainLayout)
        mainLayout.addWidget(globalFrame, 0, 0, 1, 1)
        mainLayout.addWidget(frequencyGroup, 0, 1, 1, 1)
        mainLayout.addWidget(self.configLogic, 0, 2, 1, 1)
        #mainLayout.addWidget(self.handLogic, 0, 3, 1, 1)
        mainLayout.addWidget(self.handCheckboxGroup, 0, 3, 1, 1)
        mainLayout.addWidget(config1Frame, 1, 0, 1, 4)
        mainLayout.addWidget(config2Frame, 2, 0, 1, 4)
        mainLayout.addWidget(metaInfoGroup, 3, 0, 1, 2)
        mainLayout.addWidget(self.notePanel, 3, 2, 1, 2)

        #self.testButton = QPushButton('test')
        #mainLayout.addWidget(self.testButton, 4, 0)
        #self.testButton.clicked.connect(self.test)
        self.layout().insertLayout(0, mainLayout)
Example #8
0
class TranscriptionSearchDialog(FunctionDialog):
    header = [
        'Corpus', 'Sign', 'Coder', 'Last updated', 'Token frequency', 'Note'
    ]
    about = 'Transcription search'
    name = 'transcription search'

    def __init__(self, corpus, parent, settings, recent):
        super().__init__(parent, settings, TSWorker())

        self.corpus = corpus
        self.recent = recent

        globalFrame = QGroupBox('Global options')
        globalFrame.setFixedWidth(500)
        globalLayout = QHBoxLayout()
        globalFrame.setLayout(globalLayout)

        self.forearmLogic = LogicRadioButtonGroup('vertical',
                                                  'e',
                                                  title='Forearm',
                                                  y='Yes',
                                                  n='No',
                                                  e='Either')
        self.estimateLogic = LogicRadioButtonGroup('vertical',
                                                   'e',
                                                   title='Estimated',
                                                   y='Yes',
                                                   n='No',
                                                   e='Either')
        self.uncertainLogic = LogicRadioButtonGroup('vertical',
                                                    'e',
                                                    title='Uncertain',
                                                    y='Yes',
                                                    n='No',
                                                    e='Either')
        self.incompleteLogic = LogicRadioButtonGroup('vertical',
                                                     'e',
                                                     title='Incomplete',
                                                     y='Yes',
                                                     n='No',
                                                     e='Either')

        self.configLogic = LogicRadioButtonGroup('vertical',
                                                 'e',
                                                 title='Configuration',
                                                 one='One-config signs',
                                                 two='Two-config signs',
                                                 e='Either')
        #self.configLogic.setFixedWidth(150)

        self.handCheckboxGroup = QGroupBox('Hand')
        self.box1 = QCheckBox('One-hand signs')
        self.box2 = QCheckBox('Two-hand signs (H1 == H2)')
        self.box3 = QCheckBox('Two-hand signs (H1 != H2)')

        self.box1.setChecked(True)
        self.box2.setChecked(True)
        self.box3.setChecked(True)

        vBox = QVBoxLayout()
        vBox.addWidget(self.box1)
        vBox.addWidget(self.box2)
        vBox.addWidget(self.box3)
        self.handCheckboxGroup.setLayout(vBox)
        # TODO: implement function to handle the hand widget
        #self.handCheckboxGroup.setFixedWidth(150)

        #self.handLogic = LogicRadioButtonGroup('vertical', 'e', title='Hand', one='One-hand signs', two='Two-hand signs', e='Either')
        #self.handLogic.setFixedWidth(150)

        frequencyGroup = QGroupBox('Frequency')
        frequencyGroup.setFixedWidth(100)
        freqeuncyLayout = QVBoxLayout()
        frequencyGroup.setLayout(freqeuncyLayout)
        self.minLineEdit = QLineEdit(str(self.corpus.getFrequencyRange()[0]))
        self.maxLineEdit = QLineEdit(str(self.corpus.getFrequencyRange()[1]))
        freqeuncyLayout.addWidget(QLabel('From:'))
        freqeuncyLayout.addWidget(self.minLineEdit)
        freqeuncyLayout.addWidget(QLabel('To:'))
        freqeuncyLayout.addWidget(self.maxLineEdit)

        globalLayout.addWidget(self.forearmLogic)
        globalLayout.addWidget(self.estimateLogic)
        globalLayout.addWidget(self.uncertainLogic)
        globalLayout.addWidget(self.incompleteLogic)

        config1Frame = QGroupBox('Config 1')
        config1Layout = QVBoxLayout()
        config1Frame.setLayout(config1Layout)

        self.config1 = TransConfigTab()
        self.config1.setFixedWidth(1250)
        config1Layout.addWidget(self.config1)

        config2Frame = QGroupBox('Config 2')
        config2Layout = QVBoxLayout()
        config2Frame.setLayout(config2Layout)

        self.config2 = TransConfigTab()
        self.config2.setFixedWidth(1250)
        config2Layout.addWidget(self.config2)

        self.notePanel = QLineEdit()
        self.notePanel.setPlaceholderText('Enter notes here...')

        metaInfoGroup = QGroupBox()
        metaInfoLayout = QHBoxLayout()
        metaInfoGroup.setLayout(metaInfoLayout)
        self.coderSlot = CoderSlot(self.corpus)
        self.lastUpdatedSlot = LastUpdateSlot(self.corpus)
        metaInfoLayout.addWidget(QLabel('Coder:'))
        metaInfoLayout.addWidget(self.coderSlot)
        metaInfoLayout.addWidget(QLabel('Last updated:'))
        metaInfoLayout.addWidget(self.lastUpdatedSlot)

        mainLayout = QGridLayout()
        #self.setLayout(mainLayout)
        mainLayout.addWidget(globalFrame, 0, 0, 1, 1)
        mainLayout.addWidget(frequencyGroup, 0, 1, 1, 1)
        mainLayout.addWidget(self.configLogic, 0, 2, 1, 1)
        #mainLayout.addWidget(self.handLogic, 0, 3, 1, 1)
        mainLayout.addWidget(self.handCheckboxGroup, 0, 3, 1, 1)
        mainLayout.addWidget(config1Frame, 1, 0, 1, 4)
        mainLayout.addWidget(config2Frame, 2, 0, 1, 4)
        mainLayout.addWidget(metaInfoGroup, 3, 0, 1, 2)
        mainLayout.addWidget(self.notePanel, 3, 2, 1, 2)

        #self.testButton = QPushButton('test')
        #mainLayout.addWidget(self.testButton, 4, 0)
        #self.testButton.clicked.connect(self.test)
        self.layout().insertLayout(0, mainLayout)

    #def test(self):
    #    pprint(self.lastUpdatedSlot.value())
    #     results = {'forearmLogic': self.forearmLogic.value(),
    #                'estimated': self.estimateLogic.value(),
    #                'uncertain': self.uncertainLogic.value(),
    #                'incomplete': self.incompleteLogic.value(),
    #                'configuration': self.configLogic.value(),
    #                'hand': self.handLogic.value(),
    #                'config1': self.config1.value(),
    #                'config2': self.config2.value()}
    #     pprint(results)
    #
    #     return results

    def generateKwargs(self):
        kwargs = dict()

        kwargs['corpus'] = self.corpus
        kwargs['forearm'] = self.forearmLogic.value()
        kwargs['estimated'] = self.estimateLogic.value()
        kwargs['uncertain'] = self.uncertainLogic.value()
        kwargs['incomplete'] = self.incompleteLogic.value()
        kwargs['configuration'] = self.configLogic.value()
        kwargs['hand'] = self.handLogic.value()
        kwargs['config1'] = self.config1.value()
        kwargs['config2'] = self.config2.value()
        kwargs['frequency_range'] = (float(self.minLineEdit.text()),
                                     float(self.maxLineEdit.text()))
        kwargs['coder'] = self.coderSlot.value()
        kwargs['lastUpdated'] = self.lastUpdatedSlot.value()
        self.note = self.notePanel.text()

        return kwargs

    @Slot(object)
    def setResults(self, results):
        #TODO: need to modify token frequency when implemented (right not there is not frquency info)
        #TODO: double check thread method to properly place accept()
        self.results = list()
        for sign in results:
            self.results.append({
                'Corpus': self.corpus.name,
                'Sign': sign.gloss,
                'Coder': sign.coder,
                'Last updated': str(sign.lastUpdated),
                'Token frequency': sign.frequency,
                'Note': self.note
            })
        self.accept()
Example #9
0
    def __init__(self):
        super().__init__()

        self.handPanel = LogicRadioButtonGroup('horizontal',
                                               'c1h1',
                                               title='Configuration/Hand',
                                               c1h1='Config1Hand1',
                                               c1h2='Config1Hand2',
                                               c2h1='Config2Hand1',
                                               c2h2='Config2Hand2', )

        self.includeIbutton = QCheckBox('Treat "i" as extended')
        self.includeIbutton.setChecked(False)

        self.fingerConfigPanel = ExtendedFingerPanel()
        self.fingerNumberPanel = NumExtendedFingerPanel()

        self.relationlogicPanel = LogicRadioButtonGroup('vertical',
                                                        'a',
                                                        title='Relation between finger configuration and '
                                                              'number of extended fingers',
                                                        a='Apply both',
                                                        o='Apply either',
                                                        fg='Apply only the finger configuration',
                                                        nf='Apply only the number of extended fingers')

        #self.signTypePanel = LogicRadioButtonGroup('vertical',
        #                                           'e',
        #                                           title='Sign type',
        #                                           sg='Only one-hand signs',
        #                                           db='Only two-hand signs',
        #                                           e='Either')

        self.handCheckboxGroup = QGroupBox('Hand')
        self.box1 = QCheckBox('One-hand signs')
        self.box2 = QCheckBox('Two-hand signs (H1 == H2)')
        self.box3 = QCheckBox('Two-hand signs (H1 != H2)')

        self.box1.setChecked(True)
        self.box2.setChecked(True)
        self.box3.setChecked(True)

        vBox = QVBoxLayout()
        vBox.addWidget(self.box1)
        vBox.addWidget(self.box2)
        vBox.addWidget(self.box3)
        self.handCheckboxGroup.setLayout(vBox)

        self.modePanel = LogicRadioButtonGroup('vertical',
                                               'p',
                                               title='Search mode',
                                               p='Positive',
                                               n='Negative')
        self.notePanel = QLineEdit()
        self.notePanel.setPlaceholderText('Enter notes here...')

        mainLayout = QGridLayout()
        self.setLayout(mainLayout)
        mainLayout.addWidget(self.handPanel, 0, 0, 1, 2)
        mainLayout.addWidget(self.includeIbutton, 0, 2, 1, 1)
        mainLayout.addWidget(self.fingerConfigPanel, 1, 0, 1, 3)
        mainLayout.addWidget(self.fingerNumberPanel, 2, 0, 1, 3)
        mainLayout.addWidget(self.relationlogicPanel, 3, 0, 1, 1)
        #mainLayout.addWidget(self.signTypePanel, 3, 1, 1, 1)
        mainLayout.addWidget(self.handCheckboxGroup, 3, 1, 1, 1)
        mainLayout.addWidget(self.modePanel, 3, 2, 1, 1)
        mainLayout.addWidget(self.notePanel, 4, 0, 1, 3)
Example #10
0
class BasicSearchTab(QWidget):

    def __init__(self):
        super().__init__()

        self.handPanel = LogicRadioButtonGroup('horizontal',
                                               'c1h1',
                                               title='Configuration/Hand',
                                               c1h1='Config1Hand1',
                                               c1h2='Config1Hand2',
                                               c2h1='Config2Hand1',
                                               c2h2='Config2Hand2', )

        self.includeIbutton = QCheckBox('Treat "i" as extended')
        self.includeIbutton.setChecked(False)

        self.fingerConfigPanel = ExtendedFingerPanel()
        self.fingerNumberPanel = NumExtendedFingerPanel()

        self.relationlogicPanel = LogicRadioButtonGroup('vertical',
                                                        'a',
                                                        title='Relation between finger configuration and '
                                                              'number of extended fingers',
                                                        a='Apply both',
                                                        o='Apply either',
                                                        fg='Apply only the finger configuration',
                                                        nf='Apply only the number of extended fingers')

        #self.signTypePanel = LogicRadioButtonGroup('vertical',
        #                                           'e',
        #                                           title='Sign type',
        #                                           sg='Only one-hand signs',
        #                                           db='Only two-hand signs',
        #                                           e='Either')

        self.handCheckboxGroup = QGroupBox('Hand')
        self.box1 = QCheckBox('One-hand signs')
        self.box2 = QCheckBox('Two-hand signs (H1 == H2)')
        self.box3 = QCheckBox('Two-hand signs (H1 != H2)')

        self.box1.setChecked(True)
        self.box2.setChecked(True)
        self.box3.setChecked(True)

        vBox = QVBoxLayout()
        vBox.addWidget(self.box1)
        vBox.addWidget(self.box2)
        vBox.addWidget(self.box3)
        self.handCheckboxGroup.setLayout(vBox)

        self.modePanel = LogicRadioButtonGroup('vertical',
                                               'p',
                                               title='Search mode',
                                               p='Positive',
                                               n='Negative')
        self.notePanel = QLineEdit()
        self.notePanel.setPlaceholderText('Enter notes here...')

        mainLayout = QGridLayout()
        self.setLayout(mainLayout)
        mainLayout.addWidget(self.handPanel, 0, 0, 1, 2)
        mainLayout.addWidget(self.includeIbutton, 0, 2, 1, 1)
        mainLayout.addWidget(self.fingerConfigPanel, 1, 0, 1, 3)
        mainLayout.addWidget(self.fingerNumberPanel, 2, 0, 1, 3)
        mainLayout.addWidget(self.relationlogicPanel, 3, 0, 1, 1)
        #mainLayout.addWidget(self.signTypePanel, 3, 1, 1, 1)
        mainLayout.addWidget(self.handCheckboxGroup, 3, 1, 1, 1)
        mainLayout.addWidget(self.modePanel, 3, 2, 1, 1)
        mainLayout.addWidget(self.notePanel, 4, 0, 1, 3)

    def value(self):
        handconfig = self.handPanel.value()
        fingerConfigRegExps = self.fingerConfigPanel.generateRegExp(self.includeIbutton.isChecked())
        fingerNumberRegExps = self.fingerNumberPanel.generateRegExp(self.includeIbutton.isChecked())
        reltionLogic = self.relationlogicPanel.value()
        searchMode = self.modePanel.value()

        handconfigvalue = {
            'fingerConfigRegExps': fingerConfigRegExps,
            'fingerNumberRegExps': fingerNumberRegExps,
            'relationLogic': reltionLogic,
            'searchMode': searchMode
        }

        neutralhandRegExp = re.compile('(?P<thumb>_....)..\u2205/......' \
                            '(?P<index>1...)' \
                            '(?P<middle>.2...)' \
                            '(?P<ring>.3...)' \
                            '(?P<pinky>.4...)')
        neutralhandRegExps = set()
        neutralhandRegExps.add(neutralhandRegExp)
        neutralvalue = {
            'fingerConfigRegExps': neutralhandRegExps,
            'fingerNumberRegExps': neutralhandRegExps,
            'relationLogic': 'Apply both',
            'searchMode': 'Positive'
        }

        if handconfig == 'Configuration 1 Hand 1':
            c1h1 = handconfigvalue
            c1h2 = neutralvalue
            c2h1 = neutralvalue
            c2h2 = neutralvalue
        elif handconfig == 'Configuration 1 Hand 2':
            c1h1 = neutralvalue
            c1h2 = handconfigvalue
            c2h1 = neutralvalue
            c2h2 = neutralvalue
        elif handconfig == 'Configuration 2 Hand 1':
            c1h1 = neutralvalue
            c1h2 = neutralvalue
            c2h1 = handconfigvalue
            c2h2 = neutralvalue
        else:
            c1h1 = neutralvalue
            c1h2 = neutralvalue
            c2h1 = neutralvalue
            c2h2 = handconfigvalue

        signType = set()
        for typ, check in (('one', self.box1.isChecked()),
                           ('two-same', self.box2.isChecked()),
                           ('two-diff', self.box3.isChecked())):
            if check:
                signType.add(typ)

        return {
            'c1h1': c1h1,
            'c1h2': c1h2,
            'c2h1': c2h1,
            'c2h2': c2h2,
            'logic': 'All four hand/configuration specifications',
            'signType': signType,
            'note': self.notePanel.text()
        }
class FunctionalLoadDialog(QDialog):
    def __init__(self, corpus):
        super().__init__()
        self.corpus = corpus
        self.results = list()

        self.setWindowTitle('Functional Load')
        layout = QVBoxLayout()

        #Set up top row of radio button options
        contrastBox = QGroupBox('Contrast')
        contrastLayout = QHBoxLayout()
        self.contrastGroup = QButtonGroup()
        flexionOption = QRadioButton('Degrees of flexion')
        flexionOption.click()
        ductionOption = QRadioButton('Degree of duction')
        oppositionOption = QRadioButton('Thumb opposition')
        contactOption = QRadioButton('Thumb/finger contact')
        customOption = QRadioButton('Custom options')
        self.contrastGroup.addButton(flexionOption, id=0)
        self.contrastGroup.addButton(ductionOption, id=1)
        self.contrastGroup.addButton(oppositionOption, id=2)
        self.contrastGroup.addButton(contactOption, id=3)
        self.contrastGroup.addButton(customOption, id=4)
        contrastLayout.addWidget(flexionOption)
        contrastLayout.addWidget(ductionOption)
        contrastLayout.addWidget(oppositionOption)
        contrastLayout.addWidget(contactOption)
        contrastLayout.addWidget(customOption)
        contrastBox.setLayout(contrastLayout)

        #set up stacked widgets
        self.middleWidget = QStackedWidget()

        #Collapse degress of flexion
        flexionWidget = QWidget()
        flexionLayout = QHBoxLayout()
        self.flexionFingerSelection = QComboBox()
        self.flexionFingerSelection.addItems(
            ['Thumb', 'Index', 'Middle', 'Pinky', 'Ring', 'All'])
        self.flexionJointSelection = QComboBox()
        self.flexionJointSelection.addItems(
            ['Proximal', 'Medial', 'Distal', 'All'])
        #note: Thumb+Proximal not possible, and there's an alert window that will pop up if this combination is chosen
        flexionLayout.addWidget(self.flexionFingerSelection)
        flexionLayout.addWidget(self.flexionJointSelection)
        flexionWidget.setLayout(flexionLayout)

        #Collapse degrees of duction
        ductionWidget = QWidget()
        ductionLayout = QHBoxLayout()
        self.ductionFingerSelection = QComboBox()
        self.ductionFingerSelection.addItems([
            'Thumb/Finger', 'Index/Middle', 'Middle/Ring', 'Ring/Pinky', 'All'
        ])
        ductionLayout.addWidget(self.ductionFingerSelection)
        ductionWidget.setLayout(ductionLayout)

        #Collapse thumb opposition
        oppositionWidget = QWidget()
        oppositionLayout = QHBoxLayout()
        oppositionWidget.setLayout(oppositionLayout)

        #Collapse thumb/finger contact
        contactWidget = QWidget()
        contactLayout = QHBoxLayout()
        contactWidget.setLayout(contactLayout)

        #Collapse custom slots
        customWidget = QWidget()
        customLayout = QHBoxLayout()
        customLayout.addWidget(QLabel('Merge this symbol: '))
        self.customSymbo1A = QComboBox()
        self.customSymbo1A.addItem('')
        self.customSymbo1A.addItems(STANDARD_SYMBOLS)
        self.customSymbo1A.setEditable(True)
        customLayout.addWidget(self.customSymbo1A)
        customLayout.addWidget(QLabel('with this symbol: '))
        self.customSymbolB = QComboBox()
        self.customSymbolB.addItem('')
        self.customSymbolB.addItems(STANDARD_SYMBOLS)
        self.customSymbolB.setEditable(True)
        customLayout.addWidget(self.customSymbolB)
        customLayout.addWidget(QLabel('in these slots: '))
        self.customSlots = QLineEdit()
        customLayout.addWidget(self.customSlots)
        customLayout.addWidget(
            QLabel(
                '(separate numbers with commas, leave blank to merge symbols everywhere)'
            ))
        customWidget.setLayout(customLayout)

        #Build up middle widget
        self.middleWidget.addWidget(flexionWidget)
        self.middleWidget.addWidget(ductionWidget)
        self.middleWidget.addWidget(oppositionWidget)
        self.middleWidget.addWidget(contactWidget)
        self.middleWidget.addWidget(customWidget)

        #Connect slots and signals
        flexionOption.clicked.connect(self.changeMiddleWidget)
        ductionOption.clicked.connect(self.changeMiddleWidget)
        oppositionOption.clicked.connect(self.changeMiddleWidget)
        contactOption.clicked.connect(self.changeMiddleWidget)
        customOption.clicked.connect(self.changeMiddleWidget)

        #Bottom buttons (OK/Cancel)
        buttonLayout = QHBoxLayout()
        ok = QPushButton('OK')
        ok.clicked.connect(self.accept)
        cancel = QPushButton('Cancel')
        cancel.clicked.connect(self.reject)
        buttonLayout.addWidget(ok)
        buttonLayout.addWidget(cancel)

        layout.addWidget(contrastBox)
        layout.addWidget(self.middleWidget)
        layout.addLayout(buttonLayout)

        self.setLayout(layout)

    def changeMiddleWidget(self, e):
        self.middleWidget.setCurrentIndex(self.contrastGroup.id(self.sender()))

    def accept(self):
        index = self.middleWidget.currentIndex()
        if index == 0:
            if (self.flexionFingerSelection.currentText() == 'Thumb' and
                    self.flexionJointSelection.currentText() == 'Proximal'):
                alert = QMessageBox()
                alert.setWindowTitle('Incompatible Options')
                alert.setText(
                    'Thumbs cannot be selected for proximal joint. Choose either "Medial" or "Distal"'
                )
                alert.exec_()
                return
            self.calcByFlexion()
        elif index == 1:
            self.calcByDuction()

        elif index == 4:
            slots = self.customSlots.text()
            alert = QMessageBox()
            alert.setWindowTitle('Invalid slot numbers')
            alert.setText('Slot numbers must be between 1 and 34 (inclusive)')

            try:
                slots = [int(x.strip()) for x in slots.split(',')]
            except ValueError:
                alert.exec_()
                return

            if any(n > 34 or n < 1 for n in slots):
                alert.exec_()
                return
            self.calcCustom(slots)

        super().accept()

    def calculateEntropy(self, corpus=None):
        corpus_size = len(corpus) if corpus is not None else len(self.corpus)
        return corpus_size, sum([
            1 / corpus_size * log(1 / corpus_size) for n in range(corpus_size)
        ]) * -1

    def calcByDuction(self):
        corpus_size, starting_h = self.calculateEntropy()
        duction = self.ductionFingerSelection.currentText()
        if duction == 'Thumb/Finger':
            slot = 3
        elif duction == 'Index/Middle':
            slot = 19
        elif duction == 'Middle/Ring':
            slot = 24
        elif duction == 'Ring/Pinky':
            slot = 29
        elif duction == 'All':
            slot = -1

        if slot > 1:
            print('{} DUCTION'.format(duction.upper()))
            print('Starting size = {}\nStarting entropy = {}'.format(
                corpus_size, starting_h))
            new_corpus = defaultdict(int)
            for word in self.corpus:
                ch = word.config1hand1.copy()
                ch[slot] = 'X'
                new_corpus[''.join(ch)] += 1

            new_corpus_size, ending_h = self.calculateEntropy(new_corpus)
            print('After merging size = {}\nAfter merging entropy = {}'.format(
                len(new_corpus), ending_h))
            print('Change in entropy = {}\n'.format(starting_h - ending_h))
        else:
            print('{} DUCTION'.format(duction.upper()))
            print('Starting size = {}\nStarting entropy = {}'.format(
                corpus_size, starting_h))
            new_corpus = defaultdict(int)
            for word in self.corpus:
                ch = word.config1hand1.copy()
                ch[2] = 'X'
                ch[19] = 'X'
                ch[24] = 'X'
                ch[29] = 'X'
                new_corpus[''.join(ch)] += 1
            new_corpus_size, ending_h = self.calculateEntropy(new_corpus)
            print('After merging size = {}\nAfter merging entropy = {}'.format(
                len(new_corpus), ending_h))
            print('Change in entropy = {}\n'.format(starting_h - ending_h))

        result = [
            corpus_size, starting_h, new_corpus_size, ending_h,
            starting_h - ending_h
        ]
        self.results = [result]

    def calcCustom(self, slots):
        corpus_size, starting_h = self.calculateEntropy()

        slots = [n - 1 for n in slots]
        # minus 1 because slot numbers starts at 1 but list indices start at 0

        symbolA = self.customSymbo1A.currentText()
        symbolB = self.customSymbolB.currentText()

        print('Merging {} and {}'.format(symbolA, symbolB))
        print('Starting size = {}\nStarting entropy = {}'.format(
            corpus_size, starting_h))
        new_corpus = defaultdict(int)
        for word in self.corpus:
            ch = word.config1hand1.copy()
            for slot in slots:
                if ch[slot] in [symbolA, symbolB]:
                    ch[slot] = 'X'

            new_corpus[''.join(ch)] += 1

        new_corpus_size, ending_h = self.calculateEntropy(new_corpus)
        print('After merging size = {}\nAfter merging entropy = {}'.format(
            len(new_corpus), ending_h))
        print('Change in entropy = {}\n'.format(starting_h - ending_h))
        result = [
            corpus_size, starting_h, new_corpus_size, ending_h,
            starting_h - ending_h
        ]
        self.results = [result]

    def calcByFlexion(self):
        corpus_size, starting_h = self.calculateEntropy()

        finger = self.flexionFingerSelection.currentText()
        joint = self.flexionJointSelection.currentText()

        jointDict = {'Proximal': 0, 'Medial': 1, 'Distal': 2, 'All': -1}

        fingerDict = {
            'Thumb': 2,
            'Index': 16,
            'Middle': 21,
            'Ring': 26,
            'Pinky': 31,
            'All': -1
        }

        offset = jointDict[joint]
        slot = fingerDict[finger]
        slot += offset

        if slot > 0:  #user chose particular fingers

            print('{} {} JOINTS'.format(finger.upper(), joint.upper()))
            print('Starting size = {}\nStarting entropy = {}'.format(
                corpus_size, starting_h))
            new_corpus = defaultdict(int)
            for word in self.corpus:
                ch = word.config1hand1.copy()
                ch[slot] = 'X'
                new_corpus[''.join(ch)] += 1

            new_corpus_size, ending_h = self.calculateEntropy(new_corpus)
            print('After merging size = {}\nAfter merging entropy = {}'.format(
                len(new_corpus), ending_h))
            print('Change in entropy = {}\n'.format(starting_h - ending_h))
            self.results = [[
                corpus_size, starting_h, new_corpus_size, ending_h,
                starting_h - ending_h
            ]]

        else:  #user chose an "All" option

            if joint == 'All' and finger != 'All':
                #all the joints on a particular finger

                slot = fingerDict[finger]

                print('ALL {} JOINTS'.format(finger.upper()))
                print('Starting size = {}\nStarting entropy = {}'.format(
                    corpus_size, starting_h))
                new_corpus = defaultdict(int)
                for word in self.corpus:
                    ch = word.config1hand1.copy()
                    ch[slot] = 'X'  #proximal
                    ch[slot + 1] = 'X'  #medial
                    if not finger == 'Thumb':
                        ch[slot + 2] = 'X'  #distal
                    new_corpus[''.join(ch)] += 1

                new_corpus_size, ending_h = self.calculateEntropy(new_corpus)
                print('After merging size = {}\nAfter merging entropy = {}'.
                      format(len(new_corpus), ending_h))
                print('Change in entropy = {}\n'.format(starting_h - ending_h))
                self.results = [[
                    corpus_size, starting_h, new_corpus_size, ending_h,
                    starting_h - ending_h
                ]]

            elif finger == 'All' and joint != 'All':
                #a particular joint on all the fingers

                if joint == 'Proximal':
                    slot = 17
                elif joint == 'Medial':
                    slot = 18
                elif joint == 'Distal':
                    slot = 19

                print('ALL {} JOINTS'.format(joint.upper()))
                print('Starting size = {}\nStarting entropy = {}'.format(
                    corpus_size, starting_h))
                # for finger,slot in [('INDEX', 17), ('MIDDLE',22), ('RING',27), ('PINKY',32)]:
                new_corpus = defaultdict(int)
                for word in self.corpus:
                    ch = word.config1hand1.copy()
                    ch[slot] = 'X'
                    ch[slot + 5] = 'X'
                    ch[slot + 10] = 'X'
                    ch[slot + 15] = 'X'
                    new_corpus[''.join(ch)] += 1

                    new_corpus_size, ending_h = self.calculateEntropy(
                        new_corpus)
                print('After merging size = {}\nAfter merging entropy = {}'.
                      format(len(new_corpus), ending_h))
                print('Change in entropy = {}\n'.format(starting_h - ending_h))
                self.results = [[
                    corpus_size, starting_h, new_corpus_size, ending_h,
                    starting_h - ending_h
                ]]

            elif finger == 'All' and joint == 'All':
                results = list()
                for finger, slot in [('THUMB', 2), ('INDEX', 17),
                                     ('MIDDLE', 22), ('RING', 27),
                                     ('PINKY', 31)]:
                    print('ALL {} JOINTS'.format(joint.upper()))
                    print('Starting size = {}\nStarting entropy = {}'.format(
                        corpus_size, starting_h))
                    new_corpus = defaultdict(int)
                    for word in self.corpus:
                        ch = word.config1hand1.copy()
                        ch[slot] = 'X'
                        ch[slot + 1] = 'X'
                        if not finger == 'Thumb':
                            ch[slot + 2] = 'X'
                        new_corpus[''.join(ch)] += 1

                    new_corpus_size, ending_h = self.calculateEntropy(
                        new_corpus)
                    print(
                        'After merging size = {}\nAfter merging entropy = {}'.
                        format(len(new_corpus), ending_h))
                    print('Change in entropy = {}\n'.format(starting_h -
                                                            ending_h))
                    results.append([
                        corpus_size, starting_h, new_corpus_size, ending_h,
                        starting_h - ending_h
                    ])
                self.results = results
    def __init__(self, corpus):
        super().__init__()
        self.corpus = corpus
        self.results = list()

        self.setWindowTitle('Functional Load')
        layout = QVBoxLayout()

        #Set up top row of radio button options
        contrastBox = QGroupBox('Contrast')
        contrastLayout = QHBoxLayout()
        self.contrastGroup = QButtonGroup()
        flexionOption = QRadioButton('Degrees of flexion')
        flexionOption.click()
        ductionOption = QRadioButton('Degree of duction')
        oppositionOption = QRadioButton('Thumb opposition')
        contactOption = QRadioButton('Thumb/finger contact')
        customOption = QRadioButton('Custom options')
        self.contrastGroup.addButton(flexionOption, id=0)
        self.contrastGroup.addButton(ductionOption, id=1)
        self.contrastGroup.addButton(oppositionOption, id=2)
        self.contrastGroup.addButton(contactOption, id=3)
        self.contrastGroup.addButton(customOption, id=4)
        contrastLayout.addWidget(flexionOption)
        contrastLayout.addWidget(ductionOption)
        contrastLayout.addWidget(oppositionOption)
        contrastLayout.addWidget(contactOption)
        contrastLayout.addWidget(customOption)
        contrastBox.setLayout(contrastLayout)

        #set up stacked widgets
        self.middleWidget = QStackedWidget()

        #Collapse degress of flexion
        flexionWidget = QWidget()
        flexionLayout = QHBoxLayout()
        self.flexionFingerSelection = QComboBox()
        self.flexionFingerSelection.addItems(
            ['Thumb', 'Index', 'Middle', 'Pinky', 'Ring', 'All'])
        self.flexionJointSelection = QComboBox()
        self.flexionJointSelection.addItems(
            ['Proximal', 'Medial', 'Distal', 'All'])
        #note: Thumb+Proximal not possible, and there's an alert window that will pop up if this combination is chosen
        flexionLayout.addWidget(self.flexionFingerSelection)
        flexionLayout.addWidget(self.flexionJointSelection)
        flexionWidget.setLayout(flexionLayout)

        #Collapse degrees of duction
        ductionWidget = QWidget()
        ductionLayout = QHBoxLayout()
        self.ductionFingerSelection = QComboBox()
        self.ductionFingerSelection.addItems([
            'Thumb/Finger', 'Index/Middle', 'Middle/Ring', 'Ring/Pinky', 'All'
        ])
        ductionLayout.addWidget(self.ductionFingerSelection)
        ductionWidget.setLayout(ductionLayout)

        #Collapse thumb opposition
        oppositionWidget = QWidget()
        oppositionLayout = QHBoxLayout()
        oppositionWidget.setLayout(oppositionLayout)

        #Collapse thumb/finger contact
        contactWidget = QWidget()
        contactLayout = QHBoxLayout()
        contactWidget.setLayout(contactLayout)

        #Collapse custom slots
        customWidget = QWidget()
        customLayout = QHBoxLayout()
        customLayout.addWidget(QLabel('Merge this symbol: '))
        self.customSymbo1A = QComboBox()
        self.customSymbo1A.addItem('')
        self.customSymbo1A.addItems(STANDARD_SYMBOLS)
        self.customSymbo1A.setEditable(True)
        customLayout.addWidget(self.customSymbo1A)
        customLayout.addWidget(QLabel('with this symbol: '))
        self.customSymbolB = QComboBox()
        self.customSymbolB.addItem('')
        self.customSymbolB.addItems(STANDARD_SYMBOLS)
        self.customSymbolB.setEditable(True)
        customLayout.addWidget(self.customSymbolB)
        customLayout.addWidget(QLabel('in these slots: '))
        self.customSlots = QLineEdit()
        customLayout.addWidget(self.customSlots)
        customLayout.addWidget(
            QLabel(
                '(separate numbers with commas, leave blank to merge symbols everywhere)'
            ))
        customWidget.setLayout(customLayout)

        #Build up middle widget
        self.middleWidget.addWidget(flexionWidget)
        self.middleWidget.addWidget(ductionWidget)
        self.middleWidget.addWidget(oppositionWidget)
        self.middleWidget.addWidget(contactWidget)
        self.middleWidget.addWidget(customWidget)

        #Connect slots and signals
        flexionOption.clicked.connect(self.changeMiddleWidget)
        ductionOption.clicked.connect(self.changeMiddleWidget)
        oppositionOption.clicked.connect(self.changeMiddleWidget)
        contactOption.clicked.connect(self.changeMiddleWidget)
        customOption.clicked.connect(self.changeMiddleWidget)

        #Bottom buttons (OK/Cancel)
        buttonLayout = QHBoxLayout()
        ok = QPushButton('OK')
        ok.clicked.connect(self.accept)
        cancel = QPushButton('Cancel')
        cancel.clicked.connect(self.reject)
        buttonLayout.addWidget(ok)
        buttonLayout.addWidget(cancel)

        layout.addWidget(contrastBox)
        layout.addWidget(self.middleWidget)
        layout.addLayout(buttonLayout)

        self.setLayout(layout)