src/eric7/HexEdit/HexEditSearchReplaceWidget.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
19 19
20 class HexEditSearchReplaceWidget(QWidget): 20 class HexEditSearchReplaceWidget(QWidget):
21 """ 21 """
22 Class implementing a search and replace widget for the hex editor. 22 Class implementing a search and replace widget for the hex editor.
23 """ 23 """
24
24 def __init__(self, editor, mainWindow, replace=False, parent=None): 25 def __init__(self, editor, mainWindow, replace=False, parent=None):
25 """ 26 """
26 Constructor 27 Constructor
27 28
28 @param editor reference to the hex editor widget 29 @param editor reference to the hex editor widget
29 @type HexEditWidget 30 @type HexEditWidget
30 @param mainWindow reference to the main window 31 @param mainWindow reference to the main window
31 @type HexEditMainWindow 32 @type HexEditMainWindow
32 @param replace flag indicating a replace widget 33 @param replace flag indicating a replace widget
33 @type bool 34 @type bool
34 @param parent reference to the parent widget 35 @param parent reference to the parent widget
35 @type QWidget 36 @type QWidget
36 """ 37 """
37 super().__init__(parent) 38 super().__init__(parent)
38 39
39 self.__replace = replace 40 self.__replace = replace
40 self.__editor = editor 41 self.__editor = editor
41 42
42 # keep this in sync with the logic in __getContent() 43 # keep this in sync with the logic in __getContent()
43 self.__formatAndValidators = { 44 self.__formatAndValidators = {
44 "hex": (self.tr("Hex"), QRegularExpressionValidator( 45 "hex": (
45 QRegularExpression("[0-9a-f]*"))), 46 self.tr("Hex"),
46 "dec": (self.tr("Dec"), QRegularExpressionValidator( 47 QRegularExpressionValidator(QRegularExpression("[0-9a-f]*")),
47 QRegularExpression("[0-9]*"))), 48 ),
48 "oct": (self.tr("Oct"), QRegularExpressionValidator( 49 "dec": (
49 QRegularExpression("[0-7]*"))), 50 self.tr("Dec"),
50 "bin": (self.tr("Bin"), QRegularExpressionValidator( 51 QRegularExpressionValidator(QRegularExpression("[0-9]*")),
51 QRegularExpression("[01]*"))), 52 ),
53 "oct": (
54 self.tr("Oct"),
55 QRegularExpressionValidator(QRegularExpression("[0-7]*")),
56 ),
57 "bin": (
58 self.tr("Bin"),
59 QRegularExpressionValidator(QRegularExpression("[01]*")),
60 ),
52 "iso-8859-1": (self.tr("Text"), None), 61 "iso-8859-1": (self.tr("Text"), None),
53 # text as latin-1/iso-8859-1 62 # text as latin-1/iso-8859-1
54 "utf-8": (self.tr("UTF-8"), None), 63 "utf-8": (self.tr("UTF-8"), None),
55 # text as utf-8 64 # text as utf-8
56 } 65 }
57 formatOrder = ["hex", "dec", "oct", "bin", "iso-8859-1", "utf-8"] 66 formatOrder = ["hex", "dec", "oct", "bin", "iso-8859-1", "utf-8"]
58 67
59 self.__currentFindFormat = "" 68 self.__currentFindFormat = ""
60 self.__currentReplaceFormat = "" 69 self.__currentReplaceFormat = ""
61 70
62 self.__findHistory = mainWindow.getSRHistory("search") 71 self.__findHistory = mainWindow.getSRHistory("search")
63 if replace: 72 if replace:
64 from .Ui_HexEditReplaceWidget import Ui_HexEditReplaceWidget 73 from .Ui_HexEditReplaceWidget import Ui_HexEditReplaceWidget
74
65 self.__replaceHistory = mainWindow.getSRHistory("replace") 75 self.__replaceHistory = mainWindow.getSRHistory("replace")
66 self.__ui = Ui_HexEditReplaceWidget() 76 self.__ui = Ui_HexEditReplaceWidget()
67 else: 77 else:
68 from .Ui_HexEditSearchWidget import Ui_HexEditSearchWidget 78 from .Ui_HexEditSearchWidget import Ui_HexEditSearchWidget
79
69 self.__ui = Ui_HexEditSearchWidget() 80 self.__ui = Ui_HexEditSearchWidget()
70 self.__ui.setupUi(self) 81 self.__ui.setupUi(self)
71 82
72 self.__ui.closeButton.setIcon(UI.PixmapCache.getIcon("close")) 83 self.__ui.closeButton.setIcon(UI.PixmapCache.getIcon("close"))
73 self.__ui.findPrevButton.setIcon( 84 self.__ui.findPrevButton.setIcon(UI.PixmapCache.getIcon("1leftarrow"))
74 UI.PixmapCache.getIcon("1leftarrow")) 85 self.__ui.findNextButton.setIcon(UI.PixmapCache.getIcon("1rightarrow"))
75 self.__ui.findNextButton.setIcon( 86
76 UI.PixmapCache.getIcon("1rightarrow"))
77
78 if replace: 87 if replace:
79 self.__ui.replaceButton.setIcon( 88 self.__ui.replaceButton.setIcon(UI.PixmapCache.getIcon("editReplace"))
80 UI.PixmapCache.getIcon("editReplace"))
81 self.__ui.replaceSearchButton.setIcon( 89 self.__ui.replaceSearchButton.setIcon(
82 UI.PixmapCache.getIcon("editReplaceSearch")) 90 UI.PixmapCache.getIcon("editReplaceSearch")
83 self.__ui.replaceAllButton.setIcon( 91 )
84 UI.PixmapCache.getIcon("editReplaceAll")) 92 self.__ui.replaceAllButton.setIcon(UI.PixmapCache.getIcon("editReplaceAll"))
85 93
86 for dataFormat in formatOrder: 94 for dataFormat in formatOrder:
87 formatStr, validator = self.__formatAndValidators[dataFormat] 95 formatStr, validator = self.__formatAndValidators[dataFormat]
88 self.__ui.findFormatCombo.addItem(formatStr, dataFormat) 96 self.__ui.findFormatCombo.addItem(formatStr, dataFormat)
89 if replace: 97 if replace:
90 for dataFormat in formatOrder: 98 for dataFormat in formatOrder:
91 formatStr, validator = self.__formatAndValidators[dataFormat] 99 formatStr, validator = self.__formatAndValidators[dataFormat]
92 self.__ui.replaceFormatCombo.addItem(formatStr, dataFormat) 100 self.__ui.replaceFormatCombo.addItem(formatStr, dataFormat)
93 101
94 self.__ui.findtextCombo.setCompleter(None) 102 self.__ui.findtextCombo.setCompleter(None)
95 self.__ui.findtextCombo.lineEdit().returnPressed.connect( 103 self.__ui.findtextCombo.lineEdit().returnPressed.connect(
96 self.__findByReturnPressed) 104 self.__findByReturnPressed
105 )
97 if replace: 106 if replace:
98 self.__ui.replacetextCombo.setCompleter(None) 107 self.__ui.replacetextCombo.setCompleter(None)
99 self.__ui.replacetextCombo.lineEdit().returnPressed.connect( 108 self.__ui.replacetextCombo.lineEdit().returnPressed.connect(
100 self.on_replaceButton_clicked) 109 self.on_replaceButton_clicked
101 110 )
111
102 self.findNextAct = EricAction( 112 self.findNextAct = EricAction(
103 self.tr('Find Next'), 113 self.tr("Find Next"),
104 self.tr('Find Next'), 114 self.tr("Find Next"),
105 0, 0, self, 'hexEditor_search_widget_find_next') 115 0,
116 0,
117 self,
118 "hexEditor_search_widget_find_next",
119 )
106 self.findNextAct.triggered.connect(self.on_findNextButton_clicked) 120 self.findNextAct.triggered.connect(self.on_findNextButton_clicked)
107 self.findNextAct.setEnabled(False) 121 self.findNextAct.setEnabled(False)
108 self.__ui.findtextCombo.addAction(self.findNextAct) 122 self.__ui.findtextCombo.addAction(self.findNextAct)
109 123
110 self.findPrevAct = EricAction( 124 self.findPrevAct = EricAction(
111 self.tr('Find Prev'), 125 self.tr("Find Prev"),
112 self.tr('Find Prev'), 126 self.tr("Find Prev"),
113 0, 0, self, 'hexEditor_search_widget_find_prev') 127 0,
128 0,
129 self,
130 "hexEditor_search_widget_find_prev",
131 )
114 self.findPrevAct.triggered.connect(self.on_findPrevButton_clicked) 132 self.findPrevAct.triggered.connect(self.on_findPrevButton_clicked)
115 self.findPrevAct.setEnabled(False) 133 self.findPrevAct.setEnabled(False)
116 self.__ui.findtextCombo.addAction(self.findPrevAct) 134 self.__ui.findtextCombo.addAction(self.findPrevAct)
117 135
118 self.__havefound = False 136 self.__havefound = False
119 137
120 @pyqtSlot(int) 138 @pyqtSlot(int)
121 def on_findFormatCombo_currentIndexChanged(self, idx): 139 def on_findFormatCombo_currentIndexChanged(self, idx):
122 """ 140 """
123 Private slot to handle a selection from the find format. 141 Private slot to handle a selection from the find format.
124 142
125 @param idx index of the selected entry 143 @param idx index of the selected entry
126 @type int 144 @type int
127 """ 145 """
128 if idx >= 0: 146 if idx >= 0:
129 findFormat = self.__ui.findFormatCombo.itemData(idx) 147 findFormat = self.__ui.findFormatCombo.itemData(idx)
130 148
131 if findFormat != self.__currentFindFormat: 149 if findFormat != self.__currentFindFormat:
132 txt = self.__ui.findtextCombo.currentText() 150 txt = self.__ui.findtextCombo.currentText()
133 newTxt = self.__convertText( 151 newTxt = self.__convertText(txt, self.__currentFindFormat, findFormat)
134 txt, self.__currentFindFormat, findFormat)
135 self.__currentFindFormat = findFormat 152 self.__currentFindFormat = findFormat
136 153
137 self.__ui.findtextCombo.setValidator( 154 self.__ui.findtextCombo.setValidator(
138 self.__formatAndValidators[findFormat][1]) 155 self.__formatAndValidators[findFormat][1]
139 156 )
157
140 self.__ui.findtextCombo.setEditText(newTxt) 158 self.__ui.findtextCombo.setEditText(newTxt)
141 159
142 @pyqtSlot(str) 160 @pyqtSlot(str)
143 def on_findtextCombo_editTextChanged(self, txt): 161 def on_findtextCombo_editTextChanged(self, txt):
144 """ 162 """
145 Private slot to enable/disable the find buttons. 163 Private slot to enable/disable the find buttons.
146 164
147 @param txt text of the find text combo 165 @param txt text of the find text combo
148 @type str 166 @type str
149 """ 167 """
150 if not txt: 168 if not txt:
151 self.__ui.findNextButton.setEnabled(False) 169 self.__ui.findNextButton.setEnabled(False)
163 self.findPrevAct.setEnabled(True) 181 self.findPrevAct.setEnabled(True)
164 if self.__replace: 182 if self.__replace:
165 self.__ui.replaceButton.setEnabled(False) 183 self.__ui.replaceButton.setEnabled(False)
166 self.__ui.replaceSearchButton.setEnabled(False) 184 self.__ui.replaceSearchButton.setEnabled(False)
167 self.__ui.replaceAllButton.setEnabled(True) 185 self.__ui.replaceAllButton.setEnabled(True)
168 186
169 @pyqtSlot(int) 187 @pyqtSlot(int)
170 def on_findtextCombo_activated(self, idx): 188 def on_findtextCombo_activated(self, idx):
171 """ 189 """
172 Private slot to handle a selection from the find history. 190 Private slot to handle a selection from the find history.
173 191
174 @param idx index of the selected entry 192 @param idx index of the selected entry
175 @type int 193 @type int
176 """ 194 """
177 if idx >= 0: 195 if idx >= 0:
178 formatIndex = self.__ui.findtextCombo.itemData(idx) 196 formatIndex = self.__ui.findtextCombo.itemData(idx)
179 if formatIndex is not None: 197 if formatIndex is not None:
180 self.__ui.findFormatCombo.setCurrentIndex(formatIndex) 198 self.__ui.findFormatCombo.setCurrentIndex(formatIndex)
181 199
182 def __getContent(self, replace=False): 200 def __getContent(self, replace=False):
183 """ 201 """
184 Private method to get the contents of the find/replace combo as 202 Private method to get the contents of the find/replace combo as
185 a bytearray. 203 a bytearray.
186 204
187 @param replace flag indicating to retrieve the replace contents 205 @param replace flag indicating to retrieve the replace contents
188 @type bool 206 @type bool
189 @return search or replace term as text and binary data 207 @return search or replace term as text and binary data
190 @rtype tuple of bytearray and str 208 @rtype tuple of bytearray and str
191 """ 209 """
195 history = self.__replaceHistory 213 history = self.__replaceHistory
196 else: 214 else:
197 textCombo = self.__ui.findtextCombo 215 textCombo = self.__ui.findtextCombo
198 formatCombo = self.__ui.findFormatCombo 216 formatCombo = self.__ui.findFormatCombo
199 history = self.__findHistory 217 history = self.__findHistory
200 218
201 txt = textCombo.currentText() 219 txt = textCombo.currentText()
202 idx = formatCombo.currentIndex() 220 idx = formatCombo.currentIndex()
203 findFormat = formatCombo.itemData(idx) 221 findFormat = formatCombo.itemData(idx)
204 ba = self.__text2bytearray(txt, findFormat) 222 ba = self.__text2bytearray(txt, findFormat)
205 223
206 # This moves any previous occurrence of this statement to the head 224 # This moves any previous occurrence of this statement to the head
207 # of the list and updates the combobox 225 # of the list and updates the combobox
208 historyEntry = (idx, txt) 226 historyEntry = (idx, txt)
209 if historyEntry in history: 227 if historyEntry in history:
210 history.remove(historyEntry) 228 history.remove(historyEntry)
211 history.insert(0, historyEntry) 229 history.insert(0, historyEntry)
212 textCombo.clear() 230 textCombo.clear()
213 for index, text in history: 231 for index, text in history:
214 textCombo.addItem(text, index) 232 textCombo.addItem(text, index)
215 233
216 return ba, txt 234 return ba, txt
217 235
218 @pyqtSlot() 236 @pyqtSlot()
219 def on_findNextButton_clicked(self): 237 def on_findNextButton_clicked(self):
220 """ 238 """
221 Private slot to find the next occurrence. 239 Private slot to find the next occurrence.
222 """ 240 """
223 self.findPrevNext(False) 241 self.findPrevNext(False)
224 242
225 @pyqtSlot() 243 @pyqtSlot()
226 def on_findPrevButton_clicked(self): 244 def on_findPrevButton_clicked(self):
227 """ 245 """
228 Private slot to find the previous occurrence. 246 Private slot to find the previous occurrence.
229 """ 247 """
230 self.findPrevNext(True) 248 self.findPrevNext(True)
231 249
232 def findPrevNext(self, prev=False): 250 def findPrevNext(self, prev=False):
233 """ 251 """
234 Public slot to find the next occurrence of the search term. 252 Public slot to find the next occurrence of the search term.
235 253
236 @param prev flag indicating a backwards search 254 @param prev flag indicating a backwards search
237 @type bool 255 @type bool
238 @return flag indicating a successful search 256 @return flag indicating a successful search
239 @rtype bool 257 @rtype bool
240 """ 258 """
241 if not self.__havefound or not self.__ui.findtextCombo.currentText(): 259 if not self.__havefound or not self.__ui.findtextCombo.currentText():
242 self.show() 260 self.show()
243 return False 261 return False
244 262
245 self.__findBackwards = prev 263 self.__findBackwards = prev
246 ba, txt = self.__getContent() 264 ba, txt = self.__getContent()
247 265
248 idx = -1 266 idx = -1
249 if len(ba) > 0: 267 if len(ba) > 0:
250 startIndex = self.__editor.cursorPosition() // 2 268 startIndex = self.__editor.cursorPosition() // 2
251 if prev: 269 if prev:
252 if ( 270 if (
253 self.__editor.hasSelection() and 271 self.__editor.hasSelection()
254 startIndex == self.__editor.getSelectionEnd() 272 and startIndex == self.__editor.getSelectionEnd()
255 ): 273 ):
256 # skip to the selection start 274 # skip to the selection start
257 startIndex = self.__editor.getSelectionBegin() 275 startIndex = self.__editor.getSelectionBegin()
258 idx = self.__editor.lastIndexOf(ba, startIndex) 276 idx = self.__editor.lastIndexOf(ba, startIndex)
259 else: 277 else:
260 if ( 278 if (
261 self.__editor.hasSelection() and 279 self.__editor.hasSelection()
262 startIndex == self.__editor.getSelectionBegin() - 1 280 and startIndex == self.__editor.getSelectionBegin() - 1
263 ): 281 ):
264 # skip to the selection end 282 # skip to the selection end
265 startIndex = self.__editor.getSelectionEnd() 283 startIndex = self.__editor.getSelectionEnd()
266 idx = self.__editor.indexOf(ba, startIndex) 284 idx = self.__editor.indexOf(ba, startIndex)
267 285
268 if idx >= 0: 286 if idx >= 0:
269 if self.__replace: 287 if self.__replace:
270 self.__ui.replaceButton.setEnabled(True) 288 self.__ui.replaceButton.setEnabled(True)
271 self.__ui.replaceSearchButton.setEnabled(True) 289 self.__ui.replaceSearchButton.setEnabled(True)
272 else: 290 else:
273 EricMessageBox.information( 291 EricMessageBox.information(
274 self, self.windowTitle(), 292 self, self.windowTitle(), self.tr("'{0}' was not found.").format(txt)
275 self.tr("'{0}' was not found.").format(txt)) 293 )
276 294
277 return idx >= 0 295 return idx >= 0
278 296
279 def __findByReturnPressed(self): 297 def __findByReturnPressed(self):
280 """ 298 """
281 Private slot to handle a return pressed in the find combo. 299 Private slot to handle a return pressed in the find combo.
282 """ 300 """
283 if self.__findBackwards: 301 if self.__findBackwards:
284 self.findPrevNext(True) 302 self.findPrevNext(True)
285 else: 303 else:
286 self.findPrevNext(False) 304 self.findPrevNext(False)
287 305
288 @pyqtSlot(int) 306 @pyqtSlot(int)
289 def on_replaceFormatCombo_currentIndexChanged(self, idx): 307 def on_replaceFormatCombo_currentIndexChanged(self, idx):
290 """ 308 """
291 Private slot to handle a selection from the replace format. 309 Private slot to handle a selection from the replace format.
292 310
293 @param idx index of the selected entry 311 @param idx index of the selected entry
294 @type int 312 @type int
295 """ 313 """
296 if idx >= 0: 314 if idx >= 0:
297 replaceFormat = self.__ui.replaceFormatCombo.itemData(idx) 315 replaceFormat = self.__ui.replaceFormatCombo.itemData(idx)
298 316
299 if replaceFormat != self.__currentReplaceFormat: 317 if replaceFormat != self.__currentReplaceFormat:
300 txt = self.__ui.replacetextCombo.currentText() 318 txt = self.__ui.replacetextCombo.currentText()
301 newTxt = self.__convertText( 319 newTxt = self.__convertText(
302 txt, self.__currentReplaceFormat, replaceFormat) 320 txt, self.__currentReplaceFormat, replaceFormat
321 )
303 self.__currentReplaceFormat = replaceFormat 322 self.__currentReplaceFormat = replaceFormat
304 323
305 self.__ui.replacetextCombo.setValidator( 324 self.__ui.replacetextCombo.setValidator(
306 self.__formatAndValidators[replaceFormat][1]) 325 self.__formatAndValidators[replaceFormat][1]
307 326 )
327
308 self.__ui.replacetextCombo.setEditText(newTxt) 328 self.__ui.replacetextCombo.setEditText(newTxt)
309 329
310 @pyqtSlot(int) 330 @pyqtSlot(int)
311 def on_replacetextCombo_activated(self, idx): 331 def on_replacetextCombo_activated(self, idx):
312 """ 332 """
313 Private slot to handle a selection from the replace history. 333 Private slot to handle a selection from the replace history.
314 334
315 @param idx index of the selected entry 335 @param idx index of the selected entry
316 @type int 336 @type int
317 """ 337 """
318 if idx >= 0: 338 if idx >= 0:
319 formatIndex = self.__ui.replacetextCombo.itemData(idx) 339 formatIndex = self.__ui.replacetextCombo.itemData(idx)
324 def on_replaceButton_clicked(self): 344 def on_replaceButton_clicked(self):
325 """ 345 """
326 Private slot to replace one occurrence of data. 346 Private slot to replace one occurrence of data.
327 """ 347 """
328 self.__doReplace(False) 348 self.__doReplace(False)
329 349
330 @pyqtSlot() 350 @pyqtSlot()
331 def on_replaceSearchButton_clicked(self): 351 def on_replaceSearchButton_clicked(self):
332 """ 352 """
333 Private slot to replace one occurrence of data and search for the next 353 Private slot to replace one occurrence of data and search for the next
334 one. 354 one.
335 """ 355 """
336 self.__doReplace(True) 356 self.__doReplace(True)
337 357
338 def __doReplace(self, searchNext): 358 def __doReplace(self, searchNext):
339 """ 359 """
340 Private method to replace one occurrence of data. 360 Private method to replace one occurrence of data.
341 361
342 @param searchNext flag indicating to search for the next occurrence 362 @param searchNext flag indicating to search for the next occurrence
343 @type bool 363 @type bool
344 """ 364 """
345 # Check enabled status due to dual purpose usage of this method 365 # Check enabled status due to dual purpose usage of this method
346 if ( 366 if (
347 not self.__ui.replaceButton.isEnabled() and 367 not self.__ui.replaceButton.isEnabled()
348 not self.__ui.replaceSearchButton.isEnabled() 368 and not self.__ui.replaceSearchButton.isEnabled()
349 ): 369 ):
350 return 370 return
351 371
352 fba, ftxt = self.__getContent(False) 372 fba, ftxt = self.__getContent(False)
353 rba, rtxt = self.__getContent(True) 373 rba, rtxt = self.__getContent(True)
354 374
355 ok = False 375 ok = False
356 if self.__editor.hasSelection(): 376 if self.__editor.hasSelection():
357 # we did a successful search before 377 # we did a successful search before
358 startIdx = self.__editor.getSelectionBegin() 378 startIdx = self.__editor.getSelectionBegin()
359 self.__editor.replaceByteArray(startIdx, len(fba), rba) 379 self.__editor.replaceByteArray(startIdx, len(fba), rba)
360 380
361 if searchNext: 381 if searchNext:
362 ok = self.findPrevNext(self.__findBackwards) 382 ok = self.findPrevNext(self.__findBackwards)
363 383
364 if not ok: 384 if not ok:
365 self.__ui.replaceButton.setEnabled(False) 385 self.__ui.replaceButton.setEnabled(False)
366 self.__ui.replaceSearchButton.setEnabled(False) 386 self.__ui.replaceSearchButton.setEnabled(False)
367 387
368 @pyqtSlot() 388 @pyqtSlot()
369 def on_replaceAllButton_clicked(self): 389 def on_replaceAllButton_clicked(self):
370 """ 390 """
371 Private slot to replace all occurrences of data. 391 Private slot to replace all occurrences of data.
372 """ 392 """
373 replacements = 0 393 replacements = 0
374 394
375 cursorPosition = self.__editor.cursorPosition() 395 cursorPosition = self.__editor.cursorPosition()
376 396
377 fba, ftxt = self.__getContent(False) 397 fba, ftxt = self.__getContent(False)
378 rba, rtxt = self.__getContent(True) 398 rba, rtxt = self.__getContent(True)
379 399
380 idx = 0 400 idx = 0
381 while idx >= 0: 401 while idx >= 0:
382 idx = self.__editor.indexOf(fba, idx) 402 idx = self.__editor.indexOf(fba, idx)
383 if idx >= 0: 403 if idx >= 0:
384 self.__editor.replaceByteArray(idx, len(fba), rba) 404 self.__editor.replaceByteArray(idx, len(fba), rba)
385 idx += len(rba) 405 idx += len(rba)
386 replacements += 1 406 replacements += 1
387 407
388 if replacements: 408 if replacements:
389 EricMessageBox.information( 409 EricMessageBox.information(
390 self, self.windowTitle(), 410 self,
391 self.tr("Replaced {0} occurrences.") 411 self.windowTitle(),
392 .format(replacements)) 412 self.tr("Replaced {0} occurrences.").format(replacements),
413 )
393 else: 414 else:
394 EricMessageBox.information( 415 EricMessageBox.information(
395 self, self.windowTitle(), 416 self,
396 self.tr("Nothing replaced because '{0}' was not found.") 417 self.windowTitle(),
397 .format(ftxt)) 418 self.tr("Nothing replaced because '{0}' was not found.").format(ftxt),
398 419 )
420
399 self.__editor.setCursorPosition(cursorPosition) 421 self.__editor.setCursorPosition(cursorPosition)
400 self.__editor.ensureVisible() 422 self.__editor.ensureVisible()
401 423
402 def __showFind(self, text=''): 424 def __showFind(self, text=""):
403 """ 425 """
404 Private method to display this widget in find mode. 426 Private method to display this widget in find mode.
405 427
406 @param text hex encoded text to be shown in the findtext edit 428 @param text hex encoded text to be shown in the findtext edit
407 @type str 429 @type str
408 """ 430 """
409 self.__replace = False 431 self.__replace = False
410 432
411 self.__ui.findtextCombo.clear() 433 self.__ui.findtextCombo.clear()
412 for index, txt in self.__findHistory: 434 for index, txt in self.__findHistory:
413 self.__ui.findtextCombo.addItem(txt, index) 435 self.__ui.findtextCombo.addItem(txt, index)
414 self.__ui.findFormatCombo.setCurrentIndex(0) # 0 is always Hex 436 self.__ui.findFormatCombo.setCurrentIndex(0) # 0 is always Hex
415 self.on_findFormatCombo_currentIndexChanged(0) 437 self.on_findFormatCombo_currentIndexChanged(0)
416 self.__ui.findtextCombo.setEditText(text) 438 self.__ui.findtextCombo.setEditText(text)
417 self.__ui.findtextCombo.lineEdit().selectAll() 439 self.__ui.findtextCombo.lineEdit().selectAll()
418 self.__ui.findtextCombo.setFocus() 440 self.__ui.findtextCombo.setFocus()
419 self.on_findtextCombo_editTextChanged(text) 441 self.on_findtextCombo_editTextChanged(text)
420 442
421 self.__havefound = True 443 self.__havefound = True
422 self.__findBackwards = False 444 self.__findBackwards = False
423 445
424 def __showReplace(self, text=''): 446 def __showReplace(self, text=""):
425 """ 447 """
426 Private slot to display this widget in replace mode. 448 Private slot to display this widget in replace mode.
427 449
428 @param text hex encoded text to be shown in the findtext edit 450 @param text hex encoded text to be shown in the findtext edit
429 @type str 451 @type str
430 """ 452 """
431 self.__replace = True 453 self.__replace = True
432 454
433 self.__ui.findtextCombo.clear() 455 self.__ui.findtextCombo.clear()
434 for index, txt in self.__findHistory: 456 for index, txt in self.__findHistory:
435 self.__ui.findtextCombo.addItem(txt, index) 457 self.__ui.findtextCombo.addItem(txt, index)
436 self.__ui.findFormatCombo.setCurrentIndex(0) # 0 is always Hex 458 self.__ui.findFormatCombo.setCurrentIndex(0) # 0 is always Hex
437 self.on_findFormatCombo_currentIndexChanged(0) 459 self.on_findFormatCombo_currentIndexChanged(0)
438 self.__ui.findtextCombo.setEditText(text) 460 self.__ui.findtextCombo.setEditText(text)
439 self.__ui.findtextCombo.lineEdit().selectAll() 461 self.__ui.findtextCombo.lineEdit().selectAll()
440 self.__ui.findtextCombo.setFocus() 462 self.__ui.findtextCombo.setFocus()
441 self.on_findtextCombo_editTextChanged(text) 463 self.on_findtextCombo_editTextChanged(text)
442 464
443 self.__ui.replacetextCombo.clear() 465 self.__ui.replacetextCombo.clear()
444 for index, txt in self.__replaceHistory: 466 for index, txt in self.__replaceHistory:
445 self.__ui.replacetextCombo.addItem(txt, index) 467 self.__ui.replacetextCombo.addItem(txt, index)
446 self.__ui.replaceFormatCombo.setCurrentIndex(0) # 0 is always Hex 468 self.__ui.replaceFormatCombo.setCurrentIndex(0) # 0 is always Hex
447 self.on_replaceFormatCombo_currentIndexChanged(0) 469 self.on_replaceFormatCombo_currentIndexChanged(0)
448 self.__ui.replacetextCombo.setEditText('') 470 self.__ui.replacetextCombo.setEditText("")
449 471
450 self.__havefound = True 472 self.__havefound = True
451 self.__findBackwards = False 473 self.__findBackwards = False
452 474
453 def show(self, text=''): 475 def show(self, text=""):
454 """ 476 """
455 Public slot to show the widget. 477 Public slot to show the widget.
456 478
457 @param text hex encoded text to be shown in the findtext edit 479 @param text hex encoded text to be shown in the findtext edit
458 @type str 480 @type str
459 """ 481 """
460 if self.__replace: 482 if self.__replace:
461 self.__showReplace(text) 483 self.__showReplace(text)
462 else: 484 else:
463 self.__showFind(text) 485 self.__showFind(text)
464 super().show() 486 super().show()
465 self.activateWindow() 487 self.activateWindow()
466 488
467 @pyqtSlot() 489 @pyqtSlot()
468 def on_closeButton_clicked(self): 490 def on_closeButton_clicked(self):
469 """ 491 """
470 Private slot to close the widget. 492 Private slot to close the widget.
471 """ 493 """
473 self.close() 495 self.close()
474 496
475 def keyPressEvent(self, event): 497 def keyPressEvent(self, event):
476 """ 498 """
477 Protected slot to handle key press events. 499 Protected slot to handle key press events.
478 500
479 @param event reference to the key press event 501 @param event reference to the key press event
480 @type QKeyEvent 502 @type QKeyEvent
481 """ 503 """
482 if event.key() == Qt.Key.Key_Escape: 504 if event.key() == Qt.Key.Key_Escape:
483 self.close() 505 self.close()
484 506
485 def __convertText(self, txt, oldFormat, newFormat): 507 def __convertText(self, txt, oldFormat, newFormat):
486 """ 508 """
487 Private method to convert text from one format into another. 509 Private method to convert text from one format into another.
488 510
489 @param txt text to be converted 511 @param txt text to be converted
490 @type str 512 @type str
491 @param oldFormat current format of the text 513 @param oldFormat current format of the text
492 @type str 514 @type str
493 @param newFormat format to convert to 515 @param newFormat format to convert to
496 @rtype str 518 @rtype str
497 """ 519 """
498 if txt and oldFormat and newFormat and oldFormat != newFormat: 520 if txt and oldFormat and newFormat and oldFormat != newFormat:
499 # step 1: convert the text to a byte array using the old format 521 # step 1: convert the text to a byte array using the old format
500 byteArray = self.__text2bytearray(txt, oldFormat) 522 byteArray = self.__text2bytearray(txt, oldFormat)
501 523
502 # step 2: convert the byte array to text using the new format 524 # step 2: convert the byte array to text using the new format
503 txt = self.__bytearray2text(byteArray, newFormat) 525 txt = self.__bytearray2text(byteArray, newFormat)
504 526
505 return txt 527 return txt
506 528
507 def __int2bytearray(self, value): 529 def __int2bytearray(self, value):
508 """ 530 """
509 Private method to convert an integer to a byte array. 531 Private method to convert an integer to a byte array.
510 532
511 @param value value to be converted 533 @param value value to be converted
512 @type int 534 @type int
513 @return byte array for the given value 535 @return byte array for the given value
514 @rtype bytearray 536 @rtype bytearray
515 """ 537 """
516 ba = bytearray() 538 ba = bytearray()
517 while value > 0: 539 while value > 0:
518 value, modulus = divmod(value, 256) 540 value, modulus = divmod(value, 256)
519 ba.insert(0, modulus) 541 ba.insert(0, modulus)
520 542
521 return ba 543 return ba
522 544
523 def __bytearray2int(self, array): 545 def __bytearray2int(self, array):
524 """ 546 """
525 Private method to convert a byte array to an integer value. 547 Private method to convert a byte array to an integer value.
526 548
527 @param array byte array to be converted 549 @param array byte array to be converted
528 @type bytearray 550 @type bytearray
529 @return integer value of the given array 551 @return integer value of the given array
530 @rtype int 552 @rtype int
531 """ 553 """
532 value = 0 554 value = 0
533 for b in array: 555 for b in array:
534 value = value * 256 + b 556 value = value * 256 + b
535 557
536 return value 558 return value
537 559
538 def __text2bytearray(self, txt, dataFormat): 560 def __text2bytearray(self, txt, dataFormat):
539 """ 561 """
540 Private method to convert a text to a byte array. 562 Private method to convert a text to a byte array.
541 563
542 @param txt text to be converted 564 @param txt text to be converted
543 @type str 565 @type str
544 @param dataFormat format of the text 566 @param dataFormat format of the text
545 @type str 567 @type str
546 @return converted text 568 @return converted text
548 @exception ValueError raised to indicate an invalid dataFormat 570 @exception ValueError raised to indicate an invalid dataFormat
549 parameter 571 parameter
550 """ 572 """
551 if dataFormat not in self.__formatAndValidators.keys(): 573 if dataFormat not in self.__formatAndValidators.keys():
552 raise ValueError("Bad value for 'dataFormat' parameter.") 574 raise ValueError("Bad value for 'dataFormat' parameter.")
553 575
554 if dataFormat == "hex": # hex format 576 if dataFormat == "hex": # hex format
555 ba = bytearray(QByteArray.fromHex( 577 ba = bytearray(QByteArray.fromHex(bytes(txt, encoding="ascii")))
556 bytes(txt, encoding="ascii"))) 578 elif dataFormat == "dec": # decimal format
557 elif dataFormat == "dec": # decimal format
558 ba = self.__int2bytearray(int(txt, 10)) 579 ba = self.__int2bytearray(int(txt, 10))
559 elif dataFormat == "oct": # octal format 580 elif dataFormat == "oct": # octal format
560 ba = self.__int2bytearray(int(txt, 8)) 581 ba = self.__int2bytearray(int(txt, 8))
561 elif dataFormat == "bin": # binary format 582 elif dataFormat == "bin": # binary format
562 ba = self.__int2bytearray(int(txt, 2)) 583 ba = self.__int2bytearray(int(txt, 2))
563 elif dataFormat == "iso-8859-1": # latin-1/iso-8859-1 text 584 elif dataFormat == "iso-8859-1": # latin-1/iso-8859-1 text
564 ba = bytearray(txt, encoding="iso-8859-1") 585 ba = bytearray(txt, encoding="iso-8859-1")
565 elif dataFormat == "utf-8": # utf-8 text 586 elif dataFormat == "utf-8": # utf-8 text
566 ba = bytearray(txt, encoding="utf-8") 587 ba = bytearray(txt, encoding="utf-8")
567 588
568 return ba 589 return ba
569 590
570 def __bytearray2text(self, array, dataFormat): 591 def __bytearray2text(self, array, dataFormat):
571 """ 592 """
572 Private method to convert a byte array to a text. 593 Private method to convert a byte array to a text.
573 594
574 @param array byte array to be converted 595 @param array byte array to be converted
575 @type bytearray 596 @type bytearray
576 @param dataFormat format of the text 597 @param dataFormat format of the text
577 @type str 598 @type str
578 @return formatted text 599 @return formatted text
580 @exception ValueError raised to indicate an invalid dataFormat 601 @exception ValueError raised to indicate an invalid dataFormat
581 parameter 602 parameter
582 """ 603 """
583 if dataFormat not in self.__formatAndValidators.keys(): 604 if dataFormat not in self.__formatAndValidators.keys():
584 raise ValueError("Bad value for 'dataFormat' parameter.") 605 raise ValueError("Bad value for 'dataFormat' parameter.")
585 606
586 if dataFormat == "hex": # hex format 607 if dataFormat == "hex": # hex format
587 txt = "{0:x}".format(self.__bytearray2int(array)) 608 txt = "{0:x}".format(self.__bytearray2int(array))
588 elif dataFormat == "dec": # decimal format 609 elif dataFormat == "dec": # decimal format
589 txt = "{0:d}".format(self.__bytearray2int(array)) 610 txt = "{0:d}".format(self.__bytearray2int(array))
590 elif dataFormat == "oct": # octal format 611 elif dataFormat == "oct": # octal format
591 txt = "{0:o}".format(self.__bytearray2int(array)) 612 txt = "{0:o}".format(self.__bytearray2int(array))
592 elif dataFormat == "bin": # binary format 613 elif dataFormat == "bin": # binary format
593 txt = "{0:b}".format(self.__bytearray2int(array)) 614 txt = "{0:b}".format(self.__bytearray2int(array))
594 elif dataFormat == "iso-8859-1": # latin-1/iso-8859-1 text 615 elif dataFormat == "iso-8859-1": # latin-1/iso-8859-1 text
595 txt = str(array, encoding="iso-8859-1") 616 txt = str(array, encoding="iso-8859-1")
596 elif dataFormat == "utf-8": # utf-8 text 617 elif dataFormat == "utf-8": # utf-8 text
597 txt = str(array, encoding="utf-8", errors="replace") 618 txt = str(array, encoding="utf-8", errors="replace")
598 619
599 return txt 620 return txt

eric ide

mercurial