diff options
Diffstat (limited to 'khexedit/lib/controller/kvalueeditor.cpp')
-rw-r--r-- | khexedit/lib/controller/kvalueeditor.cpp | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/khexedit/lib/controller/kvalueeditor.cpp b/khexedit/lib/controller/kvalueeditor.cpp new file mode 100644 index 0000000..ebfb589 --- /dev/null +++ b/khexedit/lib/controller/kvalueeditor.cpp @@ -0,0 +1,226 @@ +/*************************************************************************** + kvalueeditor.cpp - description + ------------------- + begin : Sa Dez 4 2004 + copyright : (C) 2004 by Friedrich W. H. Kossebau + email : Friedrich.W.H@Kossebau.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License version 2 as published by the Free Software Foundation. * + * * + ***************************************************************************/ + + +// qt specific +#include <qevent.h> +// lib specific +#include "kvaluecolumn.h" +#include "kbufferranges.h" +#include "kbuffercursor.h" +#include "khexedit.h" +#include "kvalueeditor.h" + + +using namespace KHE; + +KValueEditor::KValueEditor( KValueColumn *VC, KBufferCursor *BC, KHexEdit* HE, KController *P ) + : KEditor( BC, HE, P ), + ValueColumn( VC ), + InEditMode( false ), + EditModeByInsert( false ) +{ +} + + +bool KValueEditor::handleKeyPress( QKeyEvent *KeyEvent ) +{ + bool KeyUsed = true; + + // TODO: for now we don't touch it if there are selections + if( !HexEdit->BufferRanges->hasSelection() ) + { + // + switch( KeyEvent->key() ) + { + case Qt::Key_Plus: + doValueEditAction( IncValue ); + break; + case Qt::Key_Minus: + doValueEditAction( DecValue ); + break; + case Qt::Key_Space: + if( !InEditMode ) + { + KeyUsed = false; + break; + } + case Qt::Key_Enter: + case Qt::Key_Return: + doValueEditAction( InEditMode?LeaveValue:EnterValue ); + break; + case Qt::Key_Escape: + if( InEditMode ) + doValueEditAction( CancelValue ); + else + KeyUsed = false; + break; + case Qt::Key_Backspace: + if( InEditMode ) + doValueEditAction( ValueBackspace ); + else + KeyUsed = false; + break; + default: + // is plain char? + if( KeyEvent->text().length() > 0 + && ( !(KeyEvent->state()&( Qt::ControlButton | Qt::AltButton | Qt::MetaButton )) ) ) + { + QChar C = KeyEvent->text()[0]; + // no usable char? + if( !C.isLetterOrNumber() ) + { + KeyUsed = false; + break; + } + int Input = C.latin1(); + + if( InEditMode ) + doValueEditAction( ValueAppend, Input ); + else + { + unsigned char InputValue = 0; + const KByteCodec *ByteCodec = ValueColumn->byteCodec(); + // valid digit? + if( ByteCodec->appendDigit(&InputValue,Input) ) + { + if( HexEdit->OverWrite ) + doValueEditAction( ValueEdit, InputValue ); + else + { + int Index = BufferCursor->realIndex(); + if( HexEdit->DataBuffer->insert(Index,(char*)&InputValue,1) > 0 ) + { + HexEdit->pauseCursor(); + HexEdit->updateLength(); + + InEditMode = true; + EditModeByInsert = true; + OldValue = EditValue = InputValue; + ByteCodec->encode( ByteBuffer, 0, EditValue ); + + BufferCursor->gotoRealIndex(); + KSection ChangedRange( Index,HexEdit->DataBuffer->size()-1 ); + HexEdit->BufferRanges->addChangedRange( ChangedRange ); + HexEdit->repaintChanged(); + HexEdit->ensureCursorVisible(); + HexEdit->unpauseCursor(); + HexEdit->updateCursor(); + emit HexEdit->bufferChanged( ChangedRange.start(), ChangedRange.end() ); + } + } + } + } + } + else + KeyUsed = false; + } + } + else + KeyUsed = false; + + return KeyUsed ? true : KEditor::handleKeyPress(KeyEvent); +} + + +void KValueEditor::doValueEditAction( KValueEditAction Action, int Input ) +{ + // we are not yet in edit mode? + if( !InEditMode ) + { + int ValidIndex = BufferCursor->validIndex(); + // no valid cursor position? + if( ValidIndex == -1 || (!HexEdit->OverWrite && Input == -1) || BufferCursor->isBehind() ) + return; + + InEditMode = true; + EditModeByInsert = false; // default, to be overwritten if so + + // save old value + OldValue = EditValue = (unsigned char)HexEdit->DataBuffer->datum(ValidIndex); + } + + const KByteCodec *ByteCodec = ValueColumn->byteCodec(); + // + unsigned char NewValue = EditValue; + bool StayInEditMode = true; + bool MoveToNext = false; + + switch( Action ) + { + case ValueEdit: + NewValue = Input; + EditValue = NewValue^255; // force update + EditModeByInsert = true; + break; + case ValueBackspace: + if( NewValue > 0 ) + ByteCodec->removeLastDigit( &NewValue ); + break; + case EnterValue: + EditValue ^= 255; // force update + break; + case IncValue: + if( NewValue < 255 ) + ++NewValue; + break; + case DecValue: + if( NewValue > 0 ) + --NewValue; + break; + case ValueAppend: + if( ByteCodec->appendDigit(&NewValue,Input) ) + if( EditModeByInsert && NewValue >= ByteCodec->digitsFilledLimit() ) + { + StayInEditMode = false; + MoveToNext = true; + } + break; + case LeaveValue: + StayInEditMode = false; + MoveToNext = EditModeByInsert; + break; + case CancelValue: + NewValue = OldValue; + StayInEditMode = false; + break; + } + + bool Changed = (NewValue != EditValue); + int Index = BufferCursor->index(); + if( Changed ) + { + // sync value + EditValue = NewValue; + ByteCodec->encode( ByteBuffer, 0, EditValue ); + + HexEdit->DataBuffer->replace( Index, 1, (char*)&EditValue, 1 ); + } + + HexEdit->updateCursor(); + + if( !StayInEditMode ) + { + HexEdit->pauseCursor(); + InEditMode = false; + if( MoveToNext ) + BufferCursor->gotoNextByte(); + HexEdit->unpauseCursor(); + } + + if( Changed ) + if( Action != EnterValue ) emit HexEdit->bufferChanged( Index, Index ); +} |