HexEdit/HexEditMainWindow.py

changeset 4658
d760763dcc4a
parent 4655
f2f0abd5bc94
child 4659
2863d05e83c6
equal deleted inserted replaced
4656:ec546bd4ec56 4658:d760763dcc4a
9 9
10 from __future__ import unicode_literals 10 from __future__ import unicode_literals
11 11
12 import os 12 import os
13 13
14 from PyQt5.QtCore import pyqtSignal, pyqtSlot, QFile, QFileInfo, QSize 14 from PyQt5.QtCore import pyqtSignal, pyqtSlot, QFile, QFileInfo, QSize, \
15 QCoreApplication
15 from PyQt5.QtGui import QKeySequence 16 from PyQt5.QtGui import QKeySequence
16 from PyQt5.QtWidgets import QWhatsThis, QLabel, QWidget, QVBoxLayout 17 from PyQt5.QtWidgets import QWhatsThis, QLabel, QWidget, QVBoxLayout, \
18 QDialog, QAction
17 19
18 from E5Gui.E5Action import E5Action 20 from E5Gui.E5Action import E5Action
19 from E5Gui.E5MainWindow import E5MainWindow 21 from E5Gui.E5MainWindow import E5MainWindow
20 from E5Gui import E5FileDialog, E5MessageBox 22 from E5Gui import E5FileDialog, E5MessageBox
21 23
26 import UI.Config 28 import UI.Config
27 29
28 import Preferences 30 import Preferences
29 31
30 32
31 # TODO: implement a configuration page for the hex editor
32 class HexEditMainWindow(E5MainWindow): 33 class HexEditMainWindow(E5MainWindow):
33 """ 34 """
34 Class implementing the web browser main window. 35 Class implementing the web browser main window.
35 36
36 @signal editorClosed() emitted after the window was requested to close down 37 @signal editorClosed() emitted after the window was requested to close down
50 @keyparam project reference to the project object (Project) 51 @keyparam project reference to the project object (Project)
51 """ 52 """
52 super(HexEditMainWindow, self).__init__(parent) 53 super(HexEditMainWindow, self).__init__(parent)
53 self.setObjectName("eric6_hex_editor") 54 self.setObjectName("eric6_hex_editor")
54 55
55 self.fromEric = fromEric 56 self.__fromEric = fromEric
56 self.setWindowIcon(UI.PixmapCache.getIcon("hexEditor.png")) 57 self.setWindowIcon(UI.PixmapCache.getIcon("hexEditor.png"))
57 58
58 if not self.fromEric: 59 if not self.__fromEric:
59 self.setStyle(Preferences.getUI("Style"), 60 self.setStyle(Preferences.getUI("Style"),
60 Preferences.getUI("StyleSheet")) 61 Preferences.getUI("StyleSheet"))
61 62
62 self.__editor = HexEditWidget() 63 self.__editor = HexEditWidget()
63 self.__searchWidget = HexEditSearchReplaceWidget(self.__editor, False) 64 self.__searchWidget = HexEditSearchReplaceWidget(self.__editor, False)
94 self.__editor.currentAddressChanged.connect(self.__showAddress) 95 self.__editor.currentAddressChanged.connect(self.__showAddress)
95 self.__editor.currentSizeChanged.connect(self.__showSize) 96 self.__editor.currentSizeChanged.connect(self.__showSize)
96 self.__editor.dataChanged.connect(self.__modificationChanged) 97 self.__editor.dataChanged.connect(self.__modificationChanged)
97 self.__editor.overwriteModeChanged.connect(self.__showEditMode) 98 self.__editor.overwriteModeChanged.connect(self.__showEditMode)
98 self.__editor.readOnlyChanged.connect(self.__showReadOnlyMode) 99 self.__editor.readOnlyChanged.connect(self.__showReadOnlyMode)
99 self.__editor.readOnlyChanged.connect(self.__modificationChanged) 100 self.__editor.readOnlyChanged.connect(self.__checkActions)
101
102 self.preferencesChanged()
103 self.__editor.setOverwriteMode(
104 Preferences.getHexEditor("OpenInOverwriteMode"))
100 105
101 self.__project = project 106 self.__project = project
102 self.__lastOpenPath = "" 107 self.__lastOpenPath = ""
103 self.__lastSavePath = "" 108 self.__lastSavePath = ""
104 109
116 self.__actions = [] 121 self.__actions = []
117 122
118 self.__initFileActions() 123 self.__initFileActions()
119 self.__initEditActions() 124 self.__initEditActions()
120 self.__initHelpActions() 125 self.__initHelpActions()
126 if not self.__fromEric:
127 self.__initConfigActions()
121 128
122 def __initFileActions(self): 129 def __initFileActions(self):
123 """ 130 """
124 Private method to define the file related user interface actions. 131 Private method to define the file related user interface actions.
125 """ 132 """
136 """ window.</p>""" 143 """ window.</p>"""
137 )) 144 ))
138 self.newWindowAct.triggered.connect(self.__openHexFileNewWindow) 145 self.newWindowAct.triggered.connect(self.__openHexFileNewWindow)
139 self.__actions.append(self.newWindowAct) 146 self.__actions.append(self.newWindowAct)
140 147
148 # correct texts will be set later
141 self.openAct = E5Action( 149 self.openAct = E5Action(
142 self.tr('Open'), 150 self.tr('Open'),
143 UI.PixmapCache.getIcon("open.png"), 151 UI.PixmapCache.getIcon("open.png"),
144 self.tr('&Open...'), 152 self.tr('&Open...'),
145 QKeySequence(self.tr("Ctrl+O", "File|Open")), 153 QKeySequence(self.tr("Ctrl+O", "File|Open")),
146 0, self, 'hexEditor_file_open') 154 0, self, 'hexEditor_file_open')
147 self.openAct.setStatusTip(self.tr('Open a binary file for editing'))
148 self.openAct.setWhatsThis(self.tr(
149 """<b>Open File</b>"""
150 """<p>This opens a binary file for editing."""
151 """ It pops up a file selection dialog.</p>"""
152 ))
153 self.openAct.triggered.connect(self.__openHexFile) 155 self.openAct.triggered.connect(self.__openHexFile)
154 self.__actions.append(self.openAct) 156 self.__actions.append(self.openAct)
155 157
158 # correct texts will be set later
156 self.openReadOnlyAct = E5Action( 159 self.openReadOnlyAct = E5Action(
157 self.tr('Open Read Only'), 160 "", "",
158 self.tr('Open Read Only...'),
159 0, 0, self, 'hexEditor_file_open_read_only') 161 0, 0, self, 'hexEditor_file_open_read_only')
160 self.openReadOnlyAct.setStatusTip(self.tr(
161 'Open a binary file for viewing'))
162 self.openReadOnlyAct.setWhatsThis(self.tr(
163 """<b>Open Read Only</b>"""
164 """<p>This opens a binary file for viewing (i.e. in read only"""
165 """ mode). It pops up a file selection dialog.</p>"""
166 ))
167 self.openReadOnlyAct.triggered.connect(self.__openHexFileReadOnly) 162 self.openReadOnlyAct.triggered.connect(self.__openHexFileReadOnly)
168 self.__actions.append(self.openReadOnlyAct) 163 self.__actions.append(self.openReadOnlyAct)
169 164
170 self.saveAct = E5Action( 165 self.saveAct = E5Action(
171 self.tr('Save'), 166 self.tr('Save'),
261 self.exitAct.setStatusTip(self.tr('Quit the hex editor')) 256 self.exitAct.setStatusTip(self.tr('Quit the hex editor'))
262 self.exitAct.setWhatsThis(self.tr( 257 self.exitAct.setWhatsThis(self.tr(
263 """<b>Quit</b>""" 258 """<b>Quit</b>"""
264 """<p>Quit the hex editor.</p>""" 259 """<p>Quit the hex editor.</p>"""
265 )) 260 ))
266 if not self.fromEric: 261 if not self.__fromEric:
267 self.exitAct.triggered.connect(self.__closeAll) 262 self.exitAct.triggered.connect(self.__closeAll)
268 self.__actions.append(self.exitAct) 263 self.__actions.append(self.exitAct)
269 264
270 def __initEditActions(self): 265 def __initEditActions(self):
271 """ 266 """
554 """ using the context help button in the titlebar.</p>""" 549 """ using the context help button in the titlebar.</p>"""
555 )) 550 ))
556 self.whatsThisAct.triggered.connect(self.__whatsThis) 551 self.whatsThisAct.triggered.connect(self.__whatsThis)
557 self.__actions.append(self.whatsThisAct) 552 self.__actions.append(self.whatsThisAct)
558 553
554 def __initConfigActions(self):
555 """
556 Private method to create the Settings actions.
557 """
558 self.prefAct = E5Action(
559 self.tr('Preferences'),
560 UI.PixmapCache.getIcon("configure.png"),
561 self.tr('&Preferences...'),
562 0, 0, self, 'hexEditor_settings_preferences')
563 self.prefAct.setStatusTip(self.tr(
564 'Set the prefered configuration'))
565 self.prefAct.setWhatsThis(self.tr(
566 """<b>Preferences</b>"""
567 """<p>Set the configuration items of the application"""
568 """ with your prefered values.</p>"""
569 ))
570 self.prefAct.triggered.connect(self.__showPreferences)
571 self.prefAct.setMenuRole(QAction.PreferencesRole)
572 self.__actions.append(self.prefAct)
573
574 def __setReadOnlyActionTexts(self):
575 """
576 Private method to switch the 'Open Read Only' action between
577 'read only' and 'read write'.
578 """
579 if Preferences.getHexEditor("OpenReadOnly"):
580 self.openAct.setStatusTip(self.tr(
581 'Open a binary file for viewing'))
582 self.openAct.setWhatsThis(self.tr(
583 """<b>Open File</b>"""
584 """<p>This opens a binary file for viewing (i.e. in read"""
585 """ only mode). It pops up a file selection dialog.</p>"""
586 ))
587
588 self.openReadOnlyAct.setText(self.tr('Open for Editing...'))
589 self.openReadOnlyAct.setIconText(self.tr('Open for Editing'))
590 self.openReadOnlyAct.setStatusTip(self.tr(
591 'Open a binary file for editing'))
592 self.openReadOnlyAct.setWhatsThis(self.tr(
593 """<b>Open for Editing</b>"""
594 """<p>This opens a binary file for editing."""
595 """ It pops up a file selection dialog.</p>"""
596 ))
597 else:
598 self.openAct.setStatusTip(self.tr(
599 'Open a binary file for editing'))
600 self.openAct.setWhatsThis(self.tr(
601 """<b>Open File</b>"""
602 """<p>This opens a binary file for editing."""
603 """ It pops up a file selection dialog.</p>"""
604 ))
605
606 self.openReadOnlyAct.setText(self.tr('Open Read Only...'))
607 self.openReadOnlyAct.setIconText(self.tr('Open Read Only'))
608 self.openReadOnlyAct.setStatusTip(self.tr(
609 'Open a binary file for viewing'))
610 self.openReadOnlyAct.setWhatsThis(self.tr(
611 """<b>Open Read Only</b>"""
612 """<p>This opens a binary file for viewing (i.e. in read"""
613 """ only mode). It pops up a file selection dialog.</p>"""
614 ))
615
559 def __initMenus(self): 616 def __initMenus(self):
560 """ 617 """
561 Private method to create the menus. 618 Private method to create the menus.
562 """ 619 """
563 mb = self.menuBar() 620 mb = self.menuBar()
572 menu.addAction(self.saveAsAct) 629 menu.addAction(self.saveAsAct)
573 menu.addAction(self.saveReadableAct) 630 menu.addAction(self.saveReadableAct)
574 menu.addSeparator() 631 menu.addSeparator()
575 menu.addAction(self.closeAct) 632 menu.addAction(self.closeAct)
576 menu.addAction(self.closeOthersAct) 633 menu.addAction(self.closeOthersAct)
577 if self.fromEric: 634 if self.__fromEric:
578 menu.addAction(self.closeAllAct) 635 menu.addAction(self.closeAllAct)
579 else: 636 else:
580 menu.addSeparator() 637 menu.addSeparator()
581 menu.addAction(self.exitAct) 638 menu.addAction(self.exitAct)
582 639
599 menu.addAction(self.searchPrevAct) 656 menu.addAction(self.searchPrevAct)
600 menu.addAction(self.replaceAct) 657 menu.addAction(self.replaceAct)
601 menu.addSeparator() 658 menu.addSeparator()
602 menu.addAction(self.readonlyAct) 659 menu.addAction(self.readonlyAct)
603 660
661 if not self.__fromEric:
662 menu = mb.addMenu(self.tr("Se&ttings"))
663 menu.setTearOffEnabled(True)
664 menu.addAction(self.prefAct)
665
604 mb.addSeparator() 666 mb.addSeparator()
605 667
606 menu = mb.addMenu(self.tr("&Help")) 668 menu = mb.addMenu(self.tr("&Help"))
607 menu.addAction(self.aboutAct) 669 menu.addAction(self.aboutAct)
608 menu.addAction(self.aboutQtAct) 670 menu.addAction(self.aboutQtAct)
621 filetb.addSeparator() 683 filetb.addSeparator()
622 filetb.addAction(self.saveAct) 684 filetb.addAction(self.saveAct)
623 filetb.addAction(self.saveAsAct) 685 filetb.addAction(self.saveAsAct)
624 filetb.addSeparator() 686 filetb.addSeparator()
625 filetb.addAction(self.closeAct) 687 filetb.addAction(self.closeAct)
626 if not self.fromEric: 688 if not self.__fromEric:
627 filetb.addAction(self.exitAct) 689 filetb.addAction(self.exitAct)
628 690
629 edittb = self.addToolBar(self.tr("Edit")) 691 edittb = self.addToolBar(self.tr("Edit"))
630 edittb.setObjectName("EditToolBar") 692 edittb.setObjectName("EditToolBar")
631 edittb.setIconSize(UI.Config.ToolBarIconSize) 693 edittb.setIconSize(UI.Config.ToolBarIconSize)
641 searchtb.setIconSize(UI.Config.ToolBarIconSize) 703 searchtb.setIconSize(UI.Config.ToolBarIconSize)
642 searchtb.addAction(self.searchAct) 704 searchtb.addAction(self.searchAct)
643 searchtb.addAction(self.searchNextAct) 705 searchtb.addAction(self.searchNextAct)
644 searchtb.addAction(self.searchPrevAct) 706 searchtb.addAction(self.searchPrevAct)
645 707
708 if not self.__fromEric:
709 settingstb = self.addToolBar(self.tr("Settings"))
710 settingstb.setObjectName("SettingsToolBar")
711 settingstb.setIconSize(UI.Config.ToolBarIconSize)
712 settingstb.addAction(self.prefAct)
713
646 helptb = self.addToolBar(self.tr("Help")) 714 helptb = self.addToolBar(self.tr("Help"))
647 helptb.setObjectName("HelpToolBar") 715 helptb.setObjectName("HelpToolBar")
648 helptb.setIconSize(UI.Config.ToolBarIconSize) 716 helptb.setIconSize(UI.Config.ToolBarIconSize)
649 helptb.addAction(self.whatsThisAct) 717 helptb.addAction(self.whatsThisAct)
650 718
740 Preferences.setHexEditor("HexEditorState", state) 808 Preferences.setHexEditor("HexEditorState", state)
741 809
742 Preferences.setGeometry("HexEditorGeometry", self.saveGeometry()) 810 Preferences.setGeometry("HexEditorGeometry", self.saveGeometry())
743 811
744 try: 812 try:
745 if self.fromEric or len(self.__class__.windows) > 1: 813 if self.__fromEric or len(self.__class__.windows) > 1:
746 del self.__class__.windows[ 814 del self.__class__.windows[
747 self.__class__.windows.index(self)] 815 self.__class__.windows.index(self)]
748 except ValueError: 816 except ValueError:
749 pass 817 pass
750 818
751 if not self.fromEric: 819 if not self.__fromEric:
752 Preferences.syncPreferences() 820 Preferences.syncPreferences()
753 821
754 evt.accept() 822 evt.accept()
755 self.editorClosed.emit() 823 self.editorClosed.emit()
756 else: 824 else:
770 self.__lastOpenPath, 838 self.__lastOpenPath,
771 self.tr("All Files (*)")) 839 self.tr("All Files (*)"))
772 if fileName: 840 if fileName:
773 he = HexEditMainWindow(fileName=fileName, 841 he = HexEditMainWindow(fileName=fileName,
774 parent=self.parent(), 842 parent=self.parent(),
775 fromEric=self.fromEric, 843 fromEric=self.__fromEric,
776 project=self.__project) 844 project=self.__project)
777 he.setRecentPaths("", self.__lastSavePath) 845 he.setRecentPaths("", self.__lastSavePath)
778 he.show() 846 he.show()
779 847
780 def __maybeSave(self): 848 def __maybeSave(self):
820 file.close() 888 file.close()
821 889
822 self.__lastOpenPath = os.path.dirname(fileName) 890 self.__lastOpenPath = os.path.dirname(fileName)
823 self.__editor.setData(data) 891 self.__editor.setData(data)
824 self.__setCurrentFile(fileName) 892 self.__setCurrentFile(fileName)
893
894 self.__editor.setReadOnly(Preferences.getHexEditor("OpenReadOnly"))
825 895
826 def __openHexFile(self): 896 def __openHexFile(self):
827 """ 897 """
828 Private slot to open a binary file. 898 Private slot to open a binary file.
829 """ 899 """
844 def __openHexFileReadOnly(self): 914 def __openHexFileReadOnly(self):
845 """ 915 """
846 Private slot to open a binary file in read only mode. 916 Private slot to open a binary file in read only mode.
847 """ 917 """
848 self.__openHexFile() 918 self.__openHexFile()
849 self.__editor.setReadOnly(True) 919 self.__editor.setReadOnly(not Preferences.getHexEditor("OpenReadOnly"))
850 self.__checkActions() 920 self.__checkActions()
851 921
852 def __saveHexFile(self): 922 def __saveHexFile(self):
853 """ 923 """
854 Private method to save a binary file. 924 Private method to save a binary file.
1128 """ 1198 """
1129 Private method to handle the replace action. 1199 Private method to handle the replace action.
1130 """ 1200 """
1131 self.__searchWidget.hide() 1201 self.__searchWidget.hide()
1132 self.__replaceWidget.show() 1202 self.__replaceWidget.show()
1203
1204 def preferencesChanged(self):
1205 """
1206 Public method to (re-)read the various settings.
1207 """
1208 self.__editor.setAddressWidth(
1209 Preferences.getHexEditor("AddressAreaWidth"))
1210 self.__editor.setAddressArea(
1211 Preferences.getHexEditor("ShowAddressArea"))
1212 self.__editor.setAsciiArea(
1213 Preferences.getHexEditor("ShowAsciiArea"))
1214 self.__editor.setHighlighting(
1215 Preferences.getHexEditor("HighlightChanges"))
1216 self.__editor.setHighlightColors(
1217 Preferences.getHexEditor("HighlightingForeGround"),
1218 Preferences.getHexEditor("HighlightingBackGround"))
1219 self.__editor.setSelectionColors(
1220 Preferences.getHexEditor("SelectionForeGround"),
1221 Preferences.getHexEditor("SelectionBackGround"))
1222 self.__editor.setAddressAreaColors(
1223 Preferences.getHexEditor("AddressAreaForeGround"),
1224 Preferences.getHexEditor("AddressAreaBackGround"))
1225 self.__editor.setFont(
1226 Preferences.getHexEditor("Font"))
1227
1228 self.__setReadOnlyActionTexts()
1229
1230 def __showPreferences(self):
1231 """
1232 Private slot to set the preferences.
1233 """
1234 from Preferences.ConfigurationDialog import ConfigurationDialog
1235 dlg = ConfigurationDialog(
1236 None, 'Configuration', True, fromEric=True,
1237 displayMode=ConfigurationDialog.HexEditorMode)
1238 dlg.preferencesChanged.connect(
1239 self.__preferencesChangedByLocalPreferencesDialog)
1240 dlg.show()
1241 dlg.showConfigurationPageByName("hexEditorPage")
1242 dlg.exec_()
1243 QCoreApplication.processEvents()
1244 if dlg.result() == QDialog.Accepted:
1245 dlg.setPreferences()
1246 Preferences.syncPreferences()
1247 self.__preferencesChangedByLocalPreferencesDialog()
1248
1249 def __preferencesChangedByLocalPreferencesDialog(self):
1250 """
1251 Private slot to handle preferences changes by our local dialog.
1252 """
1253 for hexEditor in HexEditMainWindow.windows:
1254 hexEditor.preferencesChanged()

eric ide

mercurial