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 |
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 |
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() |
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): |
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() |