55 """ |
55 """ |
56 super().__init__(parent) |
56 super().__init__(parent) |
57 self.setupUi(self) |
57 self.setupUi(self) |
58 |
58 |
59 self.__repl = parent |
59 self.__repl = parent |
60 self.__deviceWithLocalAccess = device.supportsLocalFileAccess() |
60 deviceWithLocalAccess = device.supportsLocalFileAccess() |
61 |
61 |
62 self.syncButton.setIcon(EricPixmapCache.getIcon("2rightarrow")) |
62 self.syncButton.setIcon(EricPixmapCache.getIcon("2rightarrow")) |
63 self.putButton.setIcon(EricPixmapCache.getIcon("1rightarrow")) |
63 self.putButton.setIcon(EricPixmapCache.getIcon("1rightarrow")) |
64 self.putAsButton.setIcon(EricPixmapCache.getIcon("putAs")) |
64 self.putAsButton.setIcon(EricPixmapCache.getIcon("putAs")) |
65 self.getButton.setIcon(EricPixmapCache.getIcon("1leftarrow")) |
65 self.getButton.setIcon(EricPixmapCache.getIcon("1leftarrow")) |
147 self.tr("Change Directory"), self.__changeDeviceDirectory |
147 self.tr("Change Directory"), self.__changeDeviceDirectory |
148 ) |
148 ) |
149 self.__deviceMenu.addAction( |
149 self.__deviceMenu.addAction( |
150 self.tr("Create Directory"), self.__createDeviceDirectory |
150 self.tr("Create Directory"), self.__createDeviceDirectory |
151 ) |
151 ) |
152 if not self.__deviceWithLocalAccess: |
152 self.__devDelDirAct = self.__deviceMenu.addAction( |
153 self.__devDelDirAct = self.__deviceMenu.addAction( |
153 self.tr("Delete Directory"), self.__deleteDeviceDirectory |
154 self.tr("Delete Directory"), self.__deleteDeviceDirectory |
154 ) |
155 ) |
|
156 self.__devDelDirTreeAct = self.__deviceMenu.addAction( |
155 self.__devDelDirTreeAct = self.__deviceMenu.addAction( |
157 self.tr("Delete Directory Tree"), self.__deleteDeviceDirectoryTree |
156 self.tr("Delete Directory Tree"), self.__deleteDeviceDirectoryTree |
158 ) |
157 ) |
159 self.__deviceMenu.addSeparator() |
158 self.__deviceMenu.addSeparator() |
160 self.__devDelFileAct = self.__deviceMenu.addAction( |
159 self.__devDelFileAct = self.__deviceMenu.addAction( |
186 or Preferences.getMultiProject("Workspace") |
185 or Preferences.getMultiProject("Workspace") |
187 or os.path.expanduser("~") |
186 or os.path.expanduser("~") |
188 ) |
187 ) |
189 self.__listLocalFiles(dirname) |
188 self.__listLocalFiles(dirname) |
190 |
189 |
191 if self.__deviceWithLocalAccess: |
190 if self.__repl.deviceSupportsLocalFileAccess(): |
192 dirname = self.__repl.getDeviceWorkspace() |
191 dirname = self.__repl.getDeviceWorkspace() |
193 if dirname: |
192 if dirname: |
194 self.__listLocalFiles(dirname, True) |
193 self.__listLocalFiles(dirname, True) |
195 return |
194 return |
196 |
195 |
262 @param localDevice flag indicating device access via local file system |
261 @param localDevice flag indicating device access via local file system |
263 @type bool |
262 @type bool |
264 """ |
263 """ |
265 if not dirname: |
264 if not dirname: |
266 dirname = os.getcwd() |
265 dirname = os.getcwd() |
267 if dirname.endswith(os.sep): |
266 if dirname != os.sep and dirname.endswith(os.sep): |
268 dirname = dirname[:-1] |
267 dirname = dirname[:-1] |
269 if localDevice: |
268 if localDevice: |
270 self.deviceCwd.setText(dirname) |
269 self.deviceCwd.setText(dirname) |
271 showHidden = Preferences.getMicroPython("ShowHiddenDevice") |
270 showHidden = Preferences.getMicroPython("ShowHiddenDevice") |
272 else: |
271 else: |
324 self.localFileTreeWidget.selectedItems()[0].text(0).endswith("/") |
323 self.localFileTreeWidget.selectedItems()[0].text(0).endswith("/") |
325 ) |
324 ) |
326 self.putButton.setEnabled(enable) |
325 self.putButton.setEnabled(enable) |
327 self.putAsButton.setEnabled(enable) |
326 self.putAsButton.setEnabled(enable) |
328 |
327 |
|
328 @pyqtSlot(str) |
|
329 def on_localCwd_textChanged(self, cwd): |
|
330 """ |
|
331 Public slot handling a change of the current local working directory. |
|
332 |
|
333 @param cwd current local working directory |
|
334 @type str |
|
335 """ |
|
336 self.localUpButton.setEnabled(cwd != os.sep) |
|
337 |
329 @pyqtSlot() |
338 @pyqtSlot() |
330 def on_localUpButton_clicked(self): |
339 def on_localUpButton_clicked(self): |
331 """ |
340 """ |
332 Private slot to go up one directory level. |
341 Private slot to go up one directory level. |
333 """ |
342 """ |
366 @param item reference to the activated item |
375 @param item reference to the activated item |
367 @type QTreeWidgetItem |
376 @type QTreeWidgetItem |
368 @param column column of the activation |
377 @param column column of the activation |
369 @type int |
378 @type int |
370 """ |
379 """ |
371 if self.__deviceWithLocalAccess: |
380 if self.__repl.deviceSupportsLocalFileAccess(): |
372 name = os.path.join(self.deviceCwd.text(), item.text(0)) |
381 name = os.path.join(self.deviceCwd.text(), item.text(0)) |
373 if name.endswith("/"): |
382 if name.endswith("/"): |
374 # directory names end with a '/' |
383 # directory names end with a '/' |
375 self.__listLocalFiles(name[:-1], True) |
384 self.__listLocalFiles(name[:-1], True) |
376 elif Utilities.MimeTypes.isTextFile(name): |
385 elif Utilities.MimeTypes.isTextFile(name): |
409 self.getAsButton.setEnabled(enable) |
418 self.getAsButton.setEnabled(enable) |
410 |
419 |
411 self.openButton.setEnabled(enable) |
420 self.openButton.setEnabled(enable) |
412 self.saveButton.setEnabled(enable) |
421 self.saveButton.setEnabled(enable) |
413 |
422 |
|
423 @pyqtSlot(str) |
|
424 def on_deviceCwd_textChanged(self, cwd): |
|
425 """ |
|
426 Public slot handling a change of the current device working directory. |
|
427 |
|
428 @param cwd current device working directory |
|
429 @type str |
|
430 """ |
|
431 self.deviceUpButton.setEnabled(cwd != "/") |
|
432 |
414 @pyqtSlot() |
433 @pyqtSlot() |
415 def on_deviceUpButton_clicked(self): |
434 def on_deviceUpButton_clicked(self): |
416 """ |
435 """ |
417 Private slot to go up one directory level on the device. |
436 Private slot to go up one directory level on the device. |
418 """ |
437 """ |
419 cwd = self.deviceCwd.text() |
438 cwd = self.deviceCwd.text() |
420 dirname = os.path.dirname(cwd) |
439 dirname = os.path.dirname(cwd) |
421 if self.__deviceWithLocalAccess: |
440 if self.__repl.deviceSupportsLocalFileAccess(): |
422 self.__listLocalFiles(dirname, True) |
441 self.__listLocalFiles(dirname, True) |
423 else: |
442 else: |
424 self.__fileManager.cd(dirname) |
443 self.__fileManager.cd(dirname) |
425 |
444 |
426 @pyqtSlot() |
445 @pyqtSlot() |
427 def on_deviceHomeButton_clicked(self): |
446 def on_deviceHomeButton_clicked(self): |
428 """ |
447 """ |
429 Private slot to move to the device home directory. |
448 Private slot to move to the device home directory. |
430 """ |
449 """ |
431 if self.__deviceWithLocalAccess: |
450 if self.__repl.deviceSupportsLocalFileAccess(): |
432 dirname = self.__repl.getDeviceWorkspace() |
451 dirname = self.__repl.getDeviceWorkspace() |
433 if dirname: |
452 if dirname: |
434 self.__listLocalFiles(dirname, True) |
453 self.__listLocalFiles(dirname, True) |
435 return |
454 return |
436 |
455 |
441 def on_deviceReloadButton_clicked(self): |
460 def on_deviceReloadButton_clicked(self): |
442 """ |
461 """ |
443 Private slot to reload the device list. |
462 Private slot to reload the device list. |
444 """ |
463 """ |
445 dirname = self.deviceCwd.text() |
464 dirname = self.deviceCwd.text() |
446 if self.__deviceWithLocalAccess: |
465 if self.__repl.deviceSupportsLocalFileAccess(): |
447 self.__listLocalFiles(dirname, True) |
466 self.__listLocalFiles(dirname, True) |
448 else: |
467 else: |
449 if dirname: |
468 if dirname: |
450 self.__newDeviceList() |
469 self.__newDeviceList() |
451 else: |
470 else: |
506 if action == "cancel": |
525 if action == "cancel": |
507 return |
526 return |
508 elif action == "rename": |
527 elif action == "rename": |
509 deviceFilename = os.path.basename(resultFilename) |
528 deviceFilename = os.path.basename(resultFilename) |
510 |
529 |
511 if self.__deviceWithLocalAccess: |
530 if self.__repl.deviceSupportsLocalFileAccess(): |
512 shutil.copy2( |
531 shutil.copy2( |
513 os.path.join(self.localCwd.text(), filename), |
532 os.path.join(self.localCwd.text(), filename), |
514 os.path.join(self.deviceCwd.text(), deviceFilename), |
533 os.path.join(self.deviceCwd.text(), deviceFilename), |
515 ) |
534 ) |
516 self.__listLocalFiles(self.deviceCwd.text(), localDevice=True) |
535 self.__listLocalFiles(self.deviceCwd.text(), localDevice=True) |
571 if action == "cancel": |
590 if action == "cancel": |
572 return |
591 return |
573 elif action == "rename": |
592 elif action == "rename": |
574 localFilename = resultFilename |
593 localFilename = resultFilename |
575 |
594 |
576 if self.__deviceWithLocalAccess: |
595 if self.__repl.deviceSupportsLocalFileAccess(): |
577 shutil.copy2( |
596 shutil.copy2( |
578 os.path.join(self.deviceCwd.text(), filename), |
597 os.path.join(self.deviceCwd.text(), filename), |
579 os.path.join(self.localCwd.text(), localFilename), |
598 os.path.join(self.localCwd.text(), localFilename), |
580 ) |
599 ) |
581 self.__listLocalFiles(self.localCwd.text()) |
600 self.__listLocalFiles(self.localCwd.text()) |
614 """ |
633 """ |
615 self.__fileManager.rsync( |
634 self.__fileManager.rsync( |
616 self.localCwd.text(), |
635 self.localCwd.text(), |
617 self.deviceCwd.text(), |
636 self.deviceCwd.text(), |
618 mirror=True, |
637 mirror=True, |
619 localDevice=self.__deviceWithLocalAccess, |
638 localDevice=self.__repl.deviceSupportsLocalFileAccess(), |
620 ) |
639 ) |
621 |
640 |
622 @pyqtSlot(str, str) |
641 @pyqtSlot(str, str) |
623 def __handleRsyncDone(self, localDir, deviceDir): |
642 def __handleRsyncDone(self, localDir, deviceDir): |
624 """ |
643 """ |
675 Private slot to open the selected file in a new editor. |
694 Private slot to open the selected file in a new editor. |
676 """ |
695 """ |
677 selectedItems = self.deviceFileTreeWidget.selectedItems() |
696 selectedItems = self.deviceFileTreeWidget.selectedItems() |
678 if selectedItems: |
697 if selectedItems: |
679 filename = selectedItems[0].text(0).strip() |
698 filename = selectedItems[0].text(0).strip() |
680 if self.__deviceWithLocalAccess: |
699 if self.__repl.deviceSupportsLocalFileAccess(): |
681 name = os.path.join(self.deviceCwd.text(), filename) |
700 name = os.path.join(self.deviceCwd.text(), filename) |
682 if not name.endswith("/") and Utilities.MimeTypes.isTextFile(name): |
701 if not name.endswith("/") and Utilities.MimeTypes.isTextFile(name): |
683 ericApp().getObject("ViewManager").getEditor(name) |
702 ericApp().getObject("ViewManager").getEditor(name) |
684 else: |
703 else: |
685 cwd = self.deviceCwd.text() |
704 cwd = self.deviceCwd.text() |
749 return |
768 return |
750 elif action == "rename": |
769 elif action == "rename": |
751 filename = os.path.basename(resultFilename) |
770 filename = os.path.basename(resultFilename) |
752 |
771 |
753 text = aw.text() |
772 text = aw.text() |
754 if self.__deviceWithLocalAccess: |
773 if self.__repl.deviceSupportsLocalFileAccess(): |
755 with open(os.path.join(self.deviceCwd.text(), filename), "w") as f: |
774 with open(os.path.join(self.deviceCwd.text(), filename), "w") as f: |
756 f.write(text) |
775 f.write(text) |
757 else: |
776 else: |
758 deviceCwd = self.deviceCwd.text() |
777 deviceCwd = self.deviceCwd.text() |
759 if deviceCwd: |
778 if deviceCwd: |
957 isFile = not isDir |
976 isFile = not isDir |
958 else: |
977 else: |
959 isDir = False |
978 isDir = False |
960 isFile = False |
979 isFile = False |
961 if not self.__repl.isMicrobit(): |
980 if not self.__repl.isMicrobit(): |
962 if not self.__deviceWithLocalAccess: |
981 self.__devDelDirAct.setEnabled(isDir) |
963 self.__devDelDirAct.setEnabled(isDir) |
|
964 self.__devDelDirTreeAct.setEnabled(isDir) |
982 self.__devDelDirTreeAct.setEnabled(isDir) |
965 self.__devDelFileAct.setEnabled(isFile) |
983 self.__devDelFileAct.setEnabled(isFile) |
966 |
984 |
967 self.__deviceMenu.exec(self.deviceFileTreeWidget.mapToGlobal(pos)) |
985 self.__deviceMenu.exec(self.deviceFileTreeWidget.mapToGlobal(pos)) |
968 |
986 |
972 Private slot to change the current directory of the device. |
990 Private slot to change the current directory of the device. |
973 |
991 |
974 Note: This triggers a re-population of the device list for the new |
992 Note: This triggers a re-population of the device list for the new |
975 current directory. |
993 current directory. |
976 """ |
994 """ |
977 if self.__deviceWithLocalAccess: |
995 if self.__repl.deviceSupportsLocalFileAccess(): |
978 self.__changeLocalDirectory(True) |
996 self.__changeLocalDirectory(True) |
979 else: |
997 else: |
980 dirPath, ok = QInputDialog.getText( |
998 dirPath, ok = QInputDialog.getText( |
981 self, |
999 self, |
982 self.tr("Change Directory"), |
1000 self.tr("Change Directory"), |
992 @pyqtSlot() |
1010 @pyqtSlot() |
993 def __createDeviceDirectory(self): |
1011 def __createDeviceDirectory(self): |
994 """ |
1012 """ |
995 Private slot to create a directory on the device. |
1013 Private slot to create a directory on the device. |
996 """ |
1014 """ |
997 if self.__deviceWithLocalAccess: |
1015 if self.__repl.deviceSupportsLocalFileAccess(): |
998 self.__createLocalDirectory(True) |
1016 self.__createLocalDirectory(True) |
999 else: |
1017 else: |
1000 dirPath, ok = QInputDialog.getText( |
1018 dirPath, ok = QInputDialog.getText( |
1001 self, |
1019 self, |
1002 self.tr("Create Directory"), |
1020 self.tr("Create Directory"), |
1009 @pyqtSlot() |
1027 @pyqtSlot() |
1010 def __deleteDeviceDirectory(self): |
1028 def __deleteDeviceDirectory(self): |
1011 """ |
1029 """ |
1012 Private slot to delete an empty directory on the device. |
1030 Private slot to delete an empty directory on the device. |
1013 """ |
1031 """ |
1014 if self.__deviceWithLocalAccess: |
1032 if self.__repl.deviceSupportsLocalFileAccess(): |
1015 self.__deleteLocalDirectoryTree(True) |
1033 self.__deleteLocalDirectoryTree(True) |
1016 else: |
1034 else: |
1017 if bool(len(self.deviceFileTreeWidget.selectedItems())): |
1035 if bool(len(self.deviceFileTreeWidget.selectedItems())): |
1018 name = self.deviceFileTreeWidget.selectedItems()[0].text(0) |
1036 name = self.deviceFileTreeWidget.selectedItems()[0].text(0) |
1019 cwd = self.deviceCwd.text() |
1037 cwd = self.deviceCwd.text() |
1037 def __deleteDeviceDirectoryTree(self): |
1055 def __deleteDeviceDirectoryTree(self): |
1038 """ |
1056 """ |
1039 Private slot to delete a directory and all its subdirectories |
1057 Private slot to delete a directory and all its subdirectories |
1040 recursively. |
1058 recursively. |
1041 """ |
1059 """ |
1042 if self.__deviceWithLocalAccess: |
1060 if self.__repl.deviceSupportsLocalFileAccess(): |
1043 self.__deleteLocalDirectoryTree(True) |
1061 self.__deleteLocalDirectoryTree(True) |
1044 else: |
1062 else: |
1045 if bool(len(self.deviceFileTreeWidget.selectedItems())): |
1063 if bool(len(self.deviceFileTreeWidget.selectedItems())): |
1046 name = self.deviceFileTreeWidget.selectedItems()[0].text(0) |
1064 name = self.deviceFileTreeWidget.selectedItems()[0].text(0) |
1047 cwd = self.deviceCwd.text() |
1065 cwd = self.deviceCwd.text() |
1064 @pyqtSlot() |
1082 @pyqtSlot() |
1065 def __deleteDeviceFile(self): |
1083 def __deleteDeviceFile(self): |
1066 """ |
1084 """ |
1067 Private slot to delete a file. |
1085 Private slot to delete a file. |
1068 """ |
1086 """ |
1069 if self.__deviceWithLocalAccess: |
1087 if self.__repl.deviceSupportsLocalFileAccess(): |
1070 self.__deleteLocalFile(True) |
1088 self.__deleteLocalFile(True) |
1071 else: |
1089 else: |
1072 if bool(len(self.deviceFileTreeWidget.selectedItems())): |
1090 if bool(len(self.deviceFileTreeWidget.selectedItems())): |
1073 name = self.deviceFileTreeWidget.selectedItems()[0].text(0) |
1091 name = self.deviceFileTreeWidget.selectedItems()[0].text(0) |
1074 dirname = self.deviceCwd.text() |
1092 dirname = self.deviceCwd.text() |