From a7511f36548f2c94f7889f809e274753e4ef09c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 27 Feb 2004 02:51:48 +0000 Subject: [PATCH] Implemented changing the block size - that caused several changes to DataEditor::SetViewSize()/SetViewOffset() because they did not correctly update some values under certain circumstances. There is now a kMsgDataEditorParameterChange instead of just ...OffsetChange; the message will contain information about what has changed exactly. Added a new kDataViewPreferredSize notifier that indicates a change of the preferred size of the DataView. The ProbeView now listens to that instead of knowing when to update the window limits. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6772 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/diskprobe/DataEditor.cpp | 86 +++++++++++++++++++++++-------- src/apps/diskprobe/DataEditor.h | 5 +- src/apps/diskprobe/DataView.cpp | 20 +++++-- src/apps/diskprobe/DataView.h | 1 + src/apps/diskprobe/ProbeView.cpp | 55 +++++++++++++++++--- 5 files changed, 133 insertions(+), 34 deletions(-) diff --git a/src/apps/diskprobe/DataEditor.cpp b/src/apps/diskprobe/DataEditor.cpp index 89b3bf7fe9..8663d3fb1c 100644 --- a/src/apps/diskprobe/DataEditor.cpp +++ b/src/apps/diskprobe/DataEditor.cpp @@ -665,31 +665,35 @@ DataEditor::Redo() } -bool +bool DataEditor::CanUndo() const { return fLastChange != NULL; } -bool +bool DataEditor::CanRedo() const { return fChanges.IndexOf(fLastChange) < fChanges.CountItems() - 1; } -status_t +status_t DataEditor::SetFileSize(off_t size) { - fSize = size; - return B_OK; + // ToDo: implement me! + //fSize = size; + //return B_OK; + return B_ERROR; } status_t DataEditor::SetViewOffset(off_t offset, bool sendNotices) { + BAutolock locker(this); + if (fView == NULL) { status_t status = SetViewSize(fViewSize); if (status < B_OK) @@ -699,15 +703,19 @@ DataEditor::SetViewOffset(off_t offset, bool sendNotices) if (offset < 0 || offset > fSize) return B_BAD_VALUE; + offset = (offset / fViewSize) * fViewSize; if (offset == fViewOffset) return B_OK; - fRealViewOffset = (offset / fBlockSize) * fBlockSize; fViewOffset = offset; + fRealViewOffset = (fViewOffset / fBlockSize) * fBlockSize; fNeedsUpdate = true; - if (sendNotices) - SendNotices(kMsgDataEditorOffsetChange); + if (sendNotices) { + BMessage update; + update.AddInt64("offset", fViewOffset); + SendNotices(kMsgDataEditorParameterChange, &update); + } return B_OK; } @@ -721,39 +729,73 @@ DataEditor::SetViewOffset(off_t offset) status_t -DataEditor::SetViewSize(size_t size) +DataEditor::SetViewSize(size_t size, bool sendNotices) { + BAutolock locker(this); + size_t realSize = (size + fBlockSize - 1) & ~(fBlockSize - 1); // round to the next multiple of block size - if (realSize == fRealViewSize && fView != NULL) { - fViewSize = size; + if (realSize == fRealViewSize && fViewSize == size && fView != NULL) return B_OK; - } + if (realSize == 0) return B_BAD_VALUE; - uint8 *view = (uint8 *)realloc(fView, realSize); - if (view == NULL) - return B_NO_MEMORY; + if (realSize != fRealViewSize || fView == NULL) { + uint8 *view = (uint8 *)realloc(fView, realSize); + if (view == NULL) + return B_NO_MEMORY; + + fView = view; + fRealViewSize = realSize; + } - fView = view; - fRealViewSize = realSize; fViewSize = size; fNeedsUpdate = true; + // let's correct the view offset if necessary + if (fViewOffset % size) + SetViewOffset(fViewOffset); + + if (sendNotices) { + BMessage update; + update.AddInt32("view_size", size); + SendNotices(kMsgDataEditorParameterChange, &update); + } + return B_OK; } -void -DataEditor::SetBlockSize(size_t size) +status_t +DataEditor::SetViewSize(size_t size) { - fBlockSize = size; + return SetViewSize(size, true); } -status_t +status_t +DataEditor::SetBlockSize(size_t size) +{ + BAutolock locker(this); + + fBlockSize = size; + status_t status = SetViewOffset(fViewOffset, false); + // this will trigger an update of the real view offset + if (status == B_OK) + status = SetViewSize(fViewSize, false); + + BMessage update; + update.AddInt32("block_size", size); + update.AddInt64("offset", fViewOffset); + SendNotices(kMsgDataEditorParameterChange, &update); + + return status; +} + + +status_t DataEditor::Update() { ssize_t bytesRead; @@ -811,7 +853,7 @@ DataEditor::GetViewBuffer(const uint8 **_buffer) } -void +void DataEditor::SendNotices(DataChange *change) { off_t offset, size; diff --git a/src/apps/diskprobe/DataEditor.h b/src/apps/diskprobe/DataEditor.h index 82d9150f60..eca3888b17 100644 --- a/src/apps/diskprobe/DataEditor.h +++ b/src/apps/diskprobe/DataEditor.h @@ -61,7 +61,7 @@ class DataEditor : public BLocker { status_t SetViewSize(size_t size); size_t ViewSize() const { return fViewSize; } - void SetBlockSize(size_t size); + status_t SetBlockSize(size_t size); size_t BlockSize() const { return fBlockSize; } status_t UpdateIfNeeded(bool *_updated = NULL); @@ -79,6 +79,7 @@ class DataEditor : public BLocker { friend class StateWatcher; status_t SetViewOffset(off_t offset, bool sendNotices); + status_t SetViewSize(size_t size, bool sendNotices); void SendNotices(uint32 what, BMessage *message = NULL); void SendNotices(DataChange *change); status_t Update(); @@ -110,6 +111,6 @@ class DataEditor : public BLocker { static const uint32 kMsgDataEditorStateChange = 'deSC'; static const uint32 kMsgDataEditorUpdate = 'deUp'; -static const uint32 kMsgDataEditorOffsetChange = 'deOC'; +static const uint32 kMsgDataEditorParameterChange = 'dePC'; #endif /* DATA_EDITOR_H */ diff --git a/src/apps/diskprobe/DataView.cpp b/src/apps/diskprobe/DataView.cpp index 025765ed31..02c860e1cf 100644 --- a/src/apps/diskprobe/DataView.cpp +++ b/src/apps/diskprobe/DataView.cpp @@ -160,10 +160,22 @@ DataView::MessageReceived(BMessage *message) UpdateFromEditor(message); break; - case kMsgDataEditorOffsetChange: - fOffset = fEditor.ViewOffset(); - SetSelection(0, 0); + case kMsgDataEditorParameterChange: + { + int32 viewSize; + off_t offset; + if (message->FindInt64("offset", &offset) == B_OK) { + fOffset = offset; + SetSelection(0, 0); + MakeVisible(0); + } + if (message->FindInt32("view_size", &viewSize) == B_OK) { + fDataSize = viewSize; + fData = (uint8 *)realloc(fData, fDataSize); + UpdateScroller(); + } break; + } case kMsgBaseType: { @@ -1055,6 +1067,8 @@ DataView::SetFontSize(float point) SetFont(&font); UpdateScroller(); Invalidate(); + + SendNotices(kDataViewPreferredSize); } diff --git a/src/apps/diskprobe/DataView.h b/src/apps/diskprobe/DataView.h index 7743432c65..1d3c8fdac0 100644 --- a/src/apps/diskprobe/DataView.h +++ b/src/apps/diskprobe/DataView.h @@ -102,5 +102,6 @@ static const uint32 kMsgUpdateData = 'updt'; // observer notices static const uint32 kDataViewCursorPosition = 'curs'; static const uint32 kDataViewSelection = 'dsel'; +static const uint32 kDataViewPreferredSize = 'dvps'; #endif /* DATA_VIEW_H */ diff --git a/src/apps/diskprobe/ProbeView.cpp b/src/apps/diskprobe/ProbeView.cpp index bb7518e09b..bcc988bb2d 100644 --- a/src/apps/diskprobe/ProbeView.cpp +++ b/src/apps/diskprobe/ProbeView.cpp @@ -48,6 +48,7 @@ static const uint32 kMsgSliderUpdate = 'slup'; static const uint32 kMsgPositionUpdate = 'poup'; static const uint32 kMsgLastPosition = 'lpos'; static const uint32 kMsgFontSize = 'fnts'; +static const uint32 kMsgBlockSize = 'blks'; static const uint32 kMsgPrint = 'prnt'; static const uint32 kMsgPageSetup = 'pgsp'; @@ -110,6 +111,10 @@ class HeaderView : public BView, public BInvoker { base_type Base() const { return fBase; } void SetBase(base_type); + + off_t Position() const { return fPosition; } + uint32 BlockSize() const { return fBlockSize; } + void SetTo(off_t position, uint32 blockSize); private: void FormatValue(char *buffer, size_t bufferSize, off_t value); @@ -622,6 +627,20 @@ HeaderView::SetBase(base_type type) } +void +HeaderView::SetTo(off_t position, uint32 blockSize) +{ + fPosition = position; + fLastPosition = (fLastPosition / fBlockSize) * blockSize; + fBlockSize = blockSize; + + fPositionSlider->SetBlockSize(blockSize); + UpdatePositionViews(); + UpdateOffsetViews(false); + UpdateFileSizeView(); +} + + void HeaderView::NotifyTarget() { @@ -828,7 +847,7 @@ UpdateLooper::MessageReceived(BMessage *message) break; } - case kMsgDataEditorOffsetChange: + case kMsgDataEditorParameterChange: { bool updated = false; @@ -1127,10 +1146,14 @@ ProbeView::AttachedToWindow() // Block Size subMenu = new BMenu("BlockSize"); - subMenu->AddItem(item = new BMenuItem("512", NULL)); + subMenu->AddItem(item = new BMenuItem("512", message = new BMessage(kMsgBlockSize))); + message->AddInt32("block_size", 512); item->SetMarked(true); - subMenu->AddItem(new BMenuItem("1024", NULL)); - subMenu->AddItem(new BMenuItem("2048", NULL)); + subMenu->AddItem(new BMenuItem("1024", message = new BMessage(kMsgBlockSize))); + message->AddInt32("block_size", 1024); + subMenu->AddItem(new BMenuItem("2048", message = new BMessage(kMsgBlockSize))); + message->AddInt32("block_size", 2048); + subMenu->SetTargetForItems(this); subMenu->SetRadioMode(true); menu->AddItem(new BMenuItem(subMenu)); menu->AddSeparatorItem(); @@ -1161,7 +1184,7 @@ ProbeView::AttachedToWindow() } -void +void ProbeView::AllAttached() { fHeaderView->SetTarget(fUpdateLooper); @@ -1176,7 +1199,7 @@ ProbeView::WindowActivated(bool active) } -void +void ProbeView::UpdateSelectionMenuItems(int64 start, int64 end) { int64 position = 0; @@ -1354,6 +1377,9 @@ ProbeView::MessageReceived(BMessage *message) UpdateSelectionMenuItems(start, end); break; } + case kDataViewPreferredSize: + UpdateSizeLimits(); + break; } break; } @@ -1383,9 +1409,10 @@ ProbeView::MessageReceived(BMessage *message) { float size = 0.0f; message->FindFloat("font_size", &size); + // if there is no "font_size" member, the size will + // be adapted to fit the window size (0) fDataView->SetFontSize(size); - UpdateSizeLimits(); // update the applications settings BMessage update(*message); @@ -1394,6 +1421,20 @@ ProbeView::MessageReceived(BMessage *message) break; } + case kMsgBlockSize: + { + int32 blockSize; + if (message->FindInt32("block_size", &blockSize) != B_OK) + break; + + BAutolock locker(fEditor); + + if (fEditor.SetViewSize(blockSize) == B_OK + && fEditor.SetBlockSize(blockSize) == B_OK) + fHeaderView->SetTo(fEditor.ViewOffset(), blockSize); + break; + } + case kMsgPrint: Print(); break;