blob: c3ca4ed3690710577f20ea0cac0c967ff770238b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
# Copyright (c) 2016 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 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.
from UM.Resources import Resources
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.InstanceContainer import InstanceContainer
class MachineNameValidator(QObject):
"""Are machine names valid?
Performs checks based on the length of the name.
"""
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(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(ContainerRegistry.getMimeTypeForContainer(InstanceContainer).preferredSuffix)
# Characters that urllib.parse.quote_plus escapes count for 12! So now
# we must devise a regex that allows only 12 normal characters or 1
# special character, and that up to [machine_name_max_length / 12] times.
maximum_special_characters = int(machine_name_max_length / 12)
unescaped = r"[a-zA-Z0-9_\-\.\/]"
self.machine_name_regex = r"^[^\.]((" + unescaped + "){0,12}|.){0," + str(maximum_special_characters) + r"}$"
validationChanged = pyqtSignal()
def validate(self, name):
"""Check if a specified machine name is allowed.
:param name: The machine name to check.
:return: ``QValidator.Invalid`` if it's disallowed, or ``QValidator.Acceptable`` if it's allowed.
"""
#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(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." + ContainerRegistry.getMimeTypeForContainer(InstanceContainer).preferredSuffix
if len(current_settings_filename) > filename_max_length:
return QValidator.Invalid
return QValidator.Acceptable #All checks succeeded.
@pyqtSlot(str)
def updateValidation(self, new_name):
"""Updates the validation state of a machine name text field."""
is_valid = self.validate(new_name)
if is_valid == QValidator.Acceptable:
self.validation_regex = "^.*$" #Matches anything.
else:
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):
return QRegExp(self.machine_name_regex)
|