src/eric7/RemoteServerInterface/EricServerFileDialog.py

branch
server
changeset 10539
4274f189ff78
child 10548
d3e21f44887b
equal deleted inserted replaced
10531:3308e8349e4c 10539:4274f189ff78
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2024 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a file dialog showing the file system of the eric-ide server.
8 """
9
10 import enum
11 import fnmatch
12 import re
13
14 from PyQt6.QtCore import QLocale, Qt, pyqtSlot, QPoint
15 from PyQt6.QtWidgets import (
16 QDialog, QTreeWidgetItem, QAbstractItemView, QCompleter, QLineEdit, QInputDialog,
17 QMenu
18 )
19
20 from eric7.EricGui import EricPixmapCache
21 from eric7.EricGui.EricFileIconProvider import EricFileIconProvider
22 from eric7.EricWidgets import EricMessageBox
23 from eric7.EricWidgets.EricApplication import ericApp
24 from eric7.Globals import dataString
25 from eric7.SystemUtilities import FileSystemUtilities
26
27 from .Ui_EricServerFileDialog import Ui_EricServerFileDialog
28
29
30 class AcceptMode(enum.Enum):
31 """
32 Class defining the dialog accept modes.
33 """
34 AcceptOpen = 0
35 AcceptSave = 1
36
37
38 class FileMode(enum.Enum):
39 """
40 Class defining what the user may select in the file dialog.
41 """
42 AnyFile = 0
43 ExistingFile = 1
44 Directory = 2
45 ExistingFiles = 3
46
47 class EricServerFileDialog(QDialog, Ui_EricServerFileDialog):
48 """
49 Class implementing a file dialog showing the file system of the eric-ide server.
50 """
51
52 IsDirectoryRole = Qt.ItemDataRole.UserRole
53
54 def __init__(self, parent=None, caption="", directory="", filter=""):
55 """
56 Constructor
57
58 @param parent reference to the parent widget (defaults to None)
59 @type QWidget (optional)
60 @param caption dialog title (defaults to "")
61 @type str (optional)
62 @param directory initial directory (defaults to "")
63 @type str (optional)
64 @param filter Qt file filter string (defaults to "")
65 @type str (optional)
66 """
67 super().__init__(parent)
68 self.setupUi(self)
69
70 # finish UI setup
71 self.backButton.setIcon(EricPixmapCache.getIcon("1leftarrow"))
72 self.forwardButton.setIcon(EricPixmapCache.getIcon("1rightarrow"))
73 self.upButton.setIcon(EricPixmapCache.getIcon("1uparrow"))
74 self.newDirButton.setIcon(EricPixmapCache.getIcon("dirNew"))
75 self.reloadButton.setIcon(EricPixmapCache.getIcon("reload"))
76 self.cancelButton.setIcon(EricPixmapCache.getIcon("dialog-cancel"))
77
78 self.setWindowTitle(caption)
79
80 self.__iconProvider = EricFileIconProvider()
81
82 self.__nameCompleter = QCompleter()
83 self.__nameCompleter.setModel(self.listing.model())
84 self.__nameCompleter.setCompletionColumn(0)
85 self.__nameCompleter.activated.connect(self.__nameCompleterActivated)
86 self.nameEdit.setCompleter(self.__nameCompleter)
87
88 self.__contextMenu = QMenu(self)
89
90 self.__fsInterface = ericApp().getObject("EricServer").getServiceInterface(
91 "FileSystem"
92 )
93
94 # set some default values
95 self.__fileMode = FileMode.ExistingFile
96 self.__dirsOnly = False
97 self.__acceptMode = AcceptMode.AcceptOpen
98 self.__showHidden = False
99 self.__sep = "/"
100 self.__filters = []
101
102 self.__history = []
103 self.__currentHistoryIndex = -1 # empty history
104 self.__updateHistoryButtons()
105
106 self.__filenameCache = []
107 self.__directoryCache = []
108 self.__selectedDirectory = None
109
110 self.setNameFilters(filter.split(";;"))
111
112 self.reloadButton.clicked.connect(self.__reload)
113 self.cancelButton.clicked.connect(self.reject)
114
115 self.treeCombo.currentTextChanged.connect(self.setDirectory)
116
117 self.setDirectory(FileSystemUtilities.plainFileName(directory))
118
119 def acceptMode(self):
120 """
121 Public method to get the accept mode of the dialog.
122
123 @return accept mode
124 @rtype AcceptMode
125 """
126 return self.__acceptMode
127
128 def setAcceptMode(self, mode):
129 """
130 Public method to set the accept mode of the dialog.
131
132 @param mode accept mode
133 @type AcceptMode
134 """
135 self.__acceptMode = mode
136
137 self.__updateOkButton()
138
139 def fileMode(self):
140 """
141 Public method to get the current file mode of the dialog.
142
143 @return file mode
144 @rtype FileMode
145 """
146 return self.__fileMode
147
148 def setFileMode(self, mode):
149 """
150 Public method to set the file mode of the dialog.
151
152 @param mode file mode
153 @type FileMode
154 """
155 self.__fileMode = mode
156
157 self.listing.clearSelection()
158 if mode == FileMode.ExistingFiles:
159 self.listing.setSelectionMode(
160 QAbstractItemView.SelectionMode.ExtendedSelection
161 )
162 else:
163 self.listing.setSelectionMode(
164 QAbstractItemView.SelectionMode.SingleSelection
165 )
166
167 self.__updateOkButton()
168
169 def setNameFilters(self, filters):
170 """
171 Public method to set the list of file/directory name filters.
172
173 @param filters list of filter expressions
174 ("filter_name (pattern1 ... patternN)")
175 @type list of str
176 """
177 self.__filters = [
178 f.split(" (", 1)[1].split(")", 1)[0].split() for f in filters
179 ]
180
181 self.filterCombo.clear()
182 self.filterCombo.addItems(filters)
183
184 def setNameFilter(self, filter):
185 """
186 Public method to set the current name filter.
187
188 @param filter filter text to make current
189 @type str
190 """
191 self.filterCombo.setCurrentText(filter)
192
193 def setDirectoriesOnly(self, dirsOnly):
194 """
195 Public method to set a flag to just show directories.
196
197 @param dirsOnly flag indicating to just show directories
198 @type bool
199 """
200 self.__dirsOnly = dirsOnly
201
202 filters = self.__filters[self.filterCombo.currentIndex()]
203 self.__filterList(filters)
204
205 def __addToHistory(self, entry):
206 """
207 Private method to add a directory to the history list.
208
209 @param entry name of the directory to be added
210 @type str
211 """
212 try:
213 # is in the history already?
214 index = self.__history.index(entry)
215 self.__currentHistoryIndex = index
216 except ValueError:
217 # new entry
218 self.__history.append(entry)
219 self.__currentHistoryIndex = len(self.__history) - 1
220
221 self.__updateHistoryButtons()
222
223 @pyqtSlot()
224 def __updateHistoryButtons(self):
225 """
226 Private method to update the enabled state of the back and forward buttons.
227 """
228 if not self.__history:
229 self.backButton.setEnabled(False)
230 self.forwardButton.setEnabled(False)
231 else:
232 self.backButton.setEnabled(self.__currentHistoryIndex > 0)
233 self.forwardButton.setEnabled(
234 self.__currentHistoryIndex < len(self.__history) - 1
235 )
236
237 @pyqtSlot()
238 def on_backButton_clicked(self):
239 """
240 Private slot to move back in history of visited directories.
241 """
242 self.setDirectory(self.__history[self.__currentHistoryIndex - 1])
243
244 @pyqtSlot()
245 def on_forwardButton_clicked(self):
246 """
247 Private slot to move forward in history of visited directories.
248 """
249 self.setDirectory(self.__history[self.__currentHistoryIndex + 1])
250
251 @pyqtSlot()
252 def __updateUpButton(self):
253 """
254 Private slot to update the enabled state of the 'Up' button.
255 """
256 self.upButton.setEnabled(
257 self.treeCombo.currentIndex() < self.treeCombo.count() - 1
258 )
259
260 @pyqtSlot()
261 def on_upButton_clicked(self):
262 """
263 Private slot to move up one level in the hierarchy.
264 """
265 self.treeCombo.setCurrentIndex(self.treeCombo.currentIndex() + 1)
266
267 @pyqtSlot()
268 def on_newDirButton_clicked(self):
269 """
270 Private slot to create a new directory.
271 """
272 newDir, ok = QInputDialog.getText(
273 self,
274 self.tr("New Directory"),
275 self.tr("Enter the name for the new directory:"),
276 QLineEdit.EchoMode.Normal,
277 )
278 if ok and newDir:
279 if newDir in self.__directoryCache or newDir in self.__filenameCache:
280 EricMessageBox.warning(
281 self,
282 self.tr("New Directory"),
283 self.tr(
284 "<p>A file or directory with the name <b>{0}</b> exists"
285 " already. Aborting...</p>"
286 ).format(newDir),
287 )
288 return
289
290 ok, error = self.__fsInterface.mkdir(self.__getFullPath(newDir))
291 if ok:
292 # refresh
293 self.__reload()
294 else:
295 EricMessageBox.critical(
296 self,
297 self.tr("New Directory"),
298 self.tr(
299 "<p>The directory <b>{0}</b> could not be created.</p>"
300 "<p>Reason: {1}</p>"
301 ).format(
302 self.__getFullPath(newDir),
303 error if error else self.tr("Unknown"),
304 ),
305 )
306
307 @pyqtSlot()
308 def __reload(self):
309 """
310 Private slot to reload the directory listing.
311 """
312 self.setDirectory(self.treeCombo.currentText())
313
314 @pyqtSlot(QTreeWidgetItem, int)
315 def on_listing_itemActivated(self, item, column):
316 """
317 Private slot to handle the activation of an item in the list.
318
319 @param item reference to the activated item
320 @type QTreeWidgetItem
321 @param column column number (unused)
322 @type int
323 """
324 if (
325 item.data(0, EricServerFileDialog.IsDirectoryRole)
326 and self.__fileMode != FileMode.Directory
327 ):
328 self.setDirectory(self.__getFullPath(item.text(0)))
329 else:
330 self.accept()
331
332 @pyqtSlot()
333 def on_listing_itemSelectionChanged(self):
334 """
335 Private slot to handle the selection of listed items.
336 """
337 for itm in self.listing.selectedItems():
338 if itm.data(0, EricServerFileDialog.IsDirectoryRole):
339 self.__selectedDirectory = itm.text(0)
340 break
341 else:
342 self.__selectedDirectory = None
343
344 selected = []
345 for itm in self.listing.selectedItems():
346 isDir = itm.data(0, EricServerFileDialog.IsDirectoryRole)
347 if self.__fileMode == FileMode.Directory and isDir:
348 selected.append(itm.text(0))
349 elif not isDir:
350 selected.append(itm.text(0))
351
352 if len(selected) == 1:
353 self.nameEdit.setText(selected[0])
354 elif len(selected) > 1:
355 self.nameEdit.setText(
356 '"{0}"'.format('" "'.join(selected))
357 )
358
359 self.__updateOkButton()
360
361 @pyqtSlot()
362 def __nameCompleterActivated(self):
363 """
364 Private slot handling the activation of the completer.
365 """
366 if self.okButton.isEnabled():
367 self.okButton.animateClick()
368
369 @pyqtSlot(str)
370 def on_nameEdit_textChanged(self, name):
371 """
372 Private slot handling the editing of a file or directory name.
373
374 @param name current text of the name edit
375 @type str
376 """
377 self.listing.clearSelection()
378 items = self.listing.findItems(name, Qt.MatchFlag.MatchExactly)
379 for itm in items:
380 itm.setSelected(True)
381
382 self.__updateOkButton()
383
384 def __getNames(self):
385 """
386 Private method to get the selected names list.
387
388 @return list containing the selected names
389 @rtype list of str
390 """
391 namesStr = self.nameEdit.text()
392 if namesStr.startswith('"'):
393 namesStr = namesStr[1:]
394 if namesStr.endswith('"'):
395 namesStr = namesStr[:-1]
396 names = re.split(r'"\s+"', namesStr)
397 return names
398
399 def __getFullPath(self, name):
400 """
401 Private method to get the full path for a given file or directory name.
402
403 @param name name of the file or directory
404 @type str
405 @return full path of the file or directory
406 @rtype str
407 """
408 return "{0}{1}{2}".format(self.treeCombo.currentText(), self.__sep, name)
409
410 @pyqtSlot()
411 def __updateOkButton(self):
412 """
413 Private slot to set the 'OK' button state, icon and label.
414 """
415 # 1. adjust icon and label
416 if (
417 self.__acceptMode == AcceptMode.AcceptOpen
418 or self.__selectedDirectory is not None
419 ):
420 self.okButton.setIcon(EricPixmapCache.getIcon("dialog-ok"))
421 self.okButton.setText(self.tr("Open"))
422 else:
423 self.okButton.setIcon(EricPixmapCache.getIcon("fileSave"))
424 self.okButton.setText(self.tr("Save"))
425
426 # 2. adjust enabled state
427 if self.__selectedDirectory and self.__fileMode != FileMode.Directory:
428 self.okButton.setEnabled(True)
429 elif self.__fileMode == FileMode.AnyFile:
430 self.okButton.setEnabled(bool(self.nameEdit.text()))
431 elif self.__fileMode == FileMode.ExistingFile:
432 self.okButton.setEnabled(
433 self.nameEdit.text() in self.__filenameCache
434 )
435 elif self.__fileMode == FileMode.ExistingFiles:
436 names = self.__getNames()
437 self.okButton.setEnabled(
438 all(n in self.__filenameCache for n in names)
439 )
440 elif self.__fileMode == FileMode.Directory:
441 self.okButton.setEnabled(
442 self.nameEdit.text() in self.__directoryCache
443 )
444 else:
445 self.okButton.setEnabled(False)
446
447 @pyqtSlot()
448 def on_okButton_clicked(self):
449 """
450 Private slot handling the press of the OK button.
451 """
452 if self.__selectedDirectory and self.__fileMode != FileMode.Directory:
453 self.setDirectory(self.__getFullPath(self.__selectedDirectory))
454 else:
455 self.accept()
456
457 @pyqtSlot(int)
458 def on_filterCombo_currentIndexChanged(self, index):
459 """
460 Slot documentation goes here.
461
462 @param index DESCRIPTION
463 @type int
464 """
465 filters = self.__filters[index]
466 self.__filterList(filters)
467
468 @pyqtSlot(str)
469 def setDirectory(self, directory):
470 """
471 Public slot to set the current directory and populate the tree list.
472
473 @param directory directory to be set as current. An empty directory sets the
474 server's current directory.
475 @type str
476 """
477 self.__filenameCache.clear()
478 self.__directoryCache.clear()
479
480
481 directory, sep, dirListing = self.__fsInterface.listdir(directory)
482
483 self.__sep = sep
484
485 # 1. populate the directory tree combo box
486 self.treeCombo.blockSignals(True)
487 self.treeCombo.clear()
488 if len(directory) > 1 and directory.endswith(sep):
489 directory = directory[:-1]
490 if len(directory) > 2 and directory[1] == ":":
491 # starts with a Windows drive letter
492 directory = directory[2:]
493 directoryParts = directory.split(sep)
494 while directoryParts:
495 if directoryParts[-1]:
496 self.treeCombo.addItem(sep.join(directoryParts))
497 directoryParts.pop()
498 self.treeCombo.addItem(sep)
499 self.treeCombo.blockSignals(False)
500
501 # 2. populate the directory listing
502 self.listing.clear()
503 for dirEntry in sorted(
504 dirListing,
505 key=lambda d: " " + d['name'].lower() if d["is_dir"] else d["name"].lower(),
506 ):
507 if dirEntry["is_dir"]:
508 type_ = self.tr("Directory")
509 iconName = "dirClosed"
510 sizeStr = ""
511 self.__directoryCache.append(dirEntry["name"])
512 else:
513 type_ = self.tr("File")
514 iconName = self.__iconProvider.fileIconName(dirEntry["name"])
515 sizeStr = dataString(dirEntry["size"], QLocale.system())
516 self.__filenameCache.append(dirEntry["name"])
517 itm = QTreeWidgetItem(
518 self.listing,
519 [dirEntry["name"], sizeStr, type_, dirEntry["mtime"]]
520 )
521 itm.setIcon(0, EricPixmapCache.getIcon(iconName))
522 itm.setTextAlignment(1, Qt.AlignmentFlag.AlignRight)
523 itm.setTextAlignment(2, Qt.AlignmentFlag.AlignHCenter)
524 itm.setData(0, EricServerFileDialog.IsDirectoryRole, dirEntry["is_dir"])
525
526
527 filters = self.__filters[self.filterCombo.currentIndex()]
528 self.__filterList(filters)
529
530 # 3. add the directory to the history
531 self.__addToHistory(directory)
532
533 # 4. update some dependent states
534 self.nameEdit.clear()
535 self.__updateUpButton()
536
537 @pyqtSlot(QPoint)
538 def on_listing_customContextMenuRequested(self, pos):
539 """
540 Priovate slot to show a context menu.
541
542 @param pos mouse pointer position to show the menu at
543 @type QPoint
544 """
545 self.__contextMenu.clear()
546
547 itm = self.listing.itemAt(pos)
548 if itm is not None:
549 self.__contextMenu.addAction(
550 self.tr("Rename"), lambda: self.__renameItem(itm)
551 )
552 self.__contextMenu.addAction(
553 self.tr("Delete"), lambda: self.__deleteItem(itm)
554 )
555 self.__contextMenu.addSeparator()
556 act = self.__contextMenu.addAction(self.tr("Show Hidden Files"))
557 act.setCheckable(True)
558 act.setChecked(self.__showHidden)
559 act.toggled.connect(self.__showHiddenToggled)
560 self.__contextMenu.addAction(
561 self.tr("New Directory"), self.on_newDirButton_clicked
562 )
563
564 self.__contextMenu.popup(self.listing.mapToGlobal(pos))
565
566 @pyqtSlot(QTreeWidgetItem)
567 def __renameItem(self, item):
568 """
569 Private slot to rename the given file/directory item.
570
571 @param item reference to the item to be renamed
572 @type QTreeWidgetItem
573 """
574 title = (
575 self.tr("Rename Directory")
576 if item.data(0, EricServerFileDialog.IsDirectoryRole)
577 else self.tr("Rename File")
578 )
579
580 newName, ok = QInputDialog.getText(
581 self,
582 title,
583 self.tr("<p>Enter the new name <b>{0}</b>:</p>").format(item.text(0)),
584 QLineEdit.EchoMode.Normal,
585 item.text(0),
586 )
587 if ok and newName:
588 if newName in self.__directoryCache or newName in self.__filenameCache:
589 EricMessageBox.warning(
590 self,
591 title,
592 self.tr(
593 "<p>A file or directory with the name <b>{0}</b> exists"
594 " already. Aborting...</p>"
595 ).format(newName),
596 )
597 return
598
599 ok, error = self.__fsInterface.replace(
600 self.__getFullPath(item.text(0)), self.__getFullPath(newName)
601 )
602 if ok:
603 # refresh
604 self.__reload()
605 else:
606 EricMessageBox.critical(
607 self,
608 title,
609 self.tr(
610 "<p>The renaming operation failed.</p>"
611 "<p>Reason: {0}</p>"
612 ).format(error if error else self.tr("Unknown")),
613 )
614
615 @pyqtSlot(QTreeWidgetItem)
616 def __deleteItem(self, item):
617 """
618 Private slot to delete the given file/directory item.
619
620 @param item reference to the item to be deleted
621 @type QTreeWidgetItem
622 """
623 isDir = item.data(0, EricServerFileDialog.IsDirectoryRole)
624 if isDir:
625 title = self.tr("Delete Directory")
626 itemType = self.tr("directory")
627 else:
628 title = self.tr("Delete File")
629 itemType = self.tr("file")
630
631 yes = EricMessageBox.yesNo(
632 self,
633 title,
634 self.tr("Shall the selected {0} really be deleted?").format(itemType),
635 )
636 if yes:
637 ok, error = (
638 self.__fsInterface.rmdir(self.__getFullPath(item.text(0)))
639 if isDir
640 else self.__fsInterface.remove(self.__getFullPath(item.text(0)))
641 )
642 if ok:
643 # refresh
644 self.__reload()
645 else:
646 EricMessageBox.critical(
647 self,
648 title,
649 self.tr(
650 "<p>The deletion operation failed.</p>"
651 "<p>Reason: {0}</p>"
652 ).format(error if error else self.tr("Unknown")),
653 )
654
655 @pyqtSlot(bool)
656 def __showHiddenToggled(self, on):
657 """
658 Private slot to handle toggling the display of hidden files/directories.
659
660 @param on flag indicating to show hidden files and directories
661 @type bool
662 """
663 self.__showHidden = on
664 filters = self.__filters[self.filterCombo.currentIndex()]
665 self.__filterList(filters)
666
667 def selectedFiles(self):
668 """
669 Public method to get the selected files or the current viewport path.
670
671 @return selected files or current viewport path
672 @rtype str
673 """
674 return [self.__getFullPath(n) for n in self.__getNames()]
675
676 def selectedNameFilter(self):
677 """
678 Public method to get the selected name filter.
679
680 @return selected name filter
681 @rtype str
682 """
683 return self.filterCombo.currentText()
684
685 def __isHidden(self, name):
686 """
687 Private method to check, if the given name is indicating a hidden file or
688 directory.
689
690 @param name name of the file or directory
691 @type str
692 @return flag indicating a hidden file or directory
693 @rtype bool
694 """
695 return name.startswith(".") or name.endswith("~")
696
697 def __filterList(self, filters):
698 """
699 Private method to filter the files and directories list based on the given
700 filters and whether hidden files/directories should be shown.
701
702 @param filters list of filter patterns (only applied to files
703 @type list of str
704 """
705 self.listing.clearSelection()
706 for row in range(self.listing.topLevelItemCount()):
707 itm = self.listing.topLevelItem(row)
708 name = itm.text(0)
709 if (
710 self.__dirsOnly
711 and not itm.data(0, EricServerFileDialog.IsDirectoryRole)
712 ):
713 itm.setHidden(True)
714 elif not self.__showHidden and self.__isHidden(name):
715 # applies to files and directories
716 itm.setHidden(True)
717 elif not itm.data(0, EricServerFileDialog.IsDirectoryRole):
718 # it is a file item, apply the filter
719 itm.setHidden(not any(fnmatch.fnmatch(name, pat) for pat in filters))
720 else:
721 itm.setHidden(False)
722
723 # resize the columns
724 for column in range(4):
725 self.listing.resizeColumnToContents(column)
726
727 ###########################################################################
728 ## Module functions mimicing the interface of EricFileDialog/QFileDialog
729 ###########################################################################
730
731
732 def getOpenFileName(
733 parent=None, caption="", directory="", filterStr="", initialFilter="",
734 withRemote=True
735 ):
736 """
737 Module function to get the name of a file for opening it.
738
739 @param parent parent widget of the dialog (defaults to None)
740 @type QWidget (optional)
741 @param caption window title of the dialog (defaults to "")
742 @type str (optional)
743 @param directory working directory of the dialog (defaults to "")
744 @type str (optional)
745 @param filterStr filter string for the dialog (defaults to "")
746 @type str (optional)
747 @param initialFilter initial filter for the dialog (defaults to "")
748 @type str (optional)
749 @param withRemote flag indicating to create the file names with the remote
750 indicator (defaults to True)
751 @type bool (optional)
752 @return name of file to be opened
753 @rtype str
754 """
755 return getOpenFileNameAndFilter(
756 parent, caption, directory, filterStr, initialFilter, withRemote
757 )[0]
758
759
760 def getOpenFileNameAndFilter(
761 parent=None, caption="", directory="", filterStr="", initialFilter="",
762 withRemote=True
763 ):
764 """
765 Module function to get the name of a file for opening it and the selected
766 file name filter.
767
768 @param parent parent widget of the dialog (defaults to None)
769 @type QWidget (optional)
770 @param caption window title of the dialog (defaults to "")
771 @type str (optional)
772 @param directory working directory of the dialog (defaults to "")
773 @type str (optional)
774 @param filterStr filter string for the dialog (defaults to "")
775 @type str (optional)
776 @param initialFilter initial filter for the dialog (defaults to "")
777 @type str (optional)
778 @param withRemote flag indicating to create the file names with the remote
779 indicator (defaults to True)
780 @type bool (optional)
781 @return tuple containing the list of file names to be opened and the
782 selected file name filter
783 @rtype tuple of (list of str, str)
784 """
785 dlg = EricServerFileDialog(
786 parent=parent, caption=caption, directory=directory, filter=filterStr
787 )
788 dlg.setFileMode(FileMode.ExistingFile)
789 dlg.setNameFilter(initialFilter)
790 if dlg.exec() == QDialog.DialogCode.Accepted:
791 if withRemote:
792 fileName = FileSystemUtilities.remoteFileName(dlg.selectedFiles()[0])
793 else:
794 fileName = dlg.selectedFiles()[0]
795 selectedFilter = dlg.selectedNameFilter()
796 else:
797 fileName = ""
798 selectedFilter = ""
799
800 return fileName, selectedFilter
801
802
803 def getOpenFileNames(
804 parent=None, caption="", directory="", filterStr="", initialFilter="",
805 withRemote=True
806 ):
807 """
808 Module function to get a list of names of files for opening.
809
810 @param parent parent widget of the dialog (defaults to None)
811 @type QWidget (optional)
812 @param caption window title of the dialog (defaults to "")
813 @type str (optional)
814 @param directory working directory of the dialog (defaults to "")
815 @type str (optional)
816 @param filterStr filter string for the dialog (defaults to "")
817 @type str (optional)
818 @param initialFilter initial filter for the dialog (defaults to "")
819 @type str (optional)
820 @param withRemote flag indicating to create the file names with the remote
821 indicator (defaults to True)
822 @type bool (optional)
823 @return list of file names to be opened
824 @rtype list of str
825 """
826 return getOpenFileNamesAndFilter(
827 parent, caption, directory, filterStr, initialFilter, withRemote
828 )[0]
829
830
831 def getOpenFileNamesAndFilter(
832 parent=None, caption="", directory="", filterStr="", initialFilter="",
833 withRemote=True
834 ):
835 """
836 Module function to get a list of names of files for opening and the
837 selected file name filter.
838
839 @param parent parent widget of the dialog (defaults to None)
840 @type QWidget (optional)
841 @param caption window title of the dialog (defaults to "")
842 @type str (optional)
843 @param directory working directory of the dialog (defaults to "")
844 @type str (optional)
845 @param filterStr filter string for the dialog (defaults to "")
846 @type str (optional)
847 @param initialFilter initial filter for the dialog (defaults to "")
848 @type str (optional)
849 @param withRemote flag indicating to create the file names with the remote
850 indicator (defaults to True)
851 @type bool (optional)
852 @return tuple containing the list of file names to be opened and the
853 selected file name filter
854 @rtype tuple of (list of str, str)
855 """
856 dlg = EricServerFileDialog(
857 parent=parent, caption=caption, directory=directory, filter=filterStr
858 )
859 dlg.setFileMode(FileMode.ExistingFiles)
860 dlg.setNameFilter(initialFilter)
861 if dlg.exec() == QDialog.DialogCode.Accepted:
862 if withRemote:
863 filesList = [
864 FileSystemUtilities.remoteFileName(f) for f in dlg.selectedFiles()
865 ]
866 else:
867 filesList = dlg.selectedFiles()
868 selectedFilter = dlg.selectedNameFilter()
869 else:
870 filesList = []
871 selectedFilter = ""
872
873 return filesList, selectedFilter
874
875
876 def getSaveFileName(
877 parent=None, caption="", directory="", filterStr="", initialFilter="",
878 withRemote=True
879 ):
880 """
881 Module function to get the name of a file for saving.
882
883 @param parent parent widget of the dialog (defaults to None)
884 @type QWidget (optional)
885 @param caption window title of the dialog (defaults to "")
886 @type str (optional)
887 @param directory working directory of the dialog (defaults to "")
888 @type str (optional)
889 @param filterStr filter string for the dialog (defaults to "")
890 @type str (optional)
891 @param initialFilter initial filter for the dialog (defaults to "")
892 @type str (optional)
893 @param withRemote flag indicating to create the file names with the remote
894 indicator (defaults to True)
895 @type bool (optional)
896 @return name of file to be saved
897 @rtype str
898 """
899 return getSaveFileNameAndFilter(
900 parent, caption, directory, filterStr, initialFilter, withRemote
901 )[0]
902
903
904 def getSaveFileNameAndFilter(
905 parent=None, caption="", directory="", filterStr="", initialFilter="",
906 withRemote=True
907 ):
908 """
909 Module function to get the name of a file for saving and the selected file name
910 filter.
911
912 @param parent parent widget of the dialog (defaults to None)
913 @type QWidget (optional)
914 @param caption window title of the dialog (defaults to "")
915 @type str (optional)
916 @param directory working directory of the dialog (defaults to "")
917 @type str (optional)
918 @param filterStr filter string for the dialog (defaults to "")
919 @type str (optional)
920 @param initialFilter initial filter for the dialog (defaults to "")
921 @type str (optional)
922 @param withRemote flag indicating to create the file names with the remote
923 indicator (defaults to True)
924 @type bool (optional)
925 @return name of file to be saved and selected filte
926 @rtype tuple of (str, str)
927 """
928 dlg = EricServerFileDialog(
929 parent=parent, caption=caption, directory=directory, filter=filterStr
930 )
931 dlg.setFileMode(FileMode.AnyFile)
932 dlg.setNameFilter(initialFilter)
933 if dlg.exec() == QDialog.DialogCode.Accepted:
934 if withRemote:
935 fileName = FileSystemUtilities.remoteFileName(dlg.selectedFiles()[0])
936 else:
937 fileName = dlg.selectedFiles()[0]
938 selectedFilter = dlg.selectedNameFilter()
939 else:
940 fileName = ""
941 selectedFilter = ""
942
943 return fileName, selectedFilter
944
945
946 def getExistingDirectory(
947 parent=None, caption="", directory="", dirsOnly=True, withRemote=True
948 ):
949 """
950 Module function to get the name of a directory.
951
952 @param parent parent widget of the dialog (defaults to None)
953 @type QWidget (optional)
954 @param caption window title of the dialog (defaults to "")
955 @type str (optional)
956 @param directory working directory of the dialog (defaults to "")
957 @type str (optional)
958 @param dirsOnly flag indicating to just show directories (defaults to True)
959 @type bool (optional)
960 @param withRemote flag indicating to create the file names with the remote
961 indicator (defaults to True)
962 @type bool (optional)
963 @return name of selected directory
964 @rtype str
965 """
966 dlg = EricServerFileDialog(parent=parent, caption=caption, directory=directory)
967 dlg.setFileMode(FileMode.Directory)
968 dlg.setDirectoriesOnly(dirsOnly)
969 if dlg.exec() == QDialog.DialogCode.Accepted:
970 if withRemote:
971 dirName = FileSystemUtilities.remoteFileName(dlg.selectedFiles()[0])
972 else:
973 dirName = dlg.selectedFiles()[0]
974 else:
975 dirName = ""
976
977 return dirName

eric ide

mercurial