17 from E5Gui import E5MessageBox |
17 from E5Gui import E5MessageBox |
18 |
18 |
19 import UI.PixmapCache |
19 import UI.PixmapCache |
20 |
20 |
21 |
21 |
22 # TODO: add more format types (Dec, Oct, Bin, UTF-8) |
22 # TODO: add more format types (Dec, Oct, Bin) |
23 # TODO: change the text of the combo when the format changes |
23 # TODO: change the text of the combo when the format changes |
24 class HexEditSearchReplaceWidget(QWidget): |
24 class HexEditSearchReplaceWidget(QWidget): |
25 """ |
25 """ |
26 Class implementing a search and replace widget for the hex editor. |
26 Class implementing a search and replace widget for the hex editor. |
27 """ |
27 """ |
41 super(HexEditSearchReplaceWidget, self).__init__(parent) |
41 super(HexEditSearchReplaceWidget, self).__init__(parent) |
42 |
42 |
43 self.__replace = replace |
43 self.__replace = replace |
44 self.__editor = editor |
44 self.__editor = editor |
45 |
45 |
46 self.__formatAndValidators = [ |
46 # keep this in sync with the logic in __getContent() |
47 (self.tr("Hex"), QRegExpValidator((QRegExp("[0-9a-f]*")))), |
47 self.__formatAndValidators = { |
48 (self.tr("Text"), None), |
48 "hex": (self.tr("Hex"), QRegExpValidator((QRegExp("[0-9a-f]*")))), |
49 ] |
49 "text": (self.tr("Text"), None), # text as latin-1 |
|
50 "utf-8": (self.tr("UTF-8"), None), # text as utf-8 |
|
51 } |
|
52 formatOrder = ["hex", "text", "utf-8"] |
|
53 |
|
54 self.__currentFindFormat = "" |
|
55 self.__currentReplaceFormat = "" |
50 |
56 |
51 self.__findHistory = mainWindow.getSRHistory("search") |
57 self.__findHistory = mainWindow.getSRHistory("search") |
52 if replace: |
58 if replace: |
53 from .Ui_HexEditReplaceWidget import Ui_HexEditReplaceWidget |
59 from .Ui_HexEditReplaceWidget import Ui_HexEditReplaceWidget |
54 self.__replaceHistory = mainWindow.getSRHistory("replace") |
60 self.__replaceHistory = mainWindow.getSRHistory("replace") |
70 self.__ui.replaceSearchButton.setIcon( |
76 self.__ui.replaceSearchButton.setIcon( |
71 UI.PixmapCache.getIcon("editReplaceSearch.png")) |
77 UI.PixmapCache.getIcon("editReplaceSearch.png")) |
72 self.__ui.replaceAllButton.setIcon( |
78 self.__ui.replaceAllButton.setIcon( |
73 UI.PixmapCache.getIcon("editReplaceAll.png")) |
79 UI.PixmapCache.getIcon("editReplaceAll.png")) |
74 |
80 |
75 for format, validator in self.__formatAndValidators: |
81 for format in formatOrder: |
76 self.__ui.findFormatCombo.addItem(format) |
82 formatStr, validator = self.__formatAndValidators[format] |
|
83 self.__ui.findFormatCombo.addItem(formatStr, format) |
77 if replace: |
84 if replace: |
78 for format, validator in self.__formatAndValidators: |
85 for format in formatOrder: |
79 self.__ui.replaceFormatCombo.addItem(format) |
86 formatStr, validator = self.__formatAndValidators[format] |
|
87 self.__ui.replaceFormatCombo.addItem(formatStr, format) |
|
88 |
80 self.__ui.findtextCombo.setCompleter(None) |
89 self.__ui.findtextCombo.setCompleter(None) |
81 self.__ui.findtextCombo.lineEdit().returnPressed.connect( |
90 self.__ui.findtextCombo.lineEdit().returnPressed.connect( |
82 self.__findByReturnPressed) |
91 self.__findByReturnPressed) |
83 if replace: |
92 if replace: |
84 self.__ui.replacetextCombo.setCompleter(None) |
93 self.__ui.replacetextCombo.setCompleter(None) |
110 |
119 |
111 @param idx index of the selected entry |
120 @param idx index of the selected entry |
112 @type int |
121 @type int |
113 """ |
122 """ |
114 if idx >= 0: |
123 if idx >= 0: |
115 self.__ui.findtextCombo.setValidator( |
124 format = self.__ui.findFormatCombo.itemData(idx) |
116 self.__formatAndValidators[idx][1]) |
125 |
|
126 if format != self.__currentFindFormat: |
|
127 txt = self.__ui.findtextCombo.currentText() |
|
128 newTxt = self.__convertText( |
|
129 self.__currentFindFormat, format, txt) |
|
130 self.__currentFindFormat = format |
|
131 |
|
132 self.__ui.findtextCombo.setValidator( |
|
133 self.__formatAndValidators[format][1]) |
|
134 |
|
135 self.__ui.findtextCombo.setEditText(newTxt) |
117 |
136 |
118 @pyqtSlot(str) |
137 @pyqtSlot(str) |
119 def on_findtextCombo_editTextChanged(self, txt): |
138 def on_findtextCombo_editTextChanged(self, txt): |
120 """ |
139 """ |
121 Private slot to enable/disable the find buttons. |
140 Private slot to enable/disable the find buttons. |
173 formatCombo = self.__ui.findFormatCombo |
192 formatCombo = self.__ui.findFormatCombo |
174 history = self.__findHistory |
193 history = self.__findHistory |
175 |
194 |
176 txt = textCombo.currentText() |
195 txt = textCombo.currentText() |
177 idx = formatCombo.currentIndex() |
196 idx = formatCombo.currentIndex() |
178 if idx == 0: # hex format |
197 format = formatCombo.itemData(idx) |
|
198 if format == "hex": # hex format |
179 ba = bytearray(QByteArray.fromHex( |
199 ba = bytearray(QByteArray.fromHex( |
180 bytes(txt, encoding="ascii"))) |
200 bytes(txt, encoding="ascii"))) |
181 else: |
201 elif format == "text": |
|
202 ba = bytearray(txt, encoding="latin-1") |
|
203 elif format == "utf-8": |
182 ba = bytearray(txt, encoding="utf-8") |
204 ba = bytearray(txt, encoding="utf-8") |
|
205 else: |
|
206 ba = bytearray() |
183 |
207 |
184 # This moves any previous occurrence of this statement to the head |
208 # This moves any previous occurrence of this statement to the head |
185 # of the list and updates the combobox |
209 # of the list and updates the combobox |
186 historyEntry = (idx, txt) |
210 historyEntry = (idx, txt) |
187 if historyEntry in history: |
211 if historyEntry in history: |
266 |
290 |
267 @param idx index of the selected entry |
291 @param idx index of the selected entry |
268 @type int |
292 @type int |
269 """ |
293 """ |
270 if idx >= 0: |
294 if idx >= 0: |
|
295 format = self.__ui.replaceFormatCombo.itemData(idx) |
271 self.__ui.replacetextCombo.setValidator( |
296 self.__ui.replacetextCombo.setValidator( |
272 self.__formatAndValidators[idx][1]) |
297 self.__formatAndValidators[format][1]) |
273 |
298 |
274 @pyqtSlot(int) |
299 @pyqtSlot(int) |
275 def on_replacetextCombo_activated(self, idx): |
300 def on_replacetextCombo_activated(self, idx): |
276 """ |
301 """ |
277 Private slot to handle a selection from the replace history. |
302 Private slot to handle a selection from the replace history. |
440 @param event reference to the key press event |
465 @param event reference to the key press event |
441 @type QKeyEvent |
466 @type QKeyEvent |
442 """ |
467 """ |
443 if event.key() == Qt.Key_Escape: |
468 if event.key() == Qt.Key_Escape: |
444 self.close() |
469 self.close() |
|
470 |
|
471 def __convertText(self, oldFormat, newFormat, txt): |
|
472 """ |
|
473 Private method to convert text from one format into another. |
|
474 |
|
475 @param oldFormat current format of the text |
|
476 @type str |
|
477 @param newFormat format to convert to |
|
478 @type str |
|
479 @param txt text to be converted |
|
480 @type str |
|
481 @return converted text |
|
482 @rtype str |
|
483 """ |
|
484 # TODO: implement the conversion method |
|
485 return txt |