eric6/MicroPython/MicroPythonFileManagerWidget.py

branch
micropython
changeset 7083
217862c28319
parent 7082
ec199ef0cfc6
child 7084
3eddfc540614
equal deleted inserted replaced
7082:ec199ef0cfc6 7083:217862c28319
16 QWidget, QTreeWidgetItem, QHeaderView, QMenu, QInputDialog, QLineEdit 16 QWidget, QTreeWidgetItem, QHeaderView, QMenu, QInputDialog, QLineEdit
17 ) 17 )
18 18
19 from E5Gui import E5MessageBox, E5PathPickerDialog 19 from E5Gui import E5MessageBox, E5PathPickerDialog
20 from E5Gui.E5PathPicker import E5PathPickerModes 20 from E5Gui.E5PathPicker import E5PathPickerModes
21 from E5Gui.E5FileSaveConfirmDialog import confirmOverwrite
21 from E5Gui.E5Application import e5App 22 from E5Gui.E5Application import e5App
22 23
23 from .Ui_MicroPythonFileManagerWidget import Ui_MicroPythonFileManagerWidget 24 from .Ui_MicroPythonFileManagerWidget import Ui_MicroPythonFileManagerWidget
24 25
25 from .MicroPythonFileSystem import MicroPythonFileManager 26 from .MicroPythonFileSystem import MicroPythonFileManager
60 self.localFileTreeWidget.header().setSortIndicator( 61 self.localFileTreeWidget.header().setSortIndicator(
61 0, Qt.AscendingOrder) 62 0, Qt.AscendingOrder)
62 self.deviceFileTreeWidget.header().setSortIndicator( 63 self.deviceFileTreeWidget.header().setSortIndicator(
63 0, Qt.AscendingOrder) 64 0, Qt.AscendingOrder)
64 65
66 self.__progressInfoDialog = None
65 self.__fileManager = MicroPythonFileManager(port, self) 67 self.__fileManager = MicroPythonFileManager(port, self)
66 68
67 self.__fileManager.longListFiles.connect(self.__handleLongListFiles) 69 self.__fileManager.longListFiles.connect(self.__handleLongListFiles)
68 self.__fileManager.currentDir.connect(self.__handleCurrentDir) 70 self.__fileManager.currentDir.connect(self.__handleCurrentDir)
69 self.__fileManager.currentDirChanged.connect(self.__handleCurrentDir) 71 self.__fileManager.currentDirChanged.connect(self.__handleCurrentDir)
70 self.__fileManager.putFileDone.connect(self.__newDeviceList) 72 self.__fileManager.putFileDone.connect(self.__newDeviceList)
71 self.__fileManager.getFileDone.connect(self.__handleGetDone) 73 self.__fileManager.getFileDone.connect(self.__handleGetDone)
72 self.__fileManager.rsyncDone.connect(self.__handleRsyncDone) 74 self.__fileManager.rsyncDone.connect(self.__handleRsyncDone)
73 self.__fileManager.rsyncMessages.connect(self.__handleRsyncMessages) 75 self.__fileManager.rsyncMessages.connect(self.__handleRsyncMessages)
76 self.__fileManager.rsyncProgressMessage.connect(
77 self.__handleRsyncProgressMessage)
74 self.__fileManager.removeDirectoryDone.connect(self.__newDeviceList) 78 self.__fileManager.removeDirectoryDone.connect(self.__newDeviceList)
75 self.__fileManager.createDirectoryDone.connect(self.__newDeviceList) 79 self.__fileManager.createDirectoryDone.connect(self.__newDeviceList)
76 self.__fileManager.deleteFileDone.connect(self.__newDeviceList) 80 self.__fileManager.deleteFileDone.connect(self.__newDeviceList)
77 self.__fileManager.synchTimeDone.connect(self.__timeSynchronized) 81 self.__fileManager.synchTimeDone.connect(self.__timeSynchronized)
78 self.__fileManager.showTimeDone.connect(self.__deviceTimeReceived) 82 self.__fileManager.showTimeDone.connect(self.__deviceTimeReceived)
87 self.__showDeviceContextMenu) 91 self.__showDeviceContextMenu)
88 92
89 self.__localMenu = QMenu(self) 93 self.__localMenu = QMenu(self)
90 self.__localMenu.addAction(self.tr("Change Directory"), 94 self.__localMenu.addAction(self.tr("Change Directory"),
91 self.__changeLocalDirectory) 95 self.__changeLocalDirectory)
96 # TODO: add some more local entries
97 # TODO: add entry to reload
92 98
93 self.__deviceMenu = QMenu(self) 99 self.__deviceMenu = QMenu(self)
94 self.__deviceMenu.addAction( 100 self.__deviceMenu.addAction(
95 self.tr("Change Directory"), self.__changeDeviceDirectory) 101 self.tr("Change Directory"), self.__changeDeviceDirectory)
96 self.__deviceMenu.addAction( 102 self.__deviceMenu.addAction(
101 self.tr("Delete Directory Tree"), self.__deleteDeviceDirectoryTree) 107 self.tr("Delete Directory Tree"), self.__deleteDeviceDirectoryTree)
102 self.__deviceMenu.addSeparator() 108 self.__deviceMenu.addSeparator()
103 self.__devDelFileAct = self.__deviceMenu.addAction( 109 self.__devDelFileAct = self.__deviceMenu.addAction(
104 self.tr("Delete File"), self.__deleteDeviceFile) 110 self.tr("Delete File"), self.__deleteDeviceFile)
105 self.__deviceMenu.addSeparator() 111 self.__deviceMenu.addSeparator()
112 # TODO: add entry to reload
113 self.__deviceMenu.addSeparator()
106 self.__deviceMenu.addAction( 114 self.__deviceMenu.addAction(
107 self.tr("Synchronize Time"), self.__synchronizeTime) 115 self.tr("Synchronize Time"), self.__synchronizeTime)
108 self.__deviceMenu.addAction( 116 self.__deviceMenu.addAction(
109 self.tr("Show Time"), self.__showDeviceTime) 117 self.tr("Show Time"), self.__showDeviceTime)
110 self.__deviceMenu.addSeparator() 118 self.__deviceMenu.addSeparator()
317 filename = selectedItems[0].text(0).strip() 325 filename = selectedItems[0].text(0).strip()
318 if not filename.endswith("/"): 326 if not filename.endswith("/"):
319 # it is really a file 327 # it is really a file
320 if self.__isFileInList(filename, self.deviceFileTreeWidget): 328 if self.__isFileInList(filename, self.deviceFileTreeWidget):
321 # ask for overwrite permission 329 # ask for overwrite permission
322 ok = E5MessageBox.yesNo( 330 # TODO: test this
323 self, 331 action, resultFilename = confirmOverwrite(
324 self.tr("Copy File to Device"), 332 filename, self.tr("Copy File to Device"),
325 self.tr("<p>The file <b>{0}</b> exists on the" 333 self.tr("The given file exists already"
326 " connected device. Overwrite it?</p>") 334 " (Enter file name only)."),
327 .format(filename) 335 False, self)
328 ) 336 if action == "cancel":
329 if ok: 337 return
338 elif action == "rename":
339 deviceFilename = os.path.basename(resultFilename)
340 else:
330 deviceFilename = filename 341 deviceFilename = filename
331 else:
332 deviceFilename, ok = QInputDialog.getText(
333 self,
334 self.tr("Copy File to Device"),
335 self.tr("Enter a new name:"),
336 QLineEdit.Normal,
337 filename)
338 if not ok or not bool(deviceFilename):
339 return
340 else: 342 else:
341 deviceFilename = filename 343 deviceFilename = filename
342 344
343 self.__fileManager.put( 345 self.__fileManager.put(
344 os.path.join(self.localCwd.text(), filename), 346 os.path.join(self.localCwd.text(), filename),
355 filename = selectedItems[0].text(0).strip() 357 filename = selectedItems[0].text(0).strip()
356 if not filename.endswith("/"): 358 if not filename.endswith("/"):
357 # it is really a file 359 # it is really a file
358 if self.__isFileInList(filename, self.localFileTreeWidget): 360 if self.__isFileInList(filename, self.localFileTreeWidget):
359 # ask for overwrite permission 361 # ask for overwrite permission
360 ok = E5MessageBox.yesNo( 362 # TODO: test this
361 self, 363 action, resultFilename = confirmOverwrite(
362 self.tr("Copy File from Device"), 364 filename, self.tr("Copy File from Device"),
363 self.tr("<p>The file <b>{0}</b> exists locally." 365 self.tr("The given file exists already."),
364 " Overwrite it?</p>") 366 True, self)
365 .format(filename) 367 if action == "cancel":
366 ) 368 return
367 if ok: 369 elif action == "rename":
370 localFilename = resultFilename
371 else:
368 localFilename = filename 372 localFilename = filename
369 else:
370 localFilename, ok = QInputDialog.getText(
371 self,
372 self.tr("Copy File from Device"),
373 self.tr("Enter a new name:"),
374 QLineEdit.Normal,
375 filename)
376 if not ok or not bool(localFilename):
377 return
378 else: 373 else:
379 localFilename = filename 374 localFilename = filename
380 375
376 if not os.path.isabs(localFilename):
377 localFilename = os.path.join(self.localCwd.text(),
378 localFilename)
381 self.__fileManager.get( 379 self.__fileManager.get(
382 os.path.join(self.deviceCwd.text(), filename), 380 os.path.join(self.deviceCwd.text(), filename),
383 os.path.join(self.localCwd.text(), localFilename) 381 localFilename
384 ) 382 )
385 383
386 @pyqtSlot(str, str) 384 @pyqtSlot(str, str)
387 def __handleGetDone(self, deviceFile, localFile): 385 def __handleGetDone(self, deviceFile, localFile):
388 """ 386 """
393 @param localFile name of the local file 391 @param localFile name of the local file
394 @type str 392 @type str
395 """ 393 """
396 self.__listLocalFiles(self.localCwd.text()) 394 self.__listLocalFiles(self.localCwd.text())
397 395
396 # TODO: test this
398 @pyqtSlot() 397 @pyqtSlot()
399 def on_syncButton_clicked(self): 398 def on_syncButton_clicked(self):
400 """ 399 """
401 Private slot to synchronize the local directory to the device. 400 Private slot to synchronize the local directory to the device.
402 """ 401 """
434 """<ul><li>{0}</li></ul>""").format( 433 """<ul><li>{0}</li></ul>""").format(
435 "</li><li>".join(messages) 434 "</li><li>".join(messages)
436 ) 435 )
437 ) 436 )
438 437
438 @pyqtSlot(str)
439 def __handleRsyncProgressMessage(self, message):
440 """
441 Private slot handling progress messages sent by the file manager.
442 """
443 # TODO: not implemented yet
444 # create and open the info dialog, if it is None
445 # connect to the dialog finished(int) signal to set the memeber variable to None
446 # add messages to dialog
447
439 @pyqtSlot() 448 @pyqtSlot()
440 def __newDeviceList(self): 449 def __newDeviceList(self):
441 """ 450 """
442 Private slot to initiate a new long list of the device directory. 451 Private slot to initiate a new long list of the device directory.
443 """ 452 """
460 @pyqtSlot() 469 @pyqtSlot()
461 def __changeLocalDirectory(self): 470 def __changeLocalDirectory(self):
462 """ 471 """
463 Private slot to change the local directory. 472 Private slot to change the local directory.
464 """ 473 """
465 path, ok = E5PathPickerDialog.getPath( 474 dirPath, ok = E5PathPickerDialog.getPath(
466 self, 475 self,
467 self.tr("Change Directory"), 476 self.tr("Change Directory"),
468 self.tr("Select Directory"), 477 self.tr("Select Directory"),
469 E5PathPickerModes.DirectoryShowFilesMode, 478 E5PathPickerModes.DirectoryShowFilesMode,
470 defaultDirectory=self.localCwd.text(), 479 defaultDirectory=self.localCwd.text(),
471 ) 480 )
472 if ok and path: 481 if ok and dirPath:
473 self.localCwd.setText(path) 482 if not os.path.isabs(dirPath):
474 self.__listLocalFiles(path) 483 dirPath = os.path.join(self.localCwd.text(), dirPath)
484 self.localCwd.setText(dirPath)
485 self.__listLocalFiles(dirPath)
475 486
476 ################################################################## 487 ##################################################################
477 ## Context menu methods for the device files below 488 ## Context menu methods for the device files below
478 ################################################################## 489 ##################################################################
479 490
508 current directory. 519 current directory.
509 """ 520 """
510 dirPath, ok = QInputDialog.getText( 521 dirPath, ok = QInputDialog.getText(
511 self, 522 self,
512 self.tr("Change Directory"), 523 self.tr("Change Directory"),
513 self.tr("Enter the full directory path on the device:"), 524 self.tr("Enter the directory path on the device:"),
514 QLineEdit.Normal, 525 QLineEdit.Normal,
515 self.deviceCwd.text()) 526 self.deviceCwd.text())
516 if ok and dirPath: 527 if ok and dirPath:
528 if not dirPath.startswith("/"):
529 dirPath = self.deviceCwd.text() + "/" + dirPath
517 self.__fileManager.cd(dirPath) 530 self.__fileManager.cd(dirPath)
518 531
532 # TODO: test this
519 @pyqtSlot() 533 @pyqtSlot()
520 def __createDeviceDirectory(self): 534 def __createDeviceDirectory(self):
521 """ 535 """
522 Private slot to create a directory on the device. 536 Private slot to create a directory on the device.
523 """ 537 """
527 self.tr("Enter directory name:"), 541 self.tr("Enter directory name:"),
528 QLineEdit.Normal) 542 QLineEdit.Normal)
529 if ok and dirPath: 543 if ok and dirPath:
530 self.__fileManager.mkdir(dirPath) 544 self.__fileManager.mkdir(dirPath)
531 545
546 # TODO: test this
532 @pyqtSlot() 547 @pyqtSlot()
533 def __deleteDeviceDirectory(self): 548 def __deleteDeviceDirectory(self):
534 """ 549 """
535 Private slot to delete an empty directory on the device. 550 Private slot to delete an empty directory on the device.
536 """ 551 """
537 if bool(len(self.deviceFileTreeWidget.selectedItems())): 552 if bool(len(self.deviceFileTreeWidget.selectedItems())):
538 name = self.deviceFileTreeWidget.selectedItems()[0].text(0) 553 name = self.deviceFileTreeWidget.selectedItems()[0].text(0)
539 dirname = self.deviceCwd.text() + "/" + name[:-1] 554 dirname = self.deviceCwd.text() + "/" + name[:-1]
555 # TODO: add confirmation
540 self.__fileManager.rmdir(dirname) 556 self.__fileManager.rmdir(dirname)
541 557
542 @pyqtSlot() 558 @pyqtSlot()
543 def __deleteDeviceDirectoryTree(self): 559 def __deleteDeviceDirectoryTree(self):
544 """ 560 """
546 recursively. 562 recursively.
547 """ 563 """
548 if bool(len(self.deviceFileTreeWidget.selectedItems())): 564 if bool(len(self.deviceFileTreeWidget.selectedItems())):
549 name = self.deviceFileTreeWidget.selectedItems()[0].text(0) 565 name = self.deviceFileTreeWidget.selectedItems()[0].text(0)
550 dirname = self.deviceCwd.text() + "/" + name[:-1] 566 dirname = self.deviceCwd.text() + "/" + name[:-1]
567 # TODO: add confirmation
551 self.__fileManager.rmdir(dirname, recursive=True) 568 self.__fileManager.rmdir(dirname, recursive=True)
552 569
553 @pyqtSlot() 570 @pyqtSlot()
554 def __deleteDeviceFile(self): 571 def __deleteDeviceFile(self):
555 """ 572 """
556 Private slot to delete a file 573 Private slot to delete a file
557 """ 574 """
558 if bool(len(self.deviceFileTreeWidget.selectedItems())): 575 if bool(len(self.deviceFileTreeWidget.selectedItems())):
559 name = self.deviceFileTreeWidget.selectedItems()[0].text(0) 576 name = self.deviceFileTreeWidget.selectedItems()[0].text(0)
560 filename = self.deviceCwd.text() + "/" + name 577 filename = self.deviceCwd.text() + "/" + name
578 # TODO: add confirmation
561 self.__fileManager.delete(filename) 579 self.__fileManager.delete(filename)
562 580
563 @pyqtSlot() 581 @pyqtSlot()
564 def __synchronizeTime(self): 582 def __synchronizeTime(self):
565 """ 583 """
632 "<h3>Device Version Information</h3>" 650 "<h3>Device Version Information</h3>"
633 ) 651 )
634 msg += "<table>" 652 msg += "<table>"
635 for key, value in versionInfo.items(): 653 for key, value in versionInfo.items():
636 msg += "<tr><td><b>{0}</b></td><td>{1}</td></tr>".format( 654 msg += "<tr><td><b>{0}</b></td><td>{1}</td></tr>".format(
637 key, value) 655 key.capitalize(), value)
638 msg += "</table>" 656 msg += "</table>"
639 else: 657 else:
640 msg = self.tr("No version information available.") 658 msg = self.tr("No version information available.")
641 E5MessageBox.information( 659 E5MessageBox.information(
642 self, 660 self,

eric ide

mercurial