Skip to content

Commit 1dfc4c4

Browse files
committed
add file-rename dialog and error handling
1 parent abe920d commit 1dfc4c4

File tree

2 files changed

+125
-7
lines changed

2 files changed

+125
-7
lines changed

DuetRRFOutputDevice.py

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
import json
88

99
from PyQt5 import QtNetwork
10-
from PyQt5.QtCore import QFile, QUrl, QCoreApplication, QByteArray, QTimer
10+
from PyQt5.QtCore import QFile, QUrl, QObject, QCoreApplication, QByteArray, QTimer, pyqtProperty, pyqtSignal, pyqtSlot
1111
from PyQt5.QtGui import QDesktopServices
12+
from PyQt5.QtQml import QQmlComponent, QQmlContext
1213

1314
from UM.Application import Application
1415
from UM.Logger import Logger
@@ -101,7 +102,7 @@ def _send(self, command, query, next_stage=None, data=None):
101102
self._reply.finished.connect(next_stage)
102103
self._reply.error.connect(self._onNetworkError)
103104

104-
def requestWrite(self, node, fileName = None, *args, **kwargs):
105+
def requestWrite(self, node, fileName=None, *args, **kwargs):
105106
if self._stage != OutputStage.ready:
106107
raise OutputDeviceError.DeviceBusyError()
107108

@@ -111,6 +112,29 @@ def requestWrite(self, node, fileName = None, *args, **kwargs):
111112
fileName = "%s.gcode" % Application.getInstance().getPrintInformation().jobName
112113
self._fileName = fileName
113114

115+
path = QUrl.fromLocalFile(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'UploadFilename.qml'))
116+
self._component = QQmlComponent(Application.getInstance()._engine, path)
117+
Logger.log("d", "Errors:", self._component.errors())
118+
self._context = QQmlContext(Application.getInstance()._engine.rootContext())
119+
self._context.setContextProperty("manager", self)
120+
self._dialog = self._component.create(self._context)
121+
self._dialog.textChanged.connect(self.onFilenameChanged)
122+
self._dialog.accepted.connect(self.onFilenameAccepted)
123+
self._dialog.open()
124+
self._dialog.findChild(QObject, "nameField").setProperty('text', self._fileName)
125+
self._dialog.findChild(QObject, "nameField").select(0, len(self._fileName) - 6)
126+
self._dialog.findChild(QObject, "nameField").setProperty('focus', True)
127+
128+
def onFilenameChanged(self):
129+
fileName = self._dialog.findChild(QObject, "nameField").property('text')
130+
self._dialog.setProperty('validName', len(fileName) > 0)
131+
132+
def onFilenameAccepted(self):
133+
self._fileName = self._dialog.findChild(QObject, "nameField").property('text')
134+
if not self._fileName.endswith('.gcode') and '.' not in self._fileName:
135+
self._fileName += '.gcode'
136+
Logger.log("d", "Filename set to: " + self._fileName)
137+
114138
# create the temp file for the gcode
115139
self._stream = StringIO()
116140
self._stage = OutputStage.writing
@@ -137,12 +161,18 @@ def requestWrite(self, node, fileName = None, *args, **kwargs):
137161
self._send('connect', [("password", self._duet_password), self._timestamp()], self.onConnected)
138162

139163
def onConnected(self):
164+
if not self._reply or self._reply.error != QtNetwork.QNetworkReply.NoError:
165+
return
166+
140167
self._stream.seek(0)
141168
self._postData = QByteArray()
142169
self._postData.append(self._stream.getvalue().encode())
143170
self._send('upload', [("name", "0:/gcodes/" + self._fileName), self._timestamp()], self.onUploadDone, self._postData)
144171

145172
def onUploadDone(self):
173+
if not self._reply or self._reply.error != QtNetwork.QNetworkReply.NoError:
174+
return
175+
146176
self._stream.close()
147177
self.stream = None
148178

@@ -169,9 +199,15 @@ def onUploadDone(self):
169199
self._cleanupRequest()
170200

171201
def onReadyToPrint(self):
202+
if not self._reply or self._reply.error != QtNetwork.QNetworkReply.NoError:
203+
return
204+
172205
self._send('gcode', [("gcode", "M32 /gcodes/" + self._fileName)], self.onPrintStarted)
173206

174207
def onPrintStarted(self):
208+
if not self._reply or self._reply.error != QtNetwork.QNetworkReply.NoError:
209+
return
210+
175211
if self._device_type == DeviceType.simulate:
176212
self.onCheckStatus()
177213
else:
@@ -188,12 +224,21 @@ def onPrintStarted(self):
188224
self._cleanupRequest()
189225

190226
def onSimulatedPrintFinished(self):
227+
if not self._reply or self._reply.error != QtNetwork.QNetworkReply.NoError:
228+
return
229+
191230
self._send('gcode', [("gcode", "M37 S0")], self.onSimulationStopped)
192231

193232
def onCheckStatus(self):
233+
if not self._reply or self._reply.error != QtNetwork.QNetworkReply.NoError:
234+
return
235+
194236
self._send('status', [("type", "3")], self.onStatusReceived)
195237

196238
def onStatusReceived(self):
239+
if not self._reply or self._reply.error != QtNetwork.QNetworkReply.NoError:
240+
return
241+
197242
status_bytes = bytes(self._reply.readAll())
198243
Logger.log("d", status_bytes)
199244

@@ -208,12 +253,21 @@ def onStatusReceived(self):
208253
self.onSimulatedPrintFinished()
209254

210255
def onSimulationStopped(self):
256+
if not self._reply or self._reply.error != QtNetwork.QNetworkReply.NoError:
257+
return
258+
211259
self._send('gcode', [("gcode", "M37")], self.onReporting)
212260

213261
def onReporting(self):
262+
if not self._reply or self._reply.error != QtNetwork.QNetworkReply.NoError:
263+
return
264+
214265
self._send('reply', [], self.onReported)
215266

216267
def onReported(self):
268+
if not self._reply or self._reply.error != QtNetwork.QNetworkReply.NoError:
269+
return
270+
217271
if self._message:
218272
self._message.hide()
219273

@@ -262,8 +316,5 @@ def _onNetworkError(self, errorCode):
262316
message = Message(catalog.i18nc("@info:status", "There was a network error: {} {}").format(errorCode, errorString))
263317
message.show()
264318

265-
def _cancelUpload(self):
266-
if self._message:
267-
self._message.hide()
268-
self._message = None
269-
self._reply.abort()
319+
self.writeError.emit(self)
320+
self._cleanupRequest()

UploadFilename.qml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import QtQuick 2.1
2+
import QtQuick.Controls 1.1
3+
import QtQuick.Dialogs 1.2
4+
import QtQuick.Window 2.1
5+
6+
import UM 1.1 as UM
7+
8+
UM.Dialog
9+
{
10+
id: base;
11+
property string object: "";
12+
13+
property alias newName: nameField.text;
14+
property bool validName: true;
15+
property string validationError;
16+
property string dialogTitle: "Upload Filename";
17+
18+
title: dialogTitle;
19+
20+
minimumWidth: 400 * screenScaleFactor
21+
minimumHeight: 120 * screenScaleFactor
22+
width: minimumWidth
23+
height: minimumHeight
24+
25+
property variant catalog: UM.I18nCatalog { name: "uranium"; }
26+
27+
signal textChanged(string text);
28+
signal selectText()
29+
onSelectText: {
30+
nameField.selectAll();
31+
nameField.focus = true;
32+
}
33+
34+
Column {
35+
anchors.fill: parent;
36+
37+
TextField {
38+
objectName: "nameField";
39+
id: nameField;
40+
width: parent.width;
41+
text: base.object;
42+
maximumLength: 100;
43+
onTextChanged: base.textChanged(text);
44+
Keys.onReturnPressed: base.accept();
45+
Keys.onEnterPressed: base.accept();
46+
Keys.onEscapePressed: base.reject();
47+
}
48+
49+
Label {
50+
visible: !base.validName;
51+
text: base.validationError;
52+
}
53+
}
54+
55+
rightButtons: [
56+
Button {
57+
text: catalog.i18nc("@action:button", "Cancel");
58+
onClicked: base.reject();
59+
},
60+
Button {
61+
text: catalog.i18nc("@action:button", "OK");
62+
onClicked: base.accept();
63+
enabled: base.validName;
64+
isDefault: true;
65+
}
66+
]
67+
}

0 commit comments

Comments
 (0)