~ubuntu-branches/ubuntu/raring/codeblocks/raring-proposed

« back to all changes in this revision

Viewing changes to src/plugins/contrib/HexEditor/HexEditPanel.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Cosme Domínguez Díaz
  • Date: 2010-08-09 04:38:38 UTC
  • mfrom: (1.1.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20100809043838-a59ygguym4eg0jgw
Tags: 10.05-0ubuntu1
* New upstream release. Closes (LP: #322350)
 - Switch to dpkg-source 3.0 (quilt) format
 - Remove unneeded README.source
 - Add debian/get-source-orig script that removes all
   Windows prebuilt binaries
* Bump Standards-Version to 3.9.1
 - Stop shipping *.la files
* debian/control
 - Add cdbs package as Build-Depend
 - Add libbz2-dev and zlib1g-dev packages as
   Build-Depends (needed by libhelp_plugin.so)
 - Remove dpatch package of Build-Depends
 - Add codeblocks-contrib-debug package
 - Split architecture-independent files of codeblocks
   package in codeblocks-common package
* debian/rules
 - Switch to CDBS rules system
 - Add parallel build support
 - Add a call to debian/get-source-orig script
 - Use lzma compression (saves 23,5 MB of free space)
* debian/patches
 - Refresh 01_codeblocks_plugin_path
 - Add 02_no_Makefiles_in_debian_dir to remove any link
   in codeblocks build system to deleted Makefiles of debian directory
 - Drop 02_ftbfs_gcc44 and 03_ftbfs_glib221 (merged in upstream)
* debian/watch
 - Update to use the new host (berlios.de)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
* This file is part of HexEditor plugin for Code::Blocks Studio
 
3
* Copyright (C) 2008-2009 Bartlomiej Swiecki
 
4
*
 
5
* HexEditor plugin is free software; you can redistribute it and/or modify
 
6
* it under the terms of the GNU General Public License as published by
 
7
* the Free Software Foundation; either version 3 of the License, or
 
8
* (at your option) any later version.
 
9
*
 
10
* HexEditor pluging is distributed in the hope that it will be useful,
 
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
13
* GNU General Public License for more details.
 
14
*
 
15
* You should have received a copy of the GNU General Public License
 
16
* along with HexEditor. If not, see <http://www.gnu.org/licenses/>.
 
17
*
 
18
* $Revision: 5867 $
 
19
* $Id: HexEditPanel.cpp 5867 2009-10-20 08:34:02Z mortenmacfly $
 
20
* $HeadURL: svn+ssh://jenslody@svn.berlios.de/svnroot/repos/codeblocks/trunk/src/plugins/contrib/HexEditor/HexEditPanel.cpp $
 
21
*/
 
22
 
 
23
#include "HexEditPanel.h"
 
24
#include "ExpressionTester.h"
 
25
#include "SelectStoredExpressionDlg.h"
 
26
#include "ExpressionExecutor.h"
 
27
#include "ExpressionParser.h"
 
28
#include "CharacterView.h"
 
29
#include "DigitView.h"
 
30
#include "HexEditLineBuffer.h"
 
31
 
 
32
#include "ExpressionTestCases.h"
 
33
#include "FileContentDisk.h"
 
34
#include "TestCasesDlg.h"
 
35
#include "SearchDialog.h"
 
36
 
 
37
//(*InternalHeaders(HexEditPanel)
 
38
#include <wx/string.h>
 
39
#include <wx/intl.h>
 
40
//*)
 
41
 
 
42
#include <wx/dcbuffer.h>
 
43
#include <wx/dcclient.h>
 
44
#include <wx/filedlg.h>
 
45
#include <wx/filename.h>
 
46
#include <wx/numdlg.h>
 
47
#include <wx/sizer.h>
 
48
#include <wx/textdlg.h>
 
49
#include <wx/choicdlg.h>
 
50
 
 
51
#include <manager.h>
 
52
#include <editormanager.h>
 
53
#include <configmanager.h>
 
54
#include <logmanager.h>
 
55
 
 
56
namespace
 
57
{
 
58
    inline int NWD( int a, int b )
 
59
    {
 
60
        while ( b )
 
61
        {
 
62
            int c = a % b;
 
63
            a = b;
 
64
            b = c;
 
65
        }
 
66
        return a;
 
67
    }
 
68
}
 
69
 
 
70
//(*IdInit(HexEditPanel)
 
71
const long HexEditPanel::ID_STATICTEXT1 = wxNewId();
 
72
const long HexEditPanel::ID_BUTTON10 = wxNewId();
 
73
const long HexEditPanel::ID_BUTTON9 = wxNewId();
 
74
const long HexEditPanel::ID_STATICLINE2 = wxNewId();
 
75
const long HexEditPanel::ID_BUTTON7 = wxNewId();
 
76
const long HexEditPanel::ID_BUTTON4 = wxNewId();
 
77
const long HexEditPanel::ID_BUTTON6 = wxNewId();
 
78
const long HexEditPanel::ID_BUTTON5 = wxNewId();
 
79
const long HexEditPanel::ID_STATICLINE1 = wxNewId();
 
80
const long HexEditPanel::ID_BUTTON1 = wxNewId();
 
81
const long HexEditPanel::ID_BUTTON8 = wxNewId();
 
82
const long HexEditPanel::ID_CHECKBOX1 = wxNewId();
 
83
const long HexEditPanel::ID_PANEL1 = wxNewId();
 
84
const long HexEditPanel::ID_SCROLLBAR1 = wxNewId();
 
85
const long HexEditPanel::ID_STATICTEXT2 = wxNewId();
 
86
const long HexEditPanel::ID_STATICTEXT3 = wxNewId();
 
87
const long HexEditPanel::ID_STATICTEXT4 = wxNewId();
 
88
const long HexEditPanel::ID_STATICTEXT5 = wxNewId();
 
89
const long HexEditPanel::ID_STATICTEXT6 = wxNewId();
 
90
const long HexEditPanel::ID_STATICTEXT7 = wxNewId();
 
91
const long HexEditPanel::ID_STATICTEXT8 = wxNewId();
 
92
const long HexEditPanel::ID_STATICTEXT9 = wxNewId();
 
93
const long HexEditPanel::ID_STATICTEXT10 = wxNewId();
 
94
const long HexEditPanel::ID_STATICTEXT11 = wxNewId();
 
95
const long HexEditPanel::ID_STATICTEXT12 = wxNewId();
 
96
const long HexEditPanel::ID_STATICTEXT13 = wxNewId();
 
97
const long HexEditPanel::ID_STATICTEXT14 = wxNewId();
 
98
const long HexEditPanel::ID_TEXTCTRL1 = wxNewId();
 
99
const long HexEditPanel::ID_BUTTON3 = wxNewId();
 
100
const long HexEditPanel::ID_BUTTON2 = wxNewId();
 
101
const long HexEditPanel::ID_STATICTEXT15 = wxNewId();
 
102
const long HexEditPanel::ID_TIMER1 = wxNewId();
 
103
const long HexEditPanel::ID_MENUITEM2 = wxNewId();
 
104
const long HexEditPanel::ID_MENUITEM1 = wxNewId();
 
105
const long HexEditPanel::ID_MENUITEM3 = wxNewId();
 
106
const long HexEditPanel::ID_MENUITEM4 = wxNewId();
 
107
const long HexEditPanel::ID_MENUITEM5 = wxNewId();
 
108
const long HexEditPanel::ID_MENUITEM6 = wxNewId();
 
109
const long HexEditPanel::ID_MENUITEM7 = wxNewId();
 
110
const long HexEditPanel::ID_MENUITEM8 = wxNewId();
 
111
const long HexEditPanel::ID_MENUITEM9 = wxNewId();
 
112
const long HexEditPanel::ID_MENUITEM11 = wxNewId();
 
113
const long HexEditPanel::ID_MENUITEM12 = wxNewId();
 
114
const long HexEditPanel::ID_MENUITEM13 = wxNewId();
 
115
const long HexEditPanel::ID_MENUITEM14 = wxNewId();
 
116
const long HexEditPanel::ID_MENUITEM15 = wxNewId();
 
117
const long HexEditPanel::ID_MENUITEM16 = wxNewId();
 
118
const long HexEditPanel::ID_MENUITEM17 = wxNewId();
 
119
const long HexEditPanel::ID_MENUITEM18 = wxNewId();
 
120
const long HexEditPanel::ID_MENUITEM32 = wxNewId();
 
121
const long HexEditPanel::ID_MENUITEM10 = wxNewId();
 
122
const long HexEditPanel::ID_MENUITEM20 = wxNewId();
 
123
const long HexEditPanel::ID_MENUITEM21 = wxNewId();
 
124
const long HexEditPanel::ID_MENUITEM22 = wxNewId();
 
125
const long HexEditPanel::ID_MENUITEM23 = wxNewId();
 
126
const long HexEditPanel::ID_MENUITEM24 = wxNewId();
 
127
const long HexEditPanel::ID_MENUITEM25 = wxNewId();
 
128
const long HexEditPanel::ID_MENUITEM26 = wxNewId();
 
129
const long HexEditPanel::ID_MENUITEM27 = wxNewId();
 
130
const long HexEditPanel::ID_MENUITEM19 = wxNewId();
 
131
const long HexEditPanel::ID_MENUITEM29 = wxNewId();
 
132
const long HexEditPanel::ID_MENUITEM30 = wxNewId();
 
133
const long HexEditPanel::ID_MENUITEM31 = wxNewId();
 
134
const long HexEditPanel::ID_MENUITEM33 = wxNewId();
 
135
const long HexEditPanel::ID_MENUITEM28 = wxNewId();
 
136
//*)
 
137
 
 
138
BEGIN_EVENT_TABLE(HexEditPanel,EditorBase)
 
139
        //(*EventTable(HexEditPanel)
 
140
        //*)
 
141
END_EVENT_TABLE()
 
142
 
 
143
HexEditPanel::EditorsSet HexEditPanel::m_AllEditors;
 
144
 
 
145
HexEditPanel::HexEditPanel( const wxString& fileName, const wxString& title )
 
146
    : EditorBase( (wxWindow*)Manager::Get()->GetEditorManager()->GetNotebook(), fileName )
 
147
    , m_FileName( fileName )
 
148
    , m_Content( 0 )
 
149
    , m_DrawFont( 0 )
 
150
    , m_Current( 0 )
 
151
    , m_CurrentBlockStart( 0 )
 
152
    , m_CurrentBlockEnd( 0 )
 
153
    , m_MouseDown( false )
 
154
    , m_ColsMode( CM_ANY )
 
155
{
 
156
    /*
 
157
    --- Begin of comment which prevents calling Create() --
 
158
 
 
159
    //(*Initialize(HexEditPanel)
 
160
    Create(parent, wxID_ANY, wxDefaultPosition, wxSize(79,51), wxTAB_TRAVERSAL, _T("wxID_ANY"));
 
161
 
 
162
    --- End of comment which prevents calling Create() --
 
163
    */
 
164
 
 
165
    BoxSizer1 = new wxBoxSizer(wxVERTICAL);
 
166
    BoxSizer3 = new wxBoxSizer(wxHORIZONTAL);
 
167
    m_Status = new wxStaticText(this, ID_STATICTEXT1, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT1"));
 
168
    BoxSizer3->Add(m_Status, 1, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
169
    Button6 = new wxButton(this, ID_BUTTON10, _("Goto"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator, _T("ID_BUTTON10"));
 
170
    BoxSizer3->Add(Button6, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
171
    Button5 = new wxButton(this, ID_BUTTON9, _("Search"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator, _T("ID_BUTTON9"));
 
172
    BoxSizer3->Add(Button5, 0, wxLEFT|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
173
    StaticLine2 = new wxStaticLine(this, ID_STATICLINE2, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL, _T("ID_STATICLINE2"));
 
174
    BoxSizer3->Add(StaticLine2, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
175
    m_ColsModeBtn = new wxButton(this, ID_BUTTON7, _("Cols"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator, _T("ID_BUTTON7"));
 
176
    BoxSizer3->Add(m_ColsModeBtn, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
177
    m_DigitBits = new wxButton(this, ID_BUTTON4, _("Hex"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator, _T("ID_BUTTON4"));
 
178
    BoxSizer3->Add(m_DigitBits, 0, wxLEFT|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
179
    m_BlockSize = new wxButton(this, ID_BUTTON6, _("1B"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator, _T("ID_BUTTON6"));
 
180
    BoxSizer3->Add(m_BlockSize, 0, wxLEFT|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
181
    m_Endianess = new wxButton(this, ID_BUTTON5, _("BE"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator, _T("ID_BUTTON5"));
 
182
    BoxSizer3->Add(m_Endianess, 0, wxLEFT|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
183
    StaticLine1 = new wxStaticLine(this, ID_STATICLINE1, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL, _T("ID_STATICLINE1"));
 
184
    BoxSizer3->Add(StaticLine1, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
185
    Button1 = new wxButton(this, ID_BUTTON1, _("Calc"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator, _T("ID_BUTTON1"));
 
186
    BoxSizer3->Add(Button1, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
187
    Button4 = new wxButton(this, ID_BUTTON8, _("Test"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator, _T("ID_BUTTON8"));
 
188
    BoxSizer3->Add(Button4, 0, wxRIGHT|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
189
    CheckBox1 = new wxCheckBox(this, ID_CHECKBOX1, _("Value preview"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_CHECKBOX1"));
 
190
    CheckBox1->SetValue(true);
 
191
    BoxSizer3->Add(CheckBox1, 0, wxRIGHT|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
192
    BoxSizer1->Add(BoxSizer3, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
193
    BoxSizer2 = new wxBoxSizer(wxHORIZONTAL);
 
194
    m_DrawArea = new wxPanel(this, ID_PANEL1, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS|wxFULL_REPAINT_ON_RESIZE, _T("ID_PANEL1"));
 
195
    BoxSizer2->Add(m_DrawArea, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
196
    m_ContentScroll = new wxScrollBar(this, ID_SCROLLBAR1, wxDefaultPosition, wxDefaultSize, wxSB_VERTICAL, wxDefaultValidator, _T("ID_SCROLLBAR1"));
 
197
    m_ContentScroll->SetScrollbar(0, 1, 1, 1);
 
198
    BoxSizer2->Add(m_ContentScroll, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 0);
 
199
    BoxSizer1->Add(BoxSizer2, 1, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
200
    PreviewSizer = new wxBoxSizer(wxVERTICAL);
 
201
    FlexGridSizer1 = new wxFlexGridSizer(0, 8, 5, 5);
 
202
    FlexGridSizer1->AddGrowableCol(1);
 
203
    FlexGridSizer1->AddGrowableCol(4);
 
204
    FlexGridSizer1->AddGrowableCol(7);
 
205
    StaticText1 = new wxStaticText(this, ID_STATICTEXT2, _("Byte:"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT2"));
 
206
    FlexGridSizer1->Add(StaticText1, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
207
    m_ByteVal = new wxStaticText(this, ID_STATICTEXT3, _("-9999999999"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT3"));
 
208
    FlexGridSizer1->Add(m_ByteVal, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
209
    FlexGridSizer1->Add(5,5,1, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
210
    StaticText3 = new wxStaticText(this, ID_STATICTEXT4, _("Word:"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT4"));
 
211
    FlexGridSizer1->Add(StaticText3, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
212
    m_WordVal = new wxStaticText(this, ID_STATICTEXT5, _("-9999999999"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT5"));
 
213
    FlexGridSizer1->Add(m_WordVal, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
214
    FlexGridSizer1->Add(5,5,1, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
215
    StaticText2 = new wxStaticText(this, ID_STATICTEXT6, _("Dword:"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT6"));
 
216
    FlexGridSizer1->Add(StaticText2, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
217
    m_DwordVal = new wxStaticText(this, ID_STATICTEXT7, _("-9999999999"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT7"));
 
218
    FlexGridSizer1->Add(m_DwordVal, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
219
    StaticText4 = new wxStaticText(this, ID_STATICTEXT8, _("Float:"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT8"));
 
220
    FlexGridSizer1->Add(StaticText4, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
221
    m_FloatVal = new wxStaticText(this, ID_STATICTEXT9, _("-9999999999"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT9"));
 
222
    FlexGridSizer1->Add(m_FloatVal, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
223
    FlexGridSizer1->Add(5,5,1, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
224
    StaticText6 = new wxStaticText(this, ID_STATICTEXT10, _("Double:"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT10"));
 
225
    FlexGridSizer1->Add(StaticText6, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
226
    m_DoubleVal = new wxStaticText(this, ID_STATICTEXT11, _("-9999999999"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT11"));
 
227
    FlexGridSizer1->Add(m_DoubleVal, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
228
    FlexGridSizer1->Add(5,5,1, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
229
    StaticText8 = new wxStaticText(this, ID_STATICTEXT12, _("L-Double:"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT12"));
 
230
    FlexGridSizer1->Add(StaticText8, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
231
    m_LDoubleVal = new wxStaticText(this, ID_STATICTEXT13, _("-9999999999"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT13"));
 
232
    FlexGridSizer1->Add(m_LDoubleVal, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
233
    PreviewSizer->Add(FlexGridSizer1, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
234
    BoxSizer4 = new wxBoxSizer(wxHORIZONTAL);
 
235
    StaticText5 = new wxStaticText(this, ID_STATICTEXT14, _("Expression:"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT14"));
 
236
    BoxSizer4->Add(StaticText5, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
237
    m_Expression = new wxTextCtrl(this, ID_TEXTCTRL1, _("byte[ @ ]"), wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER, wxDefaultValidator, _T("ID_TEXTCTRL1"));
 
238
    BoxSizer4->Add(m_Expression, 1, wxLEFT|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
239
    Button3 = new wxButton(this, ID_BUTTON3, _("v"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator, _T("ID_BUTTON3"));
 
240
    BoxSizer4->Add(Button3, 0, wxRIGHT|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
241
    Button2 = new wxButton(this, ID_BUTTON2, _("\?"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT, wxDefaultValidator, _T("ID_BUTTON2"));
 
242
    BoxSizer4->Add(Button2, 0, wxRIGHT|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
243
    m_ExpressionVal = new wxStaticText(this, ID_STATICTEXT15, _("-9999999999"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_STATICTEXT15"));
 
244
    BoxSizer4->Add(m_ExpressionVal, 1, wxLEFT|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
245
    PreviewSizer->Add(BoxSizer4, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
246
    BoxSizer1->Add(PreviewSizer, 0, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
247
    SetSizer(BoxSizer1);
 
248
    ReparseTimer.SetOwner(this, ID_TIMER1);
 
249
    MenuItem2 = new wxMenuItem((&m_BaseMenu), ID_MENUITEM2, _("Bin"), wxEmptyString, wxITEM_NORMAL);
 
250
    m_BaseMenu.Append(MenuItem2);
 
251
    MenuItem1 = new wxMenuItem((&m_BaseMenu), ID_MENUITEM1, _("Hex"), wxEmptyString, wxITEM_NORMAL);
 
252
    m_BaseMenu.Append(MenuItem1);
 
253
    MenuItem3 = new wxMenuItem((&m_EndianessMenu), ID_MENUITEM3, _("Big Endian"), wxEmptyString, wxITEM_NORMAL);
 
254
    m_EndianessMenu.Append(MenuItem3);
 
255
    MenuItem4 = new wxMenuItem((&m_EndianessMenu), ID_MENUITEM4, _("Little Endian"), wxEmptyString, wxITEM_NORMAL);
 
256
    m_EndianessMenu.Append(MenuItem4);
 
257
    MenuItem5 = new wxMenuItem((&m_BlockSizeMenu), ID_MENUITEM5, _("1 Byte"), wxEmptyString, wxITEM_NORMAL);
 
258
    m_BlockSizeMenu.Append(MenuItem5);
 
259
    MenuItem6 = new wxMenuItem((&m_BlockSizeMenu), ID_MENUITEM6, _("2 Bytes"), wxEmptyString, wxITEM_NORMAL);
 
260
    m_BlockSizeMenu.Append(MenuItem6);
 
261
    MenuItem7 = new wxMenuItem((&m_BlockSizeMenu), ID_MENUITEM7, _("4 Bytes"), wxEmptyString, wxITEM_NORMAL);
 
262
    m_BlockSizeMenu.Append(MenuItem7);
 
263
    MenuItem8 = new wxMenuItem((&m_BlockSizeMenu), ID_MENUITEM8, _("8 Bytes"), wxEmptyString, wxITEM_NORMAL);
 
264
    m_BlockSizeMenu.Append(MenuItem8);
 
265
    MenuItem9 = new wxMenuItem((&m_ColsModeMenu), ID_MENUITEM9, _("Any"), wxEmptyString, wxITEM_NORMAL);
 
266
    m_ColsModeMenu.Append(MenuItem9);
 
267
    MenuItem10 = new wxMenu();
 
268
    MenuItem11 = new wxMenuItem(MenuItem10, ID_MENUITEM11, _("1"), wxEmptyString, wxITEM_NORMAL);
 
269
    MenuItem10->Append(MenuItem11);
 
270
    MenuItem12 = new wxMenuItem(MenuItem10, ID_MENUITEM12, _("2"), wxEmptyString, wxITEM_NORMAL);
 
271
    MenuItem10->Append(MenuItem12);
 
272
    MenuItem13 = new wxMenuItem(MenuItem10, ID_MENUITEM13, _("3"), wxEmptyString, wxITEM_NORMAL);
 
273
    MenuItem10->Append(MenuItem13);
 
274
    MenuItem14 = new wxMenuItem(MenuItem10, ID_MENUITEM14, _("4"), wxEmptyString, wxITEM_NORMAL);
 
275
    MenuItem10->Append(MenuItem14);
 
276
    MenuItem15 = new wxMenuItem(MenuItem10, ID_MENUITEM15, _("5"), wxEmptyString, wxITEM_NORMAL);
 
277
    MenuItem10->Append(MenuItem15);
 
278
    MenuItem16 = new wxMenuItem(MenuItem10, ID_MENUITEM16, _("6"), wxEmptyString, wxITEM_NORMAL);
 
279
    MenuItem10->Append(MenuItem16);
 
280
    MenuItem17 = new wxMenuItem(MenuItem10, ID_MENUITEM17, _("7"), wxEmptyString, wxITEM_NORMAL);
 
281
    MenuItem10->Append(MenuItem17);
 
282
    MenuItem18 = new wxMenuItem(MenuItem10, ID_MENUITEM18, _("8"), wxEmptyString, wxITEM_NORMAL);
 
283
    MenuItem10->Append(MenuItem18);
 
284
    MenuItem10->AppendSeparator();
 
285
    MenuItem32 = new wxMenuItem(MenuItem10, ID_MENUITEM32, _("Other"), wxEmptyString, wxITEM_NORMAL);
 
286
    MenuItem10->Append(MenuItem32);
 
287
    m_ColsModeMenu.Append(ID_MENUITEM10, _("Exactly"), MenuItem10, wxEmptyString);
 
288
    MenuItem19 = new wxMenu();
 
289
    MenuItem20 = new wxMenuItem(MenuItem19, ID_MENUITEM20, _("2"), wxEmptyString, wxITEM_NORMAL);
 
290
    MenuItem19->Append(MenuItem20);
 
291
    MenuItem21 = new wxMenuItem(MenuItem19, ID_MENUITEM21, _("3"), wxEmptyString, wxITEM_NORMAL);
 
292
    MenuItem19->Append(MenuItem21);
 
293
    MenuItem22 = new wxMenuItem(MenuItem19, ID_MENUITEM22, _("4"), wxEmptyString, wxITEM_NORMAL);
 
294
    MenuItem19->Append(MenuItem22);
 
295
    MenuItem23 = new wxMenuItem(MenuItem19, ID_MENUITEM23, _("5"), wxEmptyString, wxITEM_NORMAL);
 
296
    MenuItem19->Append(MenuItem23);
 
297
    MenuItem24 = new wxMenuItem(MenuItem19, ID_MENUITEM24, _("6"), wxEmptyString, wxITEM_NORMAL);
 
298
    MenuItem19->Append(MenuItem24);
 
299
    MenuItem25 = new wxMenuItem(MenuItem19, ID_MENUITEM25, _("7"), wxEmptyString, wxITEM_NORMAL);
 
300
    MenuItem19->Append(MenuItem25);
 
301
    MenuItem26 = new wxMenuItem(MenuItem19, ID_MENUITEM26, _("8"), wxEmptyString, wxITEM_NORMAL);
 
302
    MenuItem19->Append(MenuItem26);
 
303
    MenuItem19->AppendSeparator();
 
304
    MenuItem27 = new wxMenuItem(MenuItem19, ID_MENUITEM27, _("Other"), wxEmptyString, wxITEM_NORMAL);
 
305
    MenuItem19->Append(MenuItem27);
 
306
    m_ColsModeMenu.Append(ID_MENUITEM19, _("Multiple of"), MenuItem19, wxEmptyString);
 
307
    MenuItem28 = new wxMenu();
 
308
    MenuItem29 = new wxMenuItem(MenuItem28, ID_MENUITEM29, _("2"), wxEmptyString, wxITEM_NORMAL);
 
309
    MenuItem28->Append(MenuItem29);
 
310
    MenuItem30 = new wxMenuItem(MenuItem28, ID_MENUITEM30, _("4"), wxEmptyString, wxITEM_NORMAL);
 
311
    MenuItem28->Append(MenuItem30);
 
312
    MenuItem31 = new wxMenuItem(MenuItem28, ID_MENUITEM31, _("8"), wxEmptyString, wxITEM_NORMAL);
 
313
    MenuItem28->Append(MenuItem31);
 
314
    MenuItem28->AppendSeparator();
 
315
    MenuItem33 = new wxMenuItem(MenuItem28, ID_MENUITEM33, _("Other"), wxEmptyString, wxITEM_NORMAL);
 
316
    MenuItem28->Append(MenuItem33);
 
317
    m_ColsModeMenu.Append(ID_MENUITEM28, _("Power of"), MenuItem28, wxEmptyString);
 
318
    BoxSizer1->SetSizeHints(this);
 
319
 
 
320
    Connect(ID_BUTTON10,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&HexEditPanel::OnButton6Click);
 
321
    Connect(ID_BUTTON9,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&HexEditPanel::OnButton5Click);
 
322
    Connect(ID_BUTTON7,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&HexEditPanel::Onm_ColsModeClick);
 
323
    Connect(ID_BUTTON4,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&HexEditPanel::OnButton4Click);
 
324
    Connect(ID_BUTTON6,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&HexEditPanel::Onm_BlockSizeClick);
 
325
    Connect(ID_BUTTON5,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&HexEditPanel::Onm_EndianessClick);
 
326
    Connect(ID_BUTTON1,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&HexEditPanel::OnButton1Click);
 
327
    Connect(ID_BUTTON8,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&HexEditPanel::OnButton4Click1);
 
328
    Connect(ID_CHECKBOX1,wxEVT_COMMAND_CHECKBOX_CLICKED,(wxObjectEventFunction)&HexEditPanel::OnCheckBox1Click);
 
329
    m_DrawArea->Connect(wxEVT_PAINT,(wxObjectEventFunction)&HexEditPanel::OnContentPaint,0,this);
 
330
    m_DrawArea->Connect(wxEVT_ERASE_BACKGROUND,(wxObjectEventFunction)&HexEditPanel::OnDrawAreaEraseBackground,0,this);
 
331
    m_DrawArea->Connect(wxEVT_KEY_DOWN,(wxObjectEventFunction)&HexEditPanel::OnSpecialKeyDown,0,this);
 
332
    m_DrawArea->Connect(wxEVT_CHAR,(wxObjectEventFunction)&HexEditPanel::OnDrawAreaKeyDown,0,this);
 
333
    m_DrawArea->Connect(wxEVT_LEFT_DOWN,(wxObjectEventFunction)&HexEditPanel::OnDrawAreaLeftDown,0,this);
 
334
    m_DrawArea->Connect(wxEVT_LEFT_UP,(wxObjectEventFunction)&HexEditPanel::OnDrawAreaLeftUp,0,this);
 
335
    m_DrawArea->Connect(wxEVT_MOTION,(wxObjectEventFunction)&HexEditPanel::OnDrawAreaMouseMove,0,this);
 
336
    m_DrawArea->Connect(wxEVT_LEAVE_WINDOW,(wxObjectEventFunction)&HexEditPanel::OnDrawAreaLeftUp,0,this);
 
337
    m_DrawArea->Connect(wxEVT_MOUSEWHEEL,(wxObjectEventFunction)&HexEditPanel::OnContentMouseWheel,0,this);
 
338
    Connect(ID_SCROLLBAR1,wxEVT_SCROLL_TOP,(wxObjectEventFunction)&HexEditPanel::OnContentScroll);
 
339
    Connect(ID_SCROLLBAR1,wxEVT_SCROLL_BOTTOM,(wxObjectEventFunction)&HexEditPanel::OnContentScroll);
 
340
    Connect(ID_SCROLLBAR1,wxEVT_SCROLL_LINEUP,(wxObjectEventFunction)&HexEditPanel::OnContentScroll);
 
341
    Connect(ID_SCROLLBAR1,wxEVT_SCROLL_LINEDOWN,(wxObjectEventFunction)&HexEditPanel::OnContentScroll);
 
342
    Connect(ID_SCROLLBAR1,wxEVT_SCROLL_PAGEUP,(wxObjectEventFunction)&HexEditPanel::OnContentScroll);
 
343
    Connect(ID_SCROLLBAR1,wxEVT_SCROLL_PAGEDOWN,(wxObjectEventFunction)&HexEditPanel::OnContentScroll);
 
344
    Connect(ID_SCROLLBAR1,wxEVT_SCROLL_THUMBTRACK,(wxObjectEventFunction)&HexEditPanel::OnContentScroll);
 
345
    Connect(ID_SCROLLBAR1,wxEVT_SCROLL_THUMBRELEASE,(wxObjectEventFunction)&HexEditPanel::OnContentScroll);
 
346
    Connect(ID_SCROLLBAR1,wxEVT_SCROLL_CHANGED,(wxObjectEventFunction)&HexEditPanel::OnContentScroll);
 
347
    Connect(ID_TEXTCTRL1,wxEVT_COMMAND_TEXT_UPDATED,(wxObjectEventFunction)&HexEditPanel::Onm_ExpressionText);
 
348
    Connect(ID_TEXTCTRL1,wxEVT_COMMAND_TEXT_ENTER,(wxObjectEventFunction)&HexEditPanel::OnExpressionTextEnter);
 
349
    Connect(ID_BUTTON3,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&HexEditPanel::OnButton3Click1);
 
350
    Connect(ID_BUTTON2,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&HexEditPanel::OnButton2Click);
 
351
    Connect(ID_TIMER1,wxEVT_TIMER,(wxObjectEventFunction)&HexEditPanel::OnReparseTimerTrigger);
 
352
    Connect(ID_MENUITEM2,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetBaseBin);
 
353
    Connect(ID_MENUITEM1,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetBaseHex);
 
354
    Connect(ID_MENUITEM3,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetEndianessBig);
 
355
    Connect(ID_MENUITEM4,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetEndianessLittle);
 
356
    Connect(ID_MENUITEM5,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetBlockSize1);
 
357
    Connect(ID_MENUITEM6,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetBlockSize2);
 
358
    Connect(ID_MENUITEM7,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetBlockSize4);
 
359
    Connect(ID_MENUITEM8,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetBlockSize8);
 
360
    Connect(ID_MENUITEM9,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsMul1);
 
361
    Connect(ID_MENUITEM11,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsValue1);
 
362
    Connect(ID_MENUITEM12,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsValue2);
 
363
    Connect(ID_MENUITEM13,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsValue3);
 
364
    Connect(ID_MENUITEM14,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsValue4);
 
365
    Connect(ID_MENUITEM15,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsValue5);
 
366
    Connect(ID_MENUITEM16,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsValue6);
 
367
    Connect(ID_MENUITEM17,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsValue7);
 
368
    Connect(ID_MENUITEM18,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsValue8);
 
369
    Connect(ID_MENUITEM32,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsValueOther);
 
370
    Connect(ID_MENUITEM20,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsMul2);
 
371
    Connect(ID_MENUITEM21,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsMul3);
 
372
    Connect(ID_MENUITEM22,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsMul4);
 
373
    Connect(ID_MENUITEM23,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsMul5);
 
374
    Connect(ID_MENUITEM24,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsMul6);
 
375
    Connect(ID_MENUITEM25,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsMul7);
 
376
    Connect(ID_MENUITEM26,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsMul8);
 
377
    Connect(ID_MENUITEM27,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsMulOther);
 
378
    Connect(ID_MENUITEM29,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsPower2);
 
379
    Connect(ID_MENUITEM30,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsPower4);
 
380
    Connect(ID_MENUITEM31,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsPower8);
 
381
    Connect(ID_MENUITEM33,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&HexEditPanel::OnSetColsPowerOther);
 
382
    //*)
 
383
 
 
384
    // We connect these events manually
 
385
    m_DrawArea->Connect( wxEVT_SIZE, (wxObjectEventFunction)&HexEditPanel::OnContentSize,     0, this );
 
386
    m_DrawArea->SetBackgroundStyle( wxBG_STYLE_CUSTOM );
 
387
    Connect( wxEVT_SET_FOCUS, (wxObjectEventFunction)&HexEditPanel::OnForwardFocus );
 
388
 
 
389
    m_ActiveView = 0;
 
390
    m_LastScrollPos = 0;
 
391
    m_LastScrollUnits = 0;
 
392
    m_LinesPerScrollUnit = 1;
 
393
    CreateViews();
 
394
    RecalculateCoefs();
 
395
 
 
396
    ReparseExpression();
 
397
    SetFontSize( 8 );
 
398
    ReadContent();
 
399
 
 
400
    if ( m_Content && m_Content->GetSize() > 0x40000000ULL )
 
401
    {
 
402
        // Because of the filesize we have to map scroll units
 
403
        // to some number of lines
 
404
        m_LinesPerScrollUnit = m_Content->GetSize() / 0x20000000ULL;
 
405
    }
 
406
 
 
407
    RefreshStatus();
 
408
 
 
409
    m_Current = 0;
 
410
    PropagateOffsetChange();
 
411
 
 
412
    m_DrawArea->SetFocus();
 
413
 
 
414
    ((wxWindow*)Manager::Get()->GetEditorManager()->GetNotebook())->Layout();
 
415
 
 
416
    m_Shortname = title;
 
417
    SetTitle( m_Shortname );
 
418
 
 
419
    m_AllEditors.insert( this );
 
420
 
 
421
}
 
422
 
 
423
void HexEditPanel::CreateViews()
 
424
{
 
425
    for ( int i=0; i<MAX_VIEWS; ++i )
 
426
    {
 
427
        m_Views[ i ] = 0;
 
428
    }
 
429
 
 
430
    m_Views[ VIEW_DIGIT ] = m_DigitView = new DigitView( this );
 
431
    m_Views[ VIEW_CHARS ] = new CharacterView( this );
 
432
    ActivateView( m_Views[ 0 ] );
 
433
}
 
434
 
 
435
void HexEditPanel::ActivateView( HexEditViewBase* view )
 
436
{
 
437
    if ( view == m_ActiveView ) return;
 
438
 
 
439
    if ( m_ActiveView )
 
440
    {
 
441
        m_ActiveView->SetActive( false );
 
442
    }
 
443
 
 
444
    m_ActiveView = view;
 
445
    view->SetActive( true );
 
446
}
 
447
 
 
448
 
 
449
HexEditPanel::~HexEditPanel()
 
450
{
 
451
    for ( int i=0; i<MAX_VIEWS; ++i )
 
452
    {
 
453
        delete m_Views[ i ];
 
454
        m_Views[ i ] = 0;
 
455
    }
 
456
 
 
457
    m_AllEditors.erase( this );
 
458
 
 
459
    delete m_DrawFont;
 
460
    m_DrawFont = 0;
 
461
 
 
462
    delete m_Content;
 
463
    m_Content = 0;
 
464
 
 
465
        //(*Destroy(HexEditPanel)
 
466
        //*)
 
467
}
 
468
 
 
469
void HexEditPanel::SetFontSize( int size )
 
470
{
 
471
    delete m_DrawFont;
 
472
    m_DrawFont = wxFont::New( size, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString, wxFONTENCODING_DEFAULT );
 
473
}
 
474
 
 
475
void HexEditPanel::ReadContent()
 
476
{
 
477
    if ( m_Content ) delete m_Content;
 
478
 
 
479
    m_Content = FileContentBase::BuildInstance( m_FileName );
 
480
    if ( !m_Content )
 
481
    {
 
482
        m_ErrorString = _("Could not open the file (note that HexEditor may not be able to open big files)");
 
483
        return;
 
484
    }
 
485
 
 
486
    if ( !m_Content->ReadFile( m_FileName ) )
 
487
    {
 
488
        delete m_Content;
 
489
        m_Content = 0;
 
490
        m_ErrorString = _("Could not read the file");
 
491
        return;
 
492
    }
 
493
}
 
494
 
 
495
void HexEditPanel::RecalculateCoefs()
 
496
{
 
497
    // Calculate size of the font
 
498
    wxClientDC dc( this );
 
499
    dc.GetTextExtent( _T("0123456789ABCDEF"), &m_FontX, &m_FontY, NULL, NULL, m_DrawFont );
 
500
    m_FontX /= 16;
 
501
 
 
502
    // Calculate number of rows and columns in characters
 
503
    wxSize size = m_DrawArea->GetClientSize();
 
504
    m_Cols      = size.GetWidth() / m_FontX;
 
505
    m_Lines     = size.GetHeight() / m_FontY;
 
506
 
 
507
    // Calculate number of bytes in one line
 
508
    double avgByteCharacters = 0.0;
 
509
    int cumulativeBlockSize = 1;
 
510
    for ( int i=0; i<MAX_VIEWS; ++i )
 
511
    {
 
512
        int blockLength;
 
513
        int blockBytes;
 
514
        int spacing;
 
515
        m_Views[ i ]->GetBlockSizes( blockLength, blockBytes, spacing );
 
516
 
 
517
        avgByteCharacters  += ( (double)( blockLength + spacing ) ) / (double)blockBytes;
 
518
        cumulativeBlockSize = cumulativeBlockSize * blockBytes / NWD( cumulativeBlockSize, blockBytes );
 
519
    }
 
520
 
 
521
    int colsLeftForViews =
 
522
        m_Cols
 
523
          - 8               // Offset
 
524
          - 1               // ':' after offset
 
525
          - 2 * MAX_VIEWS   // spacing between views
 
526
          - 2;              // right margin
 
527
 
 
528
    int maxByteInLine = (int)( colsLeftForViews / avgByteCharacters );
 
529
 
 
530
    // Now we need to find such number of bytes to be multiple of cumulativeBlockSize
 
531
    // and try not to cross maxByteInLine
 
532
 
 
533
    // Additionally we try to mach required columns count,
 
534
    // this is a little bit naive approach but will work in generic way
 
535
    int maxColumns = std::max( (int)(maxByteInLine / cumulativeBlockSize), 1 );
 
536
    for ( int i=maxColumns;; i-- )
 
537
    {
 
538
        if ( i<1 )
 
539
        {
 
540
            for ( i=maxColumns+1; i<0x1000; ++i )
 
541
            {
 
542
                if ( MatchColumnsCount( i ) )
 
543
                {
 
544
                    maxColumns = i;
 
545
                    break;
 
546
                }
 
547
            }
 
548
            break;
 
549
        }
 
550
 
 
551
        if ( MatchColumnsCount( i ) )
 
552
        {
 
553
            maxColumns = i;
 
554
            break;
 
555
        }
 
556
    }
 
557
 
 
558
    m_ColsCount = maxColumns;
 
559
    m_LineBytes = maxColumns * cumulativeBlockSize;
 
560
 
 
561
    // Calculate column positions
 
562
    for ( int i=0; i<MAX_VIEWS; ++i )
 
563
    {
 
564
        int blockLength;
 
565
        int blockBytes;
 
566
        int spacing;
 
567
        m_Views[ i ]->GetBlockSizes( blockLength, blockBytes, spacing );
 
568
        m_ViewsCols[ i ] = ( ( m_LineBytes + blockBytes - 1 ) / blockBytes ) * ( blockLength + spacing );
 
569
    }
 
570
 
 
571
    // Adjust scroll bar
 
572
    OffsetT contentSize = m_Content ? m_Content->GetSize() : 0;
 
573
 
 
574
    int totalLines = ( contentSize + m_LineBytes          - 1 ) / m_LineBytes;
 
575
    int totalUnits = ( totalLines  + m_LinesPerScrollUnit - 1 ) / m_LinesPerScrollUnit;
 
576
    int thumbLines = ( m_Lines     + m_LinesPerScrollUnit - 1 ) / m_LinesPerScrollUnit;
 
577
 
 
578
    m_ContentScroll->SetScrollbar(
 
579
        m_ContentScroll->GetThumbPosition(),
 
580
        thumbLines,
 
581
        totalUnits,
 
582
        thumbLines );
 
583
}
 
584
 
 
585
void HexEditPanel::OnContentPaint( wxPaintEvent& event )
 
586
{
 
587
    wxAutoBufferedPaintDC dc( m_DrawArea );
 
588
    dc.SetBrush( GetBackgroundColour() );
 
589
    dc.SetPen  ( GetBackgroundColour() );
 
590
    dc.DrawRectangle( GetClientRect() );
 
591
 
 
592
    if ( !m_Content ) return;
 
593
 
 
594
    dc.SetFont( *m_DrawFont );
 
595
 
 
596
    OffsetT startOffs = DetectStartOffset();
 
597
 
 
598
    HexEditLineBuffer buff( m_Cols );
 
599
    char* content = new char[ m_Cols ];
 
600
 
 
601
    wxColour backgrounds[ stCount ] =
 
602
    {
 
603
        GetBackgroundColour(),
 
604
        wxColour( 0x70, 0x70, 0x70 ),
 
605
        wxColour( 0xA0, 0xA0, 0xFF ),
 
606
        wxColour( 0x80, 0x80, 0xFF ),
 
607
    };
 
608
 
 
609
    wxColour foregrounds[ stCount ] =
 
610
    {
 
611
        *wxBLACK,
 
612
        *wxWHITE,
 
613
        *wxWHITE,
 
614
        *wxBLACK,
 
615
    };
 
616
 
 
617
 
 
618
    for ( OffsetT j = 0; j < m_Lines; ++j )
 
619
    {
 
620
        buff.Reset();
 
621
 
 
622
        // Calculate offsets
 
623
        OffsetT offs    = startOffs + j * m_LineBytes;
 
624
        OffsetT offsMax = offs + m_LineBytes;
 
625
 
 
626
        // Add offset to view buffer
 
627
        for ( size_t i=8; i-->0; )
 
628
        {
 
629
            buff.PutChar( "0123456789ABCDEF"[ ( offs >> ( i << 2 ) ) & 0xF ] );
 
630
        }
 
631
        buff.PutChar(':');
 
632
 
 
633
        // Clamp offsets to content size
 
634
        offs    = wxMin( offs,    m_Content->GetSize() );
 
635
        offsMax = wxMin( offsMax, m_Content->GetSize() );
 
636
 
 
637
        if ( offs == offsMax ) continue;
 
638
 
 
639
        // Invoking views
 
640
        m_Content->Read( content, offs, offsMax - offs );
 
641
        for ( int i=0; i<MAX_VIEWS; ++i )
 
642
        {
 
643
            buff.PutString("  ");
 
644
            m_Views[ i ]->PutLine( offs, buff, content, offsMax - offs );
 
645
        }
 
646
 
 
647
        buff.Draw( dc, 0, j * m_FontY, m_FontX, m_FontY, foregrounds, backgrounds );
 
648
    }
 
649
 
 
650
    delete[] content;
 
651
}
 
652
 
 
653
void HexEditPanel::OnContentScroll( wxScrollEvent& event )
 
654
{
 
655
    if ( !m_Content || !m_Content->GetSize() )
 
656
    {
 
657
        return;
 
658
    }
 
659
 
 
660
    if ( m_ContentScroll->GetThumbPosition() == 0 )
 
661
    {
 
662
        DetectStartOffset();
 
663
        m_LastScrollPos   = 0;
 
664
    }
 
665
    else if ( m_ContentScroll->GetThumbPosition() >= m_ContentScroll->GetRange() - m_ContentScroll->GetThumbSize() )
 
666
    {
 
667
        DetectStartOffset();
 
668
        int totalLines = m_Content->GetSize() / m_LineBytes;
 
669
        m_LastScrollPos = totalLines - m_Lines + 1;
 
670
    }
 
671
 
 
672
    ClampCursorToVisibleArea();
 
673
    m_DrawArea->Refresh();
 
674
    RefreshStatus();
 
675
    m_DrawArea->SetFocus();
 
676
}
 
677
 
 
678
void HexEditPanel::OnContentScrollTop(wxScrollEvent& event)
 
679
{
 
680
    if ( !m_Content || !m_Content->GetSize() )
 
681
    {
 
682
        return;
 
683
    }
 
684
 
 
685
    m_LastScrollPos   = 0;
 
686
 
 
687
    LogManager::Get()->DebugLog( _T("Top") );
 
688
 
 
689
    OnContentScroll( event );
 
690
}
 
691
 
 
692
void HexEditPanel::OnContentScrollBottom(wxScrollEvent& event)
 
693
{
 
694
    if ( !m_Content || !m_Content->GetSize() )
 
695
    {
 
696
        return;
 
697
    }
 
698
 
 
699
    int totalLines = m_Content->GetSize() / m_LineBytes;
 
700
    m_LastScrollPos = totalLines - m_Lines + 1;
 
701
 
 
702
    LogManager::Get()->DebugLog( _T("Top") );
 
703
 
 
704
    OnContentScroll( event );
 
705
}
 
706
 
 
707
void HexEditPanel::OnContentSize( wxSizeEvent& event )
 
708
{
 
709
    RecalculateCoefs();
 
710
    EnsureCarretVisible();
 
711
    RefreshStatus();
 
712
    event.Skip();
 
713
}
 
714
 
 
715
FileContentBase::OffsetT HexEditPanel::DetectStartOffset()
 
716
{
 
717
    if ( !m_Content ) return 0;
 
718
 
 
719
    int currentUnits = m_ContentScroll->GetThumbPosition();
 
720
 
 
721
    if ( currentUnits < m_LastScrollUnits )
 
722
    {
 
723
        FileContentBase::OffsetT diff = ( m_LastScrollUnits - currentUnits ) * m_LinesPerScrollUnit;
 
724
        if ( m_LastScrollPos < diff )
 
725
        {
 
726
            m_LastScrollPos = 0;
 
727
        }
 
728
        else
 
729
        {
 
730
            m_LastScrollPos -= diff;
 
731
        }
 
732
    }
 
733
    else if ( currentUnits > m_LastScrollUnits )
 
734
    {
 
735
        m_LastScrollPos += ( currentUnits - m_LastScrollUnits ) * m_LinesPerScrollUnit;
 
736
        FileContentBase::OffsetT maxScrollPos = ( m_Content->GetSize() + m_LineBytes - 1 ) / m_LineBytes;
 
737
        if ( m_LastScrollPos >= maxScrollPos )
 
738
        {
 
739
            m_LastScrollPos = maxScrollPos-1;
 
740
        }
 
741
    }
 
742
 
 
743
    m_LastScrollUnits = currentUnits;
 
744
 
 
745
    return m_LastScrollPos * m_LineBytes;
 
746
}
 
747
 
 
748
void HexEditPanel::OnContentMouseWheel(wxMouseEvent& event)
 
749
{
 
750
    m_ContentScroll->SetThumbPosition(
 
751
        m_ContentScroll->GetThumbPosition() -
 
752
        2 * event.GetWheelRotation() / event.GetWheelDelta() );
 
753
    ClampCursorToVisibleArea();
 
754
    m_DrawArea->Refresh();
 
755
    RefreshStatus();
 
756
}
 
757
 
 
758
void HexEditPanel::RefreshStatus()
 
759
{
 
760
    if ( !m_Content )
 
761
    {
 
762
        m_Status->SetLabel( m_ErrorString );
 
763
        return;
 
764
    }
 
765
 
 
766
    FileContentBase::OffsetT size = m_Content->GetSize();
 
767
 
 
768
    if ( !size )
 
769
    {
 
770
        m_Status->SetLabel( _("File is empty") );
 
771
    }
 
772
    else
 
773
    {
 
774
        m_Status->SetLabel( F( _("Position: %llX / %llX ( %lld%% )"), m_Current, size-1, ( m_Current * 100 / (size-1) ) ) );
 
775
    }
 
776
 
 
777
    FileContentBase::OffsetT left = size - m_Current;
 
778
 
 
779
    if ( left >= sizeof( char ) )
 
780
    {
 
781
        char val;
 
782
        m_Content->Read( &val, m_Current, sizeof(val) );
 
783
        m_ByteVal->SetLabel( wxString::Format(_T("%d"),(int)val) );
 
784
    }
 
785
    else
 
786
    {
 
787
        m_ByteVal->SetLabel( _T("-") );
 
788
    }
 
789
 
 
790
    if ( left >= sizeof( short ) )
 
791
    {
 
792
        short val;
 
793
        m_Content->Read( &val, m_Current, sizeof(val) );
 
794
        m_WordVal->SetLabel( wxString::Format(_T("%d"),(int)val) );
 
795
    }
 
796
    else
 
797
    {
 
798
        m_WordVal->SetLabel( _T("-") );
 
799
    }
 
800
 
 
801
    if ( left >= sizeof( int ) )
 
802
    {
 
803
        int val;
 
804
        m_Content->Read( &val, m_Current, sizeof(val) );
 
805
        m_DwordVal->SetLabel( wxString::Format(_T("%d"),(int)val) );
 
806
    }
 
807
    else
 
808
    {
 
809
        m_DwordVal->SetLabel( _T("-") );
 
810
    }
 
811
 
 
812
    if ( left >= sizeof( float ) )
 
813
    {
 
814
        float val;
 
815
        m_Content->Read( &val, m_Current, sizeof(val) );
 
816
        m_FloatVal->SetLabel( wxString::Format(_T("%g"), val) );
 
817
    }
 
818
    else
 
819
    {
 
820
        m_FloatVal->SetLabel( _T("-") );
 
821
    }
 
822
 
 
823
    if ( left >= sizeof( double ) )
 
824
    {
 
825
        double val;
 
826
        m_Content->Read( &val, m_Current, sizeof(val) );
 
827
        m_DoubleVal->SetLabel( wxString::Format(_T("%g"), val) );
 
828
    }
 
829
    else
 
830
    {
 
831
        m_DoubleVal->SetLabel( _T("-") );
 
832
    }
 
833
 
 
834
    if ( left >= sizeof( long double ) )
 
835
    {
 
836
        long double val;
 
837
        m_Content->Read( &val, m_Current, sizeof(val) );
 
838
        if ( platform::windows )
 
839
        {
 
840
            // MinGW has broken support for long double
 
841
            m_LDoubleVal->SetLabel( wxString::Format(_T("%g"), (double)val) );
 
842
        }
 
843
        else
 
844
        {
 
845
            m_LDoubleVal->SetLabel( wxString::Format(_T("%Lg"), val) );
 
846
        }
 
847
    }
 
848
    else
 
849
    {
 
850
        m_LDoubleVal->SetLabel( _T("-") );
 
851
    }
 
852
 
 
853
    if ( m_ExpressionError.IsEmpty() )
 
854
    {
 
855
 
 
856
        Expression::Executor executor;
 
857
 
 
858
        wxStopWatch sw;
 
859
        if ( !executor.Execute( m_ExpressionCode, m_Content, m_Current ) )
 
860
        {
 
861
            m_ExpressionVal->SetLabel( executor.ErrorDesc() );
 
862
        }
 
863
        else
 
864
        {
 
865
//            LogManager::Get()->DebugLog( F( _T("HEExpr Calculate: %d"), (int)sw.Time() ) );
 
866
            unsigned long long uint;
 
867
            long long          sint;
 
868
            long double        flt;
 
869
 
 
870
            if ( executor.GetResult( uint ) )
 
871
            {
 
872
                m_ExpressionVal->SetLabel( wxString::Format( _T("%llu"), uint) );
 
873
            }
 
874
            else if ( executor.GetResult( sint ) )
 
875
            {
 
876
                m_ExpressionVal->SetLabel( wxString::Format( _T("%lld"), sint ) );
 
877
            }
 
878
            else if ( executor.GetResult( flt ) )
 
879
            {
 
880
                m_ExpressionVal->SetLabel( wxString::Format( _T("%g"), (double)flt ) );
 
881
            }
 
882
            else
 
883
            {
 
884
                m_ExpressionVal->SetLabel( _T("Error") );
 
885
            }
 
886
        }
 
887
    }
 
888
    else
 
889
    {
 
890
        m_ExpressionVal->SetLabel( m_ExpressionError );
 
891
    }
 
892
 
 
893
 
 
894
    if ( m_DigitView )
 
895
    {
 
896
        switch ( m_DigitView->GetDigitBits() )
 
897
        {
 
898
            case 1: m_DigitBits->SetLabel( _("Bin") ); break;
 
899
            case 4: m_DigitBits->SetLabel( _("Hex") ); break;
 
900
            default: m_DigitBits->SetLabel( wxString::Format( _("%d bits") , m_DigitView->GetDigitBits() ) );
 
901
        }
 
902
 
 
903
        switch ( m_DigitView->GetLittleEndian() )
 
904
        {
 
905
            case true:  m_Endianess->SetLabel( _("LE") ); break;
 
906
            case false: m_Endianess->SetLabel( _("BE") ); break;
 
907
        }
 
908
 
 
909
        m_BlockSize->SetLabel( wxString::Format( _("%dB"), m_DigitView->GetBlockBytes() ) );
 
910
 
 
911
        switch ( m_ColsMode )
 
912
        {
 
913
            case CM_SPECIFIED: m_ColsModeBtn->SetLabel( wxString::Format( _("Cols: %d"), m_ColsValue ) ); break;
 
914
            case CM_MULT:      m_ColsModeBtn->SetLabel( wxString::Format( _("Cols: %d ( n * %d )"), m_ColsCount, m_ColsValue ) ); break;
 
915
            case CM_POWER:     m_ColsModeBtn->SetLabel( wxString::Format( _("Cols: %d ( n ^ %d )"), m_ColsCount, m_ColsValue ) ); break;
 
916
            default:           m_ColsModeBtn->SetLabel( wxString::Format( _("Cols: %d ( Any )"), m_ColsCount ) );
 
917
        }
 
918
    }
 
919
}
 
920
 
 
921
void HexEditPanel::OnDrawAreaKeyDown(wxKeyEvent& event)
 
922
{
 
923
    if ( !m_Content || !m_Content->GetSize() ) return;
 
924
 
 
925
    m_ViewNotifyContentChange = false;
 
926
    m_ViewNotifyOffsetChange  = false;
 
927
 
 
928
    switch ( event.GetKeyCode() )
 
929
    {
 
930
        case WXK_LEFT:
 
931
        {
 
932
            m_ActiveView->MoveLeft();
 
933
            break;
 
934
        }
 
935
 
 
936
        case WXK_RIGHT:
 
937
        {
 
938
            m_ActiveView->MoveRight();
 
939
            break;
 
940
        }
 
941
 
 
942
        case WXK_UP:
 
943
        {
 
944
            m_ActiveView->MoveUp();
 
945
            break;
 
946
        }
 
947
 
 
948
        case WXK_DOWN:
 
949
        {
 
950
            m_ActiveView->MoveDown();
 
951
            break;
 
952
        }
 
953
 
 
954
        case WXK_PAGEDOWN:
 
955
        {
 
956
            for ( unsigned int i=0; i<m_Lines/2; i++ )
 
957
            {
 
958
                m_ActiveView->MoveDown();
 
959
            }
 
960
            break;
 
961
        }
 
962
 
 
963
        case WXK_PAGEUP:
 
964
        {
 
965
            for ( unsigned int i=0; i<m_Lines/2; i++ )
 
966
            {
 
967
                m_ActiveView->MoveUp();
 
968
            }
 
969
            break;
 
970
        }
 
971
 
 
972
        case WXK_TAB:
 
973
        {
 
974
            m_ActiveView->SetActive( false );
 
975
            int newViewId = -1;
 
976
            for ( int i=0; i<MAX_VIEWS; ++i )
 
977
            {
 
978
                if ( m_ActiveView == m_Views[ i ] )
 
979
                {
 
980
                    newViewId = ( i + 1 ) % MAX_VIEWS;
 
981
                    break;
 
982
                }
 
983
            }
 
984
            if ( newViewId < 0 ) newViewId = 0;
 
985
            m_ActiveView = m_Views[ newViewId ];
 
986
            m_ActiveView->SetActive( true );
 
987
            m_ViewNotifyContentChange = true;
 
988
            break;
 
989
        }
 
990
 
 
991
        case WXK_HOME:
 
992
        {
 
993
            m_Current = 0;
 
994
            m_ViewNotifyOffsetChange = true;
 
995
            break;
 
996
        }
 
997
 
 
998
        case WXK_END:
 
999
        {
 
1000
 
 
1001
            m_Current = m_Content->GetSize()-1;
 
1002
            m_ViewNotifyOffsetChange = true;
 
1003
            break;
 
1004
        }
 
1005
 
 
1006
        case WXK_INSERT:
 
1007
        {
 
1008
            // Insert empty byte at current position
 
1009
            FileContentBase::ExtraUndoData data(
 
1010
                m_ActiveView,
 
1011
                m_Current, m_ActiveView->GetCurrentPositionFlags(),
 
1012
                m_Current, m_ActiveView->GetCurrentPositionFlags() );
 
1013
            m_Content->Add( data, m_Current, 1, 0 );
 
1014
            m_ViewNotifyContentChange = true;
 
1015
            break;
 
1016
        }
 
1017
 
 
1018
        case WXK_DELETE:
 
1019
        {
 
1020
            FileContentBase::ExtraUndoData data(
 
1021
                m_ActiveView,
 
1022
                m_Current, m_ActiveView->GetCurrentPositionFlags(),
 
1023
                m_Current, m_ActiveView->GetCurrentPositionFlags() );
 
1024
            m_Content->Remove( data, m_Current, 1 );
 
1025
            m_ViewNotifyContentChange = true;
 
1026
            break;
 
1027
        }
 
1028
 
 
1029
        default:
 
1030
        {
 
1031
            m_ActiveView->PutChar( event.GetUnicodeKey() );
 
1032
            break;
 
1033
        }
 
1034
    }
 
1035
 
 
1036
    if ( m_ViewNotifyOffsetChange )
 
1037
    {
 
1038
        EnsureCarretVisible();
 
1039
        PropagateOffsetChange();
 
1040
        RefreshStatus();
 
1041
        m_ViewNotifyContentChange = true;
 
1042
    }
 
1043
 
 
1044
    if ( m_ViewNotifyContentChange )
 
1045
    {
 
1046
        m_DrawArea->Refresh();
 
1047
        UpdateModified();
 
1048
    }
 
1049
}
 
1050
 
 
1051
void HexEditPanel::EnsureCarretVisible()
 
1052
{
 
1053
    FileContentBase::OffsetT line      = m_Current / m_LineBytes;
 
1054
    FileContentBase::OffsetT startLine = DetectStartOffset() / m_LineBytes;
 
1055
    FileContentBase::OffsetT endLine   = startLine + m_Lines;
 
1056
 
 
1057
    if ( line < startLine )
 
1058
    {
 
1059
        m_LastScrollPos   = line;
 
1060
        m_LastScrollUnits = line / m_LinesPerScrollUnit;
 
1061
 
 
1062
        m_ContentScroll->SetThumbPosition( m_LastScrollUnits );
 
1063
        m_DrawArea->Refresh();
 
1064
    }
 
1065
    else if ( line >= endLine )
 
1066
    {
 
1067
        line = line - m_Lines + 1;
 
1068
 
 
1069
        m_LastScrollPos   = line;
 
1070
        m_LastScrollUnits = line / m_LinesPerScrollUnit;
 
1071
 
 
1072
        m_ContentScroll->SetThumbPosition( m_LastScrollUnits );
 
1073
        m_DrawArea->Refresh();
 
1074
    }
 
1075
}
 
1076
 
 
1077
void HexEditPanel::ClampCursorToVisibleArea()
 
1078
{
 
1079
    FileContentBase::OffsetT startOffs = DetectStartOffset();
 
1080
    FileContentBase::OffsetT endOffs   = startOffs + m_LineBytes * m_Lines;
 
1081
 
 
1082
    bool changed = false;
 
1083
 
 
1084
    if ( m_Current < startOffs )
 
1085
    {
 
1086
        m_Current = startOffs + ( m_Current % m_LineBytes );
 
1087
        changed = true;
 
1088
    }
 
1089
    else if ( m_Current >= endOffs )
 
1090
    {
 
1091
        m_Current = endOffs - m_LineBytes + ( m_Current % m_LineBytes );
 
1092
        changed = true;
 
1093
    }
 
1094
 
 
1095
    if ( m_Current >= m_Content->GetSize() )
 
1096
    {
 
1097
        m_Current = m_Content->GetSize() - 1;
 
1098
        changed = true;
 
1099
    }
 
1100
 
 
1101
    if ( changed )
 
1102
    {
 
1103
        PropagateOffsetChange();
 
1104
    }
 
1105
}
 
1106
 
 
1107
void HexEditPanel::PropagateOffsetChange( int flagsForCurrentView )
 
1108
{
 
1109
    if ( !m_Content ) return;
 
1110
 
 
1111
    OffsetT startOffs  = DetectStartOffset();
 
1112
 
 
1113
    OffsetT blockStart = m_Current;
 
1114
    OffsetT blockEnd   = m_Current + 1;
 
1115
 
 
1116
    // First let's calculate block size
 
1117
    for ( int i=0; i<MAX_VIEWS && m_Views[ i ]; ++i )
 
1118
    {
 
1119
        OffsetT thisBlockStart = blockStart;
 
1120
        OffsetT thisBlockEnd   = blockEnd;
 
1121
        m_Views[i]->CalculateBlockSize( startOffs, m_Current, thisBlockStart, thisBlockEnd );
 
1122
        blockStart = wxMin( blockStart, thisBlockStart );
 
1123
        blockEnd   = wxMax( blockEnd,   thisBlockEnd   );
 
1124
    }
 
1125
 
 
1126
    // Next we can propagate the offset
 
1127
    for ( int i=0; i<MAX_VIEWS && m_Views[ i ]; ++i )
 
1128
    {
 
1129
        m_Views[i]->JumpToOffset( startOffs, m_Current, blockStart, blockEnd, ( m_Views[ i ] == m_ActiveView ) ? flagsForCurrentView : -1 );
 
1130
    }
 
1131
}
 
1132
 
 
1133
void HexEditPanel::OnDrawAreaEraseBackground(wxEraseEvent& event)
 
1134
{
 
1135
}
 
1136
 
 
1137
void HexEditPanel::OnForwardFocus(wxFocusEvent& event)
 
1138
{
 
1139
    m_DrawArea->SetFocus();
 
1140
}
 
1141
 
 
1142
bool HexEditPanel::Save()
 
1143
{
 
1144
    bool ret = m_Content->WriteFile( GetFilename() );
 
1145
    UpdateModified();
 
1146
    return ret;
 
1147
}
 
1148
 
 
1149
bool HexEditPanel::SaveAs()
 
1150
{
 
1151
    wxFileName fname;
 
1152
    fname.Assign(GetFilename());
 
1153
    ConfigManager* mgr = Manager::Get()->GetConfigManager(_T("app"));
 
1154
 
 
1155
    wxString Path = fname.GetPath();
 
1156
 
 
1157
    if(mgr && Path.IsEmpty())
 
1158
        Path = mgr->Read(_T("/file_dialogs/save_file_as/directory"), Path);
 
1159
 
 
1160
    wxFileDialog dlg(Manager::Get()->GetAppWindow(),
 
1161
                      _("Save file"),
 
1162
                      Path,
 
1163
                      fname.GetFullName(),
 
1164
                      _T("*.*"),//m_filecontent->GetWildcard(),
 
1165
                      wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
 
1166
 
 
1167
    if (dlg.ShowModal() != wxID_OK) // cancelled out
 
1168
    {
 
1169
        UpdateModified();
 
1170
        return false;
 
1171
    }
 
1172
 
 
1173
    SetFilename(dlg.GetPath());
 
1174
    return Save();
 
1175
}
 
1176
 
 
1177
bool HexEditPanel::GetModified() const
 
1178
{
 
1179
    return m_Content ? m_Content->Modified() : false;
 
1180
}
 
1181
 
 
1182
void HexEditPanel::SetModified( bool modified )
 
1183
{
 
1184
    if ( m_Content ) m_Content->SetModified( modified );
 
1185
}
 
1186
 
 
1187
void HexEditPanel::UpdateModified()
 
1188
{
 
1189
    if ( GetModified() )
 
1190
    {
 
1191
        SetTitle( _T("*") + GetShortName() );
 
1192
    }
 
1193
    else
 
1194
    {
 
1195
        SetTitle( GetShortName() );
 
1196
    }
 
1197
}
 
1198
 
 
1199
void HexEditPanel::SetFilename(const wxString& filename)
 
1200
{
 
1201
    EditorBase::SetFilename(filename);
 
1202
    //m_Filename = filename; done by EditorBase::SetFilename
 
1203
    wxFileName fname;
 
1204
    fname.Assign(m_Filename);
 
1205
    m_Shortname = fname.GetFullName();
 
1206
}
 
1207
 
 
1208
void HexEditPanel::OnDrawAreaLeftDown(wxMouseEvent& event)
 
1209
{
 
1210
    if ( !m_Content ) return;
 
1211
 
 
1212
    m_DrawArea->SetFocus();
 
1213
 
 
1214
    // First we need to detect what the user has clicked on
 
1215
    int line   = event.GetY() / m_FontY;
 
1216
    int column = event.GetX() / m_FontX;
 
1217
 
 
1218
    // Just to prevent some weird situation
 
1219
    line   = wxMin( line,   (int)m_Lines - 1 );
 
1220
    column = wxMin( column, (int)m_Cols  - 1 );
 
1221
    line   = wxMax( line,   0 );
 
1222
    column = wxMax( column, 0 );
 
1223
 
 
1224
    // Detect what has been pressed
 
1225
 
 
1226
    if ( !m_MouseDown )
 
1227
    {
 
1228
        if ( column < 9 )
 
1229
        {
 
1230
            // Offset pressed
 
1231
            return;
 
1232
        }
 
1233
    }
 
1234
    column -= 9;
 
1235
 
 
1236
    int viewId = -1;
 
1237
 
 
1238
    for ( int i=0; i<MAX_VIEWS; ++i )
 
1239
    {
 
1240
        column -= 2;
 
1241
 
 
1242
        if ( !m_MouseDown )
 
1243
        {
 
1244
            if ( column < 0 ) break;
 
1245
 
 
1246
            if ( column < (int)m_ViewsCols[ i ] )
 
1247
            {
 
1248
                // Clicked on the area of i-th view
 
1249
                ActivateView( m_Views[ i ] );
 
1250
 
 
1251
                viewId = i;
 
1252
                break;
 
1253
            }
 
1254
        }
 
1255
        else if ( m_Views[ i ] == m_ActiveView )
 
1256
        {
 
1257
            viewId = i;
 
1258
            break;
 
1259
        }
 
1260
 
 
1261
        column -= m_ViewsCols[ i ];
 
1262
    }
 
1263
 
 
1264
    if ( viewId >= 0  )
 
1265
    {
 
1266
        m_MouseDown = true;
 
1267
 
 
1268
        column = wxMax( column, 0 );
 
1269
        column = wxMin( column, (int)m_ViewsCols[ viewId ] );
 
1270
 
 
1271
        int positionFlags;
 
1272
        int lineOffset = m_Views[ viewId ]->GetOffsetFromColumn( column, positionFlags );
 
1273
        lineOffset = wxMin( lineOffset, (int)m_LineBytes - 1 );
 
1274
        lineOffset = wxMax( lineOffset, 0 );
 
1275
 
 
1276
        OffsetT newCurrent = DetectStartOffset() + m_LineBytes * line + lineOffset;
 
1277
 
 
1278
        if ( newCurrent < m_Content->GetSize() )
 
1279
        {
 
1280
            if ( ( newCurrent != m_Current ) || ( positionFlags != m_Views[ viewId ]->GetCurrentPositionFlags() ) )
 
1281
            {
 
1282
                m_Current = newCurrent;
 
1283
                PropagateOffsetChange( positionFlags );
 
1284
                RefreshStatus();
 
1285
                EnsureCarretVisible();
 
1286
                m_DrawArea->Refresh();
 
1287
            }
 
1288
        }
 
1289
    }
 
1290
    else
 
1291
    {
 
1292
        m_MouseDown = false;
 
1293
        // Clicked somewhere after all views
 
1294
    }
 
1295
}
 
1296
 
 
1297
void HexEditPanel::OnDrawAreaLeftUp(wxMouseEvent& event)
 
1298
{
 
1299
    m_MouseDown = false;
 
1300
}
 
1301
 
 
1302
void HexEditPanel::OnDrawAreaMouseMove(wxMouseEvent& event)
 
1303
{
 
1304
    if ( m_MouseDown )
 
1305
    {
 
1306
        OnDrawAreaLeftDown( event );
 
1307
    }
 
1308
}
 
1309
 
 
1310
void HexEditPanel::OnCheckBox1Click(wxCommandEvent& event)
 
1311
{
 
1312
    if ( !m_Content ) return;
 
1313
    BoxSizer1->Show( PreviewSizer, CheckBox1->GetValue() );
 
1314
    m_DrawArea->SetFocus();
 
1315
    Layout();
 
1316
}
 
1317
 
 
1318
bool HexEditPanel::CanUndo() const
 
1319
{
 
1320
    return m_Content ? m_Content->CanUndo() : false;
 
1321
}
 
1322
 
 
1323
bool HexEditPanel::CanRedo() const
 
1324
{
 
1325
    return m_Content ? m_Content->CanRedo() : false;
 
1326
}
 
1327
 
 
1328
void HexEditPanel::Undo()
 
1329
{
 
1330
    if ( m_Content )
 
1331
    {
 
1332
        const FileContentBase::ExtraUndoData* extraData = m_Content->Undo();
 
1333
        if ( extraData )
 
1334
        {
 
1335
            m_Current = extraData->m_PosBefore;
 
1336
            ActivateView( extraData->m_View );
 
1337
            PropagateOffsetChange( extraData->m_PosBeforeF );
 
1338
        }
 
1339
        RefreshStatus();
 
1340
        EnsureCarretVisible();
 
1341
        m_DrawArea->Refresh();
 
1342
        UpdateModified();
 
1343
    }
 
1344
}
 
1345
 
 
1346
void HexEditPanel::Redo()
 
1347
{
 
1348
    if ( m_Content )
 
1349
    {
 
1350
        const FileContentBase::ExtraUndoData* extraData = m_Content->Redo();
 
1351
        if ( extraData )
 
1352
        {
 
1353
            m_Current = extraData->m_PosAfter;
 
1354
            ActivateView( extraData->m_View );
 
1355
            PropagateOffsetChange( extraData->m_PosAfterF );
 
1356
        }
 
1357
        RefreshStatus();
 
1358
        EnsureCarretVisible();
 
1359
        m_DrawArea->Refresh();
 
1360
        UpdateModified();
 
1361
    }
 
1362
}
 
1363
 
 
1364
void HexEditPanel::OnSpecialKeyDown(wxKeyEvent& event)
 
1365
{
 
1366
//    LogManager::Get()->DebugLog(
 
1367
//        F(
 
1368
//            _T("HexEditPanel::OnSpecialKeyDown: %d (%c%c%c)"),
 
1369
//            (int)event.GetKeyCode(),
 
1370
//            event.ControlDown() ? 'C':'c',
 
1371
//            event.AltDown() ? 'A':'a',
 
1372
//            event.CmdDown() ? 'M':'m' ) );
 
1373
 
 
1374
    if ( event.ControlDown() && !event.AltDown() )
 
1375
    {
 
1376
        switch ( event.GetKeyCode() )
 
1377
        {
 
1378
            case 'G': ProcessGoto(); return;
 
1379
            case 'F': ProcessSearch(); return;
 
1380
        }
 
1381
    }
 
1382
 
 
1383
    event.Skip();
 
1384
}
 
1385
 
 
1386
bool HexEditPanel::IsHexEditor( EditorBase* editor )
 
1387
{
 
1388
    return m_AllEditors.find( editor ) != m_AllEditors.end();
 
1389
}
 
1390
 
 
1391
void HexEditPanel::CloseAllEditors()
 
1392
{
 
1393
    EditorsSet s = m_AllEditors;
 
1394
    for ( EditorsSet::iterator i = s.begin(); i != s.end(); ++i )
 
1395
    {
 
1396
        EditorManager::Get()->QueryClose( *i );
 
1397
        (*i)->Close();
 
1398
    }
 
1399
 
 
1400
    assert( m_AllEditors.empty() );
 
1401
}
 
1402
 
 
1403
void HexEditPanel::ProcessGoto()
 
1404
{
 
1405
    if ( !m_Content ) return;
 
1406
    if ( !m_Content->GetSize() ) return;
 
1407
 
 
1408
 
 
1409
    OffsetT offset;
 
1410
    wxString str = wxString::Format( _T("%lld"), m_Current );
 
1411
    for ( ;; )
 
1412
    {
 
1413
        str = wxGetTextFromUser(
 
1414
            _("Enter offset\n"
 
1415
              "\n"
 
1416
              "Available forms are:\n"
 
1417
              " * Decimal ( 100 )\n"
 
1418
              " * Hexadecimal ( 1AB, 0x1AB, 1ABh )\n"
 
1419
              " * Offset from current ( +100, -100, +0x1AB )"),
 
1420
            _("Goto offset"),
 
1421
            str );
 
1422
 
 
1423
        if ( str.IsEmpty() ) return;
 
1424
        str.Trim( true ).Trim( false );
 
1425
 
 
1426
        // Decided to parse manually since wxString::ToULongLong does not work everywhere
 
1427
 
 
1428
        const wxChar* ptr = str.c_str();
 
1429
        bool relativePlus  = false;
 
1430
        bool relativeMinus = false;
 
1431
        bool canBeDec = true;
 
1432
        bool canBeHex = true;
 
1433
 
 
1434
        OffsetT dec = 0;
 
1435
        OffsetT hex = 0;
 
1436
 
 
1437
        if ( *ptr == _T('+') )
 
1438
        {
 
1439
            relativePlus = true;
 
1440
            ptr++;
 
1441
        }
 
1442
        else if ( *ptr == _T('-') )
 
1443
        {
 
1444
            relativeMinus = true;
 
1445
            ptr++;
 
1446
        }
 
1447
 
 
1448
        while ( wxIsspace( *ptr ) ) ptr++;
 
1449
 
 
1450
        if ( ptr[0] == _T('0') && wxToupper(ptr[1]) == _T('X') )
 
1451
        {
 
1452
            canBeDec = false;
 
1453
            ptr += 2;
 
1454
        }
 
1455
 
 
1456
        while ( *ptr )
 
1457
        {
 
1458
            int digitVal = wxString( _T("0123456789ABCDEF") ).Find( wxToupper( *ptr++ ) );
 
1459
 
 
1460
            if ( digitVal == wxNOT_FOUND )
 
1461
            {
 
1462
                canBeDec = false;
 
1463
                canBeHex = false;
 
1464
                break;
 
1465
            }
 
1466
 
 
1467
            if ( digitVal >= 10 ) canBeDec = false;
 
1468
 
 
1469
            dec = dec *   10 + digitVal;
 
1470
            hex = hex * 0x10 + digitVal;
 
1471
 
 
1472
            if ( wxToupper(ptr[0]) == _T('H') && !ptr[1] )
 
1473
            {
 
1474
                canBeDec = false;
 
1475
                break;
 
1476
            }
 
1477
        }
 
1478
 
 
1479
        if ( canBeDec || canBeHex )
 
1480
        {
 
1481
            OffsetT val = canBeDec ? dec : hex;
 
1482
            OffsetT max = m_Content->GetSize() - 1;
 
1483
            if ( relativePlus )
 
1484
            {
 
1485
                offset = m_Current + val < max ? m_Current + val : max;
 
1486
            }
 
1487
            else if ( relativeMinus )
 
1488
            {
 
1489
                offset = m_Current > val ? m_Current - val : 0;
 
1490
            }
 
1491
            else
 
1492
            {
 
1493
                offset = wxMin( max, val );
 
1494
            }
 
1495
            break;
 
1496
        }
 
1497
 
 
1498
        cbMessageBox( _("Invalid offset !!!.\n") );
 
1499
    }
 
1500
 
 
1501
    m_Current = offset;
 
1502
    PropagateOffsetChange();
 
1503
    RefreshStatus();
 
1504
    EnsureCarretVisible();
 
1505
    m_DrawArea->Refresh();
 
1506
}
 
1507
 
 
1508
void HexEditPanel::ProcessSearch()
 
1509
{
 
1510
    if ( !m_Content ) return;
 
1511
    if ( !m_Content->GetSize() ) return;
 
1512
 
 
1513
    SearchDialog dlg( this, m_Content, m_Current );
 
1514
    if ( dlg.ShowModal() == wxID_OK )
 
1515
    {
 
1516
        m_Current = dlg.GetOffset();
 
1517
        PropagateOffsetChange();
 
1518
        RefreshStatus();
 
1519
        EnsureCarretVisible();
 
1520
        m_DrawArea->Refresh();
 
1521
    }
 
1522
 
 
1523
    m_DrawArea->SetFocus();
 
1524
}
 
1525
 
 
1526
void HexEditPanel::OnButton1Click(wxCommandEvent& event)
 
1527
{
 
1528
    ExpressionTester( 0, m_Content, m_Current).ShowModal();
 
1529
}
 
1530
 
 
1531
void HexEditPanel::ReparseExpression()
 
1532
{
 
1533
    Expression::Parser parser;
 
1534
    if ( !parser.Parse( m_Expression->GetValue(), m_ExpressionCode ) )
 
1535
    {
 
1536
        int pos;
 
1537
        m_ExpressionError = parser.ParseErrorDesc( pos );
 
1538
    }
 
1539
    else
 
1540
    {
 
1541
        m_ExpressionError.Clear();
 
1542
    }
 
1543
}
 
1544
 
 
1545
void HexEditPanel::OnReparseTimerTrigger(wxTimerEvent& event)
 
1546
{
 
1547
    ReparseExpression();
 
1548
    RefreshStatus();
 
1549
}
 
1550
 
 
1551
void HexEditPanel::Onm_ExpressionText(wxCommandEvent& event)
 
1552
{
 
1553
    ReparseTimer.Start( 1000, wxTIMER_ONE_SHOT );
 
1554
}
 
1555
 
 
1556
void HexEditPanel::OnButton2Click(wxCommandEvent& event)
 
1557
{
 
1558
    cbMessageBox( Expression::Parser::GetHelpString() );
 
1559
}
 
1560
 
 
1561
void HexEditPanel::OnExpressionTextEnter(wxCommandEvent& event)
 
1562
{
 
1563
    ReparseExpression();
 
1564
    RefreshStatus();
 
1565
    ReparseTimer.Stop();
 
1566
}
 
1567
 
 
1568
void HexEditPanel::OnButton3Click1(wxCommandEvent& event)
 
1569
{
 
1570
    SelectStoredExpressionDlg dlg( this, m_Expression->GetValue() );
 
1571
    if ( dlg.ShowModal() == wxID_OK )
 
1572
    {
 
1573
        m_Expression->SetValue( dlg.GetExpression() );
 
1574
        OnExpressionTextEnter(event);
 
1575
    }
 
1576
}
 
1577
 
 
1578
void HexEditPanel::OnButton4Click(wxCommandEvent& event)
 
1579
{
 
1580
    PopupMenu( &m_BaseMenu );
 
1581
}
 
1582
 
 
1583
void HexEditPanel::OnSetBaseHex(wxCommandEvent& event)
 
1584
{
 
1585
    m_DigitView->SetDigitBits( 4 );
 
1586
    DisplayChanged();
 
1587
}
 
1588
 
 
1589
void HexEditPanel::OnSetBaseBin(wxCommandEvent& event)
 
1590
{
 
1591
    m_DigitView->SetDigitBits( 1 );
 
1592
    DisplayChanged();
 
1593
}
 
1594
 
 
1595
void HexEditPanel::DisplayChanged()
 
1596
{
 
1597
    RecalculateCoefs();
 
1598
    RefreshStatus();
 
1599
    EnsureCarretVisible();
 
1600
    m_DrawArea->Refresh();
 
1601
    m_DrawArea->SetFocus();
 
1602
}
 
1603
 
 
1604
void HexEditPanel::Onm_EndianessClick(wxCommandEvent& event)
 
1605
{
 
1606
    PopupMenu( &m_EndianessMenu );
 
1607
}
 
1608
 
 
1609
void HexEditPanel::OnSetEndianessBig(wxCommandEvent& event)
 
1610
{
 
1611
    m_DigitView->SetLittleEndian( false );
 
1612
    DisplayChanged();
 
1613
}
 
1614
 
 
1615
void HexEditPanel::OnSetEndianessLittle(wxCommandEvent& event)
 
1616
{
 
1617
    m_DigitView->SetLittleEndian( true );
 
1618
    DisplayChanged();
 
1619
}
 
1620
 
 
1621
void HexEditPanel::Onm_BlockSizeClick(wxCommandEvent& event)
 
1622
{
 
1623
    PopupMenu( &m_BlockSizeMenu );
 
1624
}
 
1625
 
 
1626
void HexEditPanel::OnSetBlockSize1(wxCommandEvent& event)
 
1627
{
 
1628
    m_DigitView->SetBlockBytes( 1 );
 
1629
    DisplayChanged();
 
1630
}
 
1631
 
 
1632
void HexEditPanel::OnSetBlockSize2(wxCommandEvent& event)
 
1633
{
 
1634
    m_DigitView->SetBlockBytes( 2 );
 
1635
    DisplayChanged();
 
1636
}
 
1637
 
 
1638
void HexEditPanel::OnSetBlockSize4(wxCommandEvent& event)
 
1639
{
 
1640
    m_DigitView->SetBlockBytes( 4 );
 
1641
    DisplayChanged();
 
1642
}
 
1643
 
 
1644
void HexEditPanel::OnSetBlockSize8(wxCommandEvent& event)
 
1645
{
 
1646
    m_DigitView->SetBlockBytes( 8 );
 
1647
    DisplayChanged();
 
1648
}
 
1649
 
 
1650
void HexEditPanel::Onm_ColsModeClick(wxCommandEvent& event)
 
1651
{
 
1652
    PopupMenu( &m_ColsModeMenu );
 
1653
}
 
1654
 
 
1655
void HexEditPanel::OnSetColsMul1(wxCommandEvent& event)
 
1656
{
 
1657
    ColsMode( CM_MULT, 1 );
 
1658
}
 
1659
 
 
1660
void HexEditPanel::OnSetColsMul2(wxCommandEvent& event)
 
1661
{
 
1662
    ColsMode( CM_MULT, 2 );
 
1663
}
 
1664
 
 
1665
void HexEditPanel::OnSetColsMul3(wxCommandEvent& event)
 
1666
{
 
1667
    ColsMode( CM_MULT, 3 );
 
1668
}
 
1669
 
 
1670
void HexEditPanel::OnSetColsMul4(wxCommandEvent& event)
 
1671
{
 
1672
    ColsMode( CM_MULT, 4 );
 
1673
}
 
1674
 
 
1675
void HexEditPanel::OnSetColsMul5(wxCommandEvent& event)
 
1676
{
 
1677
    ColsMode( CM_MULT, 5 );
 
1678
}
 
1679
 
 
1680
void HexEditPanel::OnSetColsMul6(wxCommandEvent& event)
 
1681
{
 
1682
    ColsMode( CM_MULT, 6 );
 
1683
}
 
1684
 
 
1685
void HexEditPanel::OnSetColsMul7(wxCommandEvent& event)
 
1686
{
 
1687
    ColsMode( CM_MULT, 7 );
 
1688
}
 
1689
 
 
1690
void HexEditPanel::OnSetColsMul8(wxCommandEvent& event)
 
1691
{
 
1692
    ColsMode( CM_MULT, 8 );
 
1693
}
 
1694
 
 
1695
void HexEditPanel::OnSetColsMulOther(wxCommandEvent& event)
 
1696
{
 
1697
    long val = ::wxGetNumberFromUser( _("Enter number"), _("Enter number"), _("Colums setting"), 2, 2, 100, this );
 
1698
    if ( val > 0 ) ColsMode( CM_MULT, val );
 
1699
}
 
1700
 
 
1701
void HexEditPanel::OnSetColsValue1(wxCommandEvent& event)
 
1702
{
 
1703
    ColsMode( CM_SPECIFIED, 1 );
 
1704
}
 
1705
 
 
1706
void HexEditPanel::OnSetColsValue2(wxCommandEvent& event)
 
1707
{
 
1708
    ColsMode( CM_SPECIFIED, 2 );
 
1709
}
 
1710
 
 
1711
void HexEditPanel::OnSetColsValue3(wxCommandEvent& event)
 
1712
{
 
1713
    ColsMode( CM_SPECIFIED, 3 );
 
1714
}
 
1715
 
 
1716
void HexEditPanel::OnSetColsValue4(wxCommandEvent& event)
 
1717
{
 
1718
    ColsMode( CM_SPECIFIED, 4 );
 
1719
}
 
1720
 
 
1721
void HexEditPanel::OnSetColsValue5(wxCommandEvent& event)
 
1722
{
 
1723
    ColsMode( CM_SPECIFIED, 5 );
 
1724
}
 
1725
 
 
1726
void HexEditPanel::OnSetColsValue6(wxCommandEvent& event)
 
1727
{
 
1728
    ColsMode( CM_SPECIFIED, 6 );
 
1729
}
 
1730
 
 
1731
void HexEditPanel::OnSetColsValue7(wxCommandEvent& event)
 
1732
{
 
1733
    ColsMode( CM_SPECIFIED, 7 );
 
1734
}
 
1735
 
 
1736
void HexEditPanel::OnSetColsValue8(wxCommandEvent& event)
 
1737
{
 
1738
    ColsMode( CM_SPECIFIED, 8 );
 
1739
}
 
1740
 
 
1741
void HexEditPanel::OnSetColsValueOther(wxCommandEvent& event)
 
1742
{
 
1743
    long val = ::wxGetNumberFromUser( _("Enter number"), _("Enter number"), _("Colums setting"), 1, 1, 100, this );
 
1744
    if ( val > 0 ) ColsMode( CM_SPECIFIED, val );
 
1745
}
 
1746
 
 
1747
void HexEditPanel::OnSetColsPower2(wxCommandEvent& event)
 
1748
{
 
1749
    ColsMode( CM_POWER, 2 );
 
1750
}
 
1751
 
 
1752
void HexEditPanel::OnSetColsPower4(wxCommandEvent& event)
 
1753
{
 
1754
    ColsMode( CM_POWER, 4 );
 
1755
}
 
1756
 
 
1757
void HexEditPanel::OnSetColsPower8(wxCommandEvent& event)
 
1758
{
 
1759
    ColsMode( CM_POWER, 8 );
 
1760
}
 
1761
 
 
1762
void HexEditPanel::OnSetColsPowerOther(wxCommandEvent& event)
 
1763
{
 
1764
    long val = ::wxGetNumberFromUser( _("Enter number"), _("Enter number"), _("Colums setting"), 2, 2, 100, this );
 
1765
    if ( val > 0 ) ColsMode( CM_POWER, val );
 
1766
}
 
1767
 
 
1768
void HexEditPanel::ColsMode(int mode, int value)
 
1769
{
 
1770
    m_ColsMode = mode;
 
1771
    m_ColsValue = value;
 
1772
 
 
1773
    if ( m_ColsMode == CM_MULT && m_ColsValue == 1 )
 
1774
    {
 
1775
        m_ColsMode = CM_ANY;
 
1776
    }
 
1777
 
 
1778
    DisplayChanged();
 
1779
}
 
1780
 
 
1781
bool HexEditPanel::MatchColumnsCount(int colsCount)
 
1782
{
 
1783
    switch ( m_ColsMode )
 
1784
    {
 
1785
        case CM_MULT:
 
1786
            return ( colsCount % m_ColsValue ) == 0;
 
1787
 
 
1788
        case CM_SPECIFIED:
 
1789
            return colsCount == m_ColsValue;
 
1790
 
 
1791
        case CM_POWER:
 
1792
            while ( colsCount > 1 )
 
1793
            {
 
1794
                if ( colsCount % m_ColsValue ) return false;
 
1795
                colsCount /= m_ColsValue;
 
1796
            }
 
1797
            return true;
 
1798
 
 
1799
        default:
 
1800
            return true;
 
1801
    }
 
1802
}
 
1803
 
 
1804
void HexEditPanel::OnButton4Click1(wxCommandEvent& event)
 
1805
{
 
1806
    wxString tests[] =
 
1807
    {
 
1808
        _("Expression parser"),
 
1809
        _("On-Disk file edition")
 
1810
    };
 
1811
 
 
1812
    int index = wxGetSingleChoiceIndex( _("Select tests to perform"), _("Self tests"), sizeof( tests ) / sizeof( tests[0] ), tests, this );
 
1813
    TestCasesBase* test = 0;
 
1814
 
 
1815
    switch ( index )
 
1816
    {
 
1817
        case 0: test = &Expression::GetTests(); break;
 
1818
        case 1: test = &FileContentDisk::GetTests(); break;
 
1819
    }
 
1820
 
 
1821
    if ( !test ) return;
 
1822
 
 
1823
    TestCasesDlg( this, *test ).ShowModal();
 
1824
}
 
1825
 
 
1826
 
 
1827
void HexEditPanel::OnButton6Click(wxCommandEvent& event)
 
1828
{
 
1829
    ProcessGoto();
 
1830
}
 
1831
 
 
1832
void HexEditPanel::OnButton5Click(wxCommandEvent& event)
 
1833
{
 
1834
    ProcessSearch();
 
1835
}