1 /***********************************(GPL)********************************
2 * wxHexEditor is a hex edit tool for editing massive files in Linux *
3 * Copyright (C) 2010 Erdem U. Altinyurt *
4 * *
5 * This program is free software; you can redistribute it and/or *
6 * modify it under the terms of the GNU General Public License *
7 * as published by the Free Software Foundation; either version 2 *
8 * of the License. *
9 * *
10 * This program 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 this program; *
17 * if not, write to the Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
19 * *
20 * home : www.wxhexeditor.org *
21 * email : spamjunkeater@gmail.com *
22 *************************************************************************/
23
24 #include "HexEditorCtrl.h"
25 //???
26 //BEGIN_EVENT_TABLE(,wxScrolledWindow )
27 // EVT_CHAR( wxHexCtrl::OnChar )
28 // EVT_PAINT(wxHexCtrl::OnPaint )
29 // EVT_SIZE( HexEditorCtrl::OnResize )
30 // EVT_RIGHT_DOWN( wxHexCtrl::OnMouseRight )
31 // EVT_SET_FOCUS( wxHexCtrl::OnFocus )
32 // EVT_KILL_FOCUS( wxHexCtrl::OnKillFocus )
33 //END_EVENT_TABLE()
34
35 #include <wx/arrimpl.cpp> // this is a magic incantation which must be done!
36 WX_DEFINE_OBJARRAY(wxArrayUINT64);
37
HexEditorCtrl(wxWindow * parent,int id,const wxPoint & pos,const wxSize & size,long style)38 HexEditorCtrl::HexEditorCtrl(wxWindow* parent, int id, const wxPoint& pos, const wxSize& size, long style):
39 HexEditorCtrlGui(parent, id, pos, size, wxTAB_TRAVERSAL){
40 select = new class Select( GetEventHandler() );
41
42 SetAutoLayout(true);
43
44 m_static_offset->SetLabel( wxString(wxT("+"))+_("Offset")+wxT("-") );
45 SetFont();
46
47 Dynamic_Connector();
48 offset_scroll = new wxHugeScrollBar( offset_scroll_real );
49 TAGMutex = false;
50 hex_ctrl->TagMutex = &TAGMutex;
51 text_ctrl->TagMutex = &TAGMutex;
52
53 //Using hex_ctrl ZebraStriping pointer for all 3 panels.
54 delete text_ctrl->ZebraStriping;
55 delete offset_ctrl->ZebraStriping;
56 ZebraStriping = hex_ctrl->ZebraStriping;
57 text_ctrl->ZebraStriping = ZebraStriping;
58 offset_ctrl->ZebraStriping = ZebraStriping;
59 myConfigBase::Get()->Read( _T("ZebraStriping"), &ZebraEnable, true);
60 sector_size=0;
61 }
62
~HexEditorCtrl(void)63 HexEditorCtrl::~HexEditorCtrl( void ){
64 Dynamic_Disconnector();
65 Clear();
66
67 WX_CLEAR_ARRAY(MainTagArray)
68 WX_CLEAR_ARRAY(HighlightArray)
69 WX_CLEAR_ARRAY(CompareArray)
70
71 MainTagArray.Shrink();
72 HighlightArray.Shrink();
73 CompareArray.Shrink();
74
75 delete select;
76 delete offset_scroll;
77 }
78
Dynamic_Connector()79 void HexEditorCtrl::Dynamic_Connector(){
80 this->Connect( idTagAddSelection, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( HexEditorCtrl::OnTagAddSelection ), NULL, this );
81 this->Connect( idTagQuick, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( HexEditorCtrl::OnTagQuick ), NULL, this );
82 this->Connect( idTagEdit, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( HexEditorCtrl::OnTagEdit ), NULL, this );
83 this->Connect( __idOffsetHex__, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( HexEditorCtrl::UpdateUI ) );
84 this->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler(HexEditorCtrl::OnKillFocus),NULL, this);
85 hex_ctrl->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler(HexEditorCtrl::OnKillFocus),NULL, this);
86 text_ctrl->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler(HexEditorCtrl::OnKillFocus),NULL, this);
87 hex_ctrl->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler(HexEditorCtrl::OnFocus),NULL, this);
88 text_ctrl->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler(HexEditorCtrl::OnFocus),NULL, this);
89
90
91 offset_ctrl->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler(HexEditorCtrl::OnMouseRight),NULL, this);
92 offset_ctrl->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler(HexEditorCtrl::OnMouseLeft),NULL, this);
93
94 hex_ctrl ->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler(HexEditorCtrl::OnMouseLeft),NULL, this);
95 text_ctrl->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler(HexEditorCtrl::OnMouseLeft),NULL, this);
96 hex_ctrl ->Connect( wxEVT_LEFT_UP, wxMouseEventHandler(HexEditorCtrl::OnMouseSelectionEnd),NULL, this);
97 text_ctrl->Connect( wxEVT_LEFT_UP, wxMouseEventHandler(HexEditorCtrl::OnMouseSelectionEnd),NULL, this);
98 hex_ctrl ->Connect( wxEVT_RIGHT_DOWN,wxMouseEventHandler(HexEditorCtrl::OnMouseRight),NULL, this);
99 text_ctrl->Connect( wxEVT_RIGHT_DOWN,wxMouseEventHandler(HexEditorCtrl::OnMouseRight),NULL, this);
100 hex_ctrl ->Connect( wxEVT_MOTION, wxMouseEventHandler(HexEditorCtrl::OnMouseMove),NULL, this);
101 text_ctrl->Connect( wxEVT_MOTION, wxMouseEventHandler(HexEditorCtrl::OnMouseMove),NULL, this);
102 }
103
Dynamic_Disconnector()104 void HexEditorCtrl::Dynamic_Disconnector(){
105 this->Disconnect( idTagAddSelection, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( HexEditorCtrl::OnTagAddSelection ), NULL, this );
106 this->Disconnect( idTagQuick, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( HexEditorCtrl::OnTagQuick ), NULL, this );
107 this->Disconnect( idTagEdit, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( HexEditorCtrl::OnTagEdit ), NULL, this );
108 this->Disconnect( __idOffsetHex__, wxEVT_UPDATE_UI, wxUpdateUIEventHandler( HexEditorCtrl::UpdateUI ) );
109 this->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler(HexEditorCtrl::OnKillFocus),NULL, this);
110 hex_ctrl->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler(HexEditorCtrl::OnKillFocus),NULL, this);
111 text_ctrl->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler(HexEditorCtrl::OnKillFocus),NULL, this);
112
113 offset_ctrl->Disconnect( wxEVT_RIGHT_DOWN, wxMouseEventHandler(HexEditorCtrl::OnMouseRight),NULL, this);
114 offset_ctrl->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler(HexEditorCtrl::OnMouseLeft),NULL, this);
115 hex_ctrl ->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler(HexEditorCtrl::OnMouseLeft),NULL, this);
116 text_ctrl->Disconnect( wxEVT_LEFT_DOWN, wxMouseEventHandler(HexEditorCtrl::OnMouseLeft),NULL, this);
117 hex_ctrl ->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler(HexEditorCtrl::OnMouseSelectionEnd),NULL, this);
118 text_ctrl->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler(HexEditorCtrl::OnMouseSelectionEnd),NULL, this);
119 hex_ctrl ->Disconnect( wxEVT_RIGHT_DOWN, wxMouseEventHandler(HexEditorCtrl::OnMouseRight),NULL, this);
120 text_ctrl->Disconnect( wxEVT_RIGHT_DOWN, wxMouseEventHandler(HexEditorCtrl::OnMouseRight),NULL, this);
121 hex_ctrl ->Disconnect( wxEVT_MOTION, wxMouseEventHandler(HexEditorCtrl::OnMouseMove),NULL, this);
122 text_ctrl->Disconnect( wxEVT_MOTION, wxMouseEventHandler(HexEditorCtrl::OnMouseMove),NULL, this);
123 }
124
125 //-----READ/WRITE FUNCTIONS-------//
ReadFromBuffer(uint64_t position,unsigned lenght,char * buffer,bool cursor_reset,bool paint)126 void HexEditorCtrl::ReadFromBuffer( uint64_t position, unsigned lenght, char *buffer, bool cursor_reset, bool paint ){
127 if( lenght==4294967295LL ){
128 std::cout << "Buffer has no data!" << std::endl;
129 return;
130 }
131 static wxMutex MyBufferMutex;
132 MyBufferMutex.Lock();
133 page_offset = position;
134 if( lenght != ByteCapacity() ){
135 //last line could be NULL;
136 }
137 Clear( false, cursor_reset );
138 wxString text_string;
139
140 // Optimized Code
141 // for( unsigned i=0 ; i<lenght ; i++ )
142 //text_string << text_ctrl->Filter(buffer[i]);
143 // text_string << static_cast<wxChar>((unsigned char)(buffer[i]));
144 // text_string << CP473toUnicode((unsigned char)(buffer[i]));
145
146 //Painting Zebra Stripes, -1 means no stripe. 0 means start with normal, 1 means start with zebra
147 *ZebraStriping=(ZebraEnable ? position/BytePerLine()%2 : -1);
148 if(sector_size > 1){
149 offset_ctrl->sector_size=sector_size;
150 unsigned draw_line=sector_size-(page_offset%sector_size);
151 hex_ctrl->ThinSeparationLines.Clear();
152 text_ctrl->ThinSeparationLines.Clear();
153 do{
154 hex_ctrl->ThinSeparationLines.Add( 2*draw_line );
155 text_ctrl->ThinSeparationLines.Add( draw_line );
156 draw_line += sector_size;
157 }while (draw_line < lenght );
158 }
159
160 if(ProcessRAMMap.Count()){
161 hex_ctrl->ThinSeparationLines.Clear();
162 text_ctrl->ThinSeparationLines.Clear();
163 //Notice that, ProcessRAMMap is SORTED.
164 for( unsigned i=0; i < ProcessRAMMap.Count(); i++ ){
165 int64_t M = ProcessRAMMap.Item(i);
166 if( M > page_offset + ByteCapacity() )
167 break;
168
169 if( (M > page_offset)
170 && (M <= page_offset + ByteCapacity()) ){
171
172 int draw_line = M - page_offset;
173 hex_ctrl->ThinSeparationLines.Add( 2*draw_line );
174 text_ctrl->ThinSeparationLines.Add( draw_line );
175 }
176 }
177 }
178
179 hex_ctrl->SetBinValue(buffer, lenght, false );
180 //text_ctrl->ChangeValue(text_string, false);
181 text_ctrl->SetBinValue(buffer, lenght, false);
182
183 offset_ctrl->SetValue( position, BytePerLine() );
184
185 if( offset_scroll->GetThumbPosition() != (page_offset / BytePerLine()) )
186 offset_scroll->SetThumbPosition( page_offset / BytePerLine() );
187
188 if( paint ){
189 PaintSelection();
190 }
191
192 MyBufferMutex.Unlock();
193 }
194
TextCharReplace(long char_location,const wxChar chr)195 void HexEditorCtrl::TextCharReplace( long char_location, const wxChar chr){
196 text_ctrl->Replace( char_location, chr, true );
197 char_location *= 2; //Converting Byte location to Hex Location;
198 wxString temp = wxString::Format(wxT("%02X"),chr);
199 hex_ctrl->Replace(char_location, char_location+2, temp);
200 }
201
HexCharReplace(long hex_location,const wxChar chr)202 void HexEditorCtrl::HexCharReplace(long hex_location, const wxChar chr){
203 hex_ctrl->Replace( hex_location, chr, true );
204 hex_location /=2; // Hex location is now Byte location
205 char rdchr = hex_ctrl->ReadByte(hex_location);
206 text_ctrl->Replace( hex_location, rdchr, true );
207 }
208 //-----MENUS--------//
209
ShowContextMenu(const wxMouseEvent & event)210 void HexEditorCtrl::ShowContextMenu( const wxMouseEvent& event ){
211 //Non operational code... HexEditor::ShowContextMenu() used instead
212 wxMenu menu;
213 uint64_t TagPosition=0;
214 if( event.GetEventObject() == hex_ctrl )
215 TagPosition = page_offset + (hex_ctrl->PixelCoordToInternalPosition( event.GetPosition() ) / 2);
216 if( event.GetEventObject() == text_ctrl )
217 TagPosition = page_offset + text_ctrl->PixelCoordToInternalPosition( event.GetPosition() );
218
219 TagElement *TAG;
220 for( unsigned i = 0 ; i < MainTagArray.Count() ; i++ ){
221 TAG = MainTagArray.Item(i);
222 if( TAG->isCover( TagPosition ) ){ //end not included!
223 menu.Append(idTagEdit, _T("Tag Edit"));
224 break;
225 }
226 }
227
228 if( select->GetState() ){
229 menu.Append(idTagAddSelection, _T("Tag Selection"));
230 menu.Append(idTagQuick, _T("Tag Selection"));
231 }
232 // menu.AppendSeparator();
233 wxPoint pos = event.GetPosition();
234 wxWindow *scr = static_cast<wxWindow*>( event.GetEventObject() );
235 pos += scr->GetPosition();
236 PopupMenu(&menu, pos);
237 }
238
239 //-----VISUAL FUNCTIONS------//
SetFont(wxFont f)240 void HexEditorCtrl::SetFont( wxFont f ){
241 stdfont = f;
242 m_static_offset->SetFont( stdfont );
243 m_static_address->SetFont( stdfont );
244 m_static_byteview->SetFont( stdfont );
245 SetStyle();
246 }
247
SetFont()248 void HexEditorCtrl::SetFont( ){
249 wxFont newfont;
250 int FontSize=10;
251 myConfigBase::Get()->Read( wxT("FontSize"), &FontSize, 10 );
252
253 #if defined( __WXOSX__ )
254 newfont = wxFont(FontSize, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, 0, wxT("Monaco"), wxFONTENCODING_ISO8859_1);// Fonts are too small on wxOSX 2.9.x series.
255 #elif defined( __WXMSW__ )
256 newfont = wxFont(FontSize, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, 0, wxT("Courier New"), wxFONTENCODING_ISO8859_1);
257 #else
258 newfont = wxFont(FontSize, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, 0, wxT("Monospace"), wxFONTENCODING_ISO8859_1);
259 #endif
260 SetFont( newfont );
261 }
262
SetStyle()263 void HexEditorCtrl::SetStyle( ) {
264 wxString Colour;
265 wxColour Foreground,Background;
266 wxTextAttr Style;
267
268 //Normal style set
269 if( wxConfig::Get()->Read( _T("ColourHexForeground"), &Colour) )
270 Foreground.Set( Colour );
271 else
272 Foreground = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ) ;
273
274 if( wxConfig::Get()->Read( _T("ColourHexBackground"), &Colour) )
275 Background.Set( Colour );
276 else
277 Background = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ;
278
279 Style = wxTextAttr( Foreground, Background, stdfont );
280 offset_ctrl->SetDefaultStyle( Style );
281 hex_ctrl->SetDefaultStyle( Style );
282 wxString cp;
283 myConfigBase::Get()->Read( _T("CharacterEncoding"), &cp, wxT("DOS OEM") );
284 text_ctrl->PrepareCodepageTable(cp);
285 text_ctrl->SetDefaultStyle( Style );
286
287 //Selection style set
288
289 if(wxConfig::Get()->Read( _T("ColourHexSelectionForeground"), &Colour) )
290 Foreground.Set( Colour );
291 else
292 Foreground = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHTTEXT );
293
294 if( wxConfig::Get()->Read( _T("ColourHexSelectionBackground"), &Colour) )
295 Background.Set( Colour );
296 else
297 Background = wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT );
298
299 Style = wxTextAttr( Foreground, Background, stdfont );
300 offset_ctrl->SetSelectionStyle( Style );
301 hex_ctrl->SetSelectionStyle( Style );
302 text_ctrl->SetSelectionStyle( Style );
303 }
304
305 //Handles selection operations.
Selector()306 bool HexEditorCtrl::Selector(){
307 wxWindow* FocusAt=FindFocus();
308 if( !(FocusAt == hex_ctrl || FocusAt == text_ctrl) ){ //Checks If selecton from hex or text control
309 #ifdef _DEBUG_
310 std::cout << "Selector without focus captured." << std::endl;
311 std::cout << "use last focus as a work-a-round." << std::endl;
312 #endif
313 FocusAt=LastFocused;
314 //return false;
315 }
316 #ifdef _DEBUG_SELECT_
317 std::cout << "Selector captured at CursorOffset()=" << std::dec << CursorOffset() << "\t select->StartOffset:" << select->StartOffset << std::endl;
318 #endif
319 select->EndOffset = CursorOffset(); //Than make selection
320 if( !select->GetState() ){ // If no select available,
321 select->SetState( true ); // then set start selection procedure
322 select->OriginalStartOffset = select->StartOffset = select->EndOffset;
323 return true;
324 }
325
326 if( FocusAt==text_ctrl ){ //TextCtrl capture mechanism is different since cursor is a slim line "|"
327 if( select->OriginalStartOffset > select->EndOffset ){ //Backward selection at text panel
328 select->StartOffset = select->OriginalStartOffset-1;
329 }
330 else if(select->OriginalStartOffset < select->EndOffset){ //forward selection on text panel
331 select->StartOffset = select->OriginalStartOffset;
332 select->EndOffset = select->EndOffset-1;
333 }
334 else{
335 select->SetState( false );
336 }
337 }
338
339 #ifdef _DEBUG_SELECT_
340 std::cout << "Selector Result : " << select->StartOffset << ":" << select->EndOffset << std::endl;
341 #endif
342 return select->GetState();
343 }
344
Select(uint64_t start_offset,uint64_t end_offset)345 bool HexEditorCtrl::Select ( uint64_t start_offset, uint64_t end_offset ){
346 /*
347 if( start_offset < 0 || end_offset < 0
348 // || start_offset > myfile->Length() || end_offset > myfile->Length() //??
349 ){
350 wxBell();
351 return false;
352 }
353 */
354 #ifdef _DEBUG_SELECT_
355 std::cout << "HexEditorCtrl::Select( " << std::dec << start_offset << "," << end_offset << ")" << std::endl;
356 #endif
357 select->StartOffset = start_offset;
358 select->EndOffset = end_offset;
359 select->SetState( true );
360 PaintSelection();
361 return true;
362 }
363
ClearPaint(void)364 void inline HexEditorCtrl::ClearPaint( void ){
365 hex_ctrl ->ClearSelection();
366 text_ctrl->ClearSelection();
367 }
368
PreparePaintTAGs(void)369 void HexEditorCtrl::PreparePaintTAGs( void ){//TagElement& TAG ){
370 TagHideAll();
371 WX_CLEAR_ARRAY(hex_ctrl->TagArray);
372 WX_CLEAR_ARRAY(text_ctrl->TagArray);
373
374 //MainTagArray.Sort( TagElement::TagCompare );
375 //for( unsigned i = 0 ; i < MainTagArray.Count() ; i ++ ) //Painting all TAGs here.
376 // PushTAGToControls(MainTagArray.Item(i));
377 PaintTAGsPrefilter( MainTagArray );
378
379 //HighlightArray.Sort( TagElement::TagCompare );
380 //for( unsigned i = 0 ; i < HighlightArray.Count() ; i ++ ) //Just highlighting required sections.
381 // PushTAGToControls(HighlightArray.Item(i));
382 PaintTAGsPrefilter( HighlightArray );
383
384 //CompareArray.Sort( TagElement::TagCompare );
385 //for( unsigned i = 0 ; i < CompareArray.Count() ; i ++ ) //Just highlighting diff sections.
386 // PushTAGToControls(CompareArray.Item(i));
387 PaintTAGsPrefilter( CompareArray );
388 }
389
PaintTAGsPrefilter(ArrayOfTAG & Arr)390 void HexEditorCtrl::PaintTAGsPrefilter( ArrayOfTAG& Arr ){
391 unsigned c = Arr.Count();
392 if( c==0 )
393 return;
394
395 unsigned s = 0;
396 if (c>0)
397 for( ; static_cast<uint64_t>( page_offset ) > (Arr.Item(s))->end && s<c-1; s++ );
398 unsigned e=s;
399 if (c>0)
400 for( ; page_offset + GetByteCount() > static_cast<int>( Arr.Item(e)->start ) && e<c-1 ; e++ );
401 //#ifdef _DEBUG_
402 std::cout << "Tags needed between : " << s << " - " << e << std::endl;
403 //#endif //_DEBUG_
404 for( unsigned i=s; i<=e ;i++)
405 PushTAGToControls( Arr.Item(i) );
406 }
407
408 //This functions move tags to local hex and text ctrls.
PushTAGToControls(TagElement * TAG)409 void HexEditorCtrl::PushTAGToControls( TagElement* TAG){
410 int64_t start_byte = TAG->start;
411 int64_t end_byte = TAG->end;
412
413 if(start_byte > end_byte){ // swap if start > end
414 int64_t temp = start_byte;
415 start_byte = end_byte;
416 end_byte = temp;
417 }
418
419 if( start_byte >= page_offset + GetByteCount() ) // ...[..].TAG...
420 return;
421 else if( end_byte < page_offset ) // ..TAG..[...]...
422 return;
423
424 if( start_byte <= page_offset ) // ...TA[G..]....
425 start_byte = page_offset;
426
427 if( end_byte >= page_offset + GetByteCount() ) //...[..T]AG...
428 end_byte = GetByteCount() + page_offset;
429
430 start_byte -= page_offset;
431 end_byte -= page_offset;
432
433 TagElement *TAX;//For debugging
434
435 TAX = new TagElement( start_byte/(GetCharToHexSize()/2), end_byte/(GetCharToHexSize()/2)+1, TAG->tag, TAG->FontClrData, TAG->NoteClrData );
436 text_ctrl->TagArray.Add( TAX );
437 TAX = new TagElement( start_byte*2, (end_byte+1)*2, TAG->tag, TAG->FontClrData, TAG->NoteClrData );
438 hex_ctrl->TagArray.Add( TAX );
439 }
440
PaintSelection(void)441 void HexEditorCtrl::PaintSelection( void ){
442 PreparePaintTAGs();
443 if( select->GetState() ){
444 int64_t start_byte = select->StartOffset;
445 int64_t end_byte = select->EndOffset;
446
447 if(start_byte > end_byte){ // swap if start > end
448 int64_t temp = start_byte;
449 start_byte = end_byte;
450 end_byte = temp;
451 }
452
453 if( start_byte >= page_offset + GetByteCount() ){ // ...[..].TAG...
454 ClearPaint();
455 return;
456 }
457 else if( start_byte <= page_offset ) // ...TA[G..]....
458 start_byte = page_offset;
459
460 if( end_byte < page_offset ){ // ..TAG..[...]...
461 ClearPaint();
462 return;
463 }
464 else if( end_byte >= page_offset + GetByteCount() ) //...[..T]AG...
465 end_byte = GetByteCount() + page_offset;
466
467 start_byte -= page_offset;
468 end_byte -= page_offset;
469
470 text_ctrl->SetSelection(start_byte/(GetCharToHexSize()/2), end_byte/(GetCharToHexSize()/2)+1);
471 hex_ctrl ->SetSelection(start_byte*2, (end_byte+1)*2);
472 }
473 else
474 ClearPaint();
475 }
476
MyFreeze()477 void inline HexEditorCtrl::MyFreeze(){
478 hex_ctrl->Freeze();
479 text_ctrl->Freeze();
480 offset_ctrl->Freeze();
481 }
482
MyThaw()483 void inline HexEditorCtrl::MyThaw(){
484 hex_ctrl->Thaw();
485 text_ctrl->Thaw();
486 offset_ctrl->Thaw();
487 }
488
Clear(bool RePaint,bool cursor_reset)489 void HexEditorCtrl::Clear( bool RePaint, bool cursor_reset ){
490 hex_ctrl->Clear( RePaint, cursor_reset );
491 text_ctrl->Clear( RePaint, cursor_reset );
492 offset_ctrl->Clear( RePaint, cursor_reset );
493 }
494
RePaint(void)495 void HexEditorCtrl::RePaint( void ){
496 *ZebraStriping=(ZebraEnable ? page_offset/BytePerLine()%2 : -1);
497 hex_ctrl->RePaint( );
498 text_ctrl->RePaint( );
499 offset_ctrl->RePaint( );
500 }
501
ControlShow(panels control,bool show)502 void HexEditorCtrl::ControlShow( panels control, bool show ){
503 if( control == OFFSET_CTRL ){
504 offset_ctrl->Show( show );
505 m_static_offset->Show(show);
506 }
507 else if(control == HEX_CTRL ){
508 hex_ctrl->Show( show );
509 m_static_address->Show(show);
510 }
511 else if(control == TEXT_CTRL ){
512 text_ctrl->Show( show );
513 m_static_byteview->Show(show);
514 }
515 wxYieldIfNeeded();
516 Layout();
517 Fit();
518 }
ControlIsShown(panels control)519 bool HexEditorCtrl::ControlIsShown(panels control){
520 switch(control){
521 case OFFSET_CTRL:return offset_ctrl->IsShown();
522 case HEX_CTRL : return hex_ctrl->IsShown();
523 case TEXT_CTRL : return text_ctrl->IsShown();
524 }
525 return false;
526 }
527
OnResize(wxSizeEvent & event)528 void HexEditorCtrl::OnResize( wxSizeEvent &event ){
529 int x = event.GetSize().GetX();
530 int y = event.GetSize().GetY();
531 int charx = hex_ctrl->GetCharSize().GetX();
532 int chartx = text_ctrl->GetCharSize().GetX();
533 int offset_x = offset_ctrl->GetCharSize().GetX()*offset_ctrl->GetLineSize();// + 4;
534 offset_x = offset_ctrl->IsShown() ? offset_x : 0;
535
536
537 x -= offset_x; //Remove Offset Control box X because its changeable
538 x -= offset_scroll_real->GetSize().GetX(); //Remove Offset scroll size
539 x -= 4*2; //+x 4 pixel external borders (dark ones, 2 pix each size)
540 x = wxMax(0,x); //Avoid X being negative
541 y -= m_static_byteview->GetSize().GetY(); //Remove Head Text Y
542 //AutoFill:
543 bool custom_hex_format;
544 wxConfig::Get()->Read( wxT("UseCustomHexFormat"), &custom_hex_format, false );
545 wxString fmt(wxT("xx "));
546 if( custom_hex_format )
547 wxConfig::Get()->Read( wxT("CustomHexFormat"), &fmt, wxT("xx "));
548
549 // TODO (death#1#): Move style engine somewhere else to speedy resizing.
550 hex_ctrl->SetFormat( fmt );
551
552 int cnt_chr=0; //Counted character at current format
553 for( unsigned i = 0 ; i < fmt.Len() ; i++ ){
554 if( fmt[i]!=' ' )
555 cnt_chr++;
556 }
557 cnt_chr/=2; // divide 2 for find byte per hex representation.
558
559 int hexchr=0,textchr = 0;
560 //Recalculate available area due hidden panels.
561 hexchr+=hex_ctrl->IsShown() ? fmt.Len() : 0;
562 textchr+=text_ctrl->IsShown() ? cnt_chr : 0;
563 int available_space=0;
564 available_space=x/(hexchr*charx+textchr*chartx/(GetCharToHexSize()/2));
565
566 //Limiting Bytes Per Line
567 bool use_BytesPerLineLimit;
568 wxConfig::Get()->Read( wxT("UseBytesPerLineLimit"), &use_BytesPerLineLimit, false );
569 if( use_BytesPerLineLimit ){
570 int BytesPerLineLimit;
571 wxConfig::Get()->Read( wxT("BytesPerLineLimit"), reinterpret_cast<int*>(&BytesPerLineLimit), 16);
572
573 //Downsizing is available
574 if( available_space*cnt_chr > BytesPerLineLimit )
575 available_space = BytesPerLineLimit/cnt_chr;
576 }
577
578 //Calculation of available area for Hex and Text panels.
579 int text_x = chartx*available_space*cnt_chr/(GetCharToHexSize()/2) +2 +4;
580 int hex_x = charx*available_space*fmt.Len() +2 +4 - charx ; //no need for last gap;
581 int ByteShownPerLine=available_space*cnt_chr;
582
583 text_x = text_ctrl->IsShown() ? text_x : 0;
584 hex_x = hex_ctrl->IsShown() ? hex_x : 0;
585
586 #ifdef _DEBUG_SIZE_
587 std::cout<< "HexEditorCtrl::OnResize()" << std::endl
588 << "HexEditorCtrl SizeEvent ReSize Command=(" << event.GetSize().GetX() << ',' << event.GetSize().GetY() << ")\n"
589 << "Offset Scrll: \t(" << offset_scroll->GetSize().GetX() << ',' << event.GetSize().GetY() <<")\n"
590 << "Offset Ctrl: \t(" << offset_ctrl->GetSize().GetX() << ',' << event.GetSize().GetY() <<")\n"
591 << "Hex Ctrl: \t(" << hex_x << ',' << event.GetSize().GetY() << ")\n"
592 << "Text Ctrl: \t(" << text_x << ',' << event.GetSize().GetY() << ")\n"
593 << "Hex Char: \t" << charx << std::endl
594 << "ByteShownPerLine: \t" << ByteShownPerLine << std::endl;
595 #endif
596
597 offset_ctrl->SetMinSize( wxSize( offset_x , y ) );
598 // offset_ctrl->SetSize( wxSize( offset_x , y ) ); //Not needed, Layout() Makes the job well.
599 m_static_offset->SetMinSize( wxSize(offset_x, m_static_offset->GetSize().GetY()) );
600
601 hex_ctrl->SetMinSize( wxSize( hex_x, y ));
602 // hex_ctrl->SetSize( wxSize( hex_x, y ));
603 m_static_address->SetMinSize( wxSize(hex_x, m_static_offset->GetSize().GetY()) ) ;
604
605 text_ctrl->SetMinSize( wxSize( text_x, y ));
606 // text_ctrl->SetSize( wxSize( text_x, y ));
607 m_static_byteview->SetMinSize( wxSize( text_x, m_static_offset->GetSize().GetY()) );
608
609 // Destroy the sizer created by the form builder before adding the windows
610 // managed by it to another sizer, otherwise we would crash later when
611 // destroying the sizer as it wouldn't know about the windows it contains.
612 SetSizer(NULL);
613
614 //Preparing Sizer
615 wxFlexGridSizer* fgSizer1 = new wxFlexGridSizer( 2, 4, 0, 0 );
616 #if 1
617 fgSizer1->Add( m_static_offset, 0, wxALIGN_CENTER|wxLEFT, 5 );
618 fgSizer1->Add( m_static_address, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT, 2 );
619 fgSizer1->Add( m_static_byteview, 0, wxALIGN_CENTER|wxALL, 0 );
620 fgSizer1->Add( m_static_null, 0, wxALIGN_CENTER, 3 );
621 fgSizer1->Add( offset_ctrl, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 0 );
622 fgSizer1->Add( hex_ctrl, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 0 );
623 fgSizer1->Add( text_ctrl, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 0 );
624 fgSizer1->Add( offset_scroll_real, 0, wxEXPAND, 0 );
625
626 #else
627 fgSizer1->Add( m_static_offset, 0, wxALIGN_CENTER|wxLEFT, 0 );
628 fgSizer1->Add( m_static_address, 0, wxALIGN_CENTER|wxALIGN_CENTER_VERTICAL|wxLEFT, 0 );
629 fgSizer1->Add( m_static_byteview, 0, wxALIGN_CENTER|wxALL, 0 );
630 fgSizer1->Add( m_static_null, 0, wxALIGN_CENTER, 0 );
631 fgSizer1->Add( offset_ctrl, 0, wxALIGN_CENTER|wxALL|wxEXPAND, 0 );
632 fgSizer1->Add( hex_ctrl, 0, wxALIGN_CENTER|wxALL, 0 );
633 fgSizer1->Add( text_ctrl, 0, wxALIGN_CENTER|wxALL|wxEXPAND, 0 );
634 fgSizer1->Add( offset_scroll_real, 0, wxEXPAND, 0 );
635
636
637 fgSizer1->AddGrowableCol(1,1);
638 // fgSizer1->AddGrowableRow(1,1);
639 #endif
640
641 this->SetSizer( fgSizer1 );
642 this->Layout();
643
644 #ifdef __WXMSW__
645 ///At windows, OnResize cannot update required fields immeditialy, this hack fixes this behaviour.
646 hex_ctrl->ChangeSize();
647 text_ctrl->ChangeSize();
648 offset_ctrl->ChangeSize();
649 #endif
650
651 //Formating Hex and byteview column labels
652 //This needed bellow hex_ctrl->ChangeSize() because it's updates the IsDenied function.
653 wxString address,byteview,temp_address;
654 for( int j = 0 ; j < ByteShownPerLine ; j++ ){
655 temp_address << wxString::Format( wxT("%02X"), j%0x100 );
656 //if(j >= ByteShownPerLine/(GetCharToHexSize()/2))
657 // continue;
658 byteview << wxString::Format( wxT("%01X"), (j*(GetCharToHexSize()/2))%0x10 );
659 }
660
661 //Adjusting custom hex formatting bar - Converting 00010203 -> 00 01 02 03 for "xx " format.
662 for( int x = 0, i=0 ; x < hex_x && static_cast<unsigned>(i) < temp_address.Len() ; x++ )
663 if(hex_ctrl->IsDenied(x))
664 address << wxT(" ");
665 else
666 address << temp_address[i++];
667
668 m_static_address->SetLabel(address);
669 m_static_byteview->SetLabel( byteview );
670
671 #ifdef _DEBUG_SIZE_
672 std::cout<< "HexEditorCtrl After ReSize=(" << x << ',' << y << ")\n"
673 << "Offset Scrll: \t(" << offset_scroll->GetSize().GetX() << ',' << offset_scroll->GetSize().GetY()<<")\n"
674 << "Offset Ctrl: \t(" << offset_ctrl->GetSize().GetX() << ',' << offset_ctrl->GetSize().GetY()<<")\n"
675 << "Hex Ctrl: \t(" << hex_ctrl->GetSize().GetX() << ',' << hex_ctrl->GetSize().GetY()<<")\n"
676 << "Text Ctrl: \t(" << text_ctrl->GetSize().GetX() << ',' << text_ctrl->GetSize().GetY()<<")\n";
677 #endif
678 }
679
GetCharToHexSize(void)680 inline uint8_t HexEditorCtrl::GetCharToHexSize( void ){
681 if(text_ctrl->FontEnc == wxFONTENCODING_UTF16LE ||
682 text_ctrl->FontEnc == wxFONTENCODING_UTF16BE )
683 return 4;
684 if(text_ctrl->FontEnc == wxFONTENCODING_UTF32LE ||
685 text_ctrl->FontEnc == wxFONTENCODING_UTF32BE )
686 return 8;
687 return 2;
688 }
689 //------EVENTS---------//
OnMouseLeft(wxMouseEvent & event)690 void HexEditorCtrl::OnMouseLeft(wxMouseEvent& event){
691 select->SetState( false );
692
693 if( event.GetEventObject() == hex_ctrl ){
694 hex_ctrl->SetFocus();
695 focus=HEX_CTRL;
696 SetLocalHexInsertionPoint( hex_ctrl->PixelCoordToInternalPosition( event.GetPosition() ) );
697 }
698 else if( event.GetEventObject() == text_ctrl ){
699 text_ctrl->SetFocus();
700 focus=TEXT_CTRL;
701 SetLocalHexInsertionPoint( GetCharToHexSize() * text_ctrl->PixelCoordToInternalPosition( event.GetPosition() ) );
702 }
703 else if( event.GetEventObject() == offset_ctrl ){
704 event.Skip(); //to lower level for copy offset to clipboard
705 }
706
707 ClearPaint(); //redraw cursor shadow after movement.
708 }
709
OnMouseMove(wxMouseEvent & event)710 void HexEditorCtrl::OnMouseMove( wxMouseEvent& event ){
711 if(event.m_leftDown){ //if left button is pressed
712 int new_hex_location=0; // initialize new_hex_location variable
713 if( event.GetEventObject() == hex_ctrl ) // if this event from hex_ctrl area
714 new_hex_location = hex_ctrl->PixelCoordToInternalPosition( event.GetPosition() ); //than take it's location on hex chars
715 else if ( event.GetEventObject() == text_ctrl ){ //if we got this event from text area
716 new_hex_location = GetCharToHexSize()*(text_ctrl->PixelCoordToInternalPosition( event.GetPosition() )); //Than we needed to multiply with 2 for take it's hex location.
717 }
718
719 int old_hex_location = GetLocalHexInsertionPoint(); //requesting old hex location
720 if( new_hex_location != old_hex_location ){ //if hex selection addresses are different, start selection routine
721
722 if( !select->GetState() ) //if this is new selection start
723 if( Selector() == false ) //and select without focus
724 return; //don't make anything.
725 SetLocalHexInsertionPoint( new_hex_location ); //Moving cursor to new location.
726 Selector(); //Making actual selection.
727 PaintSelection();
728 }
729 }
730 else{
731 if( event.GetEventObject() == hex_ctrl ||
732 event.GetEventObject() == text_ctrl ||
733 event.GetEventObject() == offset_ctrl ){
734 TagElement* tg = static_cast<wxHexCtrl*>(event.GetEventObject())->GetTagByPix( event.GetPosition() );
735 if( (tg == NULL && TAGMutex==true) || //If there is no Tag at under and tag mutex available
736 (tg != NULL && !tg->visible) ) // or Changed to new tag
737 TagHideAll();
738 }
739 event.Skip(); //enable tags but problems with paint?
740 }
741 }
742
OnMouseSelectionEnd(wxMouseEvent & event)743 void HexEditorCtrl::OnMouseSelectionEnd( wxMouseEvent& event ){
744 event.Skip();
745 }
746
OnMouseRight(wxMouseEvent & event)747 void HexEditorCtrl::OnMouseRight( wxMouseEvent& event ){
748 //Not used code. HexEditor::OnMouseRight( wxMouseEvent& event ) used instead.
749 if(event.GetEventObject() == hex_ctrl)
750 LastRightClickAt = hex_ctrl->PixelCoordToInternalPosition( event.GetPosition() )/2;
751 else if(event.GetEventObject() == text_ctrl)
752 LastRightClickAt = text_ctrl->PixelCoordToInternalPosition( event.GetPosition() );
753 else if( event.GetEventObject() == offset_ctrl)
754 {
755 //m_static_offset->SetLabel( offset_ctrl->hex_offset==true ? _("Offset: DEC") : _("Offset: HEX"));
756 //event.Skip(true);
757 offset_ctrl->OnMouseRight( event );
758 int x,y;
759 DoGetSize(&x,&y);
760 wxSizeEvent mevent(wxSize(x,y));
761 OnResize(mevent);
762 return;//to avoid ShowContextMenu
763 }
764 else
765 std::cout << "Right click captured without ctrl!\n";
766 ShowContextMenu( event );
767 }
768
OnFocus(wxFocusEvent & event)769 void HexEditorCtrl::OnFocus( wxFocusEvent& event){
770 #ifdef _DEBUG_
771 std::cout << "HexEditorCtrl::OnFocus( wxFocusEvent& event ) \n" ;
772 #endif
773 if( event.GetWindow() == hex_ctrl ||
774 event.GetWindow() == text_ctrl )
775 LastFocused=event.GetWindow();
776 event.Skip();//let wxHexCtrl::Focus set the cursor
777 }
778
OnKillFocus(wxFocusEvent & event)779 void HexEditorCtrl::OnKillFocus( wxFocusEvent& event){
780 #ifdef _DEBUG_
781 std::cout << "HexEditorCtrl::OnKillFocus( wxFocusEvent& event ) \n" ;
782 #endif
783 TagHideAll();
784 event.Skip();
785 }
786
TagCreator(bool QuickTag)787 void HexEditorCtrl::TagCreator( bool QuickTag ){
788 if( select->GetState() ){
789 TagElement *TE = new TagElement;
790 TE->start=select->StartOffset;
791 TE->end=select->EndOffset;
792
793 srand ( time(NULL) );
794 //static keeps color values for next tag here!
795 static wxColour last_tag_color = rand();
796 static wxColour last_font_color = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT );
797
798 TE->NoteClrData.SetColour( QuickTag ? rand() : last_tag_color );
799 TE->FontClrData.SetColour( last_font_color );
800
801 int a=wxID_SAVE;
802 if( !QuickTag ){
803 TagDialog x( *TE, this );
804 a=x.ShowModal();
805 }
806 if( a == wxID_SAVE ){
807 last_tag_color = TE->NoteClrData.GetColour();
808 last_font_color = TE->FontClrData.GetColour();
809 MainTagArray.Add( TE );
810
811 //Sorting TAGs array because of quick painting code look sorted tags and just paint required ones.
812 MainTagArray.Sort( TagElementSort );
813
814 PreparePaintTAGs();
815 ClearPaint();
816 text_ctrl->RePaint();
817 hex_ctrl ->RePaint();
818 }
819 //delete TE; NO! Don't delete this tags!
820 }
821 //event.Skip( true );
822 wxUpdateUIEvent eventx( TAG_CHANGE_EVENT );
823 GetEventHandler()->ProcessEvent( eventx );
824 }
825
OnTagQuick(wxCommandEvent & event)826 void HexEditorCtrl::OnTagQuick( wxCommandEvent& event ){
827 TagCreator( true );
828 }
829
OnTagAddSelection(wxCommandEvent & event)830 void HexEditorCtrl::OnTagAddSelection( wxCommandEvent& event ){
831 TagCreator( false );
832 }
833
OnTagEdit(wxCommandEvent & event)834 void HexEditorCtrl::OnTagEdit( wxCommandEvent& event ){
835 TagElement *TAG;
836 uint64_t pos = LastRightClickAt;
837 #ifdef _DEBUG_TAG_
838 std::cout << " Tag Edit on " << pos << std::endl;
839 #endif
840 for( unsigned i = 0 ; i < MainTagArray.Count() ; i++ ){
841 TAG = MainTagArray.Item(i);
842 if( TAG->isCover(pos) ){
843 TagHideAll(); //Hide first, or BUG by double hide...
844 TagElement TAGtemp = *TAG;
845 TagDialog *x=new TagDialog( TAGtemp, this );
846 switch( x->ShowModal() ){
847 case wxID_SAVE:
848 *TAG = TAGtemp;
849 PreparePaintTAGs();
850 ClearPaint();
851 text_ctrl->RePaint();
852 hex_ctrl ->RePaint();
853 break;
854 case wxID_DELETE:
855 delete TAG;
856 MainTagArray.Remove(TAG);
857 PreparePaintTAGs();
858 ClearPaint();
859 text_ctrl->RePaint();
860 hex_ctrl ->RePaint();
861 break;
862 default:
863 break;
864 }
865 }
866 }
867 wxUpdateUIEvent eventx( TAG_CHANGE_EVENT );
868 GetEventHandler()->ProcessEvent( eventx );
869 }
870
TagHideAll(void)871 void HexEditorCtrl::TagHideAll( void ){
872 hex_ctrl->OnTagHideAll();
873 text_ctrl->OnTagHideAll();
874 TAGMutex = false;
875 }
876
LoadTAGS(wxFileName flnm)877 bool HexEditorCtrl::LoadTAGS( wxFileName flnm ){
878 wxXmlDocument doc;
879 if( flnm.IsFileReadable() )
880 if( doc.Load( flnm.GetFullPath(), wxT("UTF-8")) )
881 if (doc.GetRoot()->GetName() == wxT("wxHexEditor_XML_TAG")){
882 wxXmlNode *child = doc.GetRoot()->GetChildren();
883
884 child = child->GetChildren(); //<filename> -> <TAG>
885
886 while (child) {
887 if (child->GetName() == wxT("TAG")) {
888 wxString propvalue = child->GetAttribute(wxT("id"), wxEmptyString);
889 #ifdef _DEBUG_TAG_
890 std::cout << "TAG ID:" << propvalue.ToAscii() << " readed.\n";
891 #endif
892 TagElement *tmp = new TagElement();
893 long long unsigned xxl=0;
894 for( wxXmlNode *element = child->GetChildren() ; element != NULL ; element = element->GetNext() ){
895 if (element->GetName() == wxT("start_offset")){
896 #ifdef __WXMSW__ //I don't knwo why but ToULongLong dowen't work on windows by mingw.
897 xxl = atoll( element->GetNodeContent().ToAscii() );
898 #else
899 element->GetNodeContent().ToULongLong( &xxl, 10 );
900 #endif
901 tmp->start = xxl;
902 }
903 else if (element->GetName() == wxT("end_offset")){
904 #ifdef __WXMSW__
905 xxl = atoll( element->GetNodeContent().ToAscii() );
906 #else
907 element->GetNodeContent().ToULongLong( &xxl, 10 );
908 #endif
909 tmp->end = xxl;
910 }
911 else if (element->GetName() == wxT("tag_text"))
912 tmp->tag = element->GetNodeContent();
913 else if (element->GetName() == wxT("font_colour"))
914 tmp->FontClrData.SetColour( wxColour(element->GetNodeContent()) );
915 else if (element->GetName() == wxT("note_colour"))
916 tmp->NoteClrData.SetColour( wxColour(element->GetNodeContent()) );
917 }
918 #ifdef _DEBUG_TAG_
919 tmp->print();
920 #endif
921 MainTagArray.Add(tmp);
922 }
923 child = child->GetNext();
924 }
925 MainTagArray.Sort(TagElementSort);
926 PreparePaintTAGs();
927 ClearPaint();
928 text_ctrl->RePaint();
929 hex_ctrl ->RePaint();
930 return true;
931 }
932 return false;
933 }
934
935 //Moves tags for deletion & insertions
MoveTAGS(uint64_t location,int64_t size)936 void HexEditorCtrl::MoveTAGS( uint64_t location, int64_t size ){
937 for( unsigned i = 0 ; i < MainTagArray.Count() ; i++ ){
938 TagElement *TAG = MainTagArray.Item(i);
939
940 //Deletion, (-size) double negation indicates deletion range.
941 if( size < 0 && TAG->start >= location && TAG->start < location+(-size) ){
942 //Deletion of code if start inside deletion selection.
943 //i-- due MainTagArray.Count() shrinks
944 MainTagArray.RemoveAt(i--);
945 continue;
946 }
947
948 //Insert operation
949 if( TAG->start >= location ){
950 TAG->start += size;
951 TAG->end += size;
952 }
953 }
954
955 for( unsigned i = 0 ; i < HighlightArray.Count() ; i++ ){
956 TagElement *TAG = HighlightArray.Item(i);
957
958 //Deletion, (-size) double negation indicates deletion range.
959 if( size < 0 && TAG->start >= location && TAG->start <= location+(-size) ){
960 //Deletion of code if start inside deletion selection.
961 //i-- due HighlightArray.Count() shrinks
962 HighlightArray.RemoveAt(i--);
963 continue;
964 }
965
966 //Insert operation
967 if( TAG->start >= location ){
968 TAG->start += size;
969 TAG->end += size;
970 }
971 }
972
973 wxUpdateUIEvent eventx( TAG_CHANGE_EVENT );
974 GetEventHandler()->ProcessEvent( eventx );
975
976 eventx.SetId( SEARCH_CHANGE_EVENT );
977 GetEventHandler()->ProcessEvent( eventx );
978 }
979
SaveTAGS(wxFileName flnm)980 bool HexEditorCtrl::SaveTAGS( wxFileName flnm ){
981 if( MainTagArray.Count() == 0){
982 // if( wxFileName::FileName( flnm.GetFullPath() ).FileExists() )
983 // wxRemoveFile( flnm.GetFullPath() );
984 if( wxFileName::FileName( flnm.GetFullPath() << wxT(".tags") ).FileExists() )
985 wxRemoveFile( flnm.GetFullPath() << wxT(".tags") );
986 return false;
987 }
988 else{
989 wxXmlDocument doc;
990
991 wxXmlNode *node_Root = new wxXmlNode( NULL, wxXML_ELEMENT_NODE, wxT("wxHexEditor_XML_TAG"), wxEmptyString, NULL , NULL);
992
993 #if wxCHECK_VERSION(3, 0, 0)
994 wxXmlAttribute *prop_filename = new wxXmlAttribute( wxT("path"), flnm.GetFullPath(), NULL);
995 #else
996 wxXmlProperty *prop_filename = new wxXmlProperty( wxT("path"), flnm.GetFullPath(), NULL);
997 #endif
998 wxXmlNode *node_File = new wxXmlNode( node_Root, wxXML_ELEMENT_NODE, wxT("filename"), wxEmptyString, prop_filename , NULL);
999
1000 MainTagArray.Sort(TagElementSort);
1001 for(signed i = MainTagArray.Count()-1 ; i>=0 ; i-- ){
1002 //Used reverse order for make XML offsets increasing.
1003 TagElement *TAG = MainTagArray.Item(i);
1004 #if wxCHECK_VERSION(3, 0, 0)
1005 wxXmlAttribute *ID = new wxXmlAttribute( wxT("id"), wxString::Format(wxT("%d"),i), NULL );
1006 #else
1007 wxXmlProperty *ID = new wxXmlProperty( wxT("id"), wxString::Format(wxT("%d"),i), NULL );
1008 #endif
1009
1010
1011 wxXmlNode *node_Tag = new wxXmlNode( node_File, wxXML_ELEMENT_NODE, wxT("TAG"), wxEmptyString, ID , NULL);
1012
1013 wxXmlNode *element_NoteColour = new wxXmlNode( node_Tag, wxXML_ELEMENT_NODE, wxT("note_colour"), wxEmptyString, NULL, NULL);
1014 new wxXmlNode( element_NoteColour, wxXML_TEXT_NODE, wxT("note_colour"), TAG->NoteClrData.GetColour().GetAsString(wxC2S_HTML_SYNTAX), NULL, NULL);
1015
1016 wxXmlNode *element_FontColour = new wxXmlNode( node_Tag, wxXML_ELEMENT_NODE, wxT("font_colour"), wxEmptyString, NULL, element_NoteColour);
1017 new wxXmlNode( element_FontColour, wxXML_TEXT_NODE, wxT("font_colour"), TAG->FontClrData.GetColour().GetAsString(wxC2S_HTML_SYNTAX), NULL, NULL);
1018
1019 wxXmlNode *element_TagText = new wxXmlNode( node_Tag, wxXML_ELEMENT_NODE, wxT("tag_text"), wxEmptyString, NULL, element_FontColour);
1020 new wxXmlNode( element_TagText, wxXML_TEXT_NODE, wxT("tag_text"), TAG->tag, NULL, NULL);
1021
1022 wxXmlNode *element_End = new wxXmlNode( node_Tag, wxXML_ELEMENT_NODE, wxT("end_offset"), wxEmptyString, NULL, element_TagText);
1023 new wxXmlNode( element_End, wxXML_TEXT_NODE, wxT("end_offset"), wxString::Format("%" wxLongLongFmtSpec "u",TAG->end ) , NULL, NULL);
1024
1025 wxXmlNode *element_Start = new wxXmlNode( node_Tag, wxXML_ELEMENT_NODE, wxT("start_offset"), wxEmptyString, NULL, element_End);
1026 new wxXmlNode( element_Start, wxXML_TEXT_NODE, wxT("start_offset"), wxString::Format("%" wxLongLongFmtSpec "u", TAG->start ), NULL, NULL);
1027 }
1028 doc.SetFileEncoding( wxT("UTF-8") );
1029 doc.SetRoot( node_Root );
1030 wxString path = flnm.GetFullPath();
1031 if( !path.Lower().EndsWith(wxT(".tags")) )
1032 path += wxT(".tags");
1033
1034 return doc.Save(path);
1035 }
1036 }
1037
UpdateUI(wxUpdateUIEvent & event)1038 void HexEditorCtrl::UpdateUI(wxUpdateUIEvent& event){
1039 std::cout << "wxHexEditorCtrl::OnUpdateUI()" << std::endl;
1040 //m_static_offset->SetLabel( offset_ctrl->hex_offset==false ? _("Offset: DEC") : _("Offset: HEX"));
1041 }
1042
1043 //------ADAPTERS----------//
1044 //returns position of Hex Cursor
GetLocalHexInsertionPoint()1045 int HexEditorCtrl::GetLocalHexInsertionPoint(){
1046 return (hex_ctrl->IsShown() ? hex_ctrl->GetInsertionPoint() : text_ctrl->GetInsertionPoint()*GetCharToHexSize() );
1047 }
1048 //returns position of Text Cursor
GetLocalInsertionPoint()1049 int HexEditorCtrl::GetLocalInsertionPoint(){
1050 return (FindFocus() == text_ctrl ? text_ctrl->GetInsertionPoint()*(GetCharToHexSize()/2) : hex_ctrl->GetInsertionPoint()/2 );
1051 }
1052
SetLocalHexInsertionPoint(int hex_location)1053 void HexEditorCtrl::SetLocalHexInsertionPoint( int hex_location ){ //Sets position of Hex Cursor
1054 #ifdef _DEBUG_CARET_
1055 std::cout<< "Caret at Hex:" << std::dec << hex_location << std::endl;
1056 #endif // _DEBUG_CARET_
1057 text_ctrl->SetInsertionPoint( hex_location/GetCharToHexSize() );
1058 hex_ctrl->SetInsertionPoint( hex_location );
1059 }
CursorOffset(void)1060 int64_t HexEditorCtrl::CursorOffset( void ){
1061 return GetLocalInsertionPoint() + page_offset;
1062 }
1063
ProcessRAM_GetFootPrint()1064 uint64_t HexEditorCtrl::ProcessRAM_GetFootPrint(){
1065 uint64_t fp = 0;
1066 for( unsigned i = 0; i+1 < ProcessRAMMap.Count() ; i+=2){
1067 fp += ProcessRAMMap.Item(i+1);
1068 fp -= ProcessRAMMap.Item(i);
1069 }
1070 return fp;
1071 }
1072
ProcessRAM_GetVirtualOffset(uint64_t offset)1073 uint64_t HexEditorCtrl::ProcessRAM_GetVirtualOffset( uint64_t offset ){
1074 uint64_t fp=0;
1075 for( unsigned i = 0; i+1 < ProcessRAMMap.Count() ; i+=2){
1076 ProcessRAMMap.Item(i);
1077 if( i == 0 && ProcessRAMMap.Item(i) > offset )
1078 return 0;
1079 //If map end smaller than offset, just add memory map size to "fp"
1080 if( offset > ProcessRAMMap.Item(i+1) ){
1081 fp += ProcessRAMMap.Item(i+1);
1082 fp -= ProcessRAMMap.Item(i);
1083 }
1084 //if map end bigger than offset, and map start smaller than offset,
1085 else if( offset >= ProcessRAMMap.Item(i) ) {
1086 ProcessRAMMap.Item(i);
1087 fp += offset - ProcessRAMMap.Item(i);
1088 return fp;
1089 }
1090 //if map start bigger than offset, means offset is non mapped region.
1091 else //( offset < ProcessRAMMap.Item(i) )
1092 return fp;
1093 }
1094 return 0;
1095 }
1096
ProcessRAM_FindNextMap(uint64_t offset,bool backward)1097 uint64_t HexEditorCtrl::ProcessRAM_FindNextMap( uint64_t offset, bool backward ){
1098 if(ProcessRAMMap.Count()){
1099 if(backward){
1100 for( int i=ProcessRAMMap.Count()-2; i >= 0 ; i-=2 )
1101 if( ProcessRAMMap.Item(i+1) < offset )
1102 return ProcessRAMMap.Item(i+1);
1103 }
1104 else{
1105 for( unsigned i=0; i < ProcessRAMMap.Count() ; i+=2 )
1106 if( ProcessRAMMap.Item(i) > offset )
1107 return ProcessRAMMap.Item(i);
1108 }
1109 }
1110 return 0;
1111 }
1112
ProcessRAM_FindMap(uint64_t offset,uint64_t & start,uint64_t & end,bool backward)1113 bool HexEditorCtrl::ProcessRAM_FindMap( uint64_t offset, uint64_t& start, uint64_t& end, bool backward ){
1114 start=0;
1115 end=0;
1116 if(ProcessRAMMap.Count())
1117 for( unsigned i=0; i < ProcessRAMMap.Count() ; i+=2 )
1118 if(( ProcessRAMMap.Item(i) <= offset ) &&
1119 ( ProcessRAMMap.Item(i+1) >= offset )){
1120 start=ProcessRAMMap.Item(i);
1121 end=ProcessRAMMap.Item(i+1);
1122 if( backward && i >= 2 ){
1123 start=ProcessRAMMap.Item(i-2);
1124 end=ProcessRAMMap.Item(i-2+1);
1125 }
1126 else
1127 return false;
1128 return true;
1129 }
1130 return false;
1131 }
1132
wxHugeScrollBar(wxScrollBar * m_scrollbar_)1133 wxHugeScrollBar::wxHugeScrollBar( wxScrollBar* m_scrollbar_ ){
1134 m_range = m_thumb = 0;
1135 m_scrollbar = m_scrollbar_;
1136
1137 m_scrollbar->Connect( wxEVT_SCROLL_TOP, wxScrollEventHandler( wxHugeScrollBar::OnOffsetScroll ), NULL, this );
1138 m_scrollbar->Connect( wxEVT_SCROLL_BOTTOM, wxScrollEventHandler( wxHugeScrollBar::OnOffsetScroll ), NULL, this );
1139 m_scrollbar->Connect( wxEVT_SCROLL_LINEUP, wxScrollEventHandler( wxHugeScrollBar::OnOffsetScroll ), NULL, this );
1140 m_scrollbar->Connect( wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler( wxHugeScrollBar::OnOffsetScroll ), NULL, this );
1141 m_scrollbar->Connect( wxEVT_SCROLL_PAGEUP, wxScrollEventHandler( wxHugeScrollBar::OnOffsetScroll ), NULL, this );
1142 m_scrollbar->Connect( wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler( wxHugeScrollBar::OnOffsetScroll ), NULL, this );
1143 m_scrollbar->Connect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( wxHugeScrollBar::OnOffsetScroll ), NULL, this );
1144 m_scrollbar->Connect( wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler( wxHugeScrollBar::OnOffsetScroll ), NULL, this );
1145 m_scrollbar->Connect( wxEVT_SCROLL_CHANGED, wxScrollEventHandler( wxHugeScrollBar::OnOffsetScroll ), NULL, this );
1146 }
1147
~wxHugeScrollBar()1148 wxHugeScrollBar::~wxHugeScrollBar(){
1149 m_scrollbar->Disconnect( wxEVT_SCROLL_TOP, wxScrollEventHandler( wxHugeScrollBar::OnOffsetScroll ), NULL, this );
1150 m_scrollbar->Disconnect( wxEVT_SCROLL_BOTTOM, wxScrollEventHandler( wxHugeScrollBar::OnOffsetScroll ), NULL, this );
1151 m_scrollbar->Disconnect( wxEVT_SCROLL_LINEUP, wxScrollEventHandler( wxHugeScrollBar::OnOffsetScroll ), NULL, this );
1152 m_scrollbar->Disconnect( wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler( wxHugeScrollBar::OnOffsetScroll ), NULL, this );
1153 m_scrollbar->Disconnect( wxEVT_SCROLL_PAGEUP, wxScrollEventHandler( wxHugeScrollBar::OnOffsetScroll ), NULL, this );
1154 m_scrollbar->Disconnect( wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler( wxHugeScrollBar::OnOffsetScroll ), NULL, this );
1155 m_scrollbar->Disconnect( wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler( wxHugeScrollBar::OnOffsetScroll ), NULL, this );
1156 m_scrollbar->Disconnect( wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler( wxHugeScrollBar::OnOffsetScroll ), NULL, this );
1157 m_scrollbar->Disconnect( wxEVT_SCROLL_CHANGED, wxScrollEventHandler( wxHugeScrollBar::OnOffsetScroll ), NULL, this );
1158 }
1159
SetThumbPosition(int64_t setpos)1160 void wxHugeScrollBar::SetThumbPosition(int64_t setpos){
1161 #ifdef _DEBUG_SCROLL_
1162 std::cout << "SetThumbPosition()" << setpos << std::endl;
1163 #endif
1164 m_thumb = setpos;
1165 if( m_range <= 2147483647){
1166 m_scrollbar->SetThumbPosition( setpos );
1167 }
1168 else{
1169 #ifdef _DEBUG_SCROLL_
1170 std::cout << "m_Range: " << m_range << std::endl;
1171 std::cout << "SetThumbPositionx(): " << static_cast<int>(setpos*(2147483648.0/m_range)) << std::endl;
1172 #endif
1173 m_scrollbar->SetThumbPosition( static_cast<int>(setpos*(2147483648.0/m_range)) );
1174 }
1175 }
1176
SetScrollbar(int64_t Current_Position,int page_x,int64_t new_range,int pagesize,bool repaint)1177 void wxHugeScrollBar::SetScrollbar( int64_t Current_Position,int page_x, int64_t new_range, int pagesize, bool repaint ){
1178 m_range = new_range;
1179 if(new_range <= 2147483647){//if representable with 32 bit
1180 m_scrollbar->SetScrollbar( Current_Position, page_x, new_range, pagesize, repaint );
1181 }
1182 else{
1183 #ifdef _DEBUG_SCROLL_
1184 std::cout << "new_range " << new_range << std::endl;
1185 std::cout << "Current_Position :" << (Current_Position*(2147483647/new_range)) << std::endl;
1186 #endif
1187 m_scrollbar->SetScrollbar( (Current_Position*(2147483647/new_range)), page_x, 2147483647, pagesize, repaint );
1188 }
1189 SetThumbPosition( Current_Position );
1190 }
1191
OnOffsetScroll(wxScrollEvent & event)1192 void wxHugeScrollBar::OnOffsetScroll( wxScrollEvent& event ){
1193 if( m_range <= 2147483647){
1194 m_thumb = event.GetPosition();
1195 }
1196 else{ //64bit mode
1197 int64_t here =event.GetPosition();
1198 if(here == 2147483646) //if maximum set
1199 m_thumb = m_range-1; //than give maximum m_thumb which is -1 from range
1200 else
1201 m_thumb = static_cast<int64_t>(here*(m_range/2147483647.0));
1202 }
1203 wxYieldIfNeeded();
1204
1205 #ifdef _DEBUG_SCROLL_
1206 if(event.GetEventType() == wxEVT_SCROLL_CHANGED)
1207 std::cout << "wxEVT_SCROLL_CHANGED" << std::endl;
1208 if(event.GetEventType() == wxEVT_SCROLL_THUMBTRACK)
1209 std::cout << "wxEVT_SCROLL_THUMBTRACK" << std::endl;
1210 if(event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE)
1211 std::cout << "wxEVT_SCROLL_THUMBRELEASE" << std::endl;
1212 if( event.GetEventType() == wxEVT_SCROLL_LINEDOWN )
1213 std::cout << "wxEVT_SCROLL_LINEDOWN" << std::endl;
1214 if( event.GetEventType() == wxEVT_SCROLL_LINEUP )
1215 std::cout << "wxEVT_SCROLL_LINEUP" << std::endl;
1216 if( event.GetEventType() == wxEVT_SCROLL_PAGEUP )
1217 std::cout << "wxEVT_SCROLL_PAGEUP" << std::endl;
1218 if( event.GetEventType() == wxEVT_SCROLL_PAGEDOWN )
1219 std::cout << "wxEVT_SCROLL_PAGEDOWN" << std::endl;
1220 if( event.GetEventType() == wxEVT_SCROLLWIN_LINEUP )
1221 std::cout << "wxEVT_SCROLLWIN_LINEUP" << std::endl;
1222 if( event.GetEventType() == wxEVT_SCROLLWIN_LINEDOWN )
1223 std::cout << "wxEVT_SCROLLWIN_LINEDOWN" << std::endl;
1224 #endif
1225 event.Skip();
1226 }
1227
1228