2 |
2 |
3 # Copyright (c) 2002 - 2020 Detlev Offenbach <detlev@die-offenbachs.de> |
3 # Copyright (c) 2002 - 2020 Detlev Offenbach <detlev@die-offenbachs.de> |
4 # |
4 # |
5 |
5 |
6 """ |
6 """ |
7 Module implementing the viewmanager base class. |
7 Module implementing the view manager base class. |
8 """ |
8 """ |
9 |
9 |
10 |
10 import re |
11 import os |
11 import os |
12 |
12 |
13 from PyQt5.QtCore import ( |
13 from PyQt5.QtCore import ( |
14 pyqtSignal, pyqtSlot, QSignalMapper, QTimer, QFileInfo, QRegExp, Qt, |
14 pyqtSignal, pyqtSlot, Qt, QSignalMapper, QTimer, QFileInfo, QPoint, |
15 QCoreApplication, QPoint |
15 QCoreApplication |
16 ) |
16 ) |
17 from PyQt5.QtGui import QColor, QKeySequence, QPalette, QPixmap |
17 from PyQt5.QtGui import QColor, QKeySequence, QPalette, QPixmap |
18 from PyQt5.QtWidgets import ( |
18 from PyQt5.QtWidgets import ( |
19 QLineEdit, QToolBar, QWidgetAction, QDialog, QApplication, QMenu, |
19 QLineEdit, QToolBar, QWidgetAction, QDialog, QApplication, QMenu, |
20 QComboBox, QWidget |
20 QComboBox, QWidget |
88 super(QuickSearchLineEdit, self).focusInEvent(evt) # pass it on |
87 super(QuickSearchLineEdit, self).focusInEvent(evt) # pass it on |
89 |
88 |
90 |
89 |
91 class ViewManager(QWidget): |
90 class ViewManager(QWidget): |
92 """ |
91 """ |
93 Base class inherited by all specific viewmanager classes. |
92 Base class inherited by all specific view manager classes. |
94 |
93 |
95 It defines the interface to be implemented by specific |
94 It defines the interface to be implemented by specific |
96 viewmanager classes and all common methods. |
95 view manager classes and all common methods. |
97 |
96 |
98 @signal changeCaption(str) emitted if a change of the caption is necessary |
97 @signal changeCaption(str) emitted if a change of the caption is necessary |
99 @signal editorChanged(str) emitted when the current editor has changed |
98 @signal editorChanged(str) emitted when the current editor has changed |
100 @signal editorChangedEd(Editor) emitted when the current editor has changed |
99 @signal editorChangedEd(Editor) emitted when the current editor has changed |
101 @signal lastEditorClosed() emitted after the last editor window was closed |
100 @signal lastEditorClosed() emitted after the last editor window was closed |
331 """ |
330 """ |
332 aw = self.activeWindow() |
331 aw = self.activeWindow() |
333 if aw is not None: |
332 if aw is not None: |
334 menu = aw.getMenu("Encodings") |
333 menu = aw.getMenu("Encodings") |
335 if menu is not None: |
334 if menu is not None: |
336 menu.exec_(pos) |
335 menu.exec(pos) |
337 |
336 |
338 ########################################################################### |
337 ########################################################################### |
339 ## methods below need to be implemented by a subclass |
338 ## methods below need to be implemented by a subclass |
340 ########################################################################### |
339 ########################################################################### |
341 |
340 |
2144 0, self.editorActGrp, 'vm_edit_swap_current_previous_line') |
2143 0, self.editorActGrp, 'vm_edit_swap_current_previous_line') |
2145 self.esm.setMapping(act, QsciScintilla.SCI_LINETRANSPOSE) |
2144 self.esm.setMapping(act, QsciScintilla.SCI_LINETRANSPOSE) |
2146 act.triggered.connect(self.esm.map) |
2145 act.triggered.connect(self.esm.map) |
2147 self.editActions.append(act) |
2146 self.editActions.append(act) |
2148 |
2147 |
2149 if QSCINTILLA_VERSION() >= 0x020B00: |
2148 act = E5Action( |
2150 act = E5Action( |
2149 QCoreApplication.translate('ViewManager', |
2151 QCoreApplication.translate('ViewManager', |
2150 'Reverse selected lines'), |
2152 'Reverse selected lines'), |
2151 QCoreApplication.translate('ViewManager', |
2153 QCoreApplication.translate('ViewManager', |
2152 'Reverse selected lines'), |
2154 'Reverse selected lines'), |
2153 QKeySequence(QCoreApplication.translate('ViewManager', |
2155 QKeySequence(QCoreApplication.translate('ViewManager', |
2154 'Meta+Alt+R')), |
2156 'Meta+Alt+R')), |
2155 0, self.editorActGrp, 'vm_edit_reverse selected_lines') |
2157 0, self.editorActGrp, 'vm_edit_reverse selected_lines') |
2156 self.esm.setMapping(act, QsciScintilla.SCI_LINEREVERSE) |
2158 self.esm.setMapping(act, QsciScintilla.SCI_LINEREVERSE) |
2157 act.triggered.connect(self.esm.map) |
2159 act.triggered.connect(self.esm.map) |
2158 self.editActions.append(act) |
2160 self.editActions.append(act) |
|
2161 |
2159 |
2162 act = E5Action( |
2160 act = E5Action( |
2163 QCoreApplication.translate('ViewManager', 'Cut current line'), |
2161 QCoreApplication.translate('ViewManager', 'Cut current line'), |
2164 QCoreApplication.translate('ViewManager', 'Cut current line'), |
2162 QCoreApplication.translate('ViewManager', 'Cut current line'), |
2165 QKeySequence(QCoreApplication.translate('ViewManager', |
2163 QKeySequence(QCoreApplication.translate('ViewManager', |
5386 """ |
5384 """ |
5387 Private method to edit the list of bookmarked files. |
5385 Private method to edit the list of bookmarked files. |
5388 """ |
5386 """ |
5389 from .BookmarkedFilesDialog import BookmarkedFilesDialog |
5387 from .BookmarkedFilesDialog import BookmarkedFilesDialog |
5390 dlg = BookmarkedFilesDialog(self.bookmarked, self.ui) |
5388 dlg = BookmarkedFilesDialog(self.bookmarked, self.ui) |
5391 if dlg.exec_() == QDialog.Accepted: |
5389 if dlg.exec() == QDialog.Accepted: |
5392 self.bookmarked = dlg.getBookmarkedFiles() |
5390 self.bookmarked = dlg.getBookmarkedFiles() |
5393 |
5391 |
5394 def __clearBookmarked(self): |
5392 def __clearBookmarked(self): |
5395 """ |
5393 """ |
5396 Private method to clear the bookmarked files menu. |
5394 Private method to clear the bookmarked files menu. |
5925 return |
5923 return |
5926 |
5924 |
5927 line, index = aw.getCursorPosition() |
5925 line, index = aw.getCursorPosition() |
5928 text = aw.text(line) |
5926 text = aw.text(line) |
5929 |
5927 |
5930 reg = QRegExp(r'[^\w_]') |
5928 rx = re.compile(r'[^\w_]') |
5931 end = reg.indexIn(text, index) |
5929 match = rx.search(text, index) |
5932 if end > index: |
5930 if match: |
5933 ext = text[index:end] |
5931 end = match.start() |
5934 txt += ext |
5932 if end > index: |
5935 self.quickFindtextCombo.lineEdit().setText(txt) |
5933 ext = text[index:end] |
|
5934 txt += ext |
|
5935 self.quickFindtextCombo.lineEdit().setText(txt) |
5936 |
5936 |
5937 def showSearchWidget(self): |
5937 def showSearchWidget(self): |
5938 """ |
5938 """ |
5939 Public method to show the search widget. |
5939 Public method to show the search widget. |
5940 """ |
5940 """ |
5995 |
5995 |
5996 aw = self.activeWindow() |
5996 aw = self.activeWindow() |
5997 lines = aw.lines() |
5997 lines = aw.lines() |
5998 curLine = aw.getCursorPosition()[0] + 1 |
5998 curLine = aw.getCursorPosition()[0] + 1 |
5999 dlg = GotoDialog(lines, curLine, self.ui, None, True) |
5999 dlg = GotoDialog(lines, curLine, self.ui, None, True) |
6000 if dlg.exec_() == QDialog.Accepted: |
6000 if dlg.exec() == QDialog.Accepted: |
6001 aw.gotoLine(dlg.getLinenumber(), expand=True) |
6001 aw.gotoLine(dlg.getLinenumber(), expand=True) |
6002 |
6002 |
6003 def __gotoBrace(self): |
6003 def __gotoBrace(self): |
6004 """ |
6004 """ |
6005 Private method to handle the goto brace action. |
6005 Private method to handle the goto brace action. |
6081 else: |
6081 else: |
6082 aw = self.activeWindow() |
6082 aw = self.activeWindow() |
6083 if aw: |
6083 if aw: |
6084 aw.zoomOut() |
6084 aw.zoomOut() |
6085 self.sbZoom.setValue(aw.getZoom()) |
6085 self.sbZoom.setValue(aw.getZoom()) |
6086 |
6086 |
6087 def __zoomReset(self): |
6087 def __zoomReset(self): |
6088 """ |
6088 """ |
6089 Private method to reset the zoom factor. |
6089 Private method to reset the zoom factor. |
6090 """ |
6090 """ |
6091 if QApplication.focusWidget() == e5App().getObject("Shell"): |
6091 self.__zoomTo(0) |
6092 e5App().getObject("Shell").zoomTo(0) |
6092 |
6093 else: |
|
6094 aw = self.activeWindow() |
|
6095 if aw: |
|
6096 aw.zoomTo(0) |
|
6097 self.sbZoom.setValue(aw.getZoom()) |
|
6098 |
|
6099 def __zoom(self): |
6093 def __zoom(self): |
6100 """ |
6094 """ |
6101 Private method to handle the zoom action. |
6095 Private method to handle the zoom action. |
6102 """ |
6096 """ |
6103 if QApplication.focusWidget() == e5App().getObject("Shell"): |
6097 if QApplication.focusWidget() == e5App().getObject("Shell"): |
6105 else: |
6099 else: |
6106 aw = self.activeWindow() |
6100 aw = self.activeWindow() |
6107 if aw: |
6101 if aw: |
6108 from QScintilla.ZoomDialog import ZoomDialog |
6102 from QScintilla.ZoomDialog import ZoomDialog |
6109 dlg = ZoomDialog(aw.getZoom(), self.ui, None, True) |
6103 dlg = ZoomDialog(aw.getZoom(), self.ui, None, True) |
6110 if dlg.exec_() == QDialog.Accepted: |
6104 if dlg.exec() == QDialog.Accepted: |
6111 value = dlg.getZoomSize() |
6105 value = dlg.getZoomSize() |
6112 self.__zoomTo(value) |
6106 self.__zoomTo(value) |
6113 |
6107 |
6114 def __zoomTo(self, value): |
6108 def __zoomTo(self, value): |
6115 """ |
6109 """ |
6587 |
6581 |
6588 @param dictionaryFile file name of the dictionary to edit (string) |
6582 @param dictionaryFile file name of the dictionary to edit (string) |
6589 """ |
6583 """ |
6590 if os.path.exists(dictionaryFile): |
6584 if os.path.exists(dictionaryFile): |
6591 try: |
6585 try: |
6592 f = open(dictionaryFile, "r", encoding="utf-8") |
6586 with open(dictionaryFile, "r", encoding="utf-8") as f: |
6593 data = f.read() |
6587 data = f.read() |
6594 f.close() |
|
6595 except (IOError, OSError) as err: |
6588 except (IOError, OSError) as err: |
6596 E5MessageBox.critical( |
6589 E5MessageBox.critical( |
6597 self.ui, |
6590 self.ui, |
6598 QCoreApplication.translate( |
6591 QCoreApplication.translate( |
6599 'ViewManager', "Edit Spelling Dictionary"), |
6592 'ViewManager', "Edit Spelling Dictionary"), |
6614 dlg = SpellingDictionaryEditDialog( |
6607 dlg = SpellingDictionaryEditDialog( |
6615 data, |
6608 data, |
6616 QCoreApplication.translate('ViewManager', "Editing {0}") |
6609 QCoreApplication.translate('ViewManager', "Editing {0}") |
6617 .format(fileInfo), |
6610 .format(fileInfo), |
6618 self.ui) |
6611 self.ui) |
6619 if dlg.exec_() == QDialog.Accepted: |
6612 if dlg.exec() == QDialog.Accepted: |
6620 data = dlg.getData() |
6613 data = dlg.getData() |
6621 try: |
6614 try: |
6622 f = open(dictionaryFile, "w", encoding="utf-8") |
6615 with open(dictionaryFile, "w", encoding="utf-8") as f: |
6623 f.write(data) |
6616 f.write(data) |
6624 f.close() |
|
6625 except (IOError, OSError) as err: |
6617 except (IOError, OSError) as err: |
6626 E5MessageBox.critical( |
6618 E5MessageBox.critical( |
6627 self.ui, |
6619 self.ui, |
6628 QCoreApplication.translate( |
6620 QCoreApplication.translate( |
6629 'ViewManager', "Edit Spelling Dictionary"), |
6621 'ViewManager', "Edit Spelling Dictionary"), |
7193 if ( |
7185 if ( |
7194 self.activeWindow() is not None and |
7186 self.activeWindow() is not None and |
7195 self.activeWindow().getFileName() |
7187 self.activeWindow().getFileName() |
7196 ): |
7188 ): |
7197 ext = os.path.splitext(self.activeWindow().getFileName())[1] |
7189 ext = os.path.splitext(self.activeWindow().getFileName())[1] |
7198 rx = QRegExp(r".*\*\.{0}[ )].*".format(ext[1:])) |
7190 rx = re.compile(r".*\*\.{0}[ )].*".format(ext[1:])) |
7199 import QScintilla.Lexers |
7191 import QScintilla.Lexers |
7200 filters = QScintilla.Lexers.getOpenFileFiltersList() |
7192 filters = QScintilla.Lexers.getOpenFileFiltersList() |
7201 index = -1 |
7193 index = -1 |
7202 for i in range(len(filters)): |
7194 for i in range(len(filters)): |
7203 if rx.exactMatch(filters[i]): |
7195 if rx.fullmatch(filters[i]): |
7204 index = i |
7196 index = i |
7205 break |
7197 break |
7206 if index == -1: |
7198 if index == -1: |
7207 return Preferences.getEditor("DefaultOpenFilter") |
7199 return Preferences.getEditor("DefaultOpenFilter") |
7208 else: |
7200 else: |