mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-03 12:03:57 -06:00
Limit number of special characters
There is also a more advanced attempt that allows more, but I've commented it out because it doesn't quite work yet. Special characters now always count for 12. Contributes to issue CURA-2652.
This commit is contained in:
parent
37d1c0be36
commit
717248bd78
2 changed files with 60 additions and 8 deletions
|
@ -1,18 +1,45 @@
|
|||
# Copyright (c) 2016 Ultimaker B.V.
|
||||
# Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot, pyqtProperty, QObject, pyqtSignal, QRegExp
|
||||
from PyQt5.QtGui import QValidator
|
||||
import os #For statvfs.
|
||||
import urllib #To escape machine names for how they're saved to file.
|
||||
|
||||
import UM.Resources
|
||||
import UM.Settings.ContainerRegistry
|
||||
import UM.Settings.InstanceContainer
|
||||
|
||||
from PyQt5.QtGui import QValidator
|
||||
import os #For statvfs.
|
||||
import urllib #To escape machine names for how they're saved to file.
|
||||
|
||||
## Are machine names valid?
|
||||
#
|
||||
# Performs checks based on the length of the name.
|
||||
class MachineNameValidator(QValidator):
|
||||
class MachineNameValidator(QObject):
|
||||
def __init__(self, parent = None):
|
||||
super().__init__(parent)
|
||||
|
||||
#Compute the validation regex for printer names. This is limited by the maximum file name length.
|
||||
try:
|
||||
filename_max_length = os.statvfs(UM.Resources.getDataStoragePath()).f_namemax
|
||||
except AttributeError: #Doesn't support statvfs. Probably because it's not a Unix system.
|
||||
filename_max_length = 255 #Assume it's Windows on NTFS.
|
||||
machine_name_max_length = filename_max_length - len("_current_settings.") - len(UM.Settings.ContainerRegistry.getMimeTypeForContainer(UM.Settings.InstanceContainer).preferredSuffix)
|
||||
# Characters that urllib.parse.quote_plus escapes count for 3! So now we
|
||||
# must devise a regex that allows only 3 normal characters or 1 special
|
||||
# character, and that up to [machine_name_max_length / 3] times.
|
||||
maximum_special_characters = int(machine_name_max_length / 12)
|
||||
unescaped = r"[a-zA-Z0-9_\-\.\/]"
|
||||
#single_length = r"[\u0000-\u007F]"
|
||||
#double_length = r"[\u0080-\u07FF]"
|
||||
#triple_length = r"[\u0800-\uFFFF]"
|
||||
#quadruple_length = r"[\u10000-\u10FFFF]"
|
||||
#self.machine_name_regex = r"((((" + unescaped + r"{0,3}|" + single_length + r"){0,2}" \
|
||||
# + r"|" + double_length + r"){0,2}" \
|
||||
# + r"|" + triple_length + r"){0,2}" \
|
||||
# + r"|" + quadruple_length + r"){0," + str(maximum_special_characters) + r"}"
|
||||
self.machine_name_regex = r"((" + unescaped + "){0,12}|.){0," + str(maximum_special_characters) + r"}"
|
||||
|
||||
validationChanged = pyqtSignal()
|
||||
|
||||
## Check if a specified machine name is allowed.
|
||||
#
|
||||
# \param name The machine name to check.
|
||||
|
@ -22,12 +49,29 @@ class MachineNameValidator(QValidator):
|
|||
def validate(self, name, position):
|
||||
#Check for file name length of the current settings container (which is the longest file we're saving with the name).
|
||||
try:
|
||||
filename_max_length = os.statvfs(UM.Resources.getDataStoragePath())
|
||||
filename_max_length = os.statvfs(UM.Resources.getDataStoragePath()).f_namemax
|
||||
except AttributeError: #Doesn't support statvfs. Probably because it's not a Unix system.
|
||||
filename_max_length = 255 #Assume it's Windows on NTFS.
|
||||
escaped_name = urllib.parse.quote_plus(name)
|
||||
current_settings_filename = escaped_name + "_current_settings." + UM.Settings.ContainerRegistry.getMimeTypeForContainer(UM.Settings.InstanceContainer).preferredSuffix
|
||||
if current_settings_filename > filename_max_length:
|
||||
if len(current_settings_filename) > filename_max_length:
|
||||
return QValidator.Invalid
|
||||
|
||||
return QValidator.Acceptable #All checks succeeded.
|
||||
|
||||
## Updates the validation state of a machine name text field.
|
||||
@pyqtSlot(str)
|
||||
def updateValidation(self, new_name):
|
||||
is_valid = self.validate(new_name, 0)
|
||||
if is_valid == QValidator.Acceptable:
|
||||
print("VALID")
|
||||
self.validation_regex = "^.*$" #Matches anything.
|
||||
else:
|
||||
print("BROKEN!")
|
||||
self.validation_regex = "a^" #Never matches (unless you manage to get "a" before the start of the string... good luck).
|
||||
self.validationChanged.emit()
|
||||
|
||||
@pyqtProperty("QRegExp", notify=validationChanged)
|
||||
def machineNameRegex(self):
|
||||
print(self.machine_name_regex)
|
||||
return QRegExp(self.machine_name_regex)
|
|
@ -175,6 +175,14 @@ UM.Dialog
|
|||
text: getMachineName()
|
||||
implicitWidth: UM.Theme.getSize("standard_list_input").width
|
||||
maximumLength: 40
|
||||
//validator: Cura.MachineNameValidator { } //TODO: Gives a segfault in PyQt5.6. For now, we must use a signal on text changed.
|
||||
validator: RegExpValidator
|
||||
{
|
||||
regExp: {
|
||||
machineName.machine_name_validator.machineNameRegex
|
||||
}
|
||||
}
|
||||
property var machine_name_validator: Cura.MachineNameValidator { }
|
||||
anchors.bottom:parent.bottom
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue