* Some refactoring and cleanups.

* Started a "View As" feature which will allow you to use the type 
  editor for the file itself - not yet enabled (or working).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23352 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-01-10 21:05:00 +00:00
parent c2b8af8b2b
commit 58e5eff96f
6 changed files with 577 additions and 279 deletions
+1
View File
@@ -88,6 +88,7 @@ FileWindow::FileWindow(BRect rect, entry_ref *ref, const BMessage *settings)
fProbeView->AddSaveMenuItems(menu, 4); fProbeView->AddSaveMenuItems(menu, 4);
fProbeView->AddPrintMenuItems(menu, menu->CountItems() - 4); fProbeView->AddPrintMenuItems(menu, menu->CountItems() - 4);
fProbeView->AddViewAsMenuItems();
fProbeView->UpdateSizeLimits(); fProbeView->UpdateSizeLimits();
} }
+310 -113
View File
@@ -1,12 +1,14 @@
/* /*
* Copyright 2004-2007, Axel Dörfler, [email protected]. All rights reserved. * Copyright 2004-2008, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#include "ProbeView.h" #include "ProbeView.h"
#include "DataView.h"
#include "DiskProbe.h" #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Application.h> #include <Application.h>
#include <Window.h> #include <Window.h>
@@ -35,10 +37,9 @@
#include <PrintJob.h> #include <PrintJob.h>
#include <Beep.h> #include <Beep.h>
#include <stdio.h> #include "DataView.h"
#include <stdlib.h> #include "DiskProbe.h"
#include <string.h> #include "TypeEditors.h"
#ifndef __HAIKU__ #ifndef __HAIKU__
# define DRAW_SLIDER_BAR # define DRAW_SLIDER_BAR
@@ -55,6 +56,7 @@ static const uint32 kMsgBlockSize = 'blks';
static const uint32 kMsgAddBookmark = 'bmrk'; static const uint32 kMsgAddBookmark = 'bmrk';
static const uint32 kMsgPrint = 'prnt'; static const uint32 kMsgPrint = 'prnt';
static const uint32 kMsgPageSetup = 'pgsp'; static const uint32 kMsgPageSetup = 'pgsp';
static const uint32 kMsgViewAs = 'vwas';
static const uint32 kMsgStopFind = 'sfnd'; static const uint32 kMsgStopFind = 'sfnd';
@@ -184,7 +186,20 @@ class EditorLooper : public BLooper {
}; };
//---------------------- class TypeView : public BView {
public:
TypeView(BRect rect, const char* name, int32 index,
DataEditor& editor, int32 resizingMode);
virtual ~TypeView();
virtual void FrameResized(float width, float height);
private:
BView* fTypeEditorView;
};
// #pragma mark - utility functions
static void static void
@@ -201,7 +216,7 @@ get_type_string(char *buffer, size_t bufferSize, type_code type)
} }
// #pragma mark - // #pragma mark - IconView
IconView::IconView(BRect rect, const entry_ref *ref, bool isDevice) IconView::IconView(BRect rect, const entry_ref *ref, bool isDevice)
@@ -285,7 +300,7 @@ IconView::UpdateIcon()
} }
// #pragma mark - // #pragma mark - PositionSlider
PositionSlider::PositionSlider(BRect rect, const char *name, BMessage *message, PositionSlider::PositionSlider(BRect rect, const char *name, BMessage *message,
@@ -407,7 +422,6 @@ void
PositionSlider::SetPosition(off_t position) PositionSlider::SetPosition(off_t position)
{ {
position /= fBlockSize; position /= fBlockSize;
printf("value: %ld\n", int32(1.0 * kMaxSliderLimit * position / ((fSize - 1) / fBlockSize) + 0.5));
SetValue(int32(1.0 * kMaxSliderLimit * position / ((fSize - 1) / fBlockSize) + 0.5)); SetValue(int32(1.0 * kMaxSliderLimit * position / ((fSize - 1) / fBlockSize) + 0.5));
} }
@@ -441,7 +455,7 @@ PositionSlider::SetBlockSize(uint32 blockSize)
} }
// #pragma mark - // #pragma mark - HeaderView
HeaderView::HeaderView(BRect frame, const entry_ref *ref, DataEditor &editor) HeaderView::HeaderView(BRect frame, const entry_ref *ref, DataEditor &editor)
@@ -474,7 +488,8 @@ HeaderView::HeaderView(BRect frame, const entry_ref *ref, DataEditor &editor)
AddChild(fStopButton); AddChild(fStopButton);
BStringView *stringView = new BStringView(BRect(50, 6, rect.right, 20), BStringView *stringView = new BStringView(BRect(50, 6, rect.right, 20),
B_EMPTY_STRING, editor.IsAttribute() ? "Attribute: " : editor.IsDevice() ? "Device: " : "File: "); B_EMPTY_STRING, editor.IsAttribute()
? "Attribute: " : editor.IsDevice() ? "Device: " : "File: ");
stringView->SetFont(&boldFont); stringView->SetFont(&boldFont);
stringView->ResizeToPreferred(); stringView->ResizeToPreferred();
AddChild(stringView); AddChild(stringView);
@@ -489,14 +504,16 @@ HeaderView::HeaderView(BRect frame, const entry_ref *ref, DataEditor &editor)
rect = stringView->Frame(); rect = stringView->Frame();
rect.left = rect.right; rect.left = rect.right;
rect.right = fStopButton->Frame().right - 1; rect.right = fStopButton->Frame().right - 1;
fPathView = new BStringView(rect, B_EMPTY_STRING, string.String(), B_FOLLOW_TOP | B_FOLLOW_LEFT_RIGHT); fPathView = new BStringView(rect, B_EMPTY_STRING, string.String(),
B_FOLLOW_TOP | B_FOLLOW_LEFT_RIGHT);
fPathView->SetFont(&plainFont); fPathView->SetFont(&plainFont);
AddChild(fPathView); AddChild(fPathView);
float top = 28; float top = 28;
if (editor.IsAttribute()) { if (editor.IsAttribute()) {
top += 3; top += 3;
stringView = new BStringView(BRect(50, top, frame.right, top + 15), B_EMPTY_STRING, "Attribute Type: "); stringView = new BStringView(BRect(50, top, frame.right, top + 15),
B_EMPTY_STRING, "Attribute Type: ");
stringView->SetFont(&boldFont); stringView->SetFont(&boldFont);
stringView->ResizeToPreferred(); stringView->ResizeToPreferred();
AddChild(stringView); AddChild(stringView);
@@ -509,7 +526,8 @@ HeaderView::HeaderView(BRect frame, const entry_ref *ref, DataEditor &editor)
char buffer[16]; char buffer[16];
get_type_string(buffer, sizeof(buffer), editor.Type()); get_type_string(buffer, sizeof(buffer), editor.Type());
fTypeControl = new BTextControl(rect, B_EMPTY_STRING, NULL, buffer, new BMessage(kMsgPositionUpdate)); fTypeControl = new BTextControl(rect, B_EMPTY_STRING, NULL, buffer,
new BMessage(kMsgPositionUpdate));
fTypeControl->SetDivider(0.0); fTypeControl->SetDivider(0.0);
fTypeControl->SetFont(&plainFont); fTypeControl->SetFont(&plainFont);
fTypeControl->TextView()->SetFontAndColor(&plainFont); fTypeControl->TextView()->SetFontAndColor(&plainFont);
@@ -521,7 +539,8 @@ HeaderView::HeaderView(BRect frame, const entry_ref *ref, DataEditor &editor)
} else } else
fTypeControl = NULL; fTypeControl = NULL;
stringView = new BStringView(BRect(50, top, frame.right, top + 15), B_EMPTY_STRING, "Block: "); stringView = new BStringView(BRect(50, top, frame.right, top + 15),
B_EMPTY_STRING, "Block: ");
stringView->SetFont(&boldFont); stringView->SetFont(&boldFont);
stringView->ResizeToPreferred(); stringView->ResizeToPreferred();
AddChild(stringView); AddChild(stringView);
@@ -531,7 +550,8 @@ HeaderView::HeaderView(BRect frame, const entry_ref *ref, DataEditor &editor)
rect.right += 75; rect.right += 75;
rect.OffsetBy(0, -2); rect.OffsetBy(0, -2);
// BTextControl oddities // BTextControl oddities
fPositionControl = new BTextControl(rect, B_EMPTY_STRING, NULL, "0x0", new BMessage(kMsgPositionUpdate)); fPositionControl = new BTextControl(rect, B_EMPTY_STRING, NULL, "0x0",
new BMessage(kMsgPositionUpdate));
fPositionControl->SetDivider(0.0); fPositionControl->SetDivider(0.0);
fPositionControl->SetFont(&plainFont); fPositionControl->SetFont(&plainFont);
fPositionControl->TextView()->SetFontAndColor(&plainFont); fPositionControl->TextView()->SetFontAndColor(&plainFont);
@@ -563,8 +583,9 @@ HeaderView::HeaderView(BRect frame, const entry_ref *ref, DataEditor &editor)
rect.left = rect.right + 4; rect.left = rect.right + 4;
rect.right = frame.right; rect.right = frame.right;
stringView = new BStringView(rect, B_EMPTY_STRING, stringView = new BStringView(rect, B_EMPTY_STRING, editor.IsAttribute()
editor.IsAttribute() ? "Attribute Offset: " : editor.IsDevice() ? "Device Offset: " : "File Offset: "); ? "Attribute Offset: " : editor.IsDevice()
? "Device Offset: " : "File Offset: ");
stringView->SetFont(&boldFont); stringView->SetFont(&boldFont);
stringView->ResizeToPreferred(); stringView->ResizeToPreferred();
AddChild(stringView); AddChild(stringView);
@@ -580,8 +601,8 @@ HeaderView::HeaderView(BRect frame, const entry_ref *ref, DataEditor &editor)
rect.InsetBy(3, 0); rect.InsetBy(3, 0);
rect.top = top + 21; rect.top = top + 21;
rect.bottom = rect.top + 12; rect.bottom = rect.top + 12;
fPositionSlider = new PositionSlider(rect, "slider", new BMessage(kMsgSliderUpdate), fPositionSlider = new PositionSlider(rect, "slider",
editor.FileSize(), editor.BlockSize()); new BMessage(kMsgSliderUpdate), editor.FileSize(), editor.BlockSize());
fPositionSlider->SetModificationMessage(new BMessage(kMsgSliderUpdate)); fPositionSlider->SetModificationMessage(new BMessage(kMsgSliderUpdate));
fPositionSlider->SetBarThickness(8); fPositionSlider->SetBarThickness(8);
fPositionSlider->ResizeToPreferred(); fPositionSlider->ResizeToPreferred();
@@ -604,13 +625,17 @@ HeaderView::AttachedToWindow()
fPositionSlider->SetTarget(this); fPositionSlider->SetTarget(this);
BMessage *message; BMessage *message;
Window()->AddShortcut(B_HOME, B_COMMAND_KEY, message = new BMessage(kMsgPositionUpdate), this); Window()->AddShortcut(B_HOME, B_COMMAND_KEY,
message = new BMessage(kMsgPositionUpdate), this);
message->AddInt64("block", 0); message->AddInt64("block", 0);
Window()->AddShortcut(B_END, B_COMMAND_KEY, message = new BMessage(kMsgPositionUpdate), this); Window()->AddShortcut(B_END, B_COMMAND_KEY,
message = new BMessage(kMsgPositionUpdate), this);
message->AddInt64("block", -1); message->AddInt64("block", -1);
Window()->AddShortcut(B_PAGE_UP, B_COMMAND_KEY, message = new BMessage(kMsgPositionUpdate), this); Window()->AddShortcut(B_PAGE_UP, B_COMMAND_KEY,
message = new BMessage(kMsgPositionUpdate), this);
message->AddInt32("delta", -1); message->AddInt32("delta", -1);
Window()->AddShortcut(B_PAGE_DOWN, B_COMMAND_KEY, message = new BMessage(kMsgPositionUpdate), this); Window()->AddShortcut(B_PAGE_DOWN, B_COMMAND_KEY,
message = new BMessage(kMsgPositionUpdate), this);
message->AddInt32("delta", 1); message->AddInt32("delta", 1);
} }
@@ -699,7 +724,8 @@ HeaderView::UpdateFileSizeView()
{ {
char buffer[64]; char buffer[64];
strcpy(buffer, "of "); strcpy(buffer, "of ");
FormatValue(buffer + 3, sizeof(buffer) - 3, (fFileSize + fBlockSize - 1) / fBlockSize); FormatValue(buffer + 3, sizeof(buffer) - 3,
(fFileSize + fBlockSize - 1) / fBlockSize);
fSizeView->SetText(buffer); fSizeView->SetText(buffer);
} }
@@ -770,7 +796,8 @@ HeaderView::MessageReceived(BMessage *message)
// If there is another message of this type in the // If there is another message of this type in the
// queue, we're just ignoring the current message. // queue, we're just ignoring the current message.
if (Looper()->MessageQueue()->FindMessage(kMsgSliderUpdate, 0) != NULL) if (Looper()->MessageQueue()->FindMessage(kMsgSliderUpdate, 0)
!= NULL)
break; break;
// if nothing has changed, we can ignore this message as well // if nothing has changed, we can ignore this message as well
@@ -791,7 +818,8 @@ HeaderView::MessageReceived(BMessage *message)
case kMsgDataEditorFindProgress: case kMsgDataEditorFindProgress:
{ {
bool state; bool state;
if (message->FindBool("running", &state) == B_OK && fFileSize > fBlockSize) { if (message->FindBool("running", &state) == B_OK
&& fFileSize > fBlockSize) {
fPositionSlider->SetEnabled(!state); fPositionSlider->SetEnabled(!state);
if (state) { if (state) {
fPathView->ResizeBy(-fStopButton->Bounds().Width(), 0); fPathView->ResizeBy(-fStopButton->Bounds().Width(), 0);
@@ -827,10 +855,12 @@ HeaderView::MessageReceived(BMessage *message)
if (position < 0) if (position < 0)
position += (fFileSize - 1) / fBlockSize + 1; position += (fFileSize - 1) / fBlockSize + 1;
fPosition = position * fBlockSize; fPosition = position * fBlockSize;
} else if (message->FindInt32("delta", &delta) == B_OK) } else if (message->FindInt32("delta", &delta) == B_OK) {
fPosition += delta * off_t(fBlockSize); fPosition += delta * off_t(fBlockSize);
else } else {
fPosition = strtoll(fPositionControl->Text(), NULL, 0) * fBlockSize; fPosition = strtoll(fPositionControl->Text(), NULL, 0)
* fBlockSize;
}
fPosition = (fPosition / fBlockSize) * fBlockSize; fPosition = (fPosition / fBlockSize) * fBlockSize;
// round to block size // round to block size
@@ -879,16 +909,16 @@ HeaderView::MessageReceived(BMessage *message)
} }
// #pragma mark - // #pragma mark - TypeMenuItem
/** The TypeMenuItem is a BMenuItem that displays a type string /*! The TypeMenuItem is a BMenuItem that displays a type string at its
* at its right border. right border.
* It is used to display the attribute and type in the attributes menu. It is used to display the attribute and type in the attributes menu.
* It does not mix nicely with short cuts. It does not mix nicely with short cuts.
*/ */
TypeMenuItem::TypeMenuItem(const char *name, const char *type,
TypeMenuItem::TypeMenuItem(const char *name, const char *type, BMessage *message) BMessage *message)
: BMenuItem(name, message), : BMenuItem(name, message),
fType(type) fType(type)
{ {
@@ -927,22 +957,21 @@ TypeMenuItem::DrawContent()
} }
// #pragma mark - // #pragma mark - EditorLooper
/** The purpose of this looper is to off-load the editor data /*! The purpose of this looper is to off-load the editor data loading from
* loading from the main window looper. the main window looper.
* It will listen to the offset changes of the editor, let
* him update its data, and will then synchronously notify It will listen to the offset changes of the editor, let him update its
* the target. data, and will then synchronously notify the target.
* That way, simple offset changes will not stop the main That way, simple offset changes will not stop the main looper from
* looper from operating. Therefore, all offset updates operating. Therefore, all offset updates for the editor will go through
* for the editor will go through this looper. this looper.
* Also, it will run the find action in the editor.
* Also, it will run the find action in the editor.
*/ */
EditorLooper::EditorLooper(const char *name, DataEditor &editor,
EditorLooper::EditorLooper(const char *name, DataEditor &editor, BMessenger target) BMessenger target)
: BLooper(name), : BLooper(name),
fEditor(editor), fEditor(editor),
fMessenger(target), fMessenger(target),
@@ -1012,7 +1041,8 @@ EditorLooper::MessageReceived(BMessage *message)
ssize_t dataSize; ssize_t dataSize;
const uint8 *data; const uint8 *data;
if (message->FindData("data", B_RAW_TYPE, (const void **)&data, &dataSize) == B_OK) if (message->FindData("data", B_RAW_TYPE, (const void **)&data,
&dataSize) == B_OK)
Find(startAt, data, dataSize, caseInsensitive, progressMonitor); Find(startAt, data, dataSize, caseInsensitive, progressMonitor);
} }
@@ -1064,12 +1094,68 @@ EditorLooper::QuitFind()
} }
// #pragma mark - // #pragma mark - TypeView
ProbeView::ProbeView(BRect rect, entry_ref *ref, const char *attribute, const BMessage *settings) TypeView::TypeView(BRect rect, const char* name, int32 index,
DataEditor& editor, int32 resizingMode)
: BView(rect, name, resizingMode, B_FRAME_EVENTS)
{
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
fTypeEditorView = GetTypeEditorAt(index, Frame(), editor);
if (fTypeEditorView == NULL) {
AddChild(new BStringView(Bounds(), "Type Editor",
"Type editor not supported", B_FOLLOW_NONE));
} else
AddChild(fTypeEditorView);
if ((fTypeEditorView->ResizingMode() & (B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM))
!= 0) {
BRect rect = Bounds();
BRect frame = fTypeEditorView->Frame();
rect.left = frame.left;
rect.top = frame.top;
if ((fTypeEditorView->ResizingMode() & B_FOLLOW_RIGHT) == 0)
rect.right = frame.right;
if ((fTypeEditorView->ResizingMode() & B_FOLLOW_BOTTOM) == 0)
rect.bottom = frame.bottom;
fTypeEditorView->ResizeTo(rect.Width(), rect.Height());
}
}
TypeView::~TypeView()
{
}
void
TypeView::FrameResized(float width, float height)
{
BRect rect = Bounds();
BView *fTypeEditorView = fTypeEditorView;
BPoint point = fTypeEditorView->Frame().LeftTop();
if ((fTypeEditorView->ResizingMode() & B_FOLLOW_RIGHT) == 0)
point.x = (rect.Width() - fTypeEditorView->Bounds().Width()) / 2;
if ((fTypeEditorView->ResizingMode() & B_FOLLOW_BOTTOM) == 0)
point.y = (rect.Height() - fTypeEditorView->Bounds().Height()) / 2;
fTypeEditorView->MoveTo(point);
}
// #pragma mark - ProbeView
ProbeView::ProbeView(BRect rect, entry_ref *ref, const char *attribute,
const BMessage *settings)
: BView(rect, "probeView", B_FOLLOW_ALL, B_WILL_DRAW), : BView(rect, "probeView", B_FOLLOW_ALL, B_WILL_DRAW),
fPrintSettings(NULL), fPrintSettings(NULL),
fTypeView(NULL),
fLastSearch(NULL) fLastSearch(NULL)
{ {
fEditor.SetTo(*ref, attribute); fEditor.SetTo(*ref, attribute);
@@ -1095,7 +1181,8 @@ ProbeView::ProbeView(BRect rect, entry_ref *ref, const char *attribute, const BM
fDataView->SetBase((base_type)baseType); fDataView->SetBase((base_type)baseType);
fDataView->SetFontSize(fontSize); fDataView->SetFontSize(fontSize);
fScrollView = new BScrollView("scroller", fDataView, B_FOLLOW_ALL, B_WILL_DRAW, true, true); fScrollView = new BScrollView("scroller", fDataView, B_FOLLOW_ALL,
B_WILL_DRAW, true, true);
AddChild(fScrollView); AddChild(fScrollView);
fDataView->UpdateScroller(); fDataView->UpdateScroller();
@@ -1117,7 +1204,8 @@ ProbeView::UpdateSizeLimits()
float width, height; float width, height;
fDataView->GetPreferredSize(&width, &height); fDataView->GetPreferredSize(&width, &height);
BRect frame = Window()->ConvertFromScreen(ConvertToScreen(fHeaderView->Frame())); BRect frame = Window()->ConvertFromScreen(ConvertToScreen(
fHeaderView->Frame()));
Window()->SetSizeLimits(250, width + B_V_SCROLL_BAR_WIDTH, Window()->SetSizeLimits(250, width + B_V_SCROLL_BAR_WIDTH,
200, height + frame.bottom + 4 + B_H_SCROLL_BAR_HEIGHT); 200, height + frame.bottom + 4 + B_H_SCROLL_BAR_HEIGHT);
@@ -1129,8 +1217,10 @@ ProbeView::UpdateSizeLimits()
BRect bounds = Window()->Bounds(); BRect bounds = Window()->Bounds();
float minWidth, maxWidth, minHeight, maxHeight; float minWidth, maxWidth, minHeight, maxHeight;
Window()->GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight); Window()->GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight);
if (maxWidth < bounds.Width() || maxHeight < bounds.Height()) if (maxWidth < bounds.Width() || maxHeight < bounds.Height()) {
Window()->ResizeTo(MIN(maxWidth, bounds.Width()), MIN(maxHeight, bounds.Height())); Window()->ResizeTo(MIN(maxWidth, bounds.Width()), MIN(maxHeight,
bounds.Height()));
}
#endif #endif
} }
@@ -1153,7 +1243,7 @@ ProbeView::DetachedFromWindow()
void void
ProbeView::UpdateAttributesMenu(BMenu *menu) ProbeView::_UpdateAttributesMenu(BMenu *menu)
{ {
// remove old contents // remove old contents
@@ -1208,8 +1298,8 @@ ProbeView::UpdateAttributesMenu(BMenu *menu)
void void
ProbeView::AddSaveMenuItems(BMenu* menu, int32 index) ProbeView::AddSaveMenuItems(BMenu* menu, int32 index)
{ {
menu->AddItem(fSaveMenuItem = new BMenuItem("Save", new BMessage(B_SAVE_REQUESTED), menu->AddItem(fSaveMenuItem = new BMenuItem("Save",
'S', B_COMMAND_KEY), index); new BMessage(B_SAVE_REQUESTED), 'S'), index);
fSaveMenuItem->SetTarget(this); fSaveMenuItem->SetTarget(this);
fSaveMenuItem->SetEnabled(false); fSaveMenuItem->SetEnabled(false);
//menu->AddItem(new BMenuItem("Save As" B_UTF8_ELLIPSIS, NULL), index); //menu->AddItem(new BMenuItem("Save As" B_UTF8_ELLIPSIS, NULL), index);
@@ -1224,15 +1314,56 @@ ProbeView::AddPrintMenuItems(BMenu *menu, int32 index)
new BMessage(kMsgPageSetup)), index++); new BMessage(kMsgPageSetup)), index++);
item->SetTarget(this); item->SetTarget(this);
menu->AddItem(item = new BMenuItem("Print" B_UTF8_ELLIPSIS, menu->AddItem(item = new BMenuItem("Print" B_UTF8_ELLIPSIS,
new BMessage(kMsgPrint), 'P', B_COMMAND_KEY), index++); new BMessage(kMsgPrint), 'P'), index++);
item->SetTarget(this); item->SetTarget(this);
} }
void
ProbeView::AddViewAsMenuItems()
{
#if 0
BMenuBar* bar = Window()->KeyMenuBar();
if (bar == NULL)
return;
BMenuItem* item = bar->FindItem("View");
BMenu* menu = NULL;
if (item != NULL)
menu = item->Submenu();
else
menu = bar->SubmenuAt(bar->CountItems() - 1);
if (menu == NULL)
return;
menu->AddSeparatorItem();
BMenu* subMenu = new BMenu("View As");
subMenu->SetRadioMode(true);
BMessage* message = new BMessage(kMsgViewAs);
subMenu->AddItem(item = new BMenuItem("Raw", message));
item->SetMarked(true);
const char* name;
for (int32 i = 0; GetNthTypeEditor(i, &name) == B_OK; i++) {
message = new BMessage(kMsgViewAs);
message->AddInt32("editor index", i);
subMenu->AddItem(new BMenuItem(name, message));
}
subMenu->SetTargetForItems(this);
menu->AddItem(new BMenuItem(subMenu));
#endif
}
void void
ProbeView::AttachedToWindow() ProbeView::AttachedToWindow()
{ {
fEditorLooper = new EditorLooper(fEditor.Ref().name, fEditor, BMessenger(fDataView)); fEditorLooper = new EditorLooper(fEditor.Ref().name, fEditor,
BMessenger(fDataView));
fEditorLooper->Run(); fEditorLooper->Run();
fEditor.StartWatching(this); fEditor.StartWatching(this);
@@ -1252,13 +1383,15 @@ ProbeView::AttachedToWindow()
MoveBy(0, bar->Bounds().Height()); MoveBy(0, bar->Bounds().Height());
ResizeBy(0, -bar->Bounds().Height()); ResizeBy(0, -bar->Bounds().Height());
BMenu *menu = new BMenu(fEditor.IsAttribute() ? "Attribute" : fEditor.IsDevice() ? "Device" : "File"); BMenu *menu = new BMenu(fEditor.IsAttribute()
? "Attribute" : fEditor.IsDevice() ? "Device" : "File");
AddSaveMenuItems(menu, 0); AddSaveMenuItems(menu, 0);
menu->AddSeparatorItem(); menu->AddSeparatorItem();
AddPrintMenuItems(menu, menu->CountItems()); AddPrintMenuItems(menu, menu->CountItems());
menu->AddSeparatorItem(); menu->AddSeparatorItem();
menu->AddItem(new BMenuItem("Close", new BMessage(B_CLOSE_REQUESTED), 'W', B_COMMAND_KEY)); menu->AddItem(new BMenuItem("Close", new BMessage(B_CLOSE_REQUESTED),
'W'));
bar->AddItem(menu); bar->AddItem(menu);
} }
@@ -1266,26 +1399,30 @@ ProbeView::AttachedToWindow()
BMenu *menu = new BMenu("Edit"); BMenu *menu = new BMenu("Edit");
BMenuItem *item; BMenuItem *item;
menu->AddItem(fUndoMenuItem = new BMenuItem("Undo", new BMessage(B_UNDO), 'Z', B_COMMAND_KEY)); menu->AddItem(fUndoMenuItem = new BMenuItem("Undo", new BMessage(B_UNDO),
'Z'));
fUndoMenuItem->SetEnabled(fEditor.CanUndo()); fUndoMenuItem->SetEnabled(fEditor.CanUndo());
fUndoMenuItem->SetTarget(fDataView); fUndoMenuItem->SetTarget(fDataView);
menu->AddItem(fRedoMenuItem = new BMenuItem("Redo", new BMessage(B_REDO), 'Z', B_COMMAND_KEY | B_SHIFT_KEY)); menu->AddItem(fRedoMenuItem = new BMenuItem("Redo", new BMessage(B_REDO),
'Z', B_SHIFT_KEY));
fRedoMenuItem->SetEnabled(fEditor.CanRedo()); fRedoMenuItem->SetEnabled(fEditor.CanRedo());
fRedoMenuItem->SetTarget(fDataView); fRedoMenuItem->SetTarget(fDataView);
menu->AddSeparatorItem(); menu->AddSeparatorItem();
menu->AddItem(item = new BMenuItem("Copy", new BMessage(B_COPY), 'C', B_COMMAND_KEY)); menu->AddItem(item = new BMenuItem("Copy", new BMessage(B_COPY), 'C'));
item->SetTarget(NULL, Window()); item->SetTarget(NULL, Window());
menu->AddItem(fPasteMenuItem = new BMenuItem("Paste", new BMessage(B_PASTE), 'V', B_COMMAND_KEY)); menu->AddItem(fPasteMenuItem = new BMenuItem("Paste", new BMessage(B_PASTE),
'V'));
fPasteMenuItem->SetTarget(NULL, Window()); fPasteMenuItem->SetTarget(NULL, Window());
CheckClipboard(); _CheckClipboard();
menu->AddItem(item = new BMenuItem("Select All", new BMessage(B_SELECT_ALL), 'A', B_COMMAND_KEY)); menu->AddItem(item = new BMenuItem("Select All", new BMessage(B_SELECT_ALL),
'A'));
item->SetTarget(NULL, Window()); item->SetTarget(NULL, Window());
menu->AddSeparatorItem(); menu->AddSeparatorItem();
menu->AddItem(item = new BMenuItem("Find" B_UTF8_ELLIPSIS, new BMessage(kMsgOpenFindWindow), menu->AddItem(item = new BMenuItem("Find" B_UTF8_ELLIPSIS,
'F', B_COMMAND_KEY)); new BMessage(kMsgOpenFindWindow), 'F'));
item->SetTarget(this); item->SetTarget(this);
menu->AddItem(fFindAgainMenuItem = new BMenuItem("Find Again", new BMessage(kMsgFind), menu->AddItem(fFindAgainMenuItem = new BMenuItem("Find Again",
'G', B_COMMAND_KEY)); new BMessage(kMsgFind), 'G'));
fFindAgainMenuItem->SetEnabled(false); fFindAgainMenuItem->SetEnabled(false);
fFindAgainMenuItem->SetTarget(this); fFindAgainMenuItem->SetTarget(this);
bar->AddItem(menu); bar->AddItem(menu);
@@ -1295,30 +1432,31 @@ ProbeView::AttachedToWindow()
menu = new BMenu("Block"); menu = new BMenu("Block");
BMessage *message = new BMessage(kMsgPositionUpdate); BMessage *message = new BMessage(kMsgPositionUpdate);
message->AddInt32("delta", 1); message->AddInt32("delta", 1);
menu->AddItem(item = new BMenuItem("Next", message, B_RIGHT_ARROW, B_COMMAND_KEY)); menu->AddItem(item = new BMenuItem("Next", message, B_RIGHT_ARROW));
item->SetTarget(fHeaderView); item->SetTarget(fHeaderView);
message = new BMessage(kMsgPositionUpdate); message = new BMessage(kMsgPositionUpdate);
message->AddInt32("delta", -1); message->AddInt32("delta", -1);
menu->AddItem(item = new BMenuItem("Previous", message, B_LEFT_ARROW, B_COMMAND_KEY)); menu->AddItem(item = new BMenuItem("Previous", message, B_LEFT_ARROW));
item->SetTarget(fHeaderView); item->SetTarget(fHeaderView);
menu->AddItem(item = new BMenuItem("Back", new BMessage(kMsgLastPosition), 'J', B_COMMAND_KEY)); menu->AddItem(item = new BMenuItem("Back", new BMessage(kMsgLastPosition),
'J'));
item->SetTarget(fHeaderView); item->SetTarget(fHeaderView);
BMenu *subMenu = new BMenu("Selection"); BMenu *subMenu = new BMenu("Selection");
message = new BMessage(kMsgPositionUpdate); message = new BMessage(kMsgPositionUpdate);
message->AddInt64("block", 0); message->AddInt64("block", 0);
subMenu->AddItem(fNativeMenuItem = new BMenuItem("", message, 'K', B_COMMAND_KEY)); subMenu->AddItem(fNativeMenuItem = new BMenuItem("", message, 'K'));
fNativeMenuItem->SetTarget(fHeaderView); fNativeMenuItem->SetTarget(fHeaderView);
message = new BMessage(*message); message = new BMessage(*message);
subMenu->AddItem(fSwappedMenuItem = new BMenuItem("", message, 'L', B_COMMAND_KEY)); subMenu->AddItem(fSwappedMenuItem = new BMenuItem("", message, 'L'));
fSwappedMenuItem->SetTarget(fHeaderView); fSwappedMenuItem->SetTarget(fHeaderView);
menu->AddItem(new BMenuItem(subMenu)); menu->AddItem(new BMenuItem(subMenu));
UpdateSelectionMenuItems(0, 0); _UpdateSelectionMenuItems(0, 0);
menu->AddSeparatorItem(); menu->AddSeparatorItem();
fBookmarkMenu = new BMenu("Bookmarks"); fBookmarkMenu = new BMenu("Bookmarks");
fBookmarkMenu->AddItem(item = new BMenuItem("Add", new BMessage(kMsgAddBookmark), fBookmarkMenu->AddItem(item = new BMenuItem("Add",
'B', B_COMMAND_KEY)); new BMessage(kMsgAddBookmark), 'B'));
item->SetTarget(this); item->SetTarget(this);
menu->AddItem(new BMenuItem(fBookmarkMenu)); menu->AddItem(new BMenuItem(fBookmarkMenu));
bar->AddItem(menu); bar->AddItem(menu);
@@ -1328,15 +1466,16 @@ ProbeView::AttachedToWindow()
BDirectory directory; BDirectory directory;
BVolume volume; BVolume volume;
if (directory.SetTo(&fEditor.AttributeRef()) == B_OK && directory.IsRootDirectory()) if (directory.SetTo(&fEditor.AttributeRef()) == B_OK
&& directory.IsRootDirectory())
directory.GetVolume(&volume); directory.GetVolume(&volume);
else else
fEditor.File().GetVolume(&volume); fEditor.File().GetVolume(&volume);
if (!fEditor.IsAttribute() if (!fEditor.IsAttribute() && volume.InitCheck() == B_OK
&& volume.InitCheck() == B_OK && (volume.KnowsMime() || volume.KnowsAttr())) { && (volume.KnowsMime() || volume.KnowsAttr())) {
bar->AddItem(menu = new BMenu("Attributes")); bar->AddItem(menu = new BMenu("Attributes"));
UpdateAttributesMenu(menu); _UpdateAttributesMenu(menu);
} }
// "View" menu // "View" menu
@@ -1348,14 +1487,14 @@ ProbeView::AttachedToWindow()
subMenu = new BMenu("Base"); subMenu = new BMenu("Base");
message = new BMessage(kMsgBaseType); message = new BMessage(kMsgBaseType);
message->AddInt32("base_type", kDecimalBase); message->AddInt32("base_type", kDecimalBase);
subMenu->AddItem(item = new BMenuItem("Decimal", message, 'D', B_COMMAND_KEY)); subMenu->AddItem(item = new BMenuItem("Decimal", message, 'D'));
item->SetTarget(this); item->SetTarget(this);
if (fHeaderView->Base() == kDecimalBase) if (fHeaderView->Base() == kDecimalBase)
item->SetMarked(true); item->SetMarked(true);
message = new BMessage(kMsgBaseType); message = new BMessage(kMsgBaseType);
message->AddInt32("base_type", kHexBase); message->AddInt32("base_type", kHexBase);
subMenu->AddItem(item = new BMenuItem("Hex", message, 'H', B_COMMAND_KEY)); subMenu->AddItem(item = new BMenuItem("Hex", message, 'H'));
item->SetTarget(this); item->SetTarget(this);
if (fHeaderView->Base() == kHexBase) if (fHeaderView->Base() == kHexBase)
item->SetMarked(true); item->SetMarked(true);
@@ -1371,8 +1510,10 @@ ProbeView::AttachedToWindow()
for (uint32 i = 0; i < sizeof(blockSizes) / sizeof(blockSizes[0]); i++) { for (uint32 i = 0; i < sizeof(blockSizes) / sizeof(blockSizes[0]); i++) {
char buffer[32]; char buffer[32];
snprintf(buffer, sizeof(buffer), "%ld%s", blockSizes[i], snprintf(buffer, sizeof(buffer), "%ld%s", blockSizes[i],
fEditor.IsDevice() && fEditor.BlockSize() == blockSizes[i] ? " (native)" : ""); fEditor.IsDevice() && fEditor.BlockSize() == blockSizes[i]
subMenu->AddItem(item = new BMenuItem(buffer, message = new BMessage(kMsgBlockSize))); ? " (native)" : "");
subMenu->AddItem(item = new BMenuItem(buffer,
message = new BMessage(kMsgBlockSize)));
message->AddInt32("block_size", blockSizes[i]); message->AddInt32("block_size", blockSizes[i]);
if (fEditor.BlockSize() == blockSizes[i]) if (fEditor.BlockSize() == blockSizes[i])
item->SetMarked(true); item->SetMarked(true);
@@ -1381,7 +1522,8 @@ ProbeView::AttachedToWindow()
// if the device has some weird block size, we'll add it here, too // if the device has some weird block size, we'll add it here, too
char buffer[32]; char buffer[32];
snprintf(buffer, sizeof(buffer), "%ld (native)", fEditor.BlockSize()); snprintf(buffer, sizeof(buffer), "%ld (native)", fEditor.BlockSize());
subMenu->AddItem(item = new BMenuItem(buffer, message = new BMessage(kMsgBlockSize))); subMenu->AddItem(item = new BMenuItem(buffer,
message = new BMessage(kMsgBlockSize)));
message->AddInt32("block_size", fEditor.BlockSize()); message->AddInt32("block_size", fEditor.BlockSize());
item->SetMarked(true); item->SetMarked(true);
} }
@@ -1400,13 +1542,15 @@ ProbeView::AttachedToWindow()
for (uint32 i = 0; i < sizeof(fontSizes) / sizeof(fontSizes[0]); i++) { for (uint32 i = 0; i < sizeof(fontSizes) / sizeof(fontSizes[0]); i++) {
char buffer[16]; char buffer[16];
snprintf(buffer, sizeof(buffer), "%ld", fontSizes[i]); snprintf(buffer, sizeof(buffer), "%ld", fontSizes[i]);
subMenu->AddItem(item = new BMenuItem(buffer, message = new BMessage(kMsgFontSize))); subMenu->AddItem(item = new BMenuItem(buffer,
message = new BMessage(kMsgFontSize)));
message->AddFloat("font_size", fontSizes[i]); message->AddFloat("font_size", fontSizes[i]);
if (fontSizes[i] == fontSize) if (fontSizes[i] == fontSize)
item->SetMarked(true); item->SetMarked(true);
} }
subMenu->AddSeparatorItem(); subMenu->AddSeparatorItem();
subMenu->AddItem(item = new BMenuItem("Fit", message = new BMessage(kMsgFontSize))); subMenu->AddItem(item = new BMenuItem("Fit",
message = new BMessage(kMsgFontSize)));
message->AddFloat("font_size", 0.0f); message->AddFloat("font_size", 0.0f);
if (fontSize == 0) if (fontSize == 0)
item->SetMarked(true); item->SetMarked(true);
@@ -1441,7 +1585,7 @@ ProbeView::WindowActivated(bool active)
void void
ProbeView::UpdateSelectionMenuItems(int64 start, int64 end) ProbeView::_UpdateSelectionMenuItems(int64 start, int64 end)
{ {
int64 position = 0; int64 position = 0;
const uint8 *data = fDataView->DataAt(start); const uint8 *data = fDataView->DataAt(start);
@@ -1489,7 +1633,7 @@ ProbeView::UpdateSelectionMenuItems(int64 start, int64 end)
void void
ProbeView::UpdateBookmarkMenuItems() ProbeView::_UpdateBookmarkMenuItems()
{ {
for (int32 i = 2; i < fBookmarkMenu->CountItems(); i++) { for (int32 i = 2; i < fBookmarkMenu->CountItems(); i++) {
BMenuItem *item = fBookmarkMenu->ItemAt(i); BMenuItem *item = fBookmarkMenu->ItemAt(i);
@@ -1514,7 +1658,7 @@ ProbeView::UpdateBookmarkMenuItems()
void void
ProbeView::AddBookmark(off_t position) ProbeView::_AddBookmark(off_t position)
{ {
int32 count = fBookmarkMenu->CountItems(); int32 count = fBookmarkMenu->CountItems();
@@ -1560,7 +1704,50 @@ ProbeView::AddBookmark(off_t position)
void void
ProbeView::CheckClipboard() ProbeView::_RemoveTypeEditor()
{
if (fTypeView == NULL)
return;
if (Parent() != NULL)
Parent()->RemoveChild(fTypeView);
else
Window()->RemoveChild(fTypeView);
delete fTypeView;
fTypeView = NULL;
}
void
ProbeView::_SetTypeEditor(int32 index)
{
if (index == -1) {
// remove type editor, show raw editor
if (IsHidden())
Show();
_RemoveTypeEditor();
} else {
// hide raw editor, create and show type editor
if (!IsHidden())
Hide();
_RemoveTypeEditor();
fTypeView = new TypeView(Frame(), "type shell", index, fEditor,
B_FOLLOW_ALL);
if (Parent() != NULL)
Parent()->AddChild(fTypeView);
else
Window()->AddChild(fTypeView);
}
}
void
ProbeView::_CheckClipboard()
{ {
if (!be_clipboard->Lock()) if (!be_clipboard->Lock())
return; return;
@@ -1582,7 +1769,7 @@ ProbeView::CheckClipboard()
status_t status_t
ProbeView::PageSetup() ProbeView::_PageSetup()
{ {
BPrintJob printJob(Window()->Title()); BPrintJob printJob(Window()->Title());
if (fPrintSettings != NULL) if (fPrintSettings != NULL)
@@ -1600,9 +1787,9 @@ ProbeView::PageSetup()
void void
ProbeView::Print() ProbeView::_Print()
{ {
if (fPrintSettings == NULL && PageSetup() != B_OK) if (fPrintSettings == NULL && _PageSetup() != B_OK)
return; return;
BPrintJob printJob(Window()->Title()); BPrintJob printJob(Window()->Title());
@@ -1627,7 +1814,7 @@ ProbeView::Print()
status_t status_t
ProbeView::Save() ProbeView::_Save()
{ {
status_t status = fEditor.Save(); status_t status = fEditor.Save();
if (status == B_OK) if (status == B_OK)
@@ -1665,7 +1852,7 @@ ProbeView::QuitRequested()
if (chosen == 1) if (chosen == 1)
return false; return false;
return Save() == B_OK; return _Save() == B_OK;
} }
@@ -1674,7 +1861,7 @@ ProbeView::MessageReceived(BMessage *message)
{ {
switch (message->what) { switch (message->what) {
case B_SAVE_REQUESTED: case B_SAVE_REQUESTED:
Save(); _Save();
break; break;
case B_OBSERVER_NOTICE_CHANGE: { case B_OBSERVER_NOTICE_CHANGE: {
@@ -1688,7 +1875,7 @@ ProbeView::MessageReceived(BMessage *message)
int64 start, end; int64 start, end;
if (message->FindInt64("start", &start) == B_OK if (message->FindInt64("start", &start) == B_OK
&& message->FindInt64("end", &end) == B_OK) && message->FindInt64("end", &end) == B_OK)
UpdateSelectionMenuItems(start, end); _UpdateSelectionMenuItems(start, end);
break; break;
} }
case kDataViewPreferredSize: case kDataViewPreferredSize:
@@ -1710,9 +1897,9 @@ ProbeView::MessageReceived(BMessage *message)
// The selection menu items depend on the base type as well // The selection menu items depend on the base type as well
int32 start, end; int32 start, end;
fDataView->GetSelection(start, end); fDataView->GetSelection(start, end);
UpdateSelectionMenuItems(start, end); _UpdateSelectionMenuItems(start, end);
UpdateBookmarkMenuItems(); _UpdateBookmarkMenuItems();
// update the application's settings // update the application's settings
BMessage update(*message); BMessage update(*message);
@@ -1750,16 +1937,26 @@ ProbeView::MessageReceived(BMessage *message)
break; break;
} }
case kMsgViewAs:
{
int32 index;
if (message->FindInt32("editor index", &index) != B_OK)
index = -1;
_SetTypeEditor(index);
break;
}
case kMsgAddBookmark: case kMsgAddBookmark:
AddBookmark(fHeaderView->Position()); _AddBookmark(fHeaderView->Position());
break; break;
case kMsgPrint: case kMsgPrint:
Print(); _Print();
break; break;
case kMsgPageSetup: case kMsgPageSetup:
PageSetup(); _PageSetup();
break; break;
case kMsgOpenFindWindow: case kMsgOpenFindWindow:
@@ -1827,7 +2024,7 @@ ProbeView::MessageReceived(BMessage *message)
if (bar != NULL) { if (bar != NULL) {
BMenuItem *item = bar->FindItem("Attributes"); BMenuItem *item = bar->FindItem("Attributes");
if (item != NULL && item->Submenu() != NULL) if (item != NULL && item->Submenu() != NULL)
UpdateAttributesMenu(item->Submenu()); _UpdateAttributesMenu(item->Submenu());
} }
} }
@@ -1844,7 +2041,7 @@ ProbeView::MessageReceived(BMessage *message)
} }
case B_CLIPBOARD_CHANGED: case B_CLIPBOARD_CHANGED:
CheckClipboard(); _CheckClipboard();
break; break;
case kMsgDataEditorStateChange: case kMsgDataEditorStateChange:
+17 -11
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef PROBE_VIEW_H #ifndef PROBE_VIEW_H
@@ -36,6 +36,7 @@ class ProbeView : public BView {
void AddSaveMenuItems(BMenu* menu, int32 index); void AddSaveMenuItems(BMenu* menu, int32 index);
void AddPrintMenuItems(BMenu* menu, int32 index); void AddPrintMenuItems(BMenu* menu, int32 index);
void AddViewAsMenuItems();
void UpdateSizeLimits(); void UpdateSizeLimits();
bool QuitRequested(); bool QuitRequested();
@@ -43,14 +44,16 @@ class ProbeView : public BView {
DataEditor& Editor() { return fEditor; } DataEditor& Editor() { return fEditor; }
private: private:
void UpdateAttributesMenu(BMenu *menu); void _UpdateAttributesMenu(BMenu* menu);
void UpdateSelectionMenuItems(int64 start, int64 end); void _UpdateSelectionMenuItems(int64 start, int64 end);
void UpdateBookmarkMenuItems(); void _UpdateBookmarkMenuItems();
void AddBookmark(off_t position); void _AddBookmark(off_t position);
void CheckClipboard(); void _RemoveTypeEditor();
status_t PageSetup(); void _SetTypeEditor(int32 index);
void Print(); void _CheckClipboard();
status_t Save(); status_t _PageSetup();
void _Print();
status_t _Save();
DataEditor fEditor; DataEditor fEditor;
EditorLooper* fEditorLooper; EditorLooper* fEditorLooper;
@@ -58,11 +61,14 @@ class ProbeView : public BView {
DataView* fDataView; DataView* fDataView;
BScrollView* fScrollView; BScrollView* fScrollView;
BMenuItem* fPasteMenuItem; BMenuItem* fPasteMenuItem;
BMenuItem *fUndoMenuItem, *fRedoMenuItem; BMenuItem* fUndoMenuItem;
BMenuItem *fNativeMenuItem, *fSwappedMenuItem; BMenuItem* fRedoMenuItem;
BMenuItem* fNativeMenuItem;
BMenuItem* fSwappedMenuItem;
BMenuItem* fSaveMenuItem; BMenuItem* fSaveMenuItem;
BMessage* fPrintSettings; BMessage* fPrintSettings;
BMenu* fBookmarkMenu; BMenu* fBookmarkMenu;
BView* fTypeView;
BMenuItem* fFindAgainMenuItem; BMenuItem* fFindAgainMenuItem;
const uint8* fLastSearch; const uint8* fLastSearch;
+185 -97
View File
@@ -43,11 +43,11 @@ class StringEditor : public TypeEditorView {
virtual void DetachedFromWindow(); virtual void DetachedFromWindow();
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
void UpdateText();
virtual void CommitChanges(); virtual void CommitChanges();
private: private:
DataEditor &fEditor; void _UpdateText();
BTextView* fTextView; BTextView* fTextView;
BString fPreviousText; BString fPreviousText;
}; };
@@ -61,11 +61,12 @@ class MimeTypeEditor : public TypeEditorView {
virtual void DetachedFromWindow(); virtual void DetachedFromWindow();
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
void UpdateText();
virtual void CommitChanges(); virtual void CommitChanges();
virtual bool TypeMatches();
private: private:
DataEditor &fEditor; void _UpdateText();
BTextControl* fTextControl; BTextControl* fTextControl;
BString fPreviousText; BString fPreviousText;
}; };
@@ -79,15 +80,15 @@ class NumberEditor : public TypeEditorView {
virtual void DetachedFromWindow(); virtual void DetachedFromWindow();
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
void UpdateText();
virtual void CommitChanges(); virtual void CommitChanges();
virtual bool TypeMatches();
private: private:
const char *TypeLabel(); void _UpdateText();
status_t Format(char *buffer); const char* _TypeLabel();
size_t Size(); status_t _Format(char* buffer);
size_t _Size();
DataEditor &fEditor;
BTextControl* fTextControl; BTextControl* fTextControl;
BString fPreviousText; BString fPreviousText;
}; };
@@ -101,11 +102,12 @@ class BooleanEditor : public TypeEditorView {
virtual void DetachedFromWindow(); virtual void DetachedFromWindow();
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
void UpdateMenuField();
virtual void CommitChanges(); virtual void CommitChanges();
virtual bool TypeMatches();
private: private:
DataEditor &fEditor; void _UpdateMenuField();
BMenuItem* fFalseMenuItem; BMenuItem* fFalseMenuItem;
BMenuItem* fTrueMenuItem; BMenuItem* fTrueMenuItem;
}; };
@@ -121,11 +123,9 @@ class ImageView : public TypeEditorView {
virtual void MessageReceived(BMessage *message); virtual void MessageReceived(BMessage *message);
virtual void Draw(BRect updateRect); virtual void Draw(BRect updateRect);
void UpdateImage();
virtual void CommitChanges();
private: private:
DataEditor &fEditor; void _UpdateImage();
BBitmap* fBitmap; BBitmap* fBitmap;
BStringView* fDescriptionView; BStringView* fDescriptionView;
BSlider* fScaleSlider; BSlider* fScaleSlider;
@@ -141,25 +141,56 @@ class MessageView : public TypeEditorView {
virtual void DetachedFromWindow(); virtual void DetachedFromWindow();
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
virtual void CommitChanges();
void SetTo(BMessage& message); void SetTo(BMessage& message);
private: private:
BString _TypeToString(type_code type); BString _TypeToString(type_code type);
void _UpdateMessage(); void _UpdateMessage();
DataEditor& fEditor;
BTextView* fTextView; BTextView* fTextView;
}; };
//----------------- // #pragma mark - TypeEditorView
TypeEditorView::TypeEditorView(BRect rect, const char *name,
uint32 resizingMode, uint32 flags, DataEditor& editor)
: BView(rect, name, resizingMode, flags),
fEditor(editor)
{
}
TypeEditorView::~TypeEditorView()
{
}
void
TypeEditorView::CommitChanges()
{
// the default just does nothing here
}
bool
TypeEditorView::TypeMatches()
{
// the default is to accept anything that easily fits into memory
system_info info;
get_system_info(&info);
return fEditor.FileSize() / B_PAGE_SIZE < info.max_pages / 2;
}
// #pragma mark - StringEditor
StringEditor::StringEditor(BRect rect, DataEditor& editor) StringEditor::StringEditor(BRect rect, DataEditor& editor)
: TypeEditorView(rect, "String Editor", B_FOLLOW_ALL, 0), : TypeEditorView(rect, "String Editor", B_FOLLOW_ALL, 0, editor)
fEditor(editor)
{ {
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
@@ -177,16 +208,6 @@ StringEditor::StringEditor(BRect rect, DataEditor &editor)
rect.OffsetToCopy(B_ORIGIN).InsetByCopy(5, 5), rect.OffsetToCopy(B_ORIGIN).InsetByCopy(5, 5),
B_FOLLOW_ALL, B_WILL_DRAW); B_FOLLOW_ALL, B_WILL_DRAW);
#if 0
char *data = (char *)malloc(info.size);
if (data != NULL) {
if (fNode.ReadAttr(attribute, info.type, 0LL, data, info.size) >= B_OK)
fTextView->SetText(data);
free(data);
}
#endif
BScrollView* scrollView = new BScrollView("scroller", fTextView, BScrollView* scrollView = new BScrollView("scroller", fTextView,
B_FOLLOW_ALL, B_WILL_DRAW, true, true); B_FOLLOW_ALL, B_WILL_DRAW, true, true);
AddChild(scrollView); AddChild(scrollView);
@@ -194,7 +215,7 @@ StringEditor::StringEditor(BRect rect, DataEditor &editor)
void void
StringEditor::UpdateText() StringEditor::_UpdateText()
{ {
BAutolock locker(fEditor); BAutolock locker(fEditor);
@@ -229,7 +250,7 @@ StringEditor::AttachedToWindow()
{ {
fEditor.StartWatching(this); fEditor.StartWatching(this);
UpdateText(); _UpdateText();
} }
@@ -249,17 +270,16 @@ StringEditor::MessageReceived(BMessage *message)
} }
// #pragma mark - // #pragma mark - MimeTypeEditor
MimeTypeEditor::MimeTypeEditor(BRect rect, DataEditor& editor) MimeTypeEditor::MimeTypeEditor(BRect rect, DataEditor& editor)
: TypeEditorView(rect, "MIME Type Editor", B_FOLLOW_LEFT_RIGHT, 0), : TypeEditorView(rect, "MIME Type Editor", B_FOLLOW_LEFT_RIGHT, 0, editor)
fEditor(editor)
{ {
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
fTextControl = new BTextControl(rect.InsetByCopy(5, 5), B_EMPTY_STRING, "MIME Type:", NULL, fTextControl = new BTextControl(rect.InsetByCopy(5, 5), B_EMPTY_STRING,
new BMessage(kMsgValueChanged), B_FOLLOW_ALL); "MIME Type:", NULL, new BMessage(kMsgValueChanged), B_FOLLOW_ALL);
fTextControl->SetDivider(StringWidth(fTextControl->Label()) + 8); fTextControl->SetDivider(StringWidth(fTextControl->Label()) + 8);
float width, height; float width, height;
@@ -273,7 +293,7 @@ MimeTypeEditor::MimeTypeEditor(BRect rect, DataEditor &editor)
void void
MimeTypeEditor::UpdateText() MimeTypeEditor::_UpdateText()
{ {
BAutolock locker(fEditor); BAutolock locker(fEditor);
@@ -295,13 +315,21 @@ MimeTypeEditor::CommitChanges()
} }
bool
MimeTypeEditor::TypeMatches()
{
// TODO: check contents?
return fEditor.FileSize() <= B_MIME_TYPE_LENGTH;
}
void void
MimeTypeEditor::AttachedToWindow() MimeTypeEditor::AttachedToWindow()
{ {
fTextControl->SetTarget(this); fTextControl->SetTarget(this);
fEditor.StartWatching(this); fEditor.StartWatching(this);
UpdateText(); _UpdateText();
} }
@@ -324,7 +352,7 @@ MimeTypeEditor::MessageReceived(BMessage *message)
break; break;
case kMsgDataEditorUpdate: case kMsgDataEditorUpdate:
UpdateText(); _UpdateText();
break; break;
default: default:
@@ -333,17 +361,16 @@ MimeTypeEditor::MessageReceived(BMessage *message)
} }
// #pragma mark - // #pragma mark - NumberEditor
NumberEditor::NumberEditor(BRect rect, DataEditor &editor) NumberEditor::NumberEditor(BRect rect, DataEditor &editor)
: TypeEditorView(rect, "Number Editor", B_FOLLOW_LEFT_RIGHT, 0), : TypeEditorView(rect, "Number Editor", B_FOLLOW_LEFT_RIGHT, 0, editor)
fEditor(editor)
{ {
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
fTextControl = new BTextControl(rect.InsetByCopy(5, 5), B_EMPTY_STRING, TypeLabel(), NULL, fTextControl = new BTextControl(rect.InsetByCopy(5, 5), B_EMPTY_STRING,
new BMessage(kMsgValueChanged), B_FOLLOW_ALL); _TypeLabel(), NULL, new BMessage(kMsgValueChanged), B_FOLLOW_ALL);
fTextControl->SetDivider(StringWidth(fTextControl->Label()) + 8); fTextControl->SetDivider(StringWidth(fTextControl->Label()) + 8);
fTextControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_RIGHT); fTextControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_RIGHT);
ResizeTo(rect.Width(), 30); ResizeTo(rect.Width(), 30);
@@ -353,7 +380,7 @@ NumberEditor::NumberEditor(BRect rect, DataEditor &editor)
void void
NumberEditor::UpdateText() NumberEditor::_UpdateText()
{ {
if (fEditor.Lock()) { if (fEditor.Lock()) {
const char* number; const char* number;
@@ -380,8 +407,8 @@ NumberEditor::UpdateText()
case B_INT64_TYPE: case B_INT64_TYPE:
case B_OFF_T_TYPE: case B_OFF_T_TYPE:
{ {
Format(format); _Format(format);
switch (Size()) { switch (_Size()) {
case 1: case 1:
{ {
int8 value = *(int8 *)number; int8 value = *(int8 *)number;
@@ -409,10 +436,11 @@ NumberEditor::UpdateText()
} }
break; break;
} }
default: default:
{ {
Format(format); _Format(format);
switch (Size()) { switch (_Size()) {
case 1: case 1:
{ {
uint8 value = *(uint8 *)number; uint8 value = *(uint8 *)number;
@@ -450,6 +478,14 @@ NumberEditor::UpdateText()
} }
bool
NumberEditor::TypeMatches()
{
return fEditor.FileSize() >= _Size();
// we only look at as many bytes we need to
}
void void
NumberEditor::CommitChanges() NumberEditor::CommitChanges()
{ {
@@ -546,13 +582,13 @@ NumberEditor::CommitChanges()
return; return;
} }
fEditor.Replace(0, buffer, Size()); fEditor.Replace(0, buffer, _Size());
fPreviousText.SetTo((char *)buffer); fPreviousText.SetTo((char *)buffer);
} }
const char* const char*
NumberEditor::TypeLabel() NumberEditor::_TypeLabel()
{ {
switch (fEditor.Type()) { switch (fEditor.Type()) {
case B_INT8_TYPE: case B_INT8_TYPE:
@@ -590,33 +626,30 @@ NumberEditor::TypeLabel()
size_t size_t
NumberEditor::Size() NumberEditor::_Size()
{ {
switch (fEditor.Type()) { switch (fEditor.Type()) {
case B_INT8_TYPE: case B_INT8_TYPE:
return 1;
case B_UINT8_TYPE: case B_UINT8_TYPE:
return 1; return 1;
case B_INT16_TYPE: case B_INT16_TYPE:
return 2;
case B_UINT16_TYPE: case B_UINT16_TYPE:
return 2; return 2;
case B_SSIZE_T_TYPE: case B_SSIZE_T_TYPE:
case B_INT32_TYPE: case B_INT32_TYPE:
return 4;
case B_SIZE_T_TYPE: case B_SIZE_T_TYPE:
case B_POINTER_TYPE: case B_POINTER_TYPE:
case B_UINT32_TYPE: case B_UINT32_TYPE:
return 4; return 4;
case B_INT64_TYPE: case B_INT64_TYPE:
case B_OFF_T_TYPE: case B_OFF_T_TYPE:
return 8;
case B_UINT64_TYPE: case B_UINT64_TYPE:
return 8; return 8;
case B_FLOAT_TYPE: case B_FLOAT_TYPE:
return 4; return 4;
case B_DOUBLE_TYPE: case B_DOUBLE_TYPE:
return 8; return 8;
default: default:
return 0; return 0;
} }
@@ -624,7 +657,7 @@ NumberEditor::Size()
status_t status_t
NumberEditor::Format(char *buffer) NumberEditor::_Format(char *buffer)
{ {
switch (fEditor.Type()) { switch (fEditor.Type()) {
case B_INT8_TYPE: case B_INT8_TYPE:
@@ -674,7 +707,7 @@ NumberEditor::AttachedToWindow()
fTextControl->SetTarget(this); fTextControl->SetTarget(this);
fEditor.StartWatching(this); fEditor.StartWatching(this);
UpdateText(); _UpdateText();
} }
@@ -695,7 +728,7 @@ NumberEditor::MessageReceived(BMessage *message)
CommitChanges(); CommitChanges();
break; break;
case kMsgDataEditorUpdate: case kMsgDataEditorUpdate:
UpdateText(); _UpdateText();
break; break;
default: default:
@@ -704,36 +737,49 @@ NumberEditor::MessageReceived(BMessage *message)
} }
// #pragma mark - // #pragma mark - BooleanEditor
BooleanEditor::BooleanEditor(BRect rect, DataEditor &editor) BooleanEditor::BooleanEditor(BRect rect, DataEditor &editor)
: TypeEditorView(rect, "Boolean Editor", B_FOLLOW_NONE, 0), : TypeEditorView(rect, "Boolean Editor", B_FOLLOW_NONE, 0, editor)
fEditor(editor)
{ {
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
BPopUpMenu *menu = new BPopUpMenu("bool"); BPopUpMenu *menu = new BPopUpMenu("bool");
BMessage *message; BMessage *message;
menu->AddItem(fFalseMenuItem = new BMenuItem("false", new BMessage(kMsgValueChanged))); menu->AddItem(fFalseMenuItem = new BMenuItem("false",
menu->AddItem(fTrueMenuItem = new BMenuItem("true", message = new BMessage(kMsgValueChanged))); new BMessage(kMsgValueChanged)));
menu->AddItem(fTrueMenuItem = new BMenuItem("true",
message = new BMessage(kMsgValueChanged)));
message->AddInt8("value", 1); message->AddInt8("value", 1);
BMenuField *menuField = new BMenuField(rect.InsetByCopy(5, 5), B_EMPTY_STRING, BMenuField *menuField = new BMenuField(rect.InsetByCopy(5, 5),
"Boolean Value:", menu, B_FOLLOW_LEFT_RIGHT); B_EMPTY_STRING, "Boolean Value:", menu, B_FOLLOW_LEFT_RIGHT);
menuField->SetDivider(StringWidth(menuField->Label()) + 8); menuField->SetDivider(StringWidth(menuField->Label()) + 8);
menuField->ResizeToPreferred(); menuField->ResizeToPreferred();
ResizeTo(menuField->Bounds().Width() + 10, menuField->Bounds().Height() + 10); ResizeTo(menuField->Bounds().Width() + 10,
menuField->Bounds().Height() + 10);
UpdateMenuField(); _UpdateMenuField();
AddChild(menuField); AddChild(menuField);
} }
void bool
BooleanEditor::UpdateMenuField() BooleanEditor::TypeMatches()
{ {
// we accept everything: we just look at the first byte, anyway
return true;
}
void
BooleanEditor::_UpdateMenuField()
{
if (fEditor.FileSize() != 1)
return;
if (fEditor.Lock()) { if (fEditor.Lock()) {
const char *buffer; const char *buffer;
if (fEditor.GetViewBuffer((const uint8 **)&buffer) == B_OK) if (fEditor.GetViewBuffer((const uint8 **)&buffer) == B_OK)
@@ -779,7 +825,7 @@ BooleanEditor::MessageReceived(BMessage *message)
break; break;
} }
case kMsgDataEditorUpdate: case kMsgDataEditorUpdate:
UpdateMenuField(); _UpdateMenuField();
break; break;
default: default:
@@ -788,12 +834,11 @@ BooleanEditor::MessageReceived(BMessage *message)
} }
// #pragma mark - // #pragma mark - ImageView
ImageView::ImageView(BRect rect, DataEditor &editor) ImageView::ImageView(BRect rect, DataEditor &editor)
: TypeEditorView(rect, "Image View", B_FOLLOW_NONE, B_WILL_DRAW), : TypeEditorView(rect, "Image View", B_FOLLOW_NONE, B_WILL_DRAW, editor),
fEditor(editor),
fBitmap(NULL), fBitmap(NULL),
fScaleSlider(NULL) fScaleSlider(NULL)
{ {
@@ -843,7 +888,7 @@ ImageView::AttachedToWindow()
if (fScaleSlider != NULL) if (fScaleSlider != NULL)
fScaleSlider->SetTarget(this); fScaleSlider->SetTarget(this);
UpdateImage(); _UpdateImage();
} }
@@ -859,11 +904,11 @@ ImageView::MessageReceived(BMessage *message)
{ {
switch (message->what) { switch (message->what) {
case kMsgDataEditorUpdate: case kMsgDataEditorUpdate:
UpdateImage(); _UpdateImage();
break; break;
case kMsgScaleChanged: case kMsgScaleChanged:
UpdateImage(); _UpdateImage();
break; break;
default: default:
@@ -884,7 +929,7 @@ ImageView::Draw(BRect updateRect)
void void
ImageView::UpdateImage() ImageView::_UpdateImage()
{ {
// ToDo: add scroller if necessary?! // ToDo: add scroller if necessary?!
@@ -903,7 +948,8 @@ ImageView::UpdateImage()
return; return;
} }
if (fBitmap != NULL && (fEditor.Type() == B_MINI_ICON_TYPE || fEditor.Type() == B_LARGE_ICON_TYPE)) { if (fBitmap != NULL && (fEditor.Type() == B_MINI_ICON_TYPE
|| fEditor.Type() == B_LARGE_ICON_TYPE)) {
// optimize icon update... // optimize icon update...
fBitmap->SetBits(data, fEditor.FileSize(), 0, B_CMAP8); fBitmap->SetBits(data, fEditor.FileSize(), 0, B_CMAP8);
fEditor.SetViewSize(viewSize); fEditor.SetViewSize(viewSize);
@@ -1073,19 +1119,11 @@ ImageView::UpdateImage()
} }
void
ImageView::CommitChanges()
{
// we're not an editor, we're just displaying something
}
// #pragma mark - MessageView // #pragma mark - MessageView
MessageView::MessageView(BRect rect, DataEditor &editor) MessageView::MessageView(BRect rect, DataEditor &editor)
: TypeEditorView(rect, "Message View", B_FOLLOW_ALL, 0), : TypeEditorView(rect, "Message View", B_FOLLOW_ALL, 0, editor)
fEditor(editor)
{ {
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
@@ -1256,13 +1294,6 @@ MessageView::MessageReceived(BMessage* message)
} }
void
MessageView::CommitChanges()
{
// we're not an editor, we're just displaying something
}
// #pragma mark - // #pragma mark -
@@ -1306,3 +1337,60 @@ GetTypeEditorFor(BRect rect, DataEditor &editor)
return NULL; return NULL;
} }
status_t
GetNthTypeEditor(int32 index, const char** _name)
{
static const char* kEditors[] = {
"Text",
"Number",
"Boolean",
"Message",
"Image"
};
if (index < 0 || index >= int32(sizeof(kEditors) / sizeof(kEditors[0])))
return B_BAD_VALUE;
*_name = kEditors[index];
return B_OK;
}
TypeEditorView*
GetTypeEditorAt(int32 index, BRect rect, DataEditor& editor)
{
TypeEditorView* view = NULL;
switch (index) {
case 0:
view = new StringEditor(rect, editor);
break;
case 1:
view = new NumberEditor(rect, editor);
break;
case 2:
view = new BooleanEditor(rect, editor);
break;
case 3:
view = new MessageView(rect, editor);
break;
case 4:
view = new ImageView(rect, editor);
break;
default:
return NULL;
}
if (view == NULL)
return NULL;
if (!view->TypeMatches()) {
delete view;
return NULL;
}
return view;
}
+11 -5
View File
@@ -13,14 +13,20 @@ class DataEditor;
class TypeEditorView : public BView { class TypeEditorView : public BView {
public: public:
TypeEditorView(BRect rect, const char *name, uint32 resizingMode, uint32 flags) TypeEditorView(BRect rect, const char* name, uint32 resizingMode,
: BView(rect, name, resizingMode, flags) uint32 flags, DataEditor& editor);
{ ~TypeEditorView();
}
virtual void CommitChanges() = 0; virtual void CommitChanges();
virtual bool TypeMatches();
protected:
DataEditor& fEditor;
}; };
extern TypeEditorView* GetTypeEditorFor(BRect rect, DataEditor& editor); extern TypeEditorView* GetTypeEditorFor(BRect rect, DataEditor& editor);
extern status_t GetNthTypeEditor(int32 index, const char** _name);
extern TypeEditorView* GetTypeEditorAt(int32 index, BRect rect,
DataEditor& editor);
#endif /* TYPE_EDITORS_H */ #endif /* TYPE_EDITORS_H */