src/eric7/HexEdit/HexEditMainWindow.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
9 9
10 import os 10 import os
11 import contextlib 11 import contextlib
12 import pathlib 12 import pathlib
13 13
14 from PyQt6.QtCore import ( 14 from PyQt6.QtCore import pyqtSignal, pyqtSlot, QSize, QCoreApplication, QLocale
15 pyqtSignal, pyqtSlot, QSize, QCoreApplication, QLocale
16 )
17 from PyQt6.QtGui import QKeySequence, QAction 15 from PyQt6.QtGui import QKeySequence, QAction
18 from PyQt6.QtWidgets import ( 16 from PyQt6.QtWidgets import (
19 QWhatsThis, QLabel, QWidget, QVBoxLayout, QDialog, QFrame, QMenu 17 QWhatsThis,
18 QLabel,
19 QWidget,
20 QVBoxLayout,
21 QDialog,
22 QFrame,
23 QMenu,
20 ) 24 )
21 25
22 from EricGui.EricAction import EricAction 26 from EricGui.EricAction import EricAction
23 from EricWidgets.EricMainWindow import EricMainWindow 27 from EricWidgets.EricMainWindow import EricMainWindow
24 from EricWidgets import EricFileDialog, EricMessageBox 28 from EricWidgets import EricFileDialog, EricMessageBox
38 42
39 43
40 class HexEditMainWindow(EricMainWindow): 44 class HexEditMainWindow(EricMainWindow):
41 """ 45 """
42 Class implementing the web browser main window. 46 Class implementing the web browser main window.
43 47
44 @signal editorClosed() emitted after the window was requested to close down 48 @signal editorClosed() emitted after the window was requested to close down
45 """ 49 """
50
46 editorClosed = pyqtSignal() 51 editorClosed = pyqtSignal()
47 52
48 windows = [] 53 windows = []
49 54
50 maxMenuFilePathLen = 75 55 maxMenuFilePathLen = 75
51 56
52 def __init__(self, fileName="", parent=None, fromEric=False, project=None): 57 def __init__(self, fileName="", parent=None, fromEric=False, project=None):
53 """ 58 """
54 Constructor 59 Constructor
55 60
56 @param fileName name of a file to load on startup (string) 61 @param fileName name of a file to load on startup (string)
57 @param parent parent widget of this window (QWidget) 62 @param parent parent widget of this window (QWidget)
58 @param fromEric flag indicating whether it was called from within 63 @param fromEric flag indicating whether it was called from within
59 eric (boolean) 64 eric (boolean)
60 @param project reference to the project object (Project) 65 @param project reference to the project object (Project)
61 """ 66 """
62 super().__init__(parent) 67 super().__init__(parent)
63 self.setObjectName("eric7_hex_editor") 68 self.setObjectName("eric7_hex_editor")
64 69
65 self.__srHistory = { 70 self.__srHistory = {
66 "search": [], 71 "search": [],
67 # list of recent searches (tuple of format type index and 72 # list of recent searches (tuple of format type index and
68 # search term) 73 # search term)
69 "replace": [], 74 "replace": [],
70 # list of recent replaces (tuple of format type index and 75 # list of recent replaces (tuple of format type index and
71 # replace term 76 # replace term
72 } 77 }
73 78
74 self.__fromEric = fromEric 79 self.__fromEric = fromEric
75 self.setWindowIcon(UI.PixmapCache.getIcon("hexEditor")) 80 self.setWindowIcon(UI.PixmapCache.getIcon("hexEditor"))
76 81
77 if not self.__fromEric: 82 if not self.__fromEric:
78 self.setStyle(Preferences.getUI("Style"), 83 self.setStyle(Preferences.getUI("Style"), Preferences.getUI("StyleSheet"))
79 Preferences.getUI("StyleSheet")) 84
80
81 self.__editor = HexEditWidget() 85 self.__editor = HexEditWidget()
82 self.__searchWidget = HexEditSearchReplaceWidget( 86 self.__searchWidget = HexEditSearchReplaceWidget(self.__editor, self, False)
83 self.__editor, self, False) 87 self.__replaceWidget = HexEditSearchReplaceWidget(self.__editor, self, True)
84 self.__replaceWidget = HexEditSearchReplaceWidget(
85 self.__editor, self, True)
86 self.__gotoWidget = HexEditGotoWidget(self.__editor) 88 self.__gotoWidget = HexEditGotoWidget(self.__editor)
87 cw = QWidget() 89 cw = QWidget()
88 layout = QVBoxLayout(cw) 90 layout = QVBoxLayout(cw)
89 layout.setContentsMargins(1, 1, 1, 1) 91 layout.setContentsMargins(1, 1, 1, 1)
90 layout.setSpacing(1) 92 layout.setSpacing(1)
95 layout.addWidget(self.__replaceWidget) 97 layout.addWidget(self.__replaceWidget)
96 self.__searchWidget.hide() 98 self.__searchWidget.hide()
97 self.__replaceWidget.hide() 99 self.__replaceWidget.hide()
98 self.__gotoWidget.hide() 100 self.__gotoWidget.hide()
99 self.setCentralWidget(cw) 101 self.setCentralWidget(cw)
100 102
101 g = Preferences.getGeometry("HexEditorGeometry") 103 g = Preferences.getGeometry("HexEditorGeometry")
102 if g.isEmpty(): 104 if g.isEmpty():
103 s = QSize(600, 500) 105 s = QSize(600, 500)
104 self.resize(s) 106 self.resize(s)
105 else: 107 else:
106 self.restoreGeometry(g) 108 self.restoreGeometry(g)
107 109
108 self.__initActions() 110 self.__initActions()
109 self.__initMenus() 111 self.__initMenus()
110 self.__initToolbars() 112 self.__initToolbars()
111 self.__createStatusBar() 113 self.__createStatusBar()
112 114
113 self.__class__.windows.append(self) 115 self.__class__.windows.append(self)
114 116
115 state = Preferences.getHexEditor("HexEditorState") 117 state = Preferences.getHexEditor("HexEditorState")
116 self.restoreState(state) 118 self.restoreState(state)
117 119
118 self.__editor.currentAddressChanged.connect(self.__showAddress) 120 self.__editor.currentAddressChanged.connect(self.__showAddress)
119 self.__editor.selectionAvailable.connect(self.__showSelectionInfo) 121 self.__editor.selectionAvailable.connect(self.__showSelectionInfo)
120 self.__editor.currentSizeChanged.connect(self.__showSize) 122 self.__editor.currentSizeChanged.connect(self.__showSize)
121 self.__editor.dataChanged.connect(self.__modificationChanged) 123 self.__editor.dataChanged.connect(self.__modificationChanged)
122 self.__editor.overwriteModeChanged.connect(self.__showEditMode) 124 self.__editor.overwriteModeChanged.connect(self.__showEditMode)
123 self.__editor.readOnlyChanged.connect(self.__showReadOnlyMode) 125 self.__editor.readOnlyChanged.connect(self.__showReadOnlyMode)
124 self.__editor.readOnlyChanged.connect(self.__checkActions) 126 self.__editor.readOnlyChanged.connect(self.__checkActions)
125 127
126 self.preferencesChanged() 128 self.preferencesChanged()
127 self.__editor.setOverwriteMode( 129 self.__editor.setOverwriteMode(Preferences.getHexEditor("OpenInOverwriteMode"))
128 Preferences.getHexEditor("OpenInOverwriteMode")) 130
129
130 self.__project = project 131 self.__project = project
131 self.__lastOpenPath = "" 132 self.__lastOpenPath = ""
132 self.__lastSavePath = "" 133 self.__lastSavePath = ""
133 134
134 self.__recent = [] 135 self.__recent = []
135 self.__loadRecent() 136 self.__loadRecent()
136 137
137 self.__setCurrentFile("") 138 self.__setCurrentFile("")
138 if fileName: 139 if fileName:
139 self.__loadHexFile(fileName) 140 self.__loadHexFile(fileName)
140 141
141 self.__checkActions() 142 self.__checkActions()
142 143
143 def __initActions(self): 144 def __initActions(self):
144 """ 145 """
145 Private method to define the user interface actions. 146 Private method to define the user interface actions.
146 """ 147 """
147 # list of all actions 148 # list of all actions
148 self.__actions = [] 149 self.__actions = []
149 150
150 self.__initFileActions() 151 self.__initFileActions()
151 self.__initEditActions() 152 self.__initEditActions()
152 self.__initHelpActions() 153 self.__initHelpActions()
153 if not self.__fromEric: 154 if not self.__fromEric:
154 self.__initConfigActions() 155 self.__initConfigActions()
155 156
156 def __initFileActions(self): 157 def __initFileActions(self):
157 """ 158 """
158 Private method to define the file related user interface actions. 159 Private method to define the file related user interface actions.
159 """ 160 """
160 self.newWindowAct = EricAction( 161 self.newWindowAct = EricAction(
161 self.tr('New Window'), 162 self.tr("New Window"),
162 UI.PixmapCache.getIcon("newWindow"), 163 UI.PixmapCache.getIcon("newWindow"),
163 self.tr('New &Window'), 164 self.tr("New &Window"),
164 0, 0, self, 'hexEditor_file_new_window') 165 0,
165 self.newWindowAct.setStatusTip(self.tr( 166 0,
166 'Open a binary file for editing in a new hex editor window')) 167 self,
167 self.newWindowAct.setWhatsThis(self.tr( 168 "hexEditor_file_new_window",
168 """<b>New Window</b>""" 169 )
169 """<p>This opens a binary file for editing in a new hex editor""" 170 self.newWindowAct.setStatusTip(
170 """ window.</p>""" 171 self.tr("Open a binary file for editing in a new hex editor window")
171 )) 172 )
173 self.newWindowAct.setWhatsThis(
174 self.tr(
175 """<b>New Window</b>"""
176 """<p>This opens a binary file for editing in a new hex editor"""
177 """ window.</p>"""
178 )
179 )
172 self.newWindowAct.triggered.connect(self.__openHexFileNewWindow) 180 self.newWindowAct.triggered.connect(self.__openHexFileNewWindow)
173 self.__actions.append(self.newWindowAct) 181 self.__actions.append(self.newWindowAct)
174 182
175 # correct texts will be set later 183 # correct texts will be set later
176 self.openAct = EricAction( 184 self.openAct = EricAction(
177 self.tr('Open'), 185 self.tr("Open"),
178 UI.PixmapCache.getIcon("open"), 186 UI.PixmapCache.getIcon("open"),
179 self.tr('&Open...'), 187 self.tr("&Open..."),
180 QKeySequence(self.tr("Ctrl+O", "File|Open")), 188 QKeySequence(self.tr("Ctrl+O", "File|Open")),
181 0, self, 'hexEditor_file_open') 189 0,
190 self,
191 "hexEditor_file_open",
192 )
182 self.openAct.triggered.connect(self.__openHexFile) 193 self.openAct.triggered.connect(self.__openHexFile)
183 self.__actions.append(self.openAct) 194 self.__actions.append(self.openAct)
184 195
185 # correct texts will be set later 196 # correct texts will be set later
186 self.openReadOnlyAct = EricAction( 197 self.openReadOnlyAct = EricAction(
187 "", "", 198 "", "", 0, 0, self, "hexEditor_file_open_read_only"
188 0, 0, self, 'hexEditor_file_open_read_only') 199 )
189 self.openReadOnlyAct.triggered.connect(self.__openHexFileReadOnly) 200 self.openReadOnlyAct.triggered.connect(self.__openHexFileReadOnly)
190 self.__actions.append(self.openReadOnlyAct) 201 self.__actions.append(self.openReadOnlyAct)
191 202
192 self.saveAct = EricAction( 203 self.saveAct = EricAction(
193 self.tr('Save'), 204 self.tr("Save"),
194 UI.PixmapCache.getIcon("fileSave"), 205 UI.PixmapCache.getIcon("fileSave"),
195 self.tr('&Save'), 206 self.tr("&Save"),
196 QKeySequence(self.tr("Ctrl+S", "File|Save")), 207 QKeySequence(self.tr("Ctrl+S", "File|Save")),
197 0, self, 'hexEditor_file_save') 208 0,
198 self.saveAct.setStatusTip(self.tr('Save the current binary file')) 209 self,
199 self.saveAct.setWhatsThis(self.tr( 210 "hexEditor_file_save",
200 """<b>Save File</b>""" 211 )
201 """<p>Save the contents of the hex editor window.</p>""" 212 self.saveAct.setStatusTip(self.tr("Save the current binary file"))
202 )) 213 self.saveAct.setWhatsThis(
214 self.tr(
215 """<b>Save File</b>"""
216 """<p>Save the contents of the hex editor window.</p>"""
217 )
218 )
203 self.saveAct.triggered.connect(self.__saveHexFile) 219 self.saveAct.triggered.connect(self.__saveHexFile)
204 self.__actions.append(self.saveAct) 220 self.__actions.append(self.saveAct)
205 221
206 self.saveAsAct = EricAction( 222 self.saveAsAct = EricAction(
207 self.tr('Save As'), 223 self.tr("Save As"),
208 UI.PixmapCache.getIcon("fileSaveAs"), 224 UI.PixmapCache.getIcon("fileSaveAs"),
209 self.tr('Save &As...'), 225 self.tr("Save &As..."),
210 QKeySequence(self.tr("Shift+Ctrl+S", "File|Save As")), 226 QKeySequence(self.tr("Shift+Ctrl+S", "File|Save As")),
211 0, self, 'hexEditor_file_save_as') 227 0,
228 self,
229 "hexEditor_file_save_as",
230 )
212 self.saveAsAct.setStatusTip( 231 self.saveAsAct.setStatusTip(
213 self.tr('Save the current binary data to a new file')) 232 self.tr("Save the current binary data to a new file")
214 self.saveAsAct.setWhatsThis(self.tr( 233 )
215 """<b>Save As...</b>""" 234 self.saveAsAct.setWhatsThis(
216 """<p>Saves the current binary data to a new file.</p>""" 235 self.tr(
217 )) 236 """<b>Save As...</b>"""
237 """<p>Saves the current binary data to a new file.</p>"""
238 )
239 )
218 self.saveAsAct.triggered.connect(self.__saveHexFileAs) 240 self.saveAsAct.triggered.connect(self.__saveHexFileAs)
219 self.__actions.append(self.saveAsAct) 241 self.__actions.append(self.saveAsAct)
220 242
221 self.saveReadableAct = EricAction( 243 self.saveReadableAct = EricAction(
222 self.tr('Save As Readable'), 244 self.tr("Save As Readable"),
223 self.tr('Save As &Readable...'), 245 self.tr("Save As &Readable..."),
224 0, 0, self, 'hexEditor_file_save_readable') 246 0,
247 0,
248 self,
249 "hexEditor_file_save_readable",
250 )
225 self.saveReadableAct.setStatusTip( 251 self.saveReadableAct.setStatusTip(
226 self.tr('Save the current binary data to a new file in a readable' 252 self.tr(
227 ' format')) 253 "Save the current binary data to a new file in a readable" " format"
228 self.saveReadableAct.setWhatsThis(self.tr( 254 )
229 """<b>Save As Readable...</b>""" 255 )
230 """<p>Saves the current binary data to a new file in a readable""" 256 self.saveReadableAct.setWhatsThis(
231 """ format.</p>""" 257 self.tr(
232 )) 258 """<b>Save As Readable...</b>"""
259 """<p>Saves the current binary data to a new file in a readable"""
260 """ format.</p>"""
261 )
262 )
233 self.saveReadableAct.triggered.connect(self.__saveHexFileReadable) 263 self.saveReadableAct.triggered.connect(self.__saveHexFileReadable)
234 self.__actions.append(self.saveReadableAct) 264 self.__actions.append(self.saveReadableAct)
235 265
236 self.closeAct = EricAction( 266 self.closeAct = EricAction(
237 self.tr('Close'), 267 self.tr("Close"),
238 UI.PixmapCache.getIcon("close"), 268 UI.PixmapCache.getIcon("close"),
239 self.tr('&Close'), 269 self.tr("&Close"),
240 QKeySequence(self.tr("Ctrl+W", "File|Close")), 270 QKeySequence(self.tr("Ctrl+W", "File|Close")),
241 0, self, 'hexEditor_file_close') 271 0,
242 self.closeAct.setStatusTip(self.tr( 272 self,
243 'Close the current hex editor window')) 273 "hexEditor_file_close",
244 self.closeAct.setWhatsThis(self.tr( 274 )
245 """<b>Close</b>""" 275 self.closeAct.setStatusTip(self.tr("Close the current hex editor window"))
246 """<p>Closes the current hex editor window.</p>""" 276 self.closeAct.setWhatsThis(
247 )) 277 self.tr(
278 """<b>Close</b>""" """<p>Closes the current hex editor window.</p>"""
279 )
280 )
248 self.closeAct.triggered.connect(self.close) 281 self.closeAct.triggered.connect(self.close)
249 self.__actions.append(self.closeAct) 282 self.__actions.append(self.closeAct)
250 283
251 self.closeAllAct = EricAction( 284 self.closeAllAct = EricAction(
252 self.tr('Close All'), 285 self.tr("Close All"),
253 self.tr('Close &All'), 286 self.tr("Close &All"),
254 0, 0, self, 'hexEditor_file_close_all') 287 0,
255 self.closeAllAct.setStatusTip(self.tr( 288 0,
256 'Close all hex editor windows')) 289 self,
257 self.closeAllAct.setWhatsThis(self.tr( 290 "hexEditor_file_close_all",
258 """<b>Close All</b>""" 291 )
259 """<p>Closes all hex editor windows.</p>""" 292 self.closeAllAct.setStatusTip(self.tr("Close all hex editor windows"))
260 )) 293 self.closeAllAct.setWhatsThis(
294 self.tr("""<b>Close All</b>""" """<p>Closes all hex editor windows.</p>""")
295 )
261 self.closeAllAct.triggered.connect(self.__closeAll) 296 self.closeAllAct.triggered.connect(self.__closeAll)
262 self.__actions.append(self.closeAllAct) 297 self.__actions.append(self.closeAllAct)
263 298
264 self.closeOthersAct = EricAction( 299 self.closeOthersAct = EricAction(
265 self.tr('Close Others'), 300 self.tr("Close Others"),
266 self.tr('Close Others'), 301 self.tr("Close Others"),
267 0, 0, self, 'hexEditor_file_close_others') 302 0,
268 self.closeOthersAct.setStatusTip(self.tr( 303 0,
269 'Close all other hex editor windows')) 304 self,
270 self.closeOthersAct.setWhatsThis(self.tr( 305 "hexEditor_file_close_others",
271 """<b>Close Others</b>""" 306 )
272 """<p>Closes all other hex editor windows.</p>""" 307 self.closeOthersAct.setStatusTip(self.tr("Close all other hex editor windows"))
273 )) 308 self.closeOthersAct.setWhatsThis(
309 self.tr(
310 """<b>Close Others</b>"""
311 """<p>Closes all other hex editor windows.</p>"""
312 )
313 )
274 self.closeOthersAct.triggered.connect(self.__closeOthers) 314 self.closeOthersAct.triggered.connect(self.__closeOthers)
275 self.__actions.append(self.closeOthersAct) 315 self.__actions.append(self.closeOthersAct)
276 316
277 self.exitAct = EricAction( 317 self.exitAct = EricAction(
278 self.tr('Quit'), 318 self.tr("Quit"),
279 UI.PixmapCache.getIcon("exit"), 319 UI.PixmapCache.getIcon("exit"),
280 self.tr('&Quit'), 320 self.tr("&Quit"),
281 QKeySequence(self.tr("Ctrl+Q", "File|Quit")), 321 QKeySequence(self.tr("Ctrl+Q", "File|Quit")),
282 0, self, 'hexEditor_file_quit') 322 0,
283 self.exitAct.setStatusTip(self.tr('Quit the hex editor')) 323 self,
284 self.exitAct.setWhatsThis(self.tr( 324 "hexEditor_file_quit",
285 """<b>Quit</b>""" 325 )
286 """<p>Quit the hex editor.</p>""" 326 self.exitAct.setStatusTip(self.tr("Quit the hex editor"))
287 )) 327 self.exitAct.setWhatsThis(
328 self.tr("""<b>Quit</b>""" """<p>Quit the hex editor.</p>""")
329 )
288 if not self.__fromEric: 330 if not self.__fromEric:
289 self.exitAct.triggered.connect(self.__closeAll) 331 self.exitAct.triggered.connect(self.__closeAll)
290 self.__actions.append(self.exitAct) 332 self.__actions.append(self.exitAct)
291 333
292 def __initEditActions(self): 334 def __initEditActions(self):
293 """ 335 """
294 Private method to create the Edit actions. 336 Private method to create the Edit actions.
295 """ 337 """
296 self.undoAct = EricAction( 338 self.undoAct = EricAction(
297 self.tr('Undo'), 339 self.tr("Undo"),
298 UI.PixmapCache.getIcon("editUndo"), 340 UI.PixmapCache.getIcon("editUndo"),
299 self.tr('&Undo'), 341 self.tr("&Undo"),
300 QKeySequence(self.tr("Ctrl+Z", "Edit|Undo")), 342 QKeySequence(self.tr("Ctrl+Z", "Edit|Undo")),
301 QKeySequence(self.tr("Alt+Backspace", "Edit|Undo")), 343 QKeySequence(self.tr("Alt+Backspace", "Edit|Undo")),
302 self, 'hexEditor_edit_undo') 344 self,
303 self.undoAct.setStatusTip(self.tr('Undo the last change')) 345 "hexEditor_edit_undo",
304 self.undoAct.setWhatsThis(self.tr( 346 )
305 """<b>Undo</b>""" 347 self.undoAct.setStatusTip(self.tr("Undo the last change"))
306 """<p>Undo the last change done.</p>""" 348 self.undoAct.setWhatsThis(
307 )) 349 self.tr("""<b>Undo</b>""" """<p>Undo the last change done.</p>""")
350 )
308 self.undoAct.triggered.connect(self.__editor.undo) 351 self.undoAct.triggered.connect(self.__editor.undo)
309 self.__actions.append(self.undoAct) 352 self.__actions.append(self.undoAct)
310 353
311 self.redoAct = EricAction( 354 self.redoAct = EricAction(
312 self.tr('Redo'), 355 self.tr("Redo"),
313 UI.PixmapCache.getIcon("editRedo"), 356 UI.PixmapCache.getIcon("editRedo"),
314 self.tr('&Redo'), 357 self.tr("&Redo"),
315 QKeySequence(self.tr("Ctrl+Shift+Z", "Edit|Redo")), 358 QKeySequence(self.tr("Ctrl+Shift+Z", "Edit|Redo")),
316 0, self, 'hexEditor_edit_redo') 359 0,
317 self.redoAct.setStatusTip(self.tr('Redo the last change')) 360 self,
318 self.redoAct.setWhatsThis(self.tr( 361 "hexEditor_edit_redo",
319 """<b>Redo</b>""" 362 )
320 """<p>Redo the last change done.</p>""" 363 self.redoAct.setStatusTip(self.tr("Redo the last change"))
321 )) 364 self.redoAct.setWhatsThis(
365 self.tr("""<b>Redo</b>""" """<p>Redo the last change done.</p>""")
366 )
322 self.redoAct.triggered.connect(self.__editor.redo) 367 self.redoAct.triggered.connect(self.__editor.redo)
323 self.__actions.append(self.redoAct) 368 self.__actions.append(self.redoAct)
324 369
325 self.revertAct = EricAction( 370 self.revertAct = EricAction(
326 self.tr('Revert to last saved state'), 371 self.tr("Revert to last saved state"),
327 self.tr('Re&vert to last saved state'), 372 self.tr("Re&vert to last saved state"),
328 QKeySequence(self.tr("Ctrl+Y", "Edit|Revert")), 373 QKeySequence(self.tr("Ctrl+Y", "Edit|Revert")),
329 0, 374 0,
330 self, 'hexEditor_edit_revert') 375 self,
331 self.revertAct.setStatusTip(self.tr('Revert to last saved state')) 376 "hexEditor_edit_revert",
332 self.revertAct.setWhatsThis(self.tr( 377 )
333 """<b>Revert to last saved state</b>""" 378 self.revertAct.setStatusTip(self.tr("Revert to last saved state"))
334 """<p>Undo all changes up to the last saved state of the""" 379 self.revertAct.setWhatsThis(
335 """ editor.</p>""" 380 self.tr(
336 )) 381 """<b>Revert to last saved state</b>"""
382 """<p>Undo all changes up to the last saved state of the"""
383 """ editor.</p>"""
384 )
385 )
337 self.revertAct.triggered.connect(self.__editor.revertToUnmodified) 386 self.revertAct.triggered.connect(self.__editor.revertToUnmodified)
338 self.__actions.append(self.revertAct) 387 self.__actions.append(self.revertAct)
339 388
340 self.cutAct = EricAction( 389 self.cutAct = EricAction(
341 self.tr('Cut'), 390 self.tr("Cut"),
342 UI.PixmapCache.getIcon("editCut"), 391 UI.PixmapCache.getIcon("editCut"),
343 self.tr('Cu&t'), 392 self.tr("Cu&t"),
344 QKeySequence(self.tr("Ctrl+X", "Edit|Cut")), 393 QKeySequence(self.tr("Ctrl+X", "Edit|Cut")),
345 QKeySequence(self.tr("Shift+Del", "Edit|Cut")), 394 QKeySequence(self.tr("Shift+Del", "Edit|Cut")),
346 self, 'hexEditor_edit_cut') 395 self,
347 self.cutAct.setStatusTip(self.tr('Cut the selection')) 396 "hexEditor_edit_cut",
348 self.cutAct.setWhatsThis(self.tr( 397 )
349 """<b>Cut</b>""" 398 self.cutAct.setStatusTip(self.tr("Cut the selection"))
350 """<p>Cut the selected binary area to the clipboard.</p>""" 399 self.cutAct.setWhatsThis(
351 )) 400 self.tr(
401 """<b>Cut</b>"""
402 """<p>Cut the selected binary area to the clipboard.</p>"""
403 )
404 )
352 self.cutAct.triggered.connect(self.__editor.cut) 405 self.cutAct.triggered.connect(self.__editor.cut)
353 self.__actions.append(self.cutAct) 406 self.__actions.append(self.cutAct)
354 407
355 self.copyAct = EricAction( 408 self.copyAct = EricAction(
356 self.tr('Copy'), 409 self.tr("Copy"),
357 UI.PixmapCache.getIcon("editCopy"), 410 UI.PixmapCache.getIcon("editCopy"),
358 self.tr('&Copy'), 411 self.tr("&Copy"),
359 QKeySequence(self.tr("Ctrl+C", "Edit|Copy")), 412 QKeySequence(self.tr("Ctrl+C", "Edit|Copy")),
360 QKeySequence(self.tr("Ctrl+Ins", "Edit|Copy")), 413 QKeySequence(self.tr("Ctrl+Ins", "Edit|Copy")),
361 self, 'hexEditor_edit_copy') 414 self,
362 self.copyAct.setStatusTip(self.tr('Copy the selection')) 415 "hexEditor_edit_copy",
363 self.copyAct.setWhatsThis(self.tr( 416 )
364 """<b>Copy</b>""" 417 self.copyAct.setStatusTip(self.tr("Copy the selection"))
365 """<p>Copy the selected binary area to the clipboard.</p>""" 418 self.copyAct.setWhatsThis(
366 )) 419 self.tr(
420 """<b>Copy</b>"""
421 """<p>Copy the selected binary area to the clipboard.</p>"""
422 )
423 )
367 self.copyAct.triggered.connect(self.__editor.copy) 424 self.copyAct.triggered.connect(self.__editor.copy)
368 self.__actions.append(self.copyAct) 425 self.__actions.append(self.copyAct)
369 426
370 self.pasteAct = EricAction( 427 self.pasteAct = EricAction(
371 self.tr('Paste'), 428 self.tr("Paste"),
372 UI.PixmapCache.getIcon("editPaste"), 429 UI.PixmapCache.getIcon("editPaste"),
373 self.tr('&Paste'), 430 self.tr("&Paste"),
374 QKeySequence(self.tr("Ctrl+V", "Edit|Paste")), 431 QKeySequence(self.tr("Ctrl+V", "Edit|Paste")),
375 QKeySequence(self.tr("Shift+Ins", "Edit|Paste")), 432 QKeySequence(self.tr("Shift+Ins", "Edit|Paste")),
376 self, 'hexEditor_edit_paste') 433 self,
377 self.pasteAct.setStatusTip(self.tr('Paste the clipboard contents')) 434 "hexEditor_edit_paste",
378 self.pasteAct.setWhatsThis(self.tr( 435 )
379 """<b>Paste</b>""" 436 self.pasteAct.setStatusTip(self.tr("Paste the clipboard contents"))
380 """<p>Paste the clipboard contents.</p>""" 437 self.pasteAct.setWhatsThis(
381 )) 438 self.tr("""<b>Paste</b>""" """<p>Paste the clipboard contents.</p>""")
439 )
382 self.pasteAct.triggered.connect(self.__editor.paste) 440 self.pasteAct.triggered.connect(self.__editor.paste)
383 self.__actions.append(self.pasteAct) 441 self.__actions.append(self.pasteAct)
384 442
385 self.selectAllAct = EricAction( 443 self.selectAllAct = EricAction(
386 self.tr('Select All'), 444 self.tr("Select All"),
387 UI.PixmapCache.getIcon("editSelectAll"), 445 UI.PixmapCache.getIcon("editSelectAll"),
388 self.tr('&Select All'), 446 self.tr("&Select All"),
389 QKeySequence(self.tr("Ctrl+A", "Edit|Select All")), 447 QKeySequence(self.tr("Ctrl+A", "Edit|Select All")),
390 0, 448 0,
391 self, 'hexEditor_edit_select_all') 449 self,
392 self.selectAllAct.setStatusTip(self.tr( 450 "hexEditor_edit_select_all",
393 'Select the complete binary data')) 451 )
394 self.selectAllAct.setWhatsThis(self.tr( 452 self.selectAllAct.setStatusTip(self.tr("Select the complete binary data"))
395 """<b>Select All</b>""" 453 self.selectAllAct.setWhatsThis(
396 """<p>Selects the complete binary data.</p>""" 454 self.tr(
397 )) 455 """<b>Select All</b>""" """<p>Selects the complete binary data.</p>"""
456 )
457 )
398 self.selectAllAct.triggered.connect(self.__editor.selectAll) 458 self.selectAllAct.triggered.connect(self.__editor.selectAll)
399 self.__actions.append(self.selectAllAct) 459 self.__actions.append(self.selectAllAct)
400 460
401 self.deselectAllAct = EricAction( 461 self.deselectAllAct = EricAction(
402 self.tr('Deselect all'), 462 self.tr("Deselect all"),
403 self.tr('&Deselect all'), 463 self.tr("&Deselect all"),
404 QKeySequence(self.tr("Alt+Ctrl+A", "Edit|Deselect all")), 464 QKeySequence(self.tr("Alt+Ctrl+A", "Edit|Deselect all")),
405 0, 465 0,
406 self, 'hexEditor_edit_deselect_all') 466 self,
407 self.deselectAllAct.setStatusTip(self.tr('Deselect all binary data')) 467 "hexEditor_edit_deselect_all",
408 self.deselectAllAct.setWhatsThis(self.tr( 468 )
409 """<b>Deselect All</b>""" 469 self.deselectAllAct.setStatusTip(self.tr("Deselect all binary data"))
410 """<p>Deselect all all binary data.</p>""" 470 self.deselectAllAct.setWhatsThis(
411 )) 471 self.tr(
472 """<b>Deselect All</b>""" """<p>Deselect all all binary data.</p>"""
473 )
474 )
412 self.deselectAllAct.triggered.connect(self.__editor.deselectAll) 475 self.deselectAllAct.triggered.connect(self.__editor.deselectAll)
413 self.__actions.append(self.deselectAllAct) 476 self.__actions.append(self.deselectAllAct)
414 477
415 self.saveSelectionReadableAct = EricAction( 478 self.saveSelectionReadableAct = EricAction(
416 self.tr('Save Selection Readable'), 479 self.tr("Save Selection Readable"),
417 self.tr('Save Selection Readable...'), 480 self.tr("Save Selection Readable..."),
418 0, 0, self, 'hexEditor_edit_selection_save_readable') 481 0,
482 0,
483 self,
484 "hexEditor_edit_selection_save_readable",
485 )
419 self.saveSelectionReadableAct.setStatusTip( 486 self.saveSelectionReadableAct.setStatusTip(
420 self.tr('Save the binary data of the current selection to a file' 487 self.tr(
421 ' in a readable format')) 488 "Save the binary data of the current selection to a file"
422 self.saveSelectionReadableAct.setWhatsThis(self.tr( 489 " in a readable format"
423 """<b>Save Selection Readable...</b>""" 490 )
424 """<p>Saves the binary data of the current selection to a file""" 491 )
425 """ in a readable format.</p>""" 492 self.saveSelectionReadableAct.setWhatsThis(
426 )) 493 self.tr(
427 self.saveSelectionReadableAct.triggered.connect( 494 """<b>Save Selection Readable...</b>"""
428 self.__saveSelectionReadable) 495 """<p>Saves the binary data of the current selection to a file"""
496 """ in a readable format.</p>"""
497 )
498 )
499 self.saveSelectionReadableAct.triggered.connect(self.__saveSelectionReadable)
429 self.__actions.append(self.saveSelectionReadableAct) 500 self.__actions.append(self.saveSelectionReadableAct)
430 501
431 self.readonlyAct = EricAction( 502 self.readonlyAct = EricAction(
432 self.tr('Set Read Only'), 503 self.tr("Set Read Only"),
433 self.tr('Set Read Only'), 504 self.tr("Set Read Only"),
434 0, 0, self, 'hexEditor_edit_readonly', True) 505 0,
435 self.readonlyAct.setStatusTip(self.tr( 506 0,
436 'Change the edit mode to read only')) 507 self,
437 self.readonlyAct.setWhatsThis(self.tr( 508 "hexEditor_edit_readonly",
438 """<b>Set Read Only</b>""" 509 True,
439 """<p>This changes the edit mode to read only (i.e. to view""" 510 )
440 """ mode).</p>""" 511 self.readonlyAct.setStatusTip(self.tr("Change the edit mode to read only"))
441 )) 512 self.readonlyAct.setWhatsThis(
513 self.tr(
514 """<b>Set Read Only</b>"""
515 """<p>This changes the edit mode to read only (i.e. to view"""
516 """ mode).</p>"""
517 )
518 )
442 self.readonlyAct.setChecked(False) 519 self.readonlyAct.setChecked(False)
443 self.readonlyAct.toggled[bool].connect(self.__editor.setReadOnly) 520 self.readonlyAct.toggled[bool].connect(self.__editor.setReadOnly)
444 self.__editor.readOnlyChanged.connect(self.readonlyAct.setChecked) 521 self.__editor.readOnlyChanged.connect(self.readonlyAct.setChecked)
445 self.__actions.append(self.readonlyAct) 522 self.__actions.append(self.readonlyAct)
446 523
447 self.searchAct = EricAction( 524 self.searchAct = EricAction(
448 self.tr('Search'), 525 self.tr("Search"),
449 UI.PixmapCache.getIcon("find"), 526 UI.PixmapCache.getIcon("find"),
450 self.tr('&Search...'), 527 self.tr("&Search..."),
451 QKeySequence(self.tr("Ctrl+F", "Search|Search")), 528 QKeySequence(self.tr("Ctrl+F", "Search|Search")),
452 0, 529 0,
453 self, 'hexEditor_edit_search') 530 self,
454 self.searchAct.setStatusTip(self.tr('Search for data')) 531 "hexEditor_edit_search",
455 self.searchAct.setWhatsThis(self.tr( 532 )
456 """<b>Search</b>""" 533 self.searchAct.setStatusTip(self.tr("Search for data"))
457 """<p>Search for some data. A dialog is shown to enter the""" 534 self.searchAct.setWhatsThis(
458 """ data to search for in various formats.</p>""" 535 self.tr(
459 )) 536 """<b>Search</b>"""
537 """<p>Search for some data. A dialog is shown to enter the"""
538 """ data to search for in various formats.</p>"""
539 )
540 )
460 self.searchAct.triggered.connect(self.__search) 541 self.searchAct.triggered.connect(self.__search)
461 self.__actions.append(self.searchAct) 542 self.__actions.append(self.searchAct)
462 543
463 self.searchNextAct = EricAction( 544 self.searchNextAct = EricAction(
464 self.tr('Search next'), 545 self.tr("Search next"),
465 UI.PixmapCache.getIcon("findNext"), 546 UI.PixmapCache.getIcon("findNext"),
466 self.tr('Search &next'), 547 self.tr("Search &next"),
467 QKeySequence(self.tr("F3", "Search|Search next")), 548 QKeySequence(self.tr("F3", "Search|Search next")),
468 0, 549 0,
469 self, 'hexEditor_edit_search_next') 550 self,
470 self.searchNextAct.setStatusTip(self.tr( 551 "hexEditor_edit_search_next",
471 'Search next occurrence')) 552 )
472 self.searchNextAct.setWhatsThis(self.tr( 553 self.searchNextAct.setStatusTip(self.tr("Search next occurrence"))
473 """<b>Search next</b>""" 554 self.searchNextAct.setWhatsThis(
474 """<p>Search the next occurrence of some data. The previously""" 555 self.tr(
475 """ entered search data are reused.</p>""" 556 """<b>Search next</b>"""
476 )) 557 """<p>Search the next occurrence of some data. The previously"""
558 """ entered search data are reused.</p>"""
559 )
560 )
477 self.searchNextAct.triggered.connect(self.__searchWidget.findPrevNext) 561 self.searchNextAct.triggered.connect(self.__searchWidget.findPrevNext)
478 self.__actions.append(self.searchNextAct) 562 self.__actions.append(self.searchNextAct)
479 563
480 self.searchPrevAct = EricAction( 564 self.searchPrevAct = EricAction(
481 self.tr('Search previous'), 565 self.tr("Search previous"),
482 UI.PixmapCache.getIcon("findPrev"), 566 UI.PixmapCache.getIcon("findPrev"),
483 self.tr('Search &previous'), 567 self.tr("Search &previous"),
484 QKeySequence(self.tr("Shift+F3", "Search|Search previous")), 568 QKeySequence(self.tr("Shift+F3", "Search|Search previous")),
485 0, 569 0,
486 self, 'hexEditor_edit_search_previous') 570 self,
487 self.searchPrevAct.setStatusTip(self.tr( 571 "hexEditor_edit_search_previous",
488 'Search previous occurrence')) 572 )
489 self.searchPrevAct.setWhatsThis(self.tr( 573 self.searchPrevAct.setStatusTip(self.tr("Search previous occurrence"))
490 """<b>Search previous</b>""" 574 self.searchPrevAct.setWhatsThis(
491 """<p>Search the previous occurrence of some data. The""" 575 self.tr(
492 """ previously entered search data are reused.</p>""" 576 """<b>Search previous</b>"""
493 )) 577 """<p>Search the previous occurrence of some data. The"""
578 """ previously entered search data are reused.</p>"""
579 )
580 )
494 self.searchPrevAct.triggered.connect( 581 self.searchPrevAct.triggered.connect(
495 lambda: self.__searchWidget.findPrevNext(True)) 582 lambda: self.__searchWidget.findPrevNext(True)
583 )
496 self.__actions.append(self.searchPrevAct) 584 self.__actions.append(self.searchPrevAct)
497 585
498 self.replaceAct = EricAction( 586 self.replaceAct = EricAction(
499 self.tr('Replace'), 587 self.tr("Replace"),
500 self.tr('&Replace...'), 588 self.tr("&Replace..."),
501 QKeySequence(self.tr("Ctrl+R", "Search|Replace")), 589 QKeySequence(self.tr("Ctrl+R", "Search|Replace")),
502 0, 590 0,
503 self, 'hexEditor_edit_search_replace') 591 self,
504 self.replaceAct.setStatusTip(self.tr('Replace data')) 592 "hexEditor_edit_search_replace",
505 self.replaceAct.setWhatsThis(self.tr( 593 )
506 """<b>Replace</b>""" 594 self.replaceAct.setStatusTip(self.tr("Replace data"))
507 """<p>Search for some data and replace it.""" 595 self.replaceAct.setWhatsThis(
508 """ A dialog is shown to enter the data to search for and the""" 596 self.tr(
509 """ replacement data in various formats.</p>""" 597 """<b>Replace</b>"""
510 )) 598 """<p>Search for some data and replace it."""
599 """ A dialog is shown to enter the data to search for and the"""
600 """ replacement data in various formats.</p>"""
601 )
602 )
511 self.replaceAct.triggered.connect(self.__replace) 603 self.replaceAct.triggered.connect(self.__replace)
512 self.__actions.append(self.replaceAct) 604 self.__actions.append(self.replaceAct)
513 605
514 self.gotoAct = EricAction( 606 self.gotoAct = EricAction(
515 self.tr('Goto Offset'), 607 self.tr("Goto Offset"),
516 UI.PixmapCache.getIcon("goto"), 608 UI.PixmapCache.getIcon("goto"),
517 self.tr('&Goto Offset...'), 609 self.tr("&Goto Offset..."),
518 QKeySequence(QCoreApplication.translate( 610 QKeySequence(
519 'ViewManager', "Ctrl+G", "Search|Goto Offset")), 611 QCoreApplication.translate(
520 0, 612 "ViewManager", "Ctrl+G", "Search|Goto Offset"
521 self, 'hexEditor_edit_goto') 613 )
522 self.gotoAct.setStatusTip(self.tr('Goto Offset')) 614 ),
523 self.gotoAct.setWhatsThis(self.tr( 615 0,
524 """<b>Goto Offset</b>""" 616 self,
525 """<p>Go to a specific address. A dialog is shown to enter""" 617 "hexEditor_edit_goto",
526 """ the movement data.</p>""" 618 )
527 )) 619 self.gotoAct.setStatusTip(self.tr("Goto Offset"))
620 self.gotoAct.setWhatsThis(
621 self.tr(
622 """<b>Goto Offset</b>"""
623 """<p>Go to a specific address. A dialog is shown to enter"""
624 """ the movement data.</p>"""
625 )
626 )
528 self.gotoAct.triggered.connect(self.__goto) 627 self.gotoAct.triggered.connect(self.__goto)
529 self.__actions.append(self.gotoAct) 628 self.__actions.append(self.gotoAct)
530 629
531 self.redoAct.setEnabled(False) 630 self.redoAct.setEnabled(False)
532 self.__editor.canRedoChanged.connect(self.redoAct.setEnabled) 631 self.__editor.canRedoChanged.connect(self.redoAct.setEnabled)
533 632
534 self.undoAct.setEnabled(False) 633 self.undoAct.setEnabled(False)
535 self.__editor.canUndoChanged.connect(self.undoAct.setEnabled) 634 self.__editor.canUndoChanged.connect(self.undoAct.setEnabled)
536 635
537 self.revertAct.setEnabled(False) 636 self.revertAct.setEnabled(False)
538 self.__editor.dataChanged.connect(self.revertAct.setEnabled) 637 self.__editor.dataChanged.connect(self.revertAct.setEnabled)
539 638
540 self.cutAct.setEnabled(False) 639 self.cutAct.setEnabled(False)
541 self.copyAct.setEnabled(False) 640 self.copyAct.setEnabled(False)
542 self.saveSelectionReadableAct.setEnabled(False) 641 self.saveSelectionReadableAct.setEnabled(False)
543 self.__editor.selectionAvailable.connect(self.__checkActions) 642 self.__editor.selectionAvailable.connect(self.__checkActions)
544 self.__editor.selectionAvailable.connect(self.copyAct.setEnabled) 643 self.__editor.selectionAvailable.connect(self.copyAct.setEnabled)
545 self.__editor.selectionAvailable.connect( 644 self.__editor.selectionAvailable.connect(
546 self.saveSelectionReadableAct.setEnabled) 645 self.saveSelectionReadableAct.setEnabled
547 646 )
647
548 def __initHelpActions(self): 648 def __initHelpActions(self):
549 """ 649 """
550 Private method to create the Help actions. 650 Private method to create the Help actions.
551 """ 651 """
552 self.aboutAct = EricAction( 652 self.aboutAct = EricAction(
553 self.tr('About'), 653 self.tr("About"), self.tr("&About"), 0, 0, self, "hexEditor_help_about"
554 self.tr('&About'), 654 )
555 0, 0, self, 'hexEditor_help_about') 655 self.aboutAct.setStatusTip(self.tr("Display information about this software"))
556 self.aboutAct.setStatusTip(self.tr( 656 self.aboutAct.setWhatsThis(
557 'Display information about this software')) 657 self.tr(
558 self.aboutAct.setWhatsThis(self.tr( 658 """<b>About</b>"""
559 """<b>About</b>""" 659 """<p>Display some information about this software.</p>"""
560 """<p>Display some information about this software.</p>""")) 660 )
661 )
561 self.aboutAct.triggered.connect(self.__about) 662 self.aboutAct.triggered.connect(self.__about)
562 self.__actions.append(self.aboutAct) 663 self.__actions.append(self.aboutAct)
563 664
564 self.aboutQtAct = EricAction( 665 self.aboutQtAct = EricAction(
565 self.tr('About Qt'), 666 self.tr("About Qt"),
566 self.tr('About &Qt'), 667 self.tr("About &Qt"),
567 0, 0, self, 'hexEditor_help_about_qt') 668 0,
669 0,
670 self,
671 "hexEditor_help_about_qt",
672 )
568 self.aboutQtAct.setStatusTip( 673 self.aboutQtAct.setStatusTip(
569 self.tr('Display information about the Qt toolkit')) 674 self.tr("Display information about the Qt toolkit")
570 self.aboutQtAct.setWhatsThis(self.tr( 675 )
571 """<b>About Qt</b>""" 676 self.aboutQtAct.setWhatsThis(
572 """<p>Display some information about the Qt toolkit.</p>""" 677 self.tr(
573 )) 678 """<b>About Qt</b>"""
679 """<p>Display some information about the Qt toolkit.</p>"""
680 )
681 )
574 self.aboutQtAct.triggered.connect(self.__aboutQt) 682 self.aboutQtAct.triggered.connect(self.__aboutQt)
575 self.__actions.append(self.aboutQtAct) 683 self.__actions.append(self.aboutQtAct)
576 684
577 self.whatsThisAct = EricAction( 685 self.whatsThisAct = EricAction(
578 self.tr('What\'s This?'), 686 self.tr("What's This?"),
579 UI.PixmapCache.getIcon("whatsThis"), 687 UI.PixmapCache.getIcon("whatsThis"),
580 self.tr('&What\'s This?'), 688 self.tr("&What's This?"),
581 QKeySequence(self.tr("Shift+F1", "Help|What's This?'")), 689 QKeySequence(self.tr("Shift+F1", "Help|What's This?'")),
582 0, self, 'hexEditor_help_whats_this') 690 0,
583 self.whatsThisAct.setStatusTip(self.tr('Context sensitive help')) 691 self,
584 self.whatsThisAct.setWhatsThis(self.tr( 692 "hexEditor_help_whats_this",
585 """<b>Display context sensitive help</b>""" 693 )
586 """<p>In What's This? mode, the mouse cursor shows an arrow""" 694 self.whatsThisAct.setStatusTip(self.tr("Context sensitive help"))
587 """ with a question mark, and you can click on the interface""" 695 self.whatsThisAct.setWhatsThis(
588 """ elements to get a short description of what they do and""" 696 self.tr(
589 """ how to use them. In dialogs, this feature can be accessed""" 697 """<b>Display context sensitive help</b>"""
590 """ using the context help button in the titlebar.</p>""" 698 """<p>In What's This? mode, the mouse cursor shows an arrow"""
591 )) 699 """ with a question mark, and you can click on the interface"""
700 """ elements to get a short description of what they do and"""
701 """ how to use them. In dialogs, this feature can be accessed"""
702 """ using the context help button in the titlebar.</p>"""
703 )
704 )
592 self.whatsThisAct.triggered.connect(self.__whatsThis) 705 self.whatsThisAct.triggered.connect(self.__whatsThis)
593 self.__actions.append(self.whatsThisAct) 706 self.__actions.append(self.whatsThisAct)
594 707
595 def __initConfigActions(self): 708 def __initConfigActions(self):
596 """ 709 """
597 Private method to create the Settings actions. 710 Private method to create the Settings actions.
598 """ 711 """
599 self.prefAct = EricAction( 712 self.prefAct = EricAction(
600 self.tr('Preferences'), 713 self.tr("Preferences"),
601 UI.PixmapCache.getIcon("configure"), 714 UI.PixmapCache.getIcon("configure"),
602 self.tr('&Preferences...'), 715 self.tr("&Preferences..."),
603 0, 0, self, 'hexEditor_settings_preferences') 716 0,
604 self.prefAct.setStatusTip(self.tr( 717 0,
605 'Set the prefered configuration')) 718 self,
606 self.prefAct.setWhatsThis(self.tr( 719 "hexEditor_settings_preferences",
607 """<b>Preferences</b>""" 720 )
608 """<p>Set the configuration items of the application""" 721 self.prefAct.setStatusTip(self.tr("Set the prefered configuration"))
609 """ with your prefered values.</p>""" 722 self.prefAct.setWhatsThis(
610 )) 723 self.tr(
724 """<b>Preferences</b>"""
725 """<p>Set the configuration items of the application"""
726 """ with your prefered values.</p>"""
727 )
728 )
611 self.prefAct.triggered.connect(self.__showPreferences) 729 self.prefAct.triggered.connect(self.__showPreferences)
612 self.prefAct.setMenuRole(QAction.MenuRole.PreferencesRole) 730 self.prefAct.setMenuRole(QAction.MenuRole.PreferencesRole)
613 self.__actions.append(self.prefAct) 731 self.__actions.append(self.prefAct)
614 732
615 def __setReadOnlyActionTexts(self): 733 def __setReadOnlyActionTexts(self):
616 """ 734 """
617 Private method to switch the 'Open Read Only' action between 735 Private method to switch the 'Open Read Only' action between
618 'read only' and 'read write'. 736 'read only' and 'read write'.
619 """ 737 """
620 if Preferences.getHexEditor("OpenReadOnly"): 738 if Preferences.getHexEditor("OpenReadOnly"):
621 self.openAct.setStatusTip(self.tr( 739 self.openAct.setStatusTip(self.tr("Open a binary file for viewing"))
622 'Open a binary file for viewing')) 740 self.openAct.setWhatsThis(
623 self.openAct.setWhatsThis(self.tr( 741 self.tr(
624 """<b>Open File</b>""" 742 """<b>Open File</b>"""
625 """<p>This opens a binary file for viewing (i.e. in read""" 743 """<p>This opens a binary file for viewing (i.e. in read"""
626 """ only mode). It pops up a file selection dialog.</p>""" 744 """ only mode). It pops up a file selection dialog.</p>"""
627 )) 745 )
628 746 )
629 self.openReadOnlyAct.setText(self.tr('Open for Editing...')) 747
630 self.openReadOnlyAct.setIconText(self.tr('Open for Editing')) 748 self.openReadOnlyAct.setText(self.tr("Open for Editing..."))
631 self.openReadOnlyAct.setStatusTip(self.tr( 749 self.openReadOnlyAct.setIconText(self.tr("Open for Editing"))
632 'Open a binary file for editing')) 750 self.openReadOnlyAct.setStatusTip(self.tr("Open a binary file for editing"))
633 self.openReadOnlyAct.setWhatsThis(self.tr( 751 self.openReadOnlyAct.setWhatsThis(
634 """<b>Open for Editing</b>""" 752 self.tr(
635 """<p>This opens a binary file for editing.""" 753 """<b>Open for Editing</b>"""
636 """ It pops up a file selection dialog.</p>""" 754 """<p>This opens a binary file for editing."""
637 )) 755 """ It pops up a file selection dialog.</p>"""
756 )
757 )
638 else: 758 else:
639 self.openAct.setStatusTip(self.tr( 759 self.openAct.setStatusTip(self.tr("Open a binary file for editing"))
640 'Open a binary file for editing')) 760 self.openAct.setWhatsThis(
641 self.openAct.setWhatsThis(self.tr( 761 self.tr(
642 """<b>Open File</b>""" 762 """<b>Open File</b>"""
643 """<p>This opens a binary file for editing.""" 763 """<p>This opens a binary file for editing."""
644 """ It pops up a file selection dialog.</p>""" 764 """ It pops up a file selection dialog.</p>"""
645 )) 765 )
646 766 )
647 self.openReadOnlyAct.setText(self.tr('Open Read Only...')) 767
648 self.openReadOnlyAct.setIconText(self.tr('Open Read Only')) 768 self.openReadOnlyAct.setText(self.tr("Open Read Only..."))
649 self.openReadOnlyAct.setStatusTip(self.tr( 769 self.openReadOnlyAct.setIconText(self.tr("Open Read Only"))
650 'Open a binary file for viewing')) 770 self.openReadOnlyAct.setStatusTip(self.tr("Open a binary file for viewing"))
651 self.openReadOnlyAct.setWhatsThis(self.tr( 771 self.openReadOnlyAct.setWhatsThis(
652 """<b>Open Read Only</b>""" 772 self.tr(
653 """<p>This opens a binary file for viewing (i.e. in read""" 773 """<b>Open Read Only</b>"""
654 """ only mode). It pops up a file selection dialog.</p>""" 774 """<p>This opens a binary file for viewing (i.e. in read"""
655 )) 775 """ only mode). It pops up a file selection dialog.</p>"""
656 776 )
777 )
778
657 def __initMenus(self): 779 def __initMenus(self):
658 """ 780 """
659 Private method to create the menus. 781 Private method to create the menus.
660 """ 782 """
661 mb = self.menuBar() 783 mb = self.menuBar()
662 784
663 menu = mb.addMenu(self.tr('&File')) 785 menu = mb.addMenu(self.tr("&File"))
664 menu.setTearOffEnabled(True) 786 menu.setTearOffEnabled(True)
665 self.__recentMenu = QMenu(self.tr('Open &Recent Files'), menu) 787 self.__recentMenu = QMenu(self.tr("Open &Recent Files"), menu)
666 menu.addAction(self.newWindowAct) 788 menu.addAction(self.newWindowAct)
667 menu.addAction(self.openAct) 789 menu.addAction(self.openAct)
668 menu.addAction(self.openReadOnlyAct) 790 menu.addAction(self.openReadOnlyAct)
669 self.__menuRecentAct = menu.addMenu(self.__recentMenu) 791 self.__menuRecentAct = menu.addMenu(self.__recentMenu)
670 menu.addSeparator() 792 menu.addSeparator()
680 menu.addSeparator() 802 menu.addSeparator()
681 menu.addAction(self.exitAct) 803 menu.addAction(self.exitAct)
682 menu.aboutToShow.connect(self.__showFileMenu) 804 menu.aboutToShow.connect(self.__showFileMenu)
683 self.__recentMenu.aboutToShow.connect(self.__showRecentMenu) 805 self.__recentMenu.aboutToShow.connect(self.__showRecentMenu)
684 self.__recentMenu.triggered.connect(self.__openRecentHexFile) 806 self.__recentMenu.triggered.connect(self.__openRecentHexFile)
685 807
686 menu = mb.addMenu(self.tr("&Edit")) 808 menu = mb.addMenu(self.tr("&Edit"))
687 menu.setTearOffEnabled(True) 809 menu.setTearOffEnabled(True)
688 menu.addAction(self.undoAct) 810 menu.addAction(self.undoAct)
689 menu.addAction(self.redoAct) 811 menu.addAction(self.redoAct)
690 menu.addAction(self.revertAct) 812 menu.addAction(self.revertAct)
703 menu.addAction(self.replaceAct) 825 menu.addAction(self.replaceAct)
704 menu.addSeparator() 826 menu.addSeparator()
705 menu.addAction(self.gotoAct) 827 menu.addAction(self.gotoAct)
706 menu.addSeparator() 828 menu.addSeparator()
707 menu.addAction(self.readonlyAct) 829 menu.addAction(self.readonlyAct)
708 830
709 if not self.__fromEric: 831 if not self.__fromEric:
710 menu = mb.addMenu(self.tr("Se&ttings")) 832 menu = mb.addMenu(self.tr("Se&ttings"))
711 menu.setTearOffEnabled(True) 833 menu.setTearOffEnabled(True)
712 menu.addAction(self.prefAct) 834 menu.addAction(self.prefAct)
713 835
714 mb.addSeparator() 836 mb.addSeparator()
715 837
716 menu = mb.addMenu(self.tr("&Help")) 838 menu = mb.addMenu(self.tr("&Help"))
717 menu.addAction(self.aboutAct) 839 menu.addAction(self.aboutAct)
718 menu.addAction(self.aboutQtAct) 840 menu.addAction(self.aboutQtAct)
719 menu.addSeparator() 841 menu.addSeparator()
720 menu.addAction(self.whatsThisAct) 842 menu.addAction(self.whatsThisAct)
721 843
722 def __initToolbars(self): 844 def __initToolbars(self):
723 """ 845 """
724 Private method to create the toolbars. 846 Private method to create the toolbars.
725 """ 847 """
726 filetb = self.addToolBar(self.tr("File")) 848 filetb = self.addToolBar(self.tr("File"))
733 filetb.addAction(self.saveAsAct) 855 filetb.addAction(self.saveAsAct)
734 filetb.addSeparator() 856 filetb.addSeparator()
735 filetb.addAction(self.closeAct) 857 filetb.addAction(self.closeAct)
736 if not self.__fromEric: 858 if not self.__fromEric:
737 filetb.addAction(self.exitAct) 859 filetb.addAction(self.exitAct)
738 860
739 edittb = self.addToolBar(self.tr("Edit")) 861 edittb = self.addToolBar(self.tr("Edit"))
740 edittb.setObjectName("EditToolBar") 862 edittb.setObjectName("EditToolBar")
741 edittb.setIconSize(UI.Config.ToolBarIconSize) 863 edittb.setIconSize(UI.Config.ToolBarIconSize)
742 edittb.addAction(self.undoAct) 864 edittb.addAction(self.undoAct)
743 edittb.addAction(self.redoAct) 865 edittb.addAction(self.redoAct)
744 edittb.addSeparator() 866 edittb.addSeparator()
745 edittb.addAction(self.cutAct) 867 edittb.addAction(self.cutAct)
746 edittb.addAction(self.copyAct) 868 edittb.addAction(self.copyAct)
747 edittb.addAction(self.pasteAct) 869 edittb.addAction(self.pasteAct)
748 870
749 searchtb = self.addToolBar(self.tr("Find")) 871 searchtb = self.addToolBar(self.tr("Find"))
750 searchtb.setObjectName("SearchToolBar") 872 searchtb.setObjectName("SearchToolBar")
751 searchtb.setIconSize(UI.Config.ToolBarIconSize) 873 searchtb.setIconSize(UI.Config.ToolBarIconSize)
752 searchtb.addAction(self.searchAct) 874 searchtb.addAction(self.searchAct)
753 searchtb.addAction(self.searchNextAct) 875 searchtb.addAction(self.searchNextAct)
754 searchtb.addAction(self.searchPrevAct) 876 searchtb.addAction(self.searchPrevAct)
755 877
756 if not self.__fromEric: 878 if not self.__fromEric:
757 settingstb = self.addToolBar(self.tr("Settings")) 879 settingstb = self.addToolBar(self.tr("Settings"))
758 settingstb.setObjectName("SettingsToolBar") 880 settingstb.setObjectName("SettingsToolBar")
759 settingstb.setIconSize(UI.Config.ToolBarIconSize) 881 settingstb.setIconSize(UI.Config.ToolBarIconSize)
760 settingstb.addAction(self.prefAct) 882 settingstb.addAction(self.prefAct)
761 883
762 helptb = self.addToolBar(self.tr("Help")) 884 helptb = self.addToolBar(self.tr("Help"))
763 helptb.setObjectName("HelpToolBar") 885 helptb.setObjectName("HelpToolBar")
764 helptb.setIconSize(UI.Config.ToolBarIconSize) 886 helptb.setIconSize(UI.Config.ToolBarIconSize)
765 helptb.addAction(self.whatsThisAct) 887 helptb.addAction(self.whatsThisAct)
766 888
767 def __createStatusBar(self): 889 def __createStatusBar(self):
768 """ 890 """
769 Private method to initialize the status bar. 891 Private method to initialize the status bar.
770 """ 892 """
771 self.__statusBar = self.statusBar() 893 self.__statusBar = self.statusBar()
772 self.__statusBar.setSizeGripEnabled(True) 894 self.__statusBar.setSizeGripEnabled(True)
773 895
774 self.__sbAddress = QLabel(self.__statusBar) 896 self.__sbAddress = QLabel(self.__statusBar)
775 self.__statusBar.addPermanentWidget(self.__sbAddress) 897 self.__statusBar.addPermanentWidget(self.__sbAddress)
776 self.__sbAddress.setWhatsThis(self.tr( 898 self.__sbAddress.setWhatsThis(
777 """<p>This part of the status bar displays the cursor""" 899 self.tr(
778 """ address.</p>""" 900 """<p>This part of the status bar displays the cursor"""
779 )) 901 """ address.</p>"""
780 self.__sbAddress.setFrameStyle( 902 )
781 QFrame.Shape.StyledPanel | QFrame.Shadow.Plain) 903 )
782 904 self.__sbAddress.setFrameStyle(QFrame.Shape.StyledPanel | QFrame.Shadow.Plain)
905
783 self.__sbSelection = QLabel(self.__statusBar) 906 self.__sbSelection = QLabel(self.__statusBar)
784 self.__statusBar.addPermanentWidget(self.__sbSelection) 907 self.__statusBar.addPermanentWidget(self.__sbSelection)
785 self.__sbSelection.setWhatsThis(self.tr( 908 self.__sbSelection.setWhatsThis(
786 """<p>This part of the status bar displays some selection""" 909 self.tr(
787 """ information.</p>""" 910 """<p>This part of the status bar displays some selection"""
788 )) 911 """ information.</p>"""
789 self.__sbSelection.setFrameStyle( 912 )
790 QFrame.Shape.StyledPanel | QFrame.Shadow.Plain) 913 )
791 914 self.__sbSelection.setFrameStyle(QFrame.Shape.StyledPanel | QFrame.Shadow.Plain)
915
792 self.__sbSize = QLabel(self.__statusBar) 916 self.__sbSize = QLabel(self.__statusBar)
793 self.__statusBar.addPermanentWidget(self.__sbSize) 917 self.__statusBar.addPermanentWidget(self.__sbSize)
794 self.__sbSize.setWhatsThis(self.tr( 918 self.__sbSize.setWhatsThis(
795 """<p>This part of the status bar displays the size of the""" 919 self.tr(
796 """ binary data.</p>""" 920 """<p>This part of the status bar displays the size of the"""
797 )) 921 """ binary data.</p>"""
798 self.__sbSize.setFrameStyle( 922 )
799 QFrame.Shape.StyledPanel | QFrame.Shadow.Plain) 923 )
800 924 self.__sbSize.setFrameStyle(QFrame.Shape.StyledPanel | QFrame.Shadow.Plain)
925
801 self.__sbEditMode = EricClickableLabel(self.__statusBar) 926 self.__sbEditMode = EricClickableLabel(self.__statusBar)
802 self.__statusBar.addPermanentWidget(self.__sbEditMode) 927 self.__statusBar.addPermanentWidget(self.__sbEditMode)
803 self.__sbEditMode.setWhatsThis(self.tr( 928 self.__sbEditMode.setWhatsThis(
804 """<p>This part of the status bar displays the edit mode.</p>""" 929 self.tr("""<p>This part of the status bar displays the edit mode.</p>""")
805 )) 930 )
806 self.__sbEditMode.setFrameStyle( 931 self.__sbEditMode.setFrameStyle(QFrame.Shape.StyledPanel | QFrame.Shadow.Plain)
807 QFrame.Shape.StyledPanel | QFrame.Shadow.Plain)
808 self.__sbEditMode.clicked.connect(self.__toggleEditMode) 932 self.__sbEditMode.clicked.connect(self.__toggleEditMode)
809 933
810 self.__sbReadOnly = EricClickableLabel(self.__statusBar) 934 self.__sbReadOnly = EricClickableLabel(self.__statusBar)
811 self.__statusBar.addPermanentWidget(self.__sbReadOnly) 935 self.__statusBar.addPermanentWidget(self.__sbReadOnly)
812 self.__sbReadOnly.setWhatsThis(self.tr( 936 self.__sbReadOnly.setWhatsThis(
813 """<p>This part of the status bar displays the read""" 937 self.tr(
814 """ only mode.</p>""" 938 """<p>This part of the status bar displays the read"""
815 )) 939 """ only mode.</p>"""
816 self.__sbReadOnly.setFrameStyle( 940 )
817 QFrame.Shape.StyledPanel | QFrame.Shadow.Plain) 941 )
942 self.__sbReadOnly.setFrameStyle(QFrame.Shape.StyledPanel | QFrame.Shadow.Plain)
818 self.__sbReadOnly.clicked.connect(self.__toggleReadOnlyMode) 943 self.__sbReadOnly.clicked.connect(self.__toggleReadOnlyMode)
819 944
820 self.__showEditMode(self.__editor.overwriteMode()) 945 self.__showEditMode(self.__editor.overwriteMode())
821 self.__showReadOnlyMode(self.__editor.isReadOnly()) 946 self.__showReadOnlyMode(self.__editor.isReadOnly())
822 947
823 @pyqtSlot(int) 948 @pyqtSlot(int)
824 def __showAddress(self, address): 949 def __showAddress(self, address):
825 """ 950 """
826 Private slot to show the address of the cursor position. 951 Private slot to show the address of the cursor position.
827 952
828 @param address address of the cursor 953 @param address address of the cursor
829 @type int 954 @type int
830 """ 955 """
831 txt = "{0:0{1}x}".format(address, self.__editor.addressWidth()) 956 txt = "{0:0{1}x}".format(address, self.__editor.addressWidth())
832 txt = strGroup(txt, ":", 4) 957 txt = strGroup(txt, ":", 4)
833 self.__sbAddress.setText(self.tr("Address: {0}").format(txt)) 958 self.__sbAddress.setText(self.tr("Address: {0}").format(txt))
834 959
835 @pyqtSlot(bool) 960 @pyqtSlot(bool)
836 def __showSelectionInfo(self, avail): 961 def __showSelectionInfo(self, avail):
837 """ 962 """
838 Private slot to show selection information. 963 Private slot to show selection information.
839 964
840 @param avail flag indicating the availability of a selection. 965 @param avail flag indicating the availability of a selection.
841 @type bool 966 @type bool
842 """ 967 """
843 if avail: 968 if avail:
844 addrWidth = self.__editor.addressWidth() 969 addrWidth = self.__editor.addressWidth()
845 start = "{0:0{1}x}".format(self.__editor.getSelectionBegin(), 970 start = "{0:0{1}x}".format(self.__editor.getSelectionBegin(), addrWidth)
846 addrWidth)
847 start = strGroup(start, ":", 4) 971 start = strGroup(start, ":", 4)
848 end = "{0:0{1}x}".format(self.__editor.getSelectionEnd(), 972 end = "{0:0{1}x}".format(self.__editor.getSelectionEnd(), addrWidth)
849 addrWidth)
850 end = strGroup(end, ":", 4) 973 end = strGroup(end, ":", 4)
851 slen = self.__editor.getSelectionLength() 974 slen = self.__editor.getSelectionLength()
852 self.__sbSelection.setText( 975 self.__sbSelection.setText(
853 self.tr("Selection: {0} - {1} ({2} Bytes)", 976 self.tr(
854 "0: start, 1: end, 2: selection length") 977 "Selection: {0} - {1} ({2} Bytes)",
855 .format(start, end, QLocale().toString(slen)) 978 "0: start, 1: end, 2: selection length",
979 ).format(start, end, QLocale().toString(slen))
856 ) 980 )
857 else: 981 else:
858 self.__sbSelection.setText( 982 self.__sbSelection.setText(
859 self.tr("Selection: -", "no selection available")) 983 self.tr("Selection: -", "no selection available")
860 984 )
985
861 @pyqtSlot(bool) 986 @pyqtSlot(bool)
862 def __showReadOnlyMode(self, on): 987 def __showReadOnlyMode(self, on):
863 """ 988 """
864 Private slot to show the read only mode. 989 Private slot to show the read only mode.
865 990
866 @param on flag indicating the read only state 991 @param on flag indicating the read only state
867 @type bool 992 @type bool
868 """ 993 """
869 self.__sbReadOnly.setText(self.tr("ro") if on else self.tr("rw")) 994 self.__sbReadOnly.setText(self.tr("ro") if on else self.tr("rw"))
870 995
871 @pyqtSlot() 996 @pyqtSlot()
872 def __toggleReadOnlyMode(self): 997 def __toggleReadOnlyMode(self):
873 """ 998 """
874 Private slot to toggle the read only mode upon a click on the status 999 Private slot to toggle the read only mode upon a click on the status
875 bar label. 1000 bar label.
876 """ 1001 """
877 self.__editor.setReadOnly(not self.__editor.isReadOnly()) 1002 self.__editor.setReadOnly(not self.__editor.isReadOnly())
878 1003
879 @pyqtSlot(bool) 1004 @pyqtSlot(bool)
880 def __showEditMode(self, overwrite): 1005 def __showEditMode(self, overwrite):
881 """ 1006 """
882 Private slot to show the edit mode. 1007 Private slot to show the edit mode.
883 1008
884 @param overwrite flag indicating overwrite mode 1009 @param overwrite flag indicating overwrite mode
885 @type bool 1010 @type bool
886 """ 1011 """
887 self.__sbEditMode.setText( 1012 self.__sbEditMode.setText(
888 self.tr("Overwrite") if overwrite else self.tr("Insert")) 1013 self.tr("Overwrite") if overwrite else self.tr("Insert")
889 1014 )
1015
890 @pyqtSlot() 1016 @pyqtSlot()
891 def __toggleEditMode(self): 1017 def __toggleEditMode(self):
892 """ 1018 """
893 Private slot to toggle the edit mode upon a click on the status bar 1019 Private slot to toggle the edit mode upon a click on the status bar
894 label. 1020 label.
895 """ 1021 """
896 self.__editor.setOverwriteMode(not self.__editor.overwriteMode()) 1022 self.__editor.setOverwriteMode(not self.__editor.overwriteMode())
897 1023
898 @pyqtSlot(int) 1024 @pyqtSlot(int)
899 def __showSize(self, size): 1025 def __showSize(self, size):
900 """ 1026 """
901 Private slot to show the binary data size. 1027 Private slot to show the binary data size.
902 1028
903 @param size size of the binary data 1029 @param size size of the binary data
904 @type int 1030 @type int
905 """ 1031 """
906 self.__sbSize.setText( 1032 self.__sbSize.setText(self.tr("Size: {0}").format(QLocale().toString(size)))
907 self.tr("Size: {0}").format(QLocale().toString(size))) 1033
908
909 def closeEvent(self, evt): 1034 def closeEvent(self, evt):
910 """ 1035 """
911 Protected event handler for the close event. 1036 Protected event handler for the close event.
912 1037
913 @param evt reference to the close event 1038 @param evt reference to the close event
914 <br />This event is simply accepted after the history has been 1039 <br />This event is simply accepted after the history has been
915 saved and all window references have been deleted. 1040 saved and all window references have been deleted.
916 @type QCloseEvent 1041 @type QCloseEvent
917 """ 1042 """
918 if self.__maybeSave(): 1043 if self.__maybeSave():
919 state = self.saveState() 1044 state = self.saveState()
920 Preferences.setHexEditor("HexEditorState", state) 1045 Preferences.setHexEditor("HexEditorState", state)
921 1046
922 Preferences.setGeometry("HexEditorGeometry", self.saveGeometry()) 1047 Preferences.setGeometry("HexEditorGeometry", self.saveGeometry())
923 1048
924 with contextlib.suppress(ValueError): 1049 with contextlib.suppress(ValueError):
925 if self.__fromEric or len(self.__class__.windows) > 1: 1050 if self.__fromEric or len(self.__class__.windows) > 1:
926 del self.__class__.windows[ 1051 del self.__class__.windows[self.__class__.windows.index(self)]
927 self.__class__.windows.index(self)] 1052
928
929 if not self.__fromEric: 1053 if not self.__fromEric:
930 Preferences.syncPreferences() 1054 Preferences.syncPreferences()
931 1055
932 self.__saveRecent() 1056 self.__saveRecent()
933 1057
934 evt.accept() 1058 evt.accept()
935 self.editorClosed.emit() 1059 self.editorClosed.emit()
936 else: 1060 else:
937 evt.ignore() 1061 evt.ignore()
938 1062
939 def __openHexFileNewWindow(self): 1063 def __openHexFileNewWindow(self):
940 """ 1064 """
941 Private slot called to open a binary file in new hex editor window. 1065 Private slot called to open a binary file in new hex editor window.
942 """ 1066 """
943 if ( 1067 if (
944 not self.__lastOpenPath and 1068 not self.__lastOpenPath
945 self.__project is not None and 1069 and self.__project is not None
946 self.__project.isOpen() 1070 and self.__project.isOpen()
947 ): 1071 ):
948 self.__lastOpenPath = self.__project.getProjectPath() 1072 self.__lastOpenPath = self.__project.getProjectPath()
949 1073
950 fileName = EricFileDialog.getOpenFileName( 1074 fileName = EricFileDialog.getOpenFileName(
951 self, 1075 self,
952 self.tr("Open binary file in new window"), 1076 self.tr("Open binary file in new window"),
953 self.__lastOpenPath, 1077 self.__lastOpenPath,
954 self.tr("All Files (*)")) 1078 self.tr("All Files (*)"),
1079 )
955 if fileName: 1080 if fileName:
956 he = HexEditMainWindow(fileName=fileName, 1081 he = HexEditMainWindow(
957 parent=self.parent(), 1082 fileName=fileName,
958 fromEric=self.__fromEric, 1083 parent=self.parent(),
959 project=self.__project) 1084 fromEric=self.__fromEric,
1085 project=self.__project,
1086 )
960 he.setRecentPaths("", self.__lastSavePath) 1087 he.setRecentPaths("", self.__lastSavePath)
961 he.show() 1088 he.show()
962 1089
963 def __maybeSave(self): 1090 def __maybeSave(self):
964 """ 1091 """
965 Private method to ask the user to save the file, if it was modified. 1092 Private method to ask the user to save the file, if it was modified.
966 1093
967 @return flag indicating, if it is ok to continue 1094 @return flag indicating, if it is ok to continue
968 @rtype bool 1095 @rtype bool
969 """ 1096 """
970 if self.__editor.isModified(): 1097 if self.__editor.isModified():
971 ret = EricMessageBox.okToClearData( 1098 ret = EricMessageBox.okToClearData(
972 self, 1099 self,
973 self.tr("eric Hex Editor"), 1100 self.tr("eric Hex Editor"),
974 self.tr("""The loaded file has unsaved changes."""), 1101 self.tr("""The loaded file has unsaved changes."""),
975 self.__saveHexFile) 1102 self.__saveHexFile,
1103 )
976 if not ret: 1104 if not ret:
977 return False 1105 return False
978 return True 1106 return True
979 1107
980 def __loadHexFile(self, fileName): 1108 def __loadHexFile(self, fileName):
981 """ 1109 """
982 Private method to load a binary file. 1110 Private method to load a binary file.
983 1111
984 @param fileName name of the binary file to load 1112 @param fileName name of the binary file to load
985 @type str 1113 @type str
986 """ 1114 """
987 if not os.path.exists(fileName): 1115 if not os.path.exists(fileName):
988 EricMessageBox.warning( 1116 EricMessageBox.warning(
989 self, self.tr("eric Hex Editor"), 1117 self,
990 self.tr("The file '{0}' does not exist.") 1118 self.tr("eric Hex Editor"),
991 .format(fileName)) 1119 self.tr("The file '{0}' does not exist.").format(fileName),
1120 )
992 return 1121 return
993 1122
994 try: 1123 try:
995 with open(fileName, "rb") as f: 1124 with open(fileName, "rb") as f:
996 data = f.read() 1125 data = f.read()
997 except OSError as err: 1126 except OSError as err:
998 EricMessageBox.warning( 1127 EricMessageBox.warning(
999 self, self.tr("eric Hex Editor"), 1128 self,
1000 self.tr("<p>Cannot read file <b>{0}</b>.</p>" 1129 self.tr("eric Hex Editor"),
1001 "<p>Reason: {1}</p>") 1130 self.tr(
1002 .format(fileName, str(err))) 1131 "<p>Cannot read file <b>{0}</b>.</p>" "<p>Reason: {1}</p>"
1132 ).format(fileName, str(err)),
1133 )
1003 return 1134 return
1004 1135
1005 self.__lastOpenPath = os.path.dirname(fileName) 1136 self.__lastOpenPath = os.path.dirname(fileName)
1006 self.__editor.setData(data) 1137 self.__editor.setData(data)
1007 self.__setCurrentFile(fileName) 1138 self.__setCurrentFile(fileName)
1008 1139
1009 self.__editor.setReadOnly(Preferences.getHexEditor("OpenReadOnly")) 1140 self.__editor.setReadOnly(Preferences.getHexEditor("OpenReadOnly"))
1010 1141
1011 self.__gotoWidget.reset() 1142 self.__gotoWidget.reset()
1012 1143
1013 def __openHexFile(self): 1144 def __openHexFile(self):
1014 """ 1145 """
1015 Private slot to open a binary file. 1146 Private slot to open a binary file.
1016 """ 1147 """
1017 if self.__maybeSave(): 1148 if self.__maybeSave():
1018 if ( 1149 if (
1019 not self.__lastOpenPath and 1150 not self.__lastOpenPath
1020 self.__project is not None and 1151 and self.__project is not None
1021 self.__project.isOpen() 1152 and self.__project.isOpen()
1022 ): 1153 ):
1023 self.__lastOpenPath = self.__project.getProjectPath() 1154 self.__lastOpenPath = self.__project.getProjectPath()
1024 1155
1025 fileName = EricFileDialog.getOpenFileName( 1156 fileName = EricFileDialog.getOpenFileName(
1026 self, 1157 self,
1027 self.tr("Open binary file"), 1158 self.tr("Open binary file"),
1028 self.__lastOpenPath, 1159 self.__lastOpenPath,
1029 self.tr("All Files (*)")) 1160 self.tr("All Files (*)"),
1161 )
1030 if fileName: 1162 if fileName:
1031 self.__loadHexFile(fileName) 1163 self.__loadHexFile(fileName)
1032 self.__checkActions() 1164 self.__checkActions()
1033 1165
1034 def __openHexFileReadOnly(self): 1166 def __openHexFileReadOnly(self):
1035 """ 1167 """
1036 Private slot to open a binary file in read only mode. 1168 Private slot to open a binary file in read only mode.
1037 """ 1169 """
1038 self.__openHexFile() 1170 self.__openHexFile()
1039 self.__editor.setReadOnly(not Preferences.getHexEditor("OpenReadOnly")) 1171 self.__editor.setReadOnly(not Preferences.getHexEditor("OpenReadOnly"))
1040 self.__checkActions() 1172 self.__checkActions()
1041 1173
1042 def __saveHexFile(self): 1174 def __saveHexFile(self):
1043 """ 1175 """
1044 Private method to save a binary file. 1176 Private method to save a binary file.
1045 1177
1046 @return flag indicating success 1178 @return flag indicating success
1047 @rtype bool 1179 @rtype bool
1048 """ 1180 """
1049 ok = ( 1181 ok = (
1050 self.__saveHexDataFile(self.__fileName) 1182 self.__saveHexDataFile(self.__fileName)
1051 if self.__fileName else 1183 if self.__fileName
1052 self.__saveHexFileAs() 1184 else self.__saveHexFileAs()
1053 ) 1185 )
1054 1186
1055 if ok: 1187 if ok:
1056 self.__editor.undoStack().setClean() 1188 self.__editor.undoStack().setClean()
1057 1189
1058 return ok 1190 return ok
1059 1191
1060 def __saveHexFileAs(self): 1192 def __saveHexFileAs(self):
1061 """ 1193 """
1062 Private method to save the data to a new file. 1194 Private method to save the data to a new file.
1063 1195
1064 @return flag indicating success 1196 @return flag indicating success
1065 @rtype bool 1197 @rtype bool
1066 """ 1198 """
1067 if ( 1199 if (
1068 not self.__lastSavePath and 1200 not self.__lastSavePath
1069 self.__project is not None and 1201 and self.__project is not None
1070 self.__project.isOpen() 1202 and self.__project.isOpen()
1071 ): 1203 ):
1072 self.__lastSavePath = self.__project.getProjectPath() 1204 self.__lastSavePath = self.__project.getProjectPath()
1073 if not self.__lastSavePath and self.__lastOpenPath: 1205 if not self.__lastSavePath and self.__lastOpenPath:
1074 self.__lastSavePath = self.__lastOpenPath 1206 self.__lastSavePath = self.__lastOpenPath
1075 1207
1076 fileName = EricFileDialog.getSaveFileName( 1208 fileName = EricFileDialog.getSaveFileName(
1077 self, 1209 self,
1078 self.tr("Save binary file"), 1210 self.tr("Save binary file"),
1079 self.__lastSavePath, 1211 self.__lastSavePath,
1080 self.tr("All Files (*)"), 1212 self.tr("All Files (*)"),
1081 EricFileDialog.DontConfirmOverwrite) 1213 EricFileDialog.DontConfirmOverwrite,
1214 )
1082 if not fileName: 1215 if not fileName:
1083 return False 1216 return False
1084 1217
1085 if pathlib.Path(fileName).exists(): 1218 if pathlib.Path(fileName).exists():
1086 res = EricMessageBox.yesNo( 1219 res = EricMessageBox.yesNo(
1087 self, 1220 self,
1088 self.tr("Save binary file"), 1221 self.tr("Save binary file"),
1089 self.tr("<p>The file <b>{0}</b> already exists." 1222 self.tr(
1090 " Overwrite it?</p>").format(fileName), 1223 "<p>The file <b>{0}</b> already exists." " Overwrite it?</p>"
1091 icon=EricMessageBox.Warning) 1224 ).format(fileName),
1225 icon=EricMessageBox.Warning,
1226 )
1092 if not res: 1227 if not res:
1093 return False 1228 return False
1094 1229
1095 self.__lastSavePath = os.path.dirname(fileName) 1230 self.__lastSavePath = os.path.dirname(fileName)
1096 1231
1097 return self.__saveHexDataFile(fileName) 1232 return self.__saveHexDataFile(fileName)
1098 1233
1099 def __saveHexDataFile(self, fileName): 1234 def __saveHexDataFile(self, fileName):
1100 """ 1235 """
1101 Private method to save the binary data to a file. 1236 Private method to save the binary data to a file.
1102 1237
1103 @param fileName name of the file to write to 1238 @param fileName name of the file to write to
1104 @type str 1239 @type str
1105 @return flag indicating success 1240 @return flag indicating success
1106 @rtype bool 1241 @rtype bool
1107 """ 1242 """
1108 try: 1243 try:
1109 with open(fileName, "wb") as f: 1244 with open(fileName, "wb") as f:
1110 f.write(self.__editor.data()) 1245 f.write(self.__editor.data())
1111 except OSError as err: 1246 except OSError as err:
1112 EricMessageBox.warning( 1247 EricMessageBox.warning(
1113 self, self.tr("eric Hex Editor"), 1248 self,
1114 self.tr("<p>Cannot write file <b>{0}</b>.</p>" 1249 self.tr("eric Hex Editor"),
1115 "<p>Reason: {1}</p>") 1250 self.tr(
1116 .format(fileName, str(err))) 1251 "<p>Cannot write file <b>{0}</b>.</p>" "<p>Reason: {1}</p>"
1252 ).format(fileName, str(err)),
1253 )
1117 self.__checkActions() 1254 self.__checkActions()
1118 return False 1255 return False
1119 1256
1120 self.__editor.setModified(False, setCleanState=True) 1257 self.__editor.setModified(False, setCleanState=True)
1121 1258
1122 self.__setCurrentFile(fileName) 1259 self.__setCurrentFile(fileName)
1123 self.__statusBar.showMessage(self.tr("File saved"), 2000) 1260 self.__statusBar.showMessage(self.tr("File saved"), 2000)
1124 1261
1125 self.__checkActions() 1262 self.__checkActions()
1126 1263
1127 return True 1264 return True
1128 1265
1129 def __saveHexFileReadable(self, selectionOnly=False): 1266 def __saveHexFileReadable(self, selectionOnly=False):
1130 """ 1267 """
1131 Private method to save the binary data in readable format. 1268 Private method to save the binary data in readable format.
1132 1269
1133 @param selectionOnly flag indicating to save the selection only 1270 @param selectionOnly flag indicating to save the selection only
1134 @type bool 1271 @type bool
1135 """ 1272 """
1136 savePath = self.__lastSavePath 1273 savePath = self.__lastSavePath
1137 if ( 1274 if not savePath and self.__project is not None and self.__project.isOpen():
1138 not savePath and
1139 self.__project is not None and
1140 self.__project.isOpen()
1141 ):
1142 savePath = self.__project.getProjectPath() 1275 savePath = self.__project.getProjectPath()
1143 if not savePath and self.__lastOpenPath: 1276 if not savePath and self.__lastOpenPath:
1144 savePath = self.__lastOpenPath 1277 savePath = self.__lastOpenPath
1145 1278
1146 fileName, selectedFilter = EricFileDialog.getSaveFileNameAndFilter( 1279 fileName, selectedFilter = EricFileDialog.getSaveFileNameAndFilter(
1147 self, 1280 self,
1148 self.tr("Save to readable file"), 1281 self.tr("Save to readable file"),
1149 savePath, 1282 savePath,
1150 self.tr("Text Files (*.txt);;All Files (*)"), 1283 self.tr("Text Files (*.txt);;All Files (*)"),
1151 self.tr("Text Files (*.txt)"), 1284 self.tr("Text Files (*.txt)"),
1152 EricFileDialog.DontConfirmOverwrite) 1285 EricFileDialog.DontConfirmOverwrite,
1286 )
1153 if not fileName: 1287 if not fileName:
1154 return 1288 return
1155 1289
1156 fpath = pathlib.Path(fileName) 1290 fpath = pathlib.Path(fileName)
1157 if not fpath.suffix: 1291 if not fpath.suffix:
1158 ex = selectedFilter.split("(*")[1].split(")")[0] 1292 ex = selectedFilter.split("(*")[1].split(")")[0]
1159 if ex: 1293 if ex:
1160 fpath = fpath.with_suffix(ex) 1294 fpath = fpath.with_suffix(ex)
1161 if fpath.exists(): 1295 if fpath.exists():
1162 res = EricMessageBox.yesNo( 1296 res = EricMessageBox.yesNo(
1163 self, 1297 self,
1164 self.tr("Save to readable file"), 1298 self.tr("Save to readable file"),
1165 self.tr("<p>The file <b>{0}</b> already exists." 1299 self.tr(
1166 " Overwrite it?</p>").format(fpath), 1300 "<p>The file <b>{0}</b> already exists." " Overwrite it?</p>"
1167 icon=EricMessageBox.Warning) 1301 ).format(fpath),
1302 icon=EricMessageBox.Warning,
1303 )
1168 if not res: 1304 if not res:
1169 return 1305 return
1170 1306
1171 readableData = ( 1307 readableData = (
1172 self.__editor.selectionToReadableString() 1308 self.__editor.selectionToReadableString()
1173 if selectionOnly else 1309 if selectionOnly
1174 self.__editor.toReadableString() 1310 else self.__editor.toReadableString()
1175 ) 1311 )
1176 try: 1312 try:
1177 with fpath.open("w", encoding="latin1") as f: 1313 with fpath.open("w", encoding="latin1") as f:
1178 f.write(readableData) 1314 f.write(readableData)
1179 except OSError as err: 1315 except OSError as err:
1180 EricMessageBox.warning( 1316 EricMessageBox.warning(
1181 self, self.tr("eric Hex Editor"), 1317 self,
1182 self.tr("<p>Cannot write file <b>{0}</b>.</p>" 1318 self.tr("eric Hex Editor"),
1183 "<p>Reason: {1}</p>") 1319 self.tr(
1184 .format(fpath, str(err))) 1320 "<p>Cannot write file <b>{0}</b>.</p>" "<p>Reason: {1}</p>"
1321 ).format(fpath, str(err)),
1322 )
1185 return 1323 return
1186 1324
1187 self.__statusBar.showMessage(self.tr("File saved"), 2000) 1325 self.__statusBar.showMessage(self.tr("File saved"), 2000)
1188 1326
1189 def __saveSelectionReadable(self): 1327 def __saveSelectionReadable(self):
1190 """ 1328 """
1191 Private method to save the data of the current selection in readable 1329 Private method to save the data of the current selection in readable
1192 format. 1330 format.
1193 """ 1331 """
1194 self.__saveHexFileReadable(selectionOnly=True) 1332 self.__saveHexFileReadable(selectionOnly=True)
1195 1333
1196 def __closeAll(self): 1334 def __closeAll(self):
1197 """ 1335 """
1198 Private slot to close all windows. 1336 Private slot to close all windows.
1199 """ 1337 """
1200 self.__closeOthers() 1338 self.__closeOthers()
1201 self.close() 1339 self.close()
1202 1340
1203 def __closeOthers(self): 1341 def __closeOthers(self):
1204 """ 1342 """
1205 Private slot to close all other windows. 1343 Private slot to close all other windows.
1206 """ 1344 """
1207 for win in self.__class__.windows[:]: 1345 for win in self.__class__.windows[:]:
1209 win.close() 1347 win.close()
1210 1348
1211 def __setCurrentFile(self, fileName): 1349 def __setCurrentFile(self, fileName):
1212 """ 1350 """
1213 Private method to register the file name of the current file. 1351 Private method to register the file name of the current file.
1214 1352
1215 @param fileName name of the file to register 1353 @param fileName name of the file to register
1216 @type str 1354 @type str
1217 """ 1355 """
1218 self.__fileName = fileName 1356 self.__fileName = fileName
1219 # insert filename into list of recently opened files 1357 # insert filename into list of recently opened files
1220 self.__addToRecentList(fileName) 1358 self.__addToRecentList(fileName)
1221 1359
1222 shownName = ( 1360 shownName = (
1223 self.tr("Untitled") 1361 self.tr("Untitled")
1224 if not self.__fileName else 1362 if not self.__fileName
1225 self.__strippedName(self.__fileName) 1363 else self.__strippedName(self.__fileName)
1226 ) 1364 )
1227 1365
1228 self.setWindowTitle(self.tr("{0}[*] - {1}") 1366 self.setWindowTitle(
1229 .format(shownName, self.tr("Hex Editor"))) 1367 self.tr("{0}[*] - {1}").format(shownName, self.tr("Hex Editor"))
1230 1368 )
1369
1231 self.setWindowModified(self.__editor.isModified()) 1370 self.setWindowModified(self.__editor.isModified())
1232 1371
1233 def __strippedName(self, fullFileName): 1372 def __strippedName(self, fullFileName):
1234 """ 1373 """
1235 Private method to return the filename part of the given path. 1374 Private method to return the filename part of the given path.
1236 1375
1237 @param fullFileName full pathname of the given file 1376 @param fullFileName full pathname of the given file
1238 @type str 1377 @type str
1239 @return filename part 1378 @return filename part
1240 @rtype str 1379 @rtype str
1241 """ 1380 """
1242 return pathlib.Path(fullFileName).name 1381 return pathlib.Path(fullFileName).name
1243 1382
1244 def setRecentPaths(self, openPath, savePath): 1383 def setRecentPaths(self, openPath, savePath):
1245 """ 1384 """
1246 Public method to set the last open and save paths. 1385 Public method to set the last open and save paths.
1247 1386
1248 @param openPath least recently used open path 1387 @param openPath least recently used open path
1249 @type str 1388 @type str
1250 @param savePath least recently used save path 1389 @param savePath least recently used save path
1251 @type str 1390 @type str
1252 """ 1391 """
1253 if openPath: 1392 if openPath:
1254 self.__lastOpenPath = openPath 1393 self.__lastOpenPath = openPath
1255 if savePath: 1394 if savePath:
1256 self.__lastSavePath = savePath 1395 self.__lastSavePath = savePath
1257 1396
1258 @pyqtSlot() 1397 @pyqtSlot()
1259 def __checkActions(self): 1398 def __checkActions(self):
1260 """ 1399 """
1261 Private slot to check some actions for their enable/disable status. 1400 Private slot to check some actions for their enable/disable status.
1262 """ 1401 """
1263 self.saveAct.setEnabled(self.__editor.isModified()) 1402 self.saveAct.setEnabled(self.__editor.isModified())
1264 1403
1265 self.cutAct.setEnabled(not self.__editor.isReadOnly() and 1404 self.cutAct.setEnabled(
1266 self.__editor.hasSelection()) 1405 not self.__editor.isReadOnly() and self.__editor.hasSelection()
1406 )
1267 self.pasteAct.setEnabled(not self.__editor.isReadOnly()) 1407 self.pasteAct.setEnabled(not self.__editor.isReadOnly())
1268 self.replaceAct.setEnabled(not self.__editor.isReadOnly()) 1408 self.replaceAct.setEnabled(not self.__editor.isReadOnly())
1269 1409
1270 @pyqtSlot(bool) 1410 @pyqtSlot(bool)
1271 def __modificationChanged(self, m): 1411 def __modificationChanged(self, m):
1272 """ 1412 """
1273 Private slot to handle the dataChanged signal. 1413 Private slot to handle the dataChanged signal.
1274 1414
1275 @param m modification status 1415 @param m modification status
1276 @type bool 1416 @type bool
1277 """ 1417 """
1278 self.setWindowModified(m) 1418 self.setWindowModified(m)
1279 self.__checkActions() 1419 self.__checkActions()
1280 1420
1281 def __about(self): 1421 def __about(self):
1282 """ 1422 """
1283 Private slot to show a little About message. 1423 Private slot to show a little About message.
1284 """ 1424 """
1285 EricMessageBox.about( 1425 EricMessageBox.about(
1286 self, self.tr("About eric Hex Editor"), 1426 self,
1287 self.tr("The eric Hex Editor is a simple editor component" 1427 self.tr("About eric Hex Editor"),
1288 " to edit binary files.")) 1428 self.tr(
1289 1429 "The eric Hex Editor is a simple editor component"
1430 " to edit binary files."
1431 ),
1432 )
1433
1290 def __aboutQt(self): 1434 def __aboutQt(self):
1291 """ 1435 """
1292 Private slot to handle the About Qt dialog. 1436 Private slot to handle the About Qt dialog.
1293 """ 1437 """
1294 EricMessageBox.aboutQt(self, "eric Hex Editor") 1438 EricMessageBox.aboutQt(self, "eric Hex Editor")
1295 1439
1296 def __whatsThis(self): 1440 def __whatsThis(self):
1297 """ 1441 """
1298 Private slot called in to enter Whats This mode. 1442 Private slot called in to enter Whats This mode.
1299 """ 1443 """
1300 QWhatsThis.enterWhatsThisMode() 1444 QWhatsThis.enterWhatsThisMode()
1301 1445
1302 def __search(self): 1446 def __search(self):
1303 """ 1447 """
1304 Private method to handle the search action. 1448 Private method to handle the search action.
1305 """ 1449 """
1306 self.__replaceWidget.hide() 1450 self.__replaceWidget.hide()
1307 self.__gotoWidget.hide() 1451 self.__gotoWidget.hide()
1308 txt = ( 1452 txt = (
1309 self.__editor.selectionToHexString() 1453 self.__editor.selectionToHexString() if self.__editor.hasSelection() else ""
1310 if self.__editor.hasSelection() else
1311 ""
1312 ) 1454 )
1313 self.__searchWidget.show(txt) 1455 self.__searchWidget.show(txt)
1314 1456
1315 def __replace(self): 1457 def __replace(self):
1316 """ 1458 """
1317 Private method to handle the replace action. 1459 Private method to handle the replace action.
1318 """ 1460 """
1319 self.__searchWidget.hide() 1461 self.__searchWidget.hide()
1320 self.__gotoWidget.hide() 1462 self.__gotoWidget.hide()
1321 txt = ( 1463 txt = (
1322 self.__editor.selectionToHexString() 1464 self.__editor.selectionToHexString() if self.__editor.hasSelection() else ""
1323 if self.__editor.hasSelection() else
1324 ""
1325 ) 1465 )
1326 self.__replaceWidget.show(txt) 1466 self.__replaceWidget.show(txt)
1327 1467
1328 def __goto(self): 1468 def __goto(self):
1329 """ 1469 """
1330 Private method to handle the goto action. 1470 Private method to handle the goto action.
1331 """ 1471 """
1332 self.__searchWidget.hide() 1472 self.__searchWidget.hide()
1333 self.__replaceWidget.hide() 1473 self.__replaceWidget.hide()
1334 self.__gotoWidget.show() 1474 self.__gotoWidget.show()
1335 1475
1336 def preferencesChanged(self): 1476 def preferencesChanged(self):
1337 """ 1477 """
1338 Public method to (re-)read the various settings. 1478 Public method to (re-)read the various settings.
1339 """ 1479 """
1340 self.__editor.setAddressWidth( 1480 self.__editor.setAddressWidth(Preferences.getHexEditor("AddressAreaWidth"))
1341 Preferences.getHexEditor("AddressAreaWidth")) 1481 self.__editor.setAddressArea(Preferences.getHexEditor("ShowAddressArea"))
1342 self.__editor.setAddressArea( 1482 self.__editor.setAsciiArea(Preferences.getHexEditor("ShowAsciiArea"))
1343 Preferences.getHexEditor("ShowAddressArea")) 1483 self.__editor.setHighlighting(Preferences.getHexEditor("HighlightChanges"))
1344 self.__editor.setAsciiArea( 1484 self.__editor.setFont(Preferences.getHexEditor("Font"))
1345 Preferences.getHexEditor("ShowAsciiArea")) 1485
1346 self.__editor.setHighlighting(
1347 Preferences.getHexEditor("HighlightChanges"))
1348 self.__editor.setFont(
1349 Preferences.getHexEditor("Font"))
1350
1351 self.__setReadOnlyActionTexts() 1486 self.__setReadOnlyActionTexts()
1352 1487
1353 def __showPreferences(self): 1488 def __showPreferences(self):
1354 """ 1489 """
1355 Private slot to set the preferences. 1490 Private slot to set the preferences.
1356 """ 1491 """
1357 from Preferences.ConfigurationDialog import ( 1492 from Preferences.ConfigurationDialog import (
1358 ConfigurationDialog, ConfigurationMode 1493 ConfigurationDialog,
1359 ) 1494 ConfigurationMode,
1495 )
1496
1360 dlg = ConfigurationDialog( 1497 dlg = ConfigurationDialog(
1361 None, 'Configuration', True, fromEric=True, 1498 None,
1362 displayMode=ConfigurationMode.HEXEDITORMODE) 1499 "Configuration",
1500 True,
1501 fromEric=True,
1502 displayMode=ConfigurationMode.HEXEDITORMODE,
1503 )
1363 dlg.preferencesChanged.connect( 1504 dlg.preferencesChanged.connect(
1364 self.__preferencesChangedByLocalPreferencesDialog) 1505 self.__preferencesChangedByLocalPreferencesDialog
1506 )
1365 dlg.show() 1507 dlg.show()
1366 dlg.showConfigurationPageByName("hexEditorPage") 1508 dlg.showConfigurationPageByName("hexEditorPage")
1367 dlg.exec() 1509 dlg.exec()
1368 QCoreApplication.processEvents() 1510 QCoreApplication.processEvents()
1369 if dlg.result() == QDialog.DialogCode.Accepted: 1511 if dlg.result() == QDialog.DialogCode.Accepted:
1370 dlg.setPreferences() 1512 dlg.setPreferences()
1371 Preferences.syncPreferences() 1513 Preferences.syncPreferences()
1372 self.__preferencesChangedByLocalPreferencesDialog() 1514 self.__preferencesChangedByLocalPreferencesDialog()
1373 1515
1374 def __preferencesChangedByLocalPreferencesDialog(self): 1516 def __preferencesChangedByLocalPreferencesDialog(self):
1375 """ 1517 """
1376 Private slot to handle preferences changes by our local dialog. 1518 Private slot to handle preferences changes by our local dialog.
1377 """ 1519 """
1378 for hexEditor in HexEditMainWindow.windows: 1520 for hexEditor in HexEditMainWindow.windows:
1379 hexEditor.preferencesChanged() 1521 hexEditor.preferencesChanged()
1380 1522
1381 def getSRHistory(self, key): 1523 def getSRHistory(self, key):
1382 """ 1524 """
1383 Public method to get the search or replace history list. 1525 Public method to get the search or replace history list.
1384 1526
1385 @param key name of list to return 1527 @param key name of list to return
1386 @type str (must be 'search' or 'replace') 1528 @type str (must be 'search' or 'replace')
1387 @return the requested history list 1529 @return the requested history list
1388 @rtype list of tuples of (int, str) 1530 @rtype list of tuples of (int, str)
1389 """ 1531 """
1390 if key in ['search', 'replace']: 1532 if key in ["search", "replace"]:
1391 return self.__srHistory[key] 1533 return self.__srHistory[key]
1392 1534
1393 return [] 1535 return []
1394 1536
1395 @pyqtSlot() 1537 @pyqtSlot()
1396 def __showFileMenu(self): 1538 def __showFileMenu(self):
1397 """ 1539 """
1398 Private slot to modify the file menu before being shown. 1540 Private slot to modify the file menu before being shown.
1399 """ 1541 """
1400 self.__menuRecentAct.setEnabled(len(self.__recent) > 0) 1542 self.__menuRecentAct.setEnabled(len(self.__recent) > 0)
1401 1543
1402 @pyqtSlot() 1544 @pyqtSlot()
1403 def __showRecentMenu(self): 1545 def __showRecentMenu(self):
1404 """ 1546 """
1405 Private slot to set up the recent files menu. 1547 Private slot to set up the recent files menu.
1406 """ 1548 """
1407 self.__loadRecent() 1549 self.__loadRecent()
1408 1550
1409 self.__recentMenu.clear() 1551 self.__recentMenu.clear()
1410 1552
1411 for idx, rs in enumerate(self.__recent, start=1): 1553 for idx, rs in enumerate(self.__recent, start=1):
1412 formatStr = '&{0:d}. {1}' if idx < 10 else '{0:d}. {1}' 1554 formatStr = "&{0:d}. {1}" if idx < 10 else "{0:d}. {1}"
1413 act = self.__recentMenu.addAction( 1555 act = self.__recentMenu.addAction(
1414 formatStr.format( 1556 formatStr.format(
1415 idx, 1557 idx, Utilities.compactPath(rs, HexEditMainWindow.maxMenuFilePathLen)
1416 Utilities.compactPath( 1558 )
1417 rs, HexEditMainWindow.maxMenuFilePathLen))) 1559 )
1418 act.setData(rs) 1560 act.setData(rs)
1419 act.setEnabled(pathlib.Path(rs).exists()) 1561 act.setEnabled(pathlib.Path(rs).exists())
1420 1562
1421 self.__recentMenu.addSeparator() 1563 self.__recentMenu.addSeparator()
1422 self.__recentMenu.addAction(self.tr('&Clear'), self.__clearRecent) 1564 self.__recentMenu.addAction(self.tr("&Clear"), self.__clearRecent)
1423 1565
1424 @pyqtSlot(QAction) 1566 @pyqtSlot(QAction)
1425 def __openRecentHexFile(self, act): 1567 def __openRecentHexFile(self, act):
1426 """ 1568 """
1427 Private method to open a file from the list of recently opened files. 1569 Private method to open a file from the list of recently opened files.
1428 1570
1429 @param act reference to the action that triggered (QAction) 1571 @param act reference to the action that triggered (QAction)
1430 """ 1572 """
1431 fileName = act.data() 1573 fileName = act.data()
1432 if fileName and self.__maybeSave(): 1574 if fileName and self.__maybeSave():
1433 self.__loadHexFile(fileName) 1575 self.__loadHexFile(fileName)
1434 self.__editor.setReadOnly(Preferences.getHexEditor("OpenReadOnly")) 1576 self.__editor.setReadOnly(Preferences.getHexEditor("OpenReadOnly"))
1435 self.__checkActions() 1577 self.__checkActions()
1436 1578
1437 @pyqtSlot() 1579 @pyqtSlot()
1438 def __clearRecent(self): 1580 def __clearRecent(self):
1439 """ 1581 """
1440 Private method to clear the list of recently opened files. 1582 Private method to clear the list of recently opened files.
1441 """ 1583 """
1442 self.__recent = [] 1584 self.__recent = []
1443 1585
1444 def __loadRecent(self): 1586 def __loadRecent(self):
1445 """ 1587 """
1446 Private method to load the list of recently opened files. 1588 Private method to load the list of recently opened files.
1447 """ 1589 """
1448 self.__recent = [] 1590 self.__recent = []
1450 rs = Preferences.Prefs.rsettings.value(recentNameHexFiles) 1592 rs = Preferences.Prefs.rsettings.value(recentNameHexFiles)
1451 if rs is not None: 1593 if rs is not None:
1452 for f in Preferences.toList(rs): 1594 for f in Preferences.toList(rs):
1453 if pathlib.Path(f).exists(): 1595 if pathlib.Path(f).exists():
1454 self.__recent.append(f) 1596 self.__recent.append(f)
1455 1597
1456 def __saveRecent(self): 1598 def __saveRecent(self):
1457 """ 1599 """
1458 Private method to save the list of recently opened files. 1600 Private method to save the list of recently opened files.
1459 """ 1601 """
1460 Preferences.Prefs.rsettings.setValue(recentNameHexFiles, self.__recent) 1602 Preferences.Prefs.rsettings.setValue(recentNameHexFiles, self.__recent)
1461 Preferences.Prefs.rsettings.sync() 1603 Preferences.Prefs.rsettings.sync()
1462 1604
1463 def __addToRecentList(self, fileName): 1605 def __addToRecentList(self, fileName):
1464 """ 1606 """
1465 Private method to add a file name to the list of recently opened files. 1607 Private method to add a file name to the list of recently opened files.
1466 1608
1467 @param fileName name of the file to be added 1609 @param fileName name of the file to be added
1468 """ 1610 """
1469 if fileName: 1611 if fileName:
1470 for recent in self.__recent[:]: 1612 for recent in self.__recent[:]:
1471 if Utilities.samepath(fileName, recent): 1613 if Utilities.samepath(fileName, recent):

eric ide

mercurial