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