Music production session manager https://www.laborejo.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

131 lines
5.5 KiB

3 years ago
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
"""
11 months ago
Copyright 2022, Nils Hilbricht, Germany ( https://www.hilbricht.net )
3 years ago
This file is part of the Laborejo Software Suite ( https://www.laborejo.org ).
3 years ago
This application is free software: you can redistribute it and/or modify
3 years ago
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import logging; logger = logging.getLogger(__name__); logger.info("import")
#Standard Library
#Engine
import engine.api as api
#Third Party
from PyQt5 import QtCore, QtWidgets
class PromptWidget(QtWidgets.QDialog):
wordlist = None
minlen = None
def __init__(self, parent):
super().__init__(parent)
layout = QtWidgets.QFormLayout()
#layout = QtWidgets.QVBoxLayout()
updateWordlist() #this is a fast index update, we can call that every time to be sure. Otherwise newly added executable-PATHs will not be reflected in the dialog without a program-database update, which takes too long to be convenient.
3 years ago
self.setLayout(layout)
self.setWindowFlag(QtCore.Qt.Popup, True)
self.comboBox = QtWidgets.QComboBox(self)
self.comboBox.setEditable(True)
self.comboBox.currentTextChanged.connect(self.check) #not called when text is changed programatically
3 years ago
if PromptWidget.wordlist:
completer = QtWidgets.QCompleter(PromptWidget.wordlist)
3 years ago
completer.setModelSorting(QtWidgets.QCompleter.CaseInsensitivelySortedModel)
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
completer.setCompletionMode(QtWidgets.QCompleter.PopupCompletion)
3 years ago
completer.activated.connect(self.process) #To avoid double-press enter to select one we hook into the activated signal and trigger process
self.comboBox.setCompleter(completer)
self.comboBox.setMinimumContentsLength(PromptWidget.minlen)
3 years ago
labelString = QtCore.QCoreApplication.translate("PromptWidget", "Type in the name of an executable file on your system.")
else:
labelString = QtCore.QCoreApplication.translate("PromptWidget", "No program database found. Please update through Control menu.")
label = QtWidgets.QLabel(labelString)
3 years ago
layout.addWidget(label)
self.comboBox.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToMinimumContentsLength)
layout.addWidget(self.comboBox)
3 years ago
errorString = QtCore.QCoreApplication.translate("PromptWidget", "Command not found or not accepted!<br>Parameters, --switches and relative paths are not allowed.<br>Use nsm-proxy or write a starter-script instead.")
3 years ago
errorString = "<i>" + errorString + "</i>"
self.errorLabel = QtWidgets.QLabel(errorString)
3 years ago
layout.addWidget(self.errorLabel)
self.errorLabel.hide() #shown in process or check
3 years ago
self.buttonBox = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel)
self.buttonBox.accepted.connect(self.process)
self.buttonBox.rejected.connect(self.reject)
layout.addWidget(self.buttonBox)
3 years ago
self.exec() #blocks until the dialog gets closed
3 years ago
def abortHandler(self):
pass
def check(self, currentText):
"""Called every keypress.
We do preliminary error and collision checking here, so the engine does not have to throw
an error """
self.errorLabel.hide() #start in good faith
ok = self.buttonBox.button(QtWidgets.QDialogButtonBox.Ok)
if currentText in PromptWidget.wordlist: #this is taken literally. Any extra char or whitespace counts as false
ok.setEnabled(True)
else:
ok.setEnabled(False)
self.errorLabel.show()
3 years ago
def process(self):
"""Careful! Calling this eats python errors without notice.
Make sure your objects exists and your syntax is correct"""
assert PromptWidget.wordlist
assert PromptWidget.minlen
3 years ago
curText = self.comboBox.currentText()
if not curText or curText == " ": #TODO: qt weirdness. This is a case when focus is lost from a valid entry. The field is filled from a chosen value, from the list. But it says " ".
#Do not show the errorLabel. This is a qt bug or so.
return
3 years ago
if curText in PromptWidget.wordlist:
api.clientAdd(curText)
logger.info(f"Prompt accepted {curText} and will send it to clientAdd")
self.done(True)
else:
logger.info(f"Prompt did not accept {curText}.Showing info to the user.")
self.errorLabel.show()
3 years ago
def updateWordlist():
"""in case programs are installed while the session is running the user can
manually call a database update"""
PromptWidget.wordlist = api.getUnfilteredExecutables()
if PromptWidget.wordlist:
PromptWidget.minlen = len(max(PromptWidget.wordlist, key=len))
else:
logger.error("Executable list came back empty! Most likely an error in application database build. Not trivial!")
def askForExecutable(parent):
PromptWidget(parent)