Exemple #1
0
    def validator(self):
        url_validate = QRegExpValidator(QRegExp(r'^.*[.amazon.in].*$'))
        price_validate = QDoubleValidator(bottom=0, decimals=0)
        email_validate = QRegExpValidator(
            QRegExp(r'^[a-z0-9]+[\._]?[a-z0-9]+[@]\w+[.]\w{2,3}$'))

        again = ""
        self.url = self.txtUrl.toPlainText()
        self.p = self.txtPrice.toPlainText()
        self.usr_email = self.txtEmail.toPlainText()

        if url_validate.validate(self.url, 0)[0] != QValidator.Acceptable:
            print(url_validate.validate(self.url, 0))
            again = again + "URL : url must be of www.amazon.in\n"
            self.txtUrl.clear()

        if price_validate.validate(self.p, 4)[0] != QValidator.Acceptable:
            print(price_validate.validate(self.p, 4))
            again = again + "Price : It must be Number without , and .\n"
            self.txtPrice.clear()

        if email_validate.validate(self.usr_email,
                                   0)[0] != QValidator.Acceptable:
            print(email_validate.validate(self.usr_email, 0))
            again = again + "Email : Please enter right email\n"
            self.txtEmail.clear()
        return again
Exemple #2
0
class Validador(QItemDelegate):
    def __init__(self):
        super().__init__()

    def createEditor(self, parent, option, index):

        regex = QRegExp("[0-9a-fA-F]{2}")
        self.rxval = QRegExpValidator(regex, self)

        self.edt_rx = QLineEdit(parent)
        self.edt_rx.textChanged[str].connect(self.verificar)
        self.edt_rx.editingFinished.connect(self.finalizado)
        return self.edt_rx

    def verificar(self, cadena):

        a = self.rxval.validate(cadena, 0)
        if a[0] == 0:
            c = self.edt_rx.text()
            c = c[0:len(c) - 1]
            self.edt_rx.setText(c)

    def finalizado(self):
        cadena = self.edt_rx.text()
        a = self.rxval.validate(cadena, 0)
        if a[0] == 1:
            c = self.edt_rx.text()
            c = c.zfill(2)
            self.edt_rx.setText(c)
            self.finalizado()
Exemple #3
0
 def letterValidator(self):
     validator = QRegExpValidator(QRegExp(self.letterPattern))
     message = "Ошибка в индексах столбцов. Допустимы только буквы латинского алфавита."
     result = validator.validate(self.widget.text(), 0)
     if self.buttonSwitcher(result[0], message) != QValidator.Acceptable:
         self.result["letter"] = True
         return result[0]
Exemple #4
0
 def numberValidator(self):
     validator = QRegExpValidator(QRegExp(self.numberPattern))
     message = "Ошибка в индексах строк. Допустимы только цифры."
     result = validator.validate(self.widget.text(), 0)
     if self.buttonSwitcher(result[0], message) != QValidator.Acceptable:
         self.result["number"] = True
         return result[0]
Exemple #5
0
class SpinBoxHex(QSpinBox):
    def __init__(self, parent=None, default_value=0):
        super().__init__(parent)

        self.validator = QRegExpValidator(QRegExp('^([ ]*[0-9A-Fa-f][ ]*){1,8}$'), self)
        self.setValue(default_value)

    def validate(self, text, pos):
        return self.validator.validate(text, pos)

    def valueFromText(self, text):
        return min(int(text.replace(' ', ''), 16), (1 << 31) - 1)

    def textFromValue(self, value):
        s = ''

        for i, c in enumerate(reversed(hex(value).replace('0x', '').upper())):
            if i % 2 == 0:
                s = ' ' + s

            s = c + s

        s = s.strip()

        if len(s.replace(' ', '')) % 2 == 1:
            s = '0' + s

        return s
Exemple #6
0
class TimeSpinBox(QSpinBox):
    """Custom widget to collect an interval in time, used primarily in the settings dialog"""
    SUFFIXES = {'s': 1, 'm':60, 'h':60*60, 'd':60*60*24}
    
    def __init__(self, parent=None, time=900):
        super(TimeSpinBox, self).__init__(parent)
        self.validator = QRegExpValidator(QRegExp(r'(\d+\s*[{}]\s*)+'.format(''.join([key for key in self.SUFFIXES.keys()]), Qt.CaseInsensitive))) 
        self.setMaximum(60*60*24*7 - 1)
        self.setValue(time)

    def validate(self, text, pos):
        '''Overriden validation alidate using regex'''
        return self.validator.validate(text, pos)

    def textFromValue(self, value):
        '''Overriden method to get the line edit's text from a value in seconds'''
        text = ''
        # add a #s entry to the text per suffix
        for suffix in sorted(self.SUFFIXES):
            if value >= self.SUFFIXES[suffix]:
                text += '{}{}{}'.format('' if text == '' else ' ', value//self.SUFFIXES[suffix], suffix)
                value %= self.SUFFIXES[suffix]
            elif text != '':
                text += ' 0{}'.format(suffix)
        return text

    def valueFromText(self, value):
        '''Overriden method to get the value in seconds from the line edit's text'''
        num = 0
        # get the number of each extension and multiply by their value in SUFFIXES
        for suffix in self.SUFFIXES:
            entry = re.search(r"(\d+)\s*{}".format(suffix), value)
            if entry:
                num += int(entry.group(1))*self.SUFFIXES[suffix]
        return num
Exemple #7
0
    def checkInput(self):
        # Check input
        validLineEdit = True
        validPLainText = True
        stringCallable = True
        methodToSolve = True

        # Get children of verticalLayout
        for count in range(self.ui.parameters_verticalLayout.count()):
            child = self.ui.parameters_verticalLayout.itemAt(count).widget()

            # Check if specified lineEdit are differ then zero
            if child.objectName() in ["mass_lineEdit", "stiffness_lineEdit", "end_time_lineEdit", "time_step_lineEdit"]:
                if child.text() == "":
                    validLineEdit = False

            # Check if excitation force is valid
            elif child.objectName() == "excitation_force_plainTextEdit":
                excitationForce = child.toPlainText()
                validator_function = QRegExpValidator(QRegExp(r"[\d|t|sin|cos| |+|-|*|/|.|(|)|=|<|>|if|else|elif|:]*"))

                # If string contains valid characters
                if validator_function.validate(excitationForce, 2)[0] == QValidator.Acceptable:
                    excitationForce = excitationForce.replace("cos", "np.cos")
                    excitationForce = excitationForce.replace("sin", "np.sin")
                    # Convert string to callable function
                    self.f = lambda t: eval(excitationForce)

                    # Test if callable string is valid
                    try:
                        self.f(0)
                    except:
                        stringCallable = False

                # If string contains also non-valid characters
                else:
                    validPLainText = False
        # Any method to solve
        methodChecked = [self.ui.solve_ForwardEuler_checkBox.isChecked(),
                         self.ui.solve_RungeKutta4th_checkBox.isChecked(),
                         self.ui.solve_LeapFrog_checkBox.isChecked(),
                         self.ui.solve_Newmark_checkBox.isChecked()]
        if not any(methodChecked):
            methodToSolve = False


        # If error show message else solve
        if not validLineEdit:
            self.errorMessage("Mass, Stiffness, End time and Time step must be bigger than 0")
        elif float(self.ui.end_time_lineEdit.text()) <= float(self.ui.time_step_lineEdit.text()):
            self.errorMessage("Time step must be smaller than End time")
        elif not validPLainText:
            self.errorMessage("Excitation force contains forbidden characters")
        elif not stringCallable:
            self.errorMessage("Check excitation force, it is not written correctly")
        elif not methodToSolve:
            self.errorMessage("Choose at least one method to solve")
        else:
            self.solveInput()
 def validate_input(self):
     reg_ex = QRegExp('^(?:0*(?:\.\d+)?|1(\.0*)?)$')
     input_validator = QRegExpValidator(reg_ex, self.input_value)
     self.input_value.setValidator(input_validator)
     state = input_validator.validate(self.input_value.text(), 0)
     if state[0] == QRegExpValidator.Acceptable:
         return 1
     else:
         return 0
Exemple #9
0
class jeu(QWidget):
  def __init__(self,num):
     global numero_question
     numero_question+=1
     super().__init__()
     self.num=num 
     self.mot=selection(self.num)
     self.melange=melanger(self.mot)
     ch=""
     for i in range(len(self.mot)):
      ch+=(" - "+self.melange[i])
     self.text=QLabel("""Devinez la mot caché derriere 
     """+ch)
     self.ligne=QLineEdit()
     self.exp=QRegExp("[a-zA-Z]{1,}")
     self.validator=QRegExpValidator(self.exp)
     """    self.ligne.setValidator(self.validator)"""
     self.boutton=QPushButton("tester le mot")
     
     self.layout =QGridLayout()
     self.layout.addWidget(self.text,0,0)
     self.layout.addWidget(self.ligne,1,0)

     self.layout.addWidget(self.boutton,2,0)
     self.setLayout(self.layout)
     self.setFixedSize(300,300)
     self.boutton.clicked.connect(self.test)
  def showing(self):
    super().show()
  def test(self):
     pos=0
     res=(self.validator.validate(self.ligne.text(),pos))[0] 
     if(self.ligne.text()==""):
        QMessageBox.critical(self,"erreur","veuillez saisir un mot")
     elif(self.ligne.text()==self.mot):
       """  fermer la fenetre actuelle et ouvrir une autre
 self.jeu=jeu(6)
       self.jeu.showing()
       super().close()
       """
       self.message=QMessageBox(self)
       self.message.setText("bravo votre réponse est correcte")
       self.message.exec()
       super().close()
       global numero_question
       self. f=principale(numero_question)
       self. f.show()
     elif( res!=2):
        QMessageBox.critical(self,"erreur","veuillez saisir uniquement des lettres")
     elif(self.ligne.text()!=self.mot):
        QMessageBox.critical(self,"mystere","mot incorrect veuillez essayer une autre foix")
Exemple #10
0
    def __validate_input(self):
        """
		Applies a regular expression to QLineEdit field and validates IPv4
		:return:
		"""
        regex = QRegExp()
        regex.setPattern(
            '(^[2][0-5][0-5]|^[1]{0,1}[0-9]{1,2})\.([0-2][0-5][0-5]|[1]{0,1}[0-9]{1,2})\.'
            '([0-2][0-5][0-5]|[1]{0,1}[0-9]{1,2})\.([0-2][0-5][0-5]|[1]{0,1}[0-9]{1,2})$'
        )
        validator = QRegExpValidator(regex, self.ui.line_IP)
        self.ui.line_IP.setValidator(validator)

        state = validator.validate(self.ui.line_IP.text(), 0)[0]

        if state == validator.Acceptable:
            return True
Exemple #11
0
class SpinBoxHex(QSpinBox):
    def __init__(self, parent=None, default_value=0, digit_block_size=2):
        super().__init__(parent)

        self.validator = QRegExpValidator(
            QRegExp('^([ ]*[0-9A-Fa-f][ ]*){1,8}$'), self)
        self.digit_block_size = digit_block_size
        self.hex_mode_enabled = True
        self.setValue(default_value)

    def enable_hex_mode(self, digit_block_size=None):
        self.hex_mode_enabled = True
        if digit_block_size is not None:
            self.digit_block_size = digit_block_size
        self.setValue(self.value())

    def disable_hex_mode(self):
        self.hex_mode_enabled = False
        self.setValue(self.value())

    def validate(self, text, pos):
        if not self.hex_mode_enabled:
            return super().validate(text, pos)
        return self.validator.validate(text, pos)

    def valueFromText(self, text):
        if not self.hex_mode_enabled:
            return super().valueFromText(text)
        return min(int(text.replace(' ', ''), 16), self.maximum())

    def textFromValue(self, value):
        if not self.hex_mode_enabled:
            return super().textFromValue(value)
        rev_text = hex(value).replace('0x', '').upper()[::-1]
        blocks = [
            rev_text[i:i + self.digit_block_size]
            for i in range(0, len(rev_text), self.digit_block_size)
        ]

        # Reverse blocks and chars in block to undo reverse on the string above
        text = ' '.join(s[::-1] for s in blocks[::-1])
        if len(blocks[0]) != self.digit_block_size:
            text = '0' * (self.digit_block_size - len(blocks[0])) + text
        return text
Exemple #12
0
class TextEdit_DropFormulas(QtWidgets.QTextEdit):
    def __init__(self, *args, **kwargs):
        QtWidgets.QTextEdit.__init__(self, *args, **kwargs)
        regexp = QtCore.QRegExp("[^\'\"¨&\[\]{};`~?|!@#$\\=]*")
        self.validator = QRegExpValidator(regexp)

    def keyPressEvent(self, event):
        keypress = self.validator.validate(event.text(), 0)
        if keypress[0] == QValidator.Acceptable or event.key(
        ) == QtCore.Qt.Key_Backspace:
            QtWidgets.QTextEdit.keyPressEvent(self, event)

    def dragEnterEvent(self, event):
        if isinstance(event.source(), QtWidgets.QListWidget):
            event.accept()
            self.setAcceptDrops(True)
            event.acceptProposedAction()

    def dragMoveEvent(self, event):
        if isinstance(event.source(), QtWidgets.QListWidget):
            event.accept()

    def dropEvent(self, event):
        if isinstance(event.source(), QtWidgets.QListWidget):
            listwidget = event.source()
            item = listwidget.item(listwidget.currentRow())

            if listwidget.objectName() == "listwidget_formulas_constants":
                text = item.data(QtCore.Qt.UserRole).name
            if listwidget.objectName() == "listwidget_formulas_variables":

                text = item.data(QtCore.Qt.UserRole).keyword

            self.insertHtml("[")
            self.insertHtml("<span style='font-size:8pt; color:#00aa00;'>" +
                            text)
            self.insertHtml("]")

            self.setFocus()
            cursor = QTextCursor(self.document())
            cursor.movePosition(QTextCursor.End)
            self.setTextCursor(cursor)
Exemple #13
0
class RomanSpinBox(QSpinBox):
    def __init__(self, parent=None):
        super(RomanSpinBox, self).__init__(parent)
        regex = QRegExp(r"^M?M?M?(?:CM|CD|D?C?C?C?)"
                        r"(?:XC|XL|L?X?X?X?)(?:IX|IV|V?I?I?I?)$")
        regex.setCaseSensitivity(Qt.CaseInsensitive)
        self.validator = QRegExpValidator(regex, self)
        self.setRange(1, 3999)
        self.valueChanged[str].connect(self.fixCase)

    def fixCase(self, text):
        self.lineEdit().setText(text.upper())

    def validate(self, text, pos):
        return self.validator.validate(text, pos)

    def valueFromText(self, text):
        return intFromRoman(str(text))

    def textFromValue(self, value):
        return romanFromInt(value)
    def check_param(self, param):
        """
        Check if 'param' is valid
        :param param: value of the field
        """
        # double
        if not param.is_array() and param.get_type() == "double":
            # double validator
            validator = get_custom_double_validator()

        # double array
        elif param.is_array() and param.get_type() == "double":
            string = ""
            # dinamic regular expresion
            for x in range(0, int(param.get_array_size())):
                if x == int(param.get_array_size()) - 1:
                    string += "-?[\\d\\.]*"
                else:
                    string += "-?[\\d\\.]*,\s*"
            regexp = QRegExp("\\[" + string + "\\]")
            validator = QRegExpValidator(regexp)

            # boolean array
        elif param.is_array() and param.get_type() == "boolean":
            string = ""
            # dinamic regular expresion
            for x in range(0, int(param.get_array_size())):
                if x == int(param.get_array_size()) - 1:
                    string += "(true|false)"
                else:
                    string += "(true|false),\s*"
            regexp = QRegExp("\\[" + string + "\\]")
            validator = QRegExpValidator(regexp)

        state = validator.validate(param.get_value(), 0)[0]
        return state
Exemple #15
0
class MainWidget(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        self.dict_gen = Dictionary_generator('merriam webster',
                                             ['noun', 'verb', 'adjective'],
                                             'random')

        self.setWindowTitle('Dictionary Text Generator')

        screen_rect = QDesktopWidget().availableGeometry(self)
        screen_w, screen_h = screen_rect.width(), screen_rect.height()
        app_w = screen_w * .25
        app_h = screen_h * .75
        self.resize(app_w, app_h)

        selectDictionaryLabel = QLabel('Select dictionary to use:')
        selectDictionaryLabel.setAlignment(Qt.AlignTop)
        self.selectDictionaryDropdown = QComboBox()
        self.selectDictionaryDropdown.addItems(
            Dictionary_generator.dictionaries)

        selectMethodLabel = QLabel('Select method to use:')
        self.selectMethodDropdown = QComboBox()
        self.selectMethodDropdown.addItems(Dictionary_generator.methods)

        originWordLabel = QLabel(
            'Choose origin word(s) (if multiple, use a comma separated list):')
        self.originWord = QLineEdit()
        regexp = QRegExp('^[a-zA-Z]+(,[ ][a-zA-Z]+)*')
        self.validator = QRegExpValidator(regexp)
        self.originWord.setValidator(self.validator)

        numberOfWordsLabel = QLabel('Choose number of words used per output:')
        self.numberOfWords = QSpinBox()
        self.numberOfWords.setMinimum(1)

        numberOfLoopsLabel = QLabel('Choose number of times to loop output:')
        self.numberOfLoops = QSpinBox()
        self.numberOfLoops.setMinimum(1)

        generateButton = QPushButton('Generate text')
        #generateButton.clicked.connect(self.generate_text)
        generateButton.clicked.connect(self.start_generation)

        noteText = QLabel(
            'Note: Parts of speech used are noun, verb, and adjective')

        self.output = QLabel('')
        self.output.setFrameStyle(QFrame.Panel | QFrame.Sunken)
        self.output.setWordWrap(True)
        self.output.setAlignment(Qt.AlignTop)

        outputScrollArea = QScrollArea()
        outputScrollArea.setWidget(self.output)
        outputScrollArea.setWidgetResizable(True)

        clearTextButton = QPushButton('Clear output')
        clearTextButton.clicked.connect(self.clear_text)

        parametersGroup = QGroupBox('Input Parameters:')
        outputGroup = QGroupBox('Output:')

        parametersLayout = QVBoxLayout()
        outputLayout = QVBoxLayout()

        parametersLayout.addWidget(selectDictionaryLabel)
        parametersLayout.addWidget(self.selectDictionaryDropdown)
        parametersLayout.addWidget(selectMethodLabel)
        parametersLayout.addWidget(self.selectMethodDropdown)
        parametersLayout.addWidget(originWordLabel)
        parametersLayout.addWidget(self.originWord)
        parametersLayout.addWidget(numberOfWordsLabel)
        parametersLayout.addWidget(self.numberOfWords)
        parametersLayout.addWidget(numberOfLoopsLabel)
        parametersLayout.addWidget(self.numberOfLoops)
        parametersLayout.addWidget(generateButton)
        parametersLayout.setAlignment(generateButton, Qt.AlignCenter)
        parametersLayout.addWidget(noteText)

        outputLayout.addWidget(outputScrollArea)
        outputLayout.addWidget(clearTextButton)
        outputLayout.setAlignment(clearTextButton, Qt.AlignCenter)

        parametersGroup.setLayout(parametersLayout)
        parametersGroup.setMaximumHeight(app_h * .4)
        outputGroup.setLayout(outputLayout)

        mainLayout = QVBoxLayout(self)
        mainLayout.addWidget(parametersGroup)
        mainLayout.addWidget(outputGroup)

        self.setLayout(mainLayout)

        #self.show()

    '''
    def generate_text(self):
        words = self.originWord.text().split(', ')
        numLoops = self.numberOfLoops.value()
        numWords = self.numberOfWords.value()
        self.dict_gen.dic_name = self.selectDictionaryDropdown.currentText()
        self.dict_gen.method = self.selectMethodDropdown.currentText()
        for _ in range(numLoops):
            for word in words:
                self.dict_gen.text= []
                self.dict_gen.words_used = []
                self.dict_gen.generate_story(numWords, word)
                curText = self.output.text()
                self.output.setText(curText + str(self.dict_gen) + '\n' + str(self.dict_gen.words_used) + '\n')
    '''

    def start_generation(self):
        lineedit_state = self.validator.validate(self.originWord.text(), 0)[0]
        if lineedit_state != QValidator.Acceptable:
            message = 'Please make sure your input words are a proper comma separated list.'
            msgbox = QMessageBox()
            msgbox.setText(message)
            msgbox.setWindowTitle('Error')
            msgbox.exec()
            return
        self.words = self.originWord.text().split(', ')
        numLoops = self.numberOfLoops.value()
        numWords = self.numberOfWords.value()
        totalNum = numLoops * len(self.words)
        message = '0 outputs out of ' + str(totalNum) + ' generated'
        self.parent().set_status_message(message)
        self.dict_gen.dic_name = self.selectDictionaryDropdown.currentText()
        self.dict_gen.method = self.selectMethodDropdown.currentText()
        self.generation_thread = OutputText(words=self.words,
                                            numWords=numWords,
                                            numLoops=numLoops,
                                            dict_gen=self.dict_gen)
        self.generation_thread.updateProgress.connect(self.update_generation)
        self.generation_thread.errorEncountered.connect(self.show_error)
        self.generation_thread.start()

    def update_generation(self, outputs_done, text_generated, words_used):
        curNum = outputs_done
        totalNum = self.numberOfLoops.value() * len(self.words)
        message = str(curNum) + ' outputs out of ' + str(
            totalNum) + ' generated'
        self.parent().set_status_message(message)
        curText = self.output.text()
        self.output.setText(curText + text_generated + '\n' + words_used +
                            '\n')

    # used in case that one of the words given does not have any appropriate example sentences in the dictionary
    def show_error(self, error_word):
        message = 'The word ' + error_word + ' does not have any available example sentences. Please try a different word.'
        msgbox = QMessageBox()
        msgbox.setText(message)
        msgbox.setWindowTitle('Error')
        msgbox.exec()

    def clear_text(self):
        self.output.setText('')
        self.parent().clear_status_message()
class CooperationPage(ConfigurationPageBase, Ui_CooperationPage):
    """
    Class implementing the Cooperation configuration page.
    """
    def __init__(self):
        """
        Constructor
        """
        super(CooperationPage, self).__init__()
        self.setupUi(self)
        self.setObjectName("CooperationPage")

        self.__bannedUserValidator = QRegExpValidator(
            QRegExp("[a-zA-Z0-9.-]+@"
                    "(?:(?:2(?:[0-4][0-9]|5[0-5])|[01]?[0-9]{1,2})\.){3}"
                    "(?:2(?:[0-4][0-9]|5[0-5])|[01]?[0-9]{1,2})"),
            self.bannedUserEdit)
        self.bannedUserEdit.setValidator(self.__bannedUserValidator)

        # set initial values
        self.autostartCheckBox.setChecked(
            Preferences.getCooperation("AutoStartServer"))
        self.otherPortsCheckBox.setChecked(
            Preferences.getCooperation("TryOtherPorts"))
        self.serverPortSpin.setValue(Preferences.getCooperation("ServerPort"))
        self.portToTrySpin.setValue(
            Preferences.getCooperation("MaxPortsToTry"))
        self.autoAcceptCheckBox.setChecked(
            Preferences.getCooperation("AutoAcceptConnections"))

        self.bannedUsersList.addItems(
            sorted(Preferences.getCooperation("BannedUsers")))

    def save(self):
        """
        Public slot to save the Cooperation configuration.
        """
        Preferences.setCooperation("AutoStartServer",
                                   self.autostartCheckBox.isChecked())
        Preferences.setCooperation("TryOtherPorts",
                                   self.otherPortsCheckBox.isChecked())
        Preferences.setCooperation("AutoAcceptConnections",
                                   self.autoAcceptCheckBox.isChecked())
        Preferences.setCooperation("ServerPort", self.serverPortSpin.value())
        Preferences.setCooperation("MaxPortsToTry", self.portToTrySpin.value())

        bannedUsers = []
        for row in range(self.bannedUsersList.count()):
            bannedUsers.append(self.bannedUsersList.item(row).text())
        Preferences.setCooperation("BannedUsers", bannedUsers)

    @pyqtSlot()
    def on_bannedUsersList_itemSelectionChanged(self):
        """
        Private slot to react on changes of selected banned users.
        """
        self.deleteBannedUsersButton.setEnabled(
            len(self.bannedUsersList.selectedItems()) > 0)

    @pyqtSlot(str)
    def on_bannedUserEdit_textChanged(self, txt):
        """
        Private slot to handle the user entering a banned user.
        
        @param txt text entered by the user (string)
        """
        self.addBannedUserButton.setEnabled(
            self.__bannedUserValidator.validate(txt, len(txt))[0] ==
            QValidator.Acceptable)

    @pyqtSlot()
    def on_deleteBannedUsersButton_clicked(self):
        """
        Private slot to remove the selected users from the list of
        banned users.
        """
        for itm in self.bannedUsersList.selectedItems():
            row = self.bannedUsersList.row(itm)
            itm = self.bannedUsersList.takeItem(row)
            del itm

    @pyqtSlot()
    def on_addBannedUserButton_clicked(self):
        """
        Private slot to add a user to the list of banned users.
        """
        self.bannedUsersList.addItem(self.bannedUserEdit.text())
        self.bannedUserEdit.clear()
Exemple #17
0
class DurationEdit(QAbstractSpinBox):
    """Duration edit."""

    valueChanged = pyqtSignal(int)

    def __init__(self, parent=None, hour_length=2):
        """Construct a duration edit."""
        super().__init__(parent)
        self._hour_length = hour_length
        regexp = QRegExp('^[0-9]{1,' + str(self._hour_length) +
                         '}:[0-5]{,1}[0-9]?$')
        self._validator = QRegExpValidator(regexp)
        self._minutes = 0
        self.lineEdit().textChanged.connect(self.text_changed)

    def __text(self):
        """Get the line edit text."""
        return self.lineEdit().text()

    def __cursor_position(self):
        """Get the cursor position."""
        return self.lineEdit().cursorPosition()

    def __max_hours(self):
        """Get the max hours that can be reached for the hour length."""
        return 10**self._hour_length - 1

    def validate(self, text, pos):
        """Determine whether input is valid."""
        return self._validator.validate(text, pos)

    @staticmethod
    def minutesToText(minutes):
        """Convert minutes to a time string."""
        return '{:02d}:{:02d}'.format(*divmod(minutes, 60))

    @staticmethod
    def textToMinutes(text):
        """Convert time text to minutes."""
        hours = minutes = 0
        array = text.split(':')
        try:
            hours = int(array[0])
        except ValueError:
            hours = 0
        if len(array) == 2:
            try:
                minutes = int(array[1])
            except ValueError:
                minutes = 0

        return hours * 60 + minutes

    @property
    def minutes(self):
        """Get the total minutes."""
        return self._minutes

    @minutes.setter
    def minutes(self, minutes):
        """Set the total minutes."""
        try:
            minutes = int(minutes)
        except TypeError:
            self._minutes = 0
            self.valueChanged.emit(self._minutes)
        else:
            hours = divmod(minutes, 60)[0]
            if hours > self.__max_hours():
                self._minutes = 0
                self.valueChanged.emit(self._minutes)
            else:
                self._minutes = minutes
                self.valueChanged.emit(self._minutes)
        self.lineEdit().setText(self.minutesToText(self._minutes))

    def stepBy(self, steps):
        """Trigger a step."""
        cursor_position = self.__cursor_position()
        text = self.__text()
        try:
            index = text.index(':')
        except ValueError:
            # we have only hours in the field
            self.minutes = self.minutes + steps * 60
        else:
            value = 0
            if 0 <= cursor_position <= index:
                value = steps * 60
            elif index + 1 <= cursor_position <= len(text):
                value = steps
            self.minutes = self.minutes + value

        self.lineEdit().setCursorPosition(cursor_position)

    def stepEnabled(self):
        """Determine whether stepping up and down is legal at any time."""
        cursor_position = self.__cursor_position()
        text = self.__text()
        try:
            index = text.index(':')
        except ValueError:
            # no : in string
            try:
                hours = int(text)
            except ValueError:
                hours = 0

            # we have only hours in the field
            if hours <= 0:
                return QAbstractSpinBox.StepUpEnabled
            elif hours >= self.__max_hours():
                return QAbstractSpinBox.StepDownEnabled
            else:
                return (QAbstractSpinBox.StepUpEnabled
                        | QAbstractSpinBox.StepDownEnabled)
        else:
            try:
                hours = int(text[:index])
            except ValueError:
                hours = 0
            try:
                minutes = int(text[index + 1:])
            except ValueError:
                minutes = 0

            if 0 <= cursor_position <= index:
                if hours <= 0:
                    return QAbstractSpinBox.StepUpEnabled
                elif hours >= self.__max_hours():
                    return QAbstractSpinBox.StepDownEnabled
                else:
                    return (QAbstractSpinBox.StepUpEnabled
                            | QAbstractSpinBox.StepDownEnabled)
            elif index + 1 <= cursor_position <= len(text):
                if minutes <= 0:
                    return QAbstractSpinBox.StepUpEnabled
                elif minutes >= 59:
                    return QAbstractSpinBox.StepDownEnabled
                else:
                    return (QAbstractSpinBox.StepUpEnabled
                            | QAbstractSpinBox.StepDownEnabled)

        return QAbstractSpinBox.StepNone

    def event(self, event):
        """Handle event and check for Tab and Shift+Tab."""
        if event.type() == QEvent.KeyPress:
            key = event.key()
            if key in (Qt.Key_Enter, Qt.Key_Return):
                self.minutes = self.textToMinutes(self.__text())
                return super().event(event)

            text = self.__text()
            try:
                index = text.index(':')
            except ValueError:
                # no : in string, on tab or backtab, go to next field, but
                # format this one before
                if key in (Qt.Key_Tab, Qt.Key_Backtab):
                    self.minutes = self.textToMinutes(self.__text())
                    return super().event(event)
            else:
                cursor_position = self.__cursor_position()
                if key == Qt.Key_Colon:
                    # go to minutes on : type if cursor is on hours
                    if cursor_position <= index:
                        self.lineEdit().setSelection(index + 1, len(text))
                        return True
                    else:
                        return False
                if key == Qt.Key_Tab:
                    if cursor_position <= index:
                        # go to minutes on tab
                        self.lineEdit().setSelection(index + 1, len(text))
                        return True
                    else:
                        # go to next field on tab, but update minutes before
                        self.minutes = self.textToMinutes(self.__text())
                        return super().event(event)
                elif key == Qt.Key_Backtab:
                    if cursor_position > index:
                        # go to hours on backtab
                        self.lineEdit().setSelection(0, index)
                        return True
                    else:
                        # go to previous field on backtab, but update minutes
                        # before
                        self.minutes = self.textToMinutes(self.__text())
                        return super().event(event)

        if event.type() == QEvent.KeyRelease:
            # on [0-9] key release, if hours are filled, go to minutes
            if event.key() in (Qt.Key_0, Qt.Key_1, Qt.Key_3, Qt.Key_2,
                               Qt.Key_4, Qt.Key_5, Qt.Key_6, Qt.Key_7,
                               Qt.Key_8, Qt.Key_9):
                text = self.__text()
                try:
                    index = text.index(':')
                except ValueError:
                    pass
                else:
                    cursor_position = self.__cursor_position()
                    if index == cursor_position == self._hour_length:
                        self.lineEdit().setSelection(index + 1, len(text))
                        return True

        return super().event(event)

    def focusOutEvent(self, event):
        """Receive keyboard focus events (focus lost) for the widget."""
        super().focusOutEvent(event)

        self.minutes = self.textToMinutes(self.__text())

    def focusInEvent(self, event):
        """Receive keyboard focus events (focus received) for the widget."""
        super().focusInEvent(event)

        text = self.__text()
        reason = event.reason()
        try:
            index = text.index(':')
        except ValueError:
            pass
        else:
            if reason == Qt.BacktabFocusReason:
                self.lineEdit().setSelection(index + 1, len(text))
            elif reason == Qt.TabFocusReason:
                self.lineEdit().setSelection(0, index)

    @pyqtSlot(str)
    def text_changed(self, text):
        """Update the stored value."""
        self._minutes = self.textToMinutes(text)

    def sizeHint(self):
        """Return the recommended size for the widget."""
        string = '_' * self._hour_length + ':__ '
        fm = self.fontMetrics()
        height = self.lineEdit().sizeHint().height()
        width = fm.width(string) + 12

        hint = QSize(width, height)
        option = QStyleOptionSpinBox()
        return (self.style().sizeFromContents(QStyle.CT_SpinBox, option, hint,
                                              self).expandedTo(
                                                  QApplication.globalStrut()))
Exemple #18
0
class QTimeSelect(QDoubleSpinBox):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        regex = QRegExp(r"\d:\d{1,2}:\d{1,2}(?:\.\d{0,9})")
        regex.setCaseSensitivity(Qt.CaseInsensitive)
        self._validator = QRegExpValidator(regex)
        self.setDecimals(9)

    def validate(self, text, pos):
        return self._validator.validate(text, pos)

    def valueFromText(self, text):
        matches = regex.findall(r"^(\d+):(\d+):(\d+(?:\.\d*))$", text)

        if matches:
            (h, m, s), = matches
            return 3600 * int(h) + 60 * int(m) + float(s)

    def textFromValue(self, value):
        m, s = divmod(value, 60)
        h, m = divmod(int(m), 60)
        return f"{h}:{m:02d}:{s:012.9f}"

    def stepBy(self, dt):
        currentValue = self.value()
        currentText = self.text()
        currentPosition = self.lineEdit().cursorPosition()
        matches = regex.findall(r"^(\d+):(\d+):(\d+(?:\.\d*))$", currentText)

        if matches:
            (h, m, s), = matches

        if currentPosition <= len(h):
            self.setValue(currentValue + 3600 * dt)
            self.selectHours()

        elif currentPosition <= len(f"{h}:{m}"):
            self.setValue(currentValue + 60 * dt)
            self.selectMinutes()

        else:
            self.setValue(currentValue + dt)
            self.selectSeconds()

    def keyPressEvent(self, event):
        selectedText = self.lineEdit().selectedText()

        if ":" in selectedText:
            if event.key() not in (Qt.Key_Right, Qt.Key_Left):
                return

        selectionStart = self.lineEdit().selectionStart()
        selectionEnd = selectionStart + len(selectedText)
        currentPosition = self.lineEdit().cursorPosition()
        text = self.text()
        textBeforeCursor = text[:currentPosition]
        textAfterCursor = text[currentPosition:]

        matches = regex.findall(r"^(\d+):(\d+):(\d+(?:\.\d*))$", text)

        if matches:
            (h, m, s), = matches

        else:
            h = m = s = ""

        if (event.key() == Qt.Key_Right
                and event.modifiers() == Qt.ControlModifier):
            if currentPosition <= len(h):
                self.selectMinutes()

            elif currentPosition <= len(f"{h}:{m}"):
                self.selectSeconds()

            return

        if (event.key() == Qt.Key_Left
                and event.modifiers() == Qt.ControlModifier):
            if currentPosition >= len(f"{h}:{m}:"):
                self.selectMinutes()

            elif currentPosition >= len(f"{h}:"):
                self.selectHours()

            return

        if event.key() == Qt.Key_Backspace:
            if selectedText == "" and textBeforeCursor.endswith(":"):
                return

        if event.key() == Qt.Key_Delete:
            if selectedText == "" and textAfterCursor.startswith(":"):
                return

        if event.key() == Qt.Key_Colon:
            if textAfterCursor.startswith(":") and not selectedText:
                nextColon = textAfterCursor.find(":", 1)

                if nextColon >= 0:
                    self.lineEdit().setSelection(
                        len(textBeforeCursor) + 1, nextColon - 1)

                else:
                    self.lineEdit().setSelection(
                        len(textBeforeCursor) + 1,
                        len(textAfterCursor) - 1)

            return

        super().keyPressEvent(event)

        maxhours = int(self.maximum() // 3600)
        maxhourdigits = 1

        while maxhours > 10:
            maxhourdigits += 1
            maxhours //= 10

        if Qt.Key_0 <= event.key() <= Qt.Key_9:
            if currentPosition == len(h) == maxhourdigits - 1:
                self.selectMinutes()

            elif len(selectedText) == 1 and selectionEnd == maxhourdigits:
                self.selectMinutes()

            elif currentPosition == len(f"{h}:{m}") and len(m) == 1:
                self.selectSeconds()

            elif len(selectedText) == 1 and selectionEnd == len(f"{h}:00"):
                self.selectSeconds()

    def selectHours(self):
        text = self.text()
        matches = regex.findall(r"^(\d+):(\d+):(\d+(?:\.\d*))$", text)

        if matches:
            (h, m, s), = matches
            self.lineEdit().setSelection(0, len(h))

    def selectMinutes(self):
        text = self.text()
        matches = regex.findall(r"^(\d+):(\d+):(\d+(?:\.\d*))$", text)

        if matches:
            (h, m, s), = matches
            self.lineEdit().setSelection(len(f"{h}:"), len(m))

    def selectSeconds(self):
        text = self.text()
        matches = regex.findall(r"^(\d+):(\d+):(\d+(?:\.\d*))$", text)

        if matches:
            (h, m, s), = matches
            self.lineEdit().setSelection(len(f"{h}:{m}:"), len(s))
class TopicsAnalyser_UI(QMainWindow):
    def __init__(self):
        super(TopicsAnalyser_UI, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.run_btn.clicked.connect(self.run_topics_analyser)
        self.ui.browse_btn.clicked.connect(self.getfile)
        self.setup_validators()

    def run_topics_analyser(self):
        status = self.validate_inputs()
        if (status != 0):
            return

        def get_wordlist(string_: str):
            return [word.strip() for word in string_.split(',')
                    ] if (len(string_) > 0) else []

        groupby_cols = get_wordlist(self.ui.groupby_cols_txt.text())
        addl_stopwords = get_wordlist(self.ui.addl_stopwords_txt.text())

        # TODO: these column names should come from the input screen
        text_col = 'Reason for filling position(s) with Federal Government Employee -OTHER'
        # text_col = 'Please briefly describe an example of one burdensome administrative task or process which you believe is "low value"'
        other_cols = [
            'AGENCY', 'COMPONENT', 'SUB_COMPONENT', 'GRADELEVEL', 'SUP_STATUS'
        ]
        data = TextFileReader.get_dataframe(self.ui.data_file_txt.text(),
                                            text_col, other_cols)

        analyser = TopicsAnalyser(data)
        message = analyser.get_topics(self.ui.num_topics_spb.value(),
                                      groupby_cols,
                                      self.ui.num_ngrams_spb.value(),
                                      addl_stopwords)
        self.ui.statusbar.showMessage(message)

    def setup_validators(self):
        # check if the text is an empty string
        rx = QRegExp('^(?!\\s*$).+')
        self.filename_validator = QRegExpValidator(rx)

    def validate_inputs(self):
        self.error_dialog = QErrorMessage()
        errors = []
        filename_val_status, _, _ = self.filename_validator.validate(
            self.ui.data_file_txt.text(), 0)
        if (filename_val_status != 2):
            errors.append('Data file is required.')

        if (len(errors) > 0):
            self.error_dialog.showMessage('\n'.join(errors))
            return -1
        return 0

    def getfile(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        filename, _ = QFileDialog.getOpenFileName(self,
                                                  "Open File",
                                                  "",
                                                  "Excel files (*.xlsx)",
                                                  options=options)
        if (filename):
            self.ui.data_file_txt.setText(filename)
Exemple #20
0
class CooperationPage(ConfigurationPageBase, Ui_CooperationPage):
    """
    Class implementing the Cooperation configuration page.
    """
    def __init__(self):
        """
        Constructor
        """
        super(CooperationPage, self).__init__()
        self.setupUi(self)
        self.setObjectName("CooperationPage")
        
        self.__bannedUserValidator = QRegExpValidator(
            QRegExp("[a-zA-Z0-9.-]+@"
                    "(?:(?:2(?:[0-4][0-9]|5[0-5])|[01]?[0-9]{1,2})\.){3}"
                    "(?:2(?:[0-4][0-9]|5[0-5])|[01]?[0-9]{1,2})"),
            self.bannedUserEdit)
        self.bannedUserEdit.setValidator(self.__bannedUserValidator)
        
        # set initial values
        self.autostartCheckBox.setChecked(
            Preferences.getCooperation("AutoStartServer"))
        self.otherPortsCheckBox.setChecked(
            Preferences.getCooperation("TryOtherPorts"))
        self.serverPortSpin.setValue(
            Preferences.getCooperation("ServerPort"))
        self.portToTrySpin.setValue(
            Preferences.getCooperation("MaxPortsToTry"))
        self.autoAcceptCheckBox.setChecked(
            Preferences.getCooperation("AutoAcceptConnections"))
        
        self.bannedUsersList.addItems(sorted(
            Preferences.getCooperation("BannedUsers")))
    
    def save(self):
        """
        Public slot to save the Cooperation configuration.
        """
        Preferences.setCooperation(
            "AutoStartServer",
            self.autostartCheckBox.isChecked())
        Preferences.setCooperation(
            "TryOtherPorts",
            self.otherPortsCheckBox.isChecked())
        Preferences.setCooperation(
            "AutoAcceptConnections",
            self.autoAcceptCheckBox.isChecked())
        Preferences.setCooperation(
            "ServerPort",
            self.serverPortSpin.value())
        Preferences.setCooperation(
            "MaxPortsToTry",
            self.portToTrySpin.value())
        
        bannedUsers = []
        for row in range(self.bannedUsersList.count()):
            bannedUsers.append(self.bannedUsersList.item(row).text())
        Preferences.setCooperation("BannedUsers", bannedUsers)
    
    @pyqtSlot()
    def on_bannedUsersList_itemSelectionChanged(self):
        """
        Private slot to react on changes of selected banned users.
        """
        self.deleteBannedUsersButton.setEnabled(
            len(self.bannedUsersList.selectedItems()) > 0)
    
    @pyqtSlot(str)
    def on_bannedUserEdit_textChanged(self, txt):
        """
        Private slot to handle the user entering a banned user.
        
        @param txt text entered by the user (string)
        """
        self.addBannedUserButton.setEnabled(
            self.__bannedUserValidator.validate(txt, len(txt))[0] ==
            QValidator.Acceptable)
    
    @pyqtSlot()
    def on_deleteBannedUsersButton_clicked(self):
        """
        Private slot to remove the selected users from the list of
        banned users.
        """
        for itm in self.bannedUsersList.selectedItems():
            row = self.bannedUsersList.row(itm)
            itm = self.bannedUsersList.takeItem(row)
            del itm
    
    @pyqtSlot()
    def on_addBannedUserButton_clicked(self):
        """
        Private slot to add a user to the list of banned users.
        """
        self.bannedUsersList.addItem(self.bannedUserEdit.text())
        self.bannedUserEdit.clear()
Exemple #21
0
class SubCubeControl(QWidget):

    __LOG: Logger = LogHelper.logger("SubCubeControl")

    cancel = pyqtSignal()
    save = pyqtSignal(SaveSubCubeEvent)

    def __init__(self, files: Dict[str, FileSubCubeParams], parent=None):
        super().__init__(parent)
        self.__files = files
        num_files = len(self.__files)

        layout = QVBoxLayout()
        form_layout = QFormLayout()

        self.__file_list = QComboBox(self)

        if num_files > 1:
            self.__file_list.insertItem(0, "Select origin file...")
            self.__file_list.insertItems(1, self.__files.keys())
        else:
            self.__file_list.insertItems(0, self.__files.keys())

        self.__file_list.currentIndexChanged.connect(self.__handle_file_select)
        form_layout.addRow("Original File:", self.__file_list)

        self.__file_type = QComboBox(self)
        self.__format_map = {
            OpenSpectraHeader.BIL_INTERLEAVE: "BIL - Band Interleaved by Line",
            OpenSpectraHeader.BSQ_INTERLEAVE: "BSQ - Band Sequential",
            OpenSpectraHeader.BIP_INTERLEAVE: "BIP - Band Interleaved by Pixel"
        }
        self.__file_type.insertItem(0, "")
        self.__file_type.insertItems(1, self.__format_map.values())
        form_layout.addRow("Output File Interleave:", self.__file_type)

        self.__sample_range = RangeSelector(self)
        form_layout.addRow("Sample Range:", self.__sample_range)

        self.__line_range = RangeSelector(self)
        form_layout.addRow("Line Range:", self.__line_range)

        self.__band_select = QLineEdit(self)
        self.__band_select.setMinimumWidth(250)
        self.__band_validator = QRegExpValidator(
            QRegExp("[1-9][0-9]*((-|,)([1-9][0-9]*))*"))
        self.__band_select.setValidator(self.__band_validator)
        self.__band_select.setToolTip\
                ("Use '-' for a range, ',' to separate ranges and single bands.\nExample: 1-10,12,14,19-21")
        self.__max_band = 0

        form_layout.addRow("Bands:", self.__band_select)
        layout.addLayout(form_layout)

        button_layout = QHBoxLayout()
        cancel_button = QPushButton("Cancel", self)
        cancel_button.clicked.connect(self.cancel)
        button_layout.addWidget(cancel_button)

        self.__save_button = QPushButton("Save", self)
        self.__save_button.setDisabled(True)
        self.__save_button.clicked.connect(self.__handle_save)
        button_layout.addWidget(self.__save_button)
        layout.addLayout(button_layout)
        self.setLayout(layout)

        self.__handle_file_select(0)

    @pyqtSlot(int)
    def __handle_file_select(self, index: int):
        if index == 0 and len(self.__files) > 1:
            self.__save_button.setDisabled(True)
            self.__line_range.clear()
            self.__sample_range.clear()
            self.__max_band = 0
            self.__band_select.clear()
            self.__file_type.setCurrentIndex(0)
        else:
            selected_file_name = self.__file_list.currentText()
            params: FileSubCubeParams = self.__files[selected_file_name]
            self.__line_range.set_range(1, params.lines())
            self.__sample_range.set_range(1, params.samples())
            self.__max_band = params.bands()
            self.__band_select.setText("1-" + str(self.__max_band))
            self.__file_type.setCurrentText(
                self.__format_map[params.file_format()])
            self.__save_button.setDisabled(False)

    @pyqtSlot()
    def __handle_save(self):
        source_file_name = self.__file_list.currentText()
        file_type = self.__file_type.currentText()[0:3].lower()

        # Convert to zero based indexing using slice range rules
        lines = self.__line_range.from_value() - 1, self.__line_range.to_value(
        )
        samples = self.__sample_range.from_value(
        ) - 1, self.__sample_range.to_value()
        bands_str = self.__band_select.text()

        SubCubeControl.__LOG.debug(
            "save button clicked, source file: {0}, type: {1}, lines: {2}, samples: {3}, bands: {4}"
            .format(source_file_name, file_type, lines, samples, bands_str))

        # validate bands args and build the parameter
        bands = self.__get_band_list(bands_str)
        SubCubeControl.__LOG.debug("get_band_list returned: {0}".format(bands))
        if bands is not None:
            cube_params = CubeParams(file_type, lines, samples, bands)
            self.save.emit(SaveSubCubeEvent(source_file_name, cube_params))

    def __get_band_list(self, bands: str) -> Union[Tuple[int, int], List[int]]:
        bands_str = bands
        validate_result = self.__band_validator.validate(bands_str, 0)
        if validate_result[0] == QValidator.Invalid:
            self.__show_error(
                "Cannot validate band list argument of {0}".format(
                    self.__band_select.text()))
            return None

        elif validate_result[0] == QValidator.Intermediate:
            if str.endswith(bands_str, (",", "-")):
                bands_str = bands_str[:len(bands_str) - 1]
                SubCubeControl.__LOG.debug(
                    "attempted to fix band str and got: {0}".format(bands_str))

                validate_result = self.__band_validator.validate(bands_str, 0)
                if validate_result[0] != QValidator.Acceptable:
                    self.__show_error(
                        "Cannot validate band list argument of {0}".format(
                            self.__band_select.text()))
                    return None

        # collect up the ranges and single bands
        ranges: List[Tuple[int, int]] = list()
        single_bands: List[int] = list()

        # this should produce a list of ranges, 1-5, and individual values
        # we also convert indexes from 1 based to 0 here
        # thanks to the validator we should not be getting 0 or negative values so no need to check
        # validate against self.__max_bands
        band_range_strs = str.split(bands_str, ",")
        for band_range in band_range_strs:
            range_parts = str.split(band_range, "-")
            if len(range_parts) == 2:
                # make sure tuple ranges have the lesser value first
                # it will make things a bit more simple below
                r1 = int(range_parts[0]) - 1
                r2 = int(range_parts[1])

                if r1 > self.__max_band:
                    self.__show_error(
                        "Band range value cannot exceed {0}, received range with one end {1}"
                        .format(self.__max_band, range_parts[0]))

                if r2 > self.__max_band:
                    self.__show_error(
                        "Band range value cannot exceed {0}, received range with one end {1}"
                        .format(self.__max_band, range_parts[1]))

                if r1 < r2:
                    ranges.append((r1, r2))
                elif r2 < r1:
                    ranges.append((r2, r1))
                else:
                    # they were equal
                    single_bands.append(r1)

            elif len(range_parts) == 1:
                b = int(range_parts[0])
                if b >= self.__max_band:
                    self.__show_error(
                        "Band value cannot exceed {0}, received single band index of {1}"
                        .format(self.__max_band, range_parts[0]))
                single_bands.append(b)
            else:
                self.__show_error(
                    "Cannot validate band list argument of {0}".format(
                        self.__band_select.text()))
                return None

        # check to see if we just have a single range or band
        range_cnt = len(ranges)
        singles_cnt = len(single_bands)
        if range_cnt == 1 and singles_cnt == 0:
            return ranges[0]

        if range_cnt == 0 and singles_cnt == 1:
            return single_bands

        # otherwise consolidate the lists to a minimum set of ranges and single bands
        # reducing it to a tuple if possible
        # first generate a list of containing all the ranges
        range_list_list = [list(range(r[0], r[1])) for r in ranges]
        # SubCubeControl.__LOG.debug("range_list_list: {0}".format(range_list_list))

        band_list = list(chain.from_iterable(range_list_list))
        # SubCubeControl.__LOG.debug("band_list: {0}".format(band_list))

        band_list.extend(single_bands)
        # SubCubeControl.__LOG.debug("full band_list: {0}".format(band_list))

        # now we have all the bands specified by both ranges and single bands
        # so now create a set from the list to eliminate duplicates
        band_set = set(band_list)
        sorted_band_list = sorted(band_set)
        # SubCubeControl.__LOG.debug("sorted band_set: {0}".format(sorted_band_list))

        # now see if it's contiguous and can be returned as a tuple
        is_contiguous = True
        last_index = -1
        for band_index in sorted_band_list:
            if last_index == -1:
                last_index = band_index
            elif band_index != last_index + 1:
                is_contiguous = False
                break
            else:
                last_index = band_index

        if is_contiguous:
            # then return the bounds as a tuple
            return sorted_band_list[0], sorted_band_list[len(sorted_band_list)
                                                         - 1]
        else:
            return sorted_band_list

    def __show_error(self, message: str):
        dialog = QMessageBox(self)
        dialog.setIcon(QMessageBox.Critical)
        dialog.setText(message)
        dialog.addButton(QMessageBox.Ok)
        dialog.exec()