Added a method to access DataView's internal buffer.
Implemented editing functionality for both focus types. Optimized InvalidateRange() if the update spans over the whole view. Now resets the cursor position/selection when the editor offset changed. UpdateFromEditor() now takes the range of the size into account. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6739 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
4897914eca
commit
32d3a4554d
@ -9,10 +9,14 @@
|
||||
|
||||
#include <Window.h>
|
||||
#include <ScrollBar.h>
|
||||
#include <Autolock.h>
|
||||
#include <Clipboard.h>
|
||||
#include <Mime.h>
|
||||
|
||||
|
||||
typedef uint32 addr_t;
|
||||
// this one is not yet defined in a public place
|
||||
|
||||
static const uint32 kBlockSize = 16;
|
||||
static const uint32 kHorizontalSpace = 8;
|
||||
static const uint32 kVerticalSpace = 4;
|
||||
@ -60,6 +64,7 @@ DataView::DataView(BRect rect, DataEditor &editor)
|
||||
|
||||
if (fEditor.Lock()) {
|
||||
fDataSize = fEditor.ViewSize();
|
||||
fOffset = fEditor.ViewOffset();
|
||||
fEditor.Unlock();
|
||||
} else
|
||||
fDataSize = 512;
|
||||
@ -92,15 +97,33 @@ DataView::AttachedToWindow()
|
||||
|
||||
|
||||
void
|
||||
DataView::UpdateFromEditor(BMessage */*message*/)
|
||||
DataView::UpdateFromEditor(BMessage *message)
|
||||
{
|
||||
if (fData == NULL)
|
||||
return;
|
||||
|
||||
if (fEditor.Lock()) {
|
||||
fOffset = fEditor.ViewOffset();
|
||||
fFileSize = fEditor.FileSize();
|
||||
|
||||
// get the range of the changes
|
||||
|
||||
int32 start = 0, end = fDataSize - 1;
|
||||
off_t offset, size;
|
||||
if (message != NULL
|
||||
&& message->FindInt64("offset", &offset) == B_OK
|
||||
&& message->FindInt64("size", &size) == B_OK) {
|
||||
if (offset > fOffset + fDataSize
|
||||
|| offset + size < fOffset) {
|
||||
// the changes are not within our scope, so we can ignore them
|
||||
return;
|
||||
}
|
||||
|
||||
if (offset > fOffset)
|
||||
start = offset - fOffset;
|
||||
if (offset + size < fOffset + fDataSize)
|
||||
end = offset + size - fOffset;
|
||||
}
|
||||
|
||||
if (fOffset + fDataSize > fFileSize)
|
||||
fSizeInView = fFileSize - fOffset;
|
||||
else
|
||||
@ -108,11 +131,12 @@ DataView::UpdateFromEditor(BMessage */*message*/)
|
||||
|
||||
const uint8 *data;
|
||||
if (fEditor.GetViewBuffer(&data) == B_OK)
|
||||
// ToDo: copy only the relevant part
|
||||
memcpy(fData, data, fDataSize);
|
||||
|
||||
fEditor.Unlock();
|
||||
|
||||
Invalidate();
|
||||
InvalidateRange(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,6 +150,10 @@ DataView::MessageReceived(BMessage *message)
|
||||
UpdateFromEditor(message);
|
||||
break;
|
||||
|
||||
case kMsgDataEditorOffsetChange:
|
||||
SetSelection(0, 0);
|
||||
break;
|
||||
|
||||
case kMsgBaseType:
|
||||
{
|
||||
int32 type;
|
||||
@ -541,6 +569,8 @@ DataView::SetSelection(int32 start, int32 end, view_focus focus)
|
||||
fEnd = end;
|
||||
|
||||
DrawSelection();
|
||||
|
||||
fBitPosition = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -555,6 +585,11 @@ DataView::GetSelection(int32 &start, int32 &end)
|
||||
void
|
||||
DataView::InvalidateRange(int32 start, int32 end)
|
||||
{
|
||||
if (start <= 0 && end >= int32(fDataSize) - 1) {
|
||||
Invalidate();
|
||||
return;
|
||||
}
|
||||
|
||||
int32 startLine = start / kBlockSize;
|
||||
int32 endLine = end / kBlockSize;
|
||||
|
||||
@ -618,6 +653,16 @@ DataView::MakeVisible(int32 position)
|
||||
}
|
||||
|
||||
|
||||
const uint8 *
|
||||
DataView::DataAt(int32 start)
|
||||
{
|
||||
if (start < 0 || start >= int32(fSizeInView) || fData == NULL)
|
||||
return NULL;
|
||||
|
||||
return fData + start;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DataView::SetBase(base_type type)
|
||||
{
|
||||
@ -865,6 +910,66 @@ DataView::KeyDown(const char *bytes, int32 numBytes)
|
||||
SetFocus(fFocus == kHexFocus ? kAsciiFocus : kHexFocus);
|
||||
MakeVisible(fStart);
|
||||
break;
|
||||
|
||||
case B_FUNCTION_KEY:
|
||||
// this is ignored
|
||||
break;
|
||||
|
||||
case B_BACKSPACE:
|
||||
if (fBitPosition == 0)
|
||||
SetSelection(fStart - 1, fStart - 1);
|
||||
|
||||
if (fFocus == kHexFocus)
|
||||
fBitPosition = (fBitPosition + 4) % 8;
|
||||
|
||||
// supposed to fall through
|
||||
case B_DELETE:
|
||||
{
|
||||
BAutolock locker(fEditor);
|
||||
|
||||
if (fFocus == kHexFocus) {
|
||||
const uint8 *data = DataAt(fStart);
|
||||
if (data == NULL)
|
||||
break;
|
||||
|
||||
uint8 c = data[0] & (fBitPosition == 0 ? 0x0f : 0xf0);
|
||||
// mask out region to be cleared
|
||||
|
||||
fEditor.Replace(fOffset + fStart, &c, 1);
|
||||
} else
|
||||
fEditor.Replace(fOffset + fStart, (const uint8 *)"", 1);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
BAutolock locker(fEditor);
|
||||
|
||||
if (fFocus == kHexFocus) {
|
||||
// only hexadecimal characters are allowed to be entered
|
||||
const uint8 *data = DataAt(fStart);
|
||||
uint8 c = bytes[0];
|
||||
if (c >= 'A' && c <= 'F')
|
||||
c += 'A' - 'a';
|
||||
const char *hexNumbers = "0123456789abcdef";
|
||||
addr_t number;
|
||||
if (data == NULL || (number = (addr_t)strchr(hexNumbers, c)) == NULL)
|
||||
break;
|
||||
|
||||
number -= (addr_t)hexNumbers;
|
||||
fBitPosition = (fBitPosition + 4) % 8;
|
||||
|
||||
c = (data[0] & (fBitPosition ? 0x0f : 0xf0)) | (number << fBitPosition);
|
||||
// mask out overwritten region and bit-wise or the number to be inserted
|
||||
|
||||
if (fEditor.Replace(fOffset + fStart, &c, 1) == B_OK && fBitPosition == 0)
|
||||
SetSelection(fStart + 1, fStart + 1);
|
||||
} else {
|
||||
if (fEditor.Replace(fOffset + fStart, (const uint8 *)bytes, numBytes) == B_OK)
|
||||
SetSelection(fStart + 1, fStart + 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,8 @@ class DataView : public BView {
|
||||
base_type Base() const { return fBase; }
|
||||
void SetBase(base_type type);
|
||||
|
||||
const uint8 *DataAt(int32 start);
|
||||
|
||||
private:
|
||||
BRect DataBounds(bool inView = false) const;
|
||||
BRect SelectionFrame(view_focus which, int32 start, int32 end);
|
||||
@ -88,6 +90,7 @@ class DataView : public BView {
|
||||
bool fIsActive;
|
||||
int32 fStart, fEnd;
|
||||
int32 fMouseSelectionStart;
|
||||
int32 fBitPosition;
|
||||
};
|
||||
|
||||
static const uint32 kMsgBaseType = 'base';
|
||||
|
Loading…
Reference in New Issue
Block a user