13 import re |
13 import re |
14 |
14 |
15 from PyQt6.Qsci import QsciScintilla |
15 from PyQt6.Qsci import QsciScintilla |
16 from PyQt6.QtCore import ( |
16 from PyQt6.QtCore import ( |
17 QCoreApplication, |
17 QCoreApplication, |
18 QFileSystemWatcher, |
|
19 QPoint, |
18 QPoint, |
20 QSignalMapper, |
19 QSignalMapper, |
21 Qt, |
20 Qt, |
22 pyqtSignal, |
21 pyqtSignal, |
23 pyqtSlot, |
22 pyqtSlot, |
24 ) |
23 ) |
25 from PyQt6.QtGui import QKeySequence, QPixmap |
24 from PyQt6.QtGui import QKeySequence, QPixmap |
26 from PyQt6.QtWidgets import QApplication, QDialog, QMenu, QToolBar, QWidget |
25 from PyQt6.QtWidgets import QApplication, QDialog, QMenu, QToolBar, QWidget |
27 |
26 |
28 from eric7 import Preferences |
27 from eric7 import Preferences |
|
28 from eric7.EricCore import EricFileSystemWatcher |
29 from eric7.EricGui import EricPixmapCache |
29 from eric7.EricGui import EricPixmapCache |
30 from eric7.EricGui.EricAction import EricAction, createActionGroup |
30 from eric7.EricGui.EricAction import EricAction, createActionGroup |
31 from eric7.EricWidgets import EricFileDialog, EricMessageBox |
31 from eric7.EricWidgets import EricFileDialog, EricMessageBox |
32 from eric7.EricWidgets.EricApplication import ericApp |
32 from eric7.EricWidgets.EricApplication import ericApp |
33 from eric7.Globals import recentNameFiles |
33 from eric7.Globals import recentNameFiles |
144 self.__cooperationClient = None |
144 self.__cooperationClient = None |
145 |
145 |
146 self.__lastFocusWidget = None |
146 self.__lastFocusWidget = None |
147 |
147 |
148 # initialize the file system watcher |
148 # initialize the file system watcher |
149 self.__watcher = QFileSystemWatcher(self) |
149 watcher = EricFileSystemWatcher.instance() |
150 self.__watcher.fileChanged.connect(self.__watchedFileChanged) |
150 watcher.fileModified.connect(self.__watchedFileChanged) |
|
151 |
|
152 self.__watchedFilePaths = [] |
151 |
153 |
152 def setReferences(self, ui, dbs, remoteServerInterface): |
154 def setReferences(self, ui, dbs, remoteServerInterface): |
153 """ |
155 """ |
154 Public method to set some references needed later on. |
156 Public method to set some references needed later on. |
155 |
157 |
678 ) |
680 ) |
679 self.openRemoteAct.triggered.connect(self.__openRemoteFiles) |
681 self.openRemoteAct.triggered.connect(self.__openRemoteFiles) |
680 self.openRemoteAct.setEnabled(False) |
682 self.openRemoteAct.setEnabled(False) |
681 self.fileActions.append(self.openRemoteAct) |
683 self.fileActions.append(self.openRemoteAct) |
682 |
684 |
|
685 self.reloadAct = EricAction( |
|
686 QCoreApplication.translate("ViewManager", "Reload"), |
|
687 EricPixmapCache.getIcon("reload"), |
|
688 QCoreApplication.translate("ViewManager", "Reload"), |
|
689 0, |
|
690 0, |
|
691 self, |
|
692 "vm_file_reload", |
|
693 ) |
|
694 self.reloadAct.setStatusTip( |
|
695 QCoreApplication.translate("ViewManager", "Reload the current file") |
|
696 ) |
|
697 self.reloadAct.setWhatsThis( |
|
698 QCoreApplication.translate( |
|
699 "ViewManager", |
|
700 """<b>Reload</b>""" |
|
701 """<p>Reload the contents of current editor window. If the editor""" |
|
702 """ contents was modified, a warning will be issued.</p>""", |
|
703 ) |
|
704 ) |
|
705 self.reloadAct.triggered.connect(self.__reloadCurrentEditor) |
|
706 self.fileActions.append(self.reloadAct) |
|
707 |
683 self.closeActGrp = createActionGroup(self) |
708 self.closeActGrp = createActionGroup(self) |
684 |
709 |
685 self.closeAct = EricAction( |
710 self.closeAct = EricAction( |
686 QCoreApplication.translate("ViewManager", "Close"), |
711 QCoreApplication.translate("ViewManager", "Close"), |
687 EricPixmapCache.getIcon("closeEditor"), |
712 EricPixmapCache.getIcon("closeEditor"), |
952 menu.setTearOffEnabled(True) |
977 menu.setTearOffEnabled(True) |
953 |
978 |
954 menu.addAction(self.newAct) |
979 menu.addAction(self.newAct) |
955 menu.addAction(self.openAct) |
980 menu.addAction(self.openAct) |
956 menu.addAction(self.openRemoteAct) |
981 menu.addAction(self.openRemoteAct) |
|
982 menu.addAction(self.reloadAct) |
957 self.menuRecentAct = menu.addMenu(self.recentMenu) |
983 self.menuRecentAct = menu.addMenu(self.recentMenu) |
958 menu.addMenu(self.bookmarkedMenu) |
984 menu.addMenu(self.bookmarkedMenu) |
959 menu.addSeparator() |
985 menu.addSeparator() |
960 menu.addAction(self.closeAct) |
986 menu.addAction(self.closeAct) |
961 menu.addAction(self.closeAllAct) |
987 menu.addAction(self.closeAllAct) |
996 tb.setToolTip(QCoreApplication.translate("ViewManager", "File")) |
1022 tb.setToolTip(QCoreApplication.translate("ViewManager", "File")) |
997 |
1023 |
998 tb.addAction(self.newAct) |
1024 tb.addAction(self.newAct) |
999 tb.addAction(self.openAct) |
1025 tb.addAction(self.openAct) |
1000 tb.addAction(self.openRemoteAct) |
1026 tb.addAction(self.openRemoteAct) |
|
1027 tb.addAction(self.reloadAct) |
1001 tb.addAction(self.closeAct) |
1028 tb.addAction(self.closeAct) |
1002 tb.addSeparator() |
1029 tb.addSeparator() |
1003 tb.addAction(self.saveAct) |
1030 tb.addAction(self.saveAct) |
1004 tb.addAction(self.saveAsAct) |
1031 tb.addAction(self.saveAsAct) |
1005 tb.addAction(self.saveAsRemoteAct) |
1032 tb.addAction(self.saveAsRemoteAct) |
5505 if FileSystemUtilities.isPlainFileName(prog): |
5532 if FileSystemUtilities.isPlainFileName(prog): |
5506 prog = os.path.abspath(prog) |
5533 prog = os.path.abspath(prog) |
5507 # Open up the new files. |
5534 # Open up the new files. |
5508 self.openSourceFile(prog) |
5535 self.openSourceFile(prog) |
5509 |
5536 |
|
5537 @pyqtSlot() |
|
5538 def __reloadCurrentEditor(self): |
|
5539 """ |
|
5540 Private slot to reload the contents of the current editor. |
|
5541 """ |
|
5542 aw = self.activeWindow() |
|
5543 if aw: |
|
5544 aw.reload() |
|
5545 |
5510 def checkDirty(self, editor, autosave=False, closeIt=False): |
5546 def checkDirty(self, editor, autosave=False, closeIt=False): |
5511 """ |
5547 """ |
5512 Public method to check the dirty status and open a message window. |
5548 Public method to check the dirty status and open a message window. |
5513 |
5549 |
5514 @param editor editor window to check |
5550 @param editor editor window to check |
5770 @param pos position within the line to place the cursor at |
5806 @param pos position within the line to place the cursor at |
5771 @type int |
5807 @type int |
5772 @param addNext flag indicating to add the file next to the current |
5808 @param addNext flag indicating to add the file next to the current |
5773 editor |
5809 editor |
5774 @type bool |
5810 @type bool |
5775 @param indexes of the editor, first the split view index, second the |
5811 @param indexes indexes of the editor, first the split view index, second the |
5776 index within the view |
5812 index within the view |
5777 @type tuple of two int |
5813 @type tuple of two int |
5778 @return reference to the opened editor |
5814 @return reference to the opened editor |
5779 @rtype Editor |
5815 @rtype Editor |
5780 """ |
5816 """ |
5815 # insert filename into list of recently opened files |
5851 # insert filename into list of recently opened files |
5816 self.addToRecentList(fn) |
5852 self.addToRecentList(fn) |
5817 |
5853 |
5818 return editor |
5854 return editor |
5819 |
5855 |
|
5856 @pyqtSlot(str, int, int) |
|
5857 def openSourceFileLinePos(self, fn, lineno, pos): |
|
5858 """ |
|
5859 Public slot to display a file in an editor at a given line and position. |
|
5860 |
|
5861 @param fn name of file to be opened |
|
5862 @type str |
|
5863 @param lineno line number to place the cursor at |
|
5864 @type int |
|
5865 @param pos position within line to position cursor at |
|
5866 @type int |
|
5867 """ |
|
5868 self.openSourceFile(fn, lineno=lineno, pos=pos + 1) |
|
5869 |
5820 def __connectEditor(self, editor): |
5870 def __connectEditor(self, editor): |
5821 """ |
5871 """ |
5822 Private method to establish all editor connections. |
5872 Private method to establish all editor connections. |
5823 |
5873 |
5824 @param editor reference to the editor object to be connected |
5874 @param editor reference to the editor object to be connected |
5847 editor.selectionChanged.connect( |
5897 editor.selectionChanged.connect( |
5848 lambda: self.__searchReplaceWidget.selectionChanged(editor) |
5898 lambda: self.__searchReplaceWidget.selectionChanged(editor) |
5849 ) |
5899 ) |
5850 editor.selectionChanged.connect(lambda: self.__editorSelectionChanged(editor)) |
5900 editor.selectionChanged.connect(lambda: self.__editorSelectionChanged(editor)) |
5851 editor.lastEditPositionAvailable.connect(self.__lastEditPositionAvailable) |
5901 editor.lastEditPositionAvailable.connect(self.__lastEditPositionAvailable) |
5852 editor.zoomValueChanged.connect(lambda v: self.zoomValueChanged(v, editor)) |
|
5853 editor.mouseDoubleClick.connect( |
5902 editor.mouseDoubleClick.connect( |
5854 lambda pos, buttons: self.__editorDoubleClicked(editor, pos, buttons) |
5903 lambda pos, buttons: self.__editorDoubleClicked(editor, pos, buttons) |
5855 ) |
5904 ) |
5856 |
5905 |
5857 editor.languageChanged.connect(lambda: self.editorLanguageChanged.emit(editor)) |
5906 editor.languageChanged.connect(lambda: self.editorLanguageChanged.emit(editor)) |
6693 self.copyActGrp.setEnabled(False) |
6742 self.copyActGrp.setEnabled(False) |
6694 self.viewActGrp.setEnabled(False) |
6743 self.viewActGrp.setEnabled(False) |
6695 self.sbZoom.setEnabled(False) |
6744 self.sbZoom.setEnabled(False) |
6696 else: |
6745 else: |
6697 self.sbZoom.setEnabled(True) |
6746 self.sbZoom.setEnabled(True) |
6698 self.sbZoom.setValue(now.getZoom()) |
6747 if isinstance(now, Shell): |
|
6748 self.sbZoom.setValue(now.getZoom()) |
6699 |
6749 |
6700 if not isinstance(now, (Editor, Shell)): |
6750 if not isinstance(now, (Editor, Shell)): |
6701 self.searchActGrp.setEnabled(False) |
6751 self.searchActGrp.setEnabled(False) |
6702 |
6752 |
6703 if not isinstance(now, (Editor, Shell)): |
6753 if not isinstance(now, (Editor, Shell)): |
7125 @param value new zoom value |
7175 @param value new zoom value |
7126 @type int |
7176 @type int |
7127 @param zoomingWidget reference to the widget triggering the slot |
7177 @param zoomingWidget reference to the widget triggering the slot |
7128 @type Editor or Shell |
7178 @type Editor or Shell |
7129 """ |
7179 """ |
7130 aw = ( |
7180 if QApplication.focusWidget() == ericApp().getObject("Shell"): # noqa: Y108 |
7131 ericApp().getObject("Shell") |
7181 aw = ericApp().getObject("Shell") |
7132 if QApplication.focusWidget() == ericApp().getObject("Shell") |
7182 else: |
7133 else self.activeWindow() |
7183 aw = ( |
7134 ) |
7184 self.activeWindow() |
|
7185 if self.activeWindow() == QApplication.focusWidget() |
|
7186 else QApplication.focusWidget() |
|
7187 ) |
7135 if aw and aw == zoomingWidget: |
7188 if aw and aw == zoomingWidget: |
7136 self.sbZoom.setValue(value) |
7189 self.sbZoom.setValue(value) |
7137 |
7190 |
7138 def __clearAllFolds(self): |
7191 def __clearAllFolds(self): |
7139 """ |
7192 """ |
7703 |
7756 |
7704 def __lastEditorClosed(self): |
7757 def __lastEditorClosed(self): |
7705 """ |
7758 """ |
7706 Private slot to handle the lastEditorClosed signal. |
7759 Private slot to handle the lastEditorClosed signal. |
7707 """ |
7760 """ |
|
7761 self.reloadAct.setEnabled(False) |
7708 self.closeActGrp.setEnabled(False) |
7762 self.closeActGrp.setEnabled(False) |
7709 self.saveActGrp.setEnabled(False) |
7763 self.saveActGrp.setEnabled(False) |
7710 self.exportersMenuAct.setEnabled(False) |
7764 self.exportersMenuAct.setEnabled(False) |
7711 self.printAct.setEnabled(False) |
7765 self.printAct.setEnabled(False) |
7712 if self.printPreviewAct: |
7766 if self.printPreviewAct: |
7780 @type Editor |
7834 @type Editor |
7781 @param setSb flag indicating an update of the status bar is wanted |
7835 @param setSb flag indicating an update of the status bar is wanted |
7782 @type bool |
7836 @type bool |
7783 """ |
7837 """ |
7784 if editor is not None: |
7838 if editor is not None: |
|
7839 self.reloadAct.setEnabled(bool(editor.getFileName())) |
7785 self.saveAct.setEnabled(editor.isModified()) |
7840 self.saveAct.setEnabled(editor.isModified()) |
7786 self.revertAct.setEnabled(editor.isModified()) |
7841 self.revertAct.setEnabled(editor.isModified()) |
7787 |
7842 |
7788 self.undoAct.setEnabled(editor.isUndoAvailable()) |
7843 self.undoAct.setEnabled(editor.isUndoAvailable()) |
7789 self.redoAct.setEnabled(editor.isRedoAvailable()) |
7844 self.redoAct.setEnabled(editor.isRedoAvailable()) |
8150 Public method to add a file to the list of monitored files. |
8205 Public method to add a file to the list of monitored files. |
8151 |
8206 |
8152 @param filePath path of the file to be added |
8207 @param filePath path of the file to be added |
8153 @type str |
8208 @type str |
8154 """ |
8209 """ |
8155 if filePath and FileSystemUtilities.isPlainFileName(filePath): |
8210 if ( |
8156 self.__watcher.addPath(filePath) |
8211 filePath |
|
8212 and FileSystemUtilities.isPlainFileName(filePath) |
|
8213 and filePath not in self.__watchedFilePaths |
|
8214 ): |
|
8215 watcher = EricFileSystemWatcher.instance() |
|
8216 watcher.addPath(filePath) |
|
8217 self.__watchedFilePaths.append(filePath) |
8157 |
8218 |
8158 def removeWatchedFilePath(self, filePath): |
8219 def removeWatchedFilePath(self, filePath): |
8159 """ |
8220 """ |
8160 Public method to remove a file from the list of monitored files. |
8221 Public method to remove a file from the list of monitored files. |
8161 |
8222 |
8162 @param filePath path of the file to be removed |
8223 @param filePath path of the file to be removed |
8163 @type str |
8224 @type str |
8164 """ |
8225 """ |
8165 if self.getOpenEditorCount( |
8226 if ( |
8166 filePath |
8227 filePath |
8167 ) == 0 and FileSystemUtilities.isPlainFileName(filePath): |
8228 and self.getOpenEditorCount(filePath) == 0 |
8168 self.__watcher.removePath(filePath) |
8229 and FileSystemUtilities.isPlainFileName(filePath) |
|
8230 and filePath in self.__watchedFilePaths |
|
8231 ): |
|
8232 watcher = EricFileSystemWatcher.instance() |
|
8233 watcher.removePath(filePath) |
|
8234 self.__watchedFilePaths.remove(filePath) |
8169 |
8235 |
8170 ################################################################## |
8236 ################################################################## |
8171 ## Below are protected utility methods |
8237 ## Below are protected utility methods |
8172 ################################################################## |
8238 ################################################################## |
8173 |
8239 |