* 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
+2 -2
View File
@@ -49,9 +49,9 @@ EditorTabView::EditorTabView(BRect frame, const char *name, button_width width,
fRawTab(-1)
{
ContainerView()->MoveBy(-ContainerView()->Frame().left,
TabHeight() + 1 - ContainerView()->Frame().top);
TabHeight() + 1 - ContainerView()->Frame().top);
fNoEditorView = new BStringView(ContainerView()->Bounds(), "Type Editor",
"No type editor available", B_FOLLOW_NONE);
"No type editor available", B_FOLLOW_NONE);
fNoEditorView->ResizeToPreferred();
fNoEditorView->SetAlignment(B_ALIGN_CENTER);
fTypeEditorView = fNoEditorView;
+1
View File
@@ -88,6 +88,7 @@ FileWindow::FileWindow(BRect rect, entry_ref *ref, const BMessage *settings)
fProbeView->AddSaveMenuItems(menu, 4);
fProbeView->AddPrintMenuItems(menu, menu->CountItems() - 4);
fProbeView->AddViewAsMenuItems();
fProbeView->UpdateSizeLimits();
}
+315 -118
View File
@@ -1,12 +1,14 @@
/*
* Copyright 2004-2007, 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.
*/
#include "ProbeView.h"
#include "DataView.h"
#include "DiskProbe.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Application.h>
#include <Window.h>
@@ -35,10 +37,9 @@
#include <PrintJob.h>
#include <Beep.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "DataView.h"
#include "DiskProbe.h"
#include "TypeEditors.h"
#ifndef __HAIKU__
# define DRAW_SLIDER_BAR
@@ -55,6 +56,7 @@ static const uint32 kMsgBlockSize = 'blks';
static const uint32 kMsgAddBookmark = 'bmrk';
static const uint32 kMsgPrint = 'prnt';
static const uint32 kMsgPageSetup = 'pgsp';
static const uint32 kMsgViewAs = 'vwas';
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
@@ -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)
@@ -285,7 +300,7 @@ IconView::UpdateIcon()
}
// #pragma mark -
// #pragma mark - PositionSlider
PositionSlider::PositionSlider(BRect rect, const char *name, BMessage *message,
@@ -407,7 +422,6 @@ void
PositionSlider::SetPosition(off_t position)
{
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));
}
@@ -441,7 +455,7 @@ PositionSlider::SetBlockSize(uint32 blockSize)
}
// #pragma mark -
// #pragma mark - HeaderView
HeaderView::HeaderView(BRect frame, const entry_ref *ref, DataEditor &editor)
@@ -466,7 +480,7 @@ HeaderView::HeaderView(BRect frame, const entry_ref *ref, DataEditor &editor)
BRect rect = Bounds();
fStopButton = new BButton(BRect(0, 0, 20, 20), B_EMPTY_STRING, "Stop",
new BMessage(kMsgStopFind), B_FOLLOW_TOP | B_FOLLOW_RIGHT);
new BMessage(kMsgStopFind), B_FOLLOW_TOP | B_FOLLOW_RIGHT);
fStopButton->SetFont(&plainFont);
fStopButton->ResizeToPreferred();
fStopButton->MoveTo(rect.right - 4 - fStopButton->Bounds().Width(), 4);
@@ -474,7 +488,8 @@ HeaderView::HeaderView(BRect frame, const entry_ref *ref, DataEditor &editor)
AddChild(fStopButton);
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->ResizeToPreferred();
AddChild(stringView);
@@ -489,14 +504,16 @@ HeaderView::HeaderView(BRect frame, const entry_ref *ref, DataEditor &editor)
rect = stringView->Frame();
rect.left = rect.right;
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);
AddChild(fPathView);
float top = 28;
if (editor.IsAttribute()) {
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->ResizeToPreferred();
AddChild(stringView);
@@ -509,7 +526,8 @@ HeaderView::HeaderView(BRect frame, const entry_ref *ref, DataEditor &editor)
char buffer[16];
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->SetFont(&plainFont);
fTypeControl->TextView()->SetFontAndColor(&plainFont);
@@ -521,7 +539,8 @@ HeaderView::HeaderView(BRect frame, const entry_ref *ref, DataEditor &editor)
} else
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->ResizeToPreferred();
AddChild(stringView);
@@ -531,7 +550,8 @@ HeaderView::HeaderView(BRect frame, const entry_ref *ref, DataEditor &editor)
rect.right += 75;
rect.OffsetBy(0, -2);
// 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->SetFont(&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.right = frame.right;
stringView = new BStringView(rect, B_EMPTY_STRING,
editor.IsAttribute() ? "Attribute Offset: " : editor.IsDevice() ? "Device Offset: " : "File Offset: ");
stringView = new BStringView(rect, B_EMPTY_STRING, editor.IsAttribute()
? "Attribute Offset: " : editor.IsDevice()
? "Device Offset: " : "File Offset: ");
stringView->SetFont(&boldFont);
stringView->ResizeToPreferred();
AddChild(stringView);
@@ -580,8 +601,8 @@ HeaderView::HeaderView(BRect frame, const entry_ref *ref, DataEditor &editor)
rect.InsetBy(3, 0);
rect.top = top + 21;
rect.bottom = rect.top + 12;
fPositionSlider = new PositionSlider(rect, "slider", new BMessage(kMsgSliderUpdate),
editor.FileSize(), editor.BlockSize());
fPositionSlider = new PositionSlider(rect, "slider",
new BMessage(kMsgSliderUpdate), editor.FileSize(), editor.BlockSize());
fPositionSlider->SetModificationMessage(new BMessage(kMsgSliderUpdate));
fPositionSlider->SetBarThickness(8);
fPositionSlider->ResizeToPreferred();
@@ -604,13 +625,17 @@ HeaderView::AttachedToWindow()
fPositionSlider->SetTarget(this);
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);
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);
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);
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);
}
@@ -699,7 +724,8 @@ HeaderView::UpdateFileSizeView()
{
char buffer[64];
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);
}
@@ -770,7 +796,8 @@ HeaderView::MessageReceived(BMessage *message)
// If there is another message of this type in the
// queue, we're just ignoring the current message.
if (Looper()->MessageQueue()->FindMessage(kMsgSliderUpdate, 0) != NULL)
if (Looper()->MessageQueue()->FindMessage(kMsgSliderUpdate, 0)
!= NULL)
break;
// if nothing has changed, we can ignore this message as well
@@ -791,7 +818,8 @@ HeaderView::MessageReceived(BMessage *message)
case kMsgDataEditorFindProgress:
{
bool state;
if (message->FindBool("running", &state) == B_OK && fFileSize > fBlockSize) {
if (message->FindBool("running", &state) == B_OK
&& fFileSize > fBlockSize) {
fPositionSlider->SetEnabled(!state);
if (state) {
fPathView->ResizeBy(-fStopButton->Bounds().Width(), 0);
@@ -827,10 +855,12 @@ HeaderView::MessageReceived(BMessage *message)
if (position < 0)
position += (fFileSize - 1) / fBlockSize + 1;
fPosition = position * fBlockSize;
} else if (message->FindInt32("delta", &delta) == B_OK)
} else if (message->FindInt32("delta", &delta) == B_OK) {
fPosition += delta * off_t(fBlockSize);
else
fPosition = strtoll(fPositionControl->Text(), NULL, 0) * fBlockSize;
} else {
fPosition = strtoll(fPositionControl->Text(), NULL, 0)
* fBlockSize;
}
fPosition = (fPosition / fBlockSize) * fBlockSize;
// 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
* at its right border.
* It is used to display the attribute and type in the attributes menu.
* It does not mix nicely with short cuts.
*/
TypeMenuItem::TypeMenuItem(const char *name, const char *type, BMessage *message)
/*! The TypeMenuItem is a BMenuItem that displays a type string at its
right border.
It is used to display the attribute and type in the attributes menu.
It does not mix nicely with short cuts.
*/
TypeMenuItem::TypeMenuItem(const char *name, const char *type,
BMessage *message)
: BMenuItem(name, message),
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
* loading from the main window looper.
* It will listen to the offset changes of the editor, let
* him update its data, and will then synchronously notify
* the target.
* That way, simple offset changes will not stop the main
* looper from operating. Therefore, all offset updates
* for the editor will go through this looper.
*
* Also, it will run the find action in the editor.
*/
/*! The purpose of this looper is to off-load the editor data loading from
the main window looper.
EditorLooper::EditorLooper(const char *name, DataEditor &editor, BMessenger target)
It will listen to the offset changes of the editor, let him update its
data, and will then synchronously notify the target.
That way, simple offset changes will not stop the main looper from
operating. Therefore, all offset updates for the editor will go through
this looper.
Also, it will run the find action in the editor.
*/
EditorLooper::EditorLooper(const char *name, DataEditor &editor,
BMessenger target)
: BLooper(name),
fEditor(editor),
fMessenger(target),
@@ -1012,7 +1041,8 @@ EditorLooper::MessageReceived(BMessage *message)
ssize_t dataSize;
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);
}
@@ -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),
fPrintSettings(NULL),
fTypeView(NULL),
fLastSearch(NULL)
{
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->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);
fDataView->UpdateScroller();
@@ -1117,7 +1204,8 @@ ProbeView::UpdateSizeLimits()
float 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,
200, height + frame.bottom + 4 + B_H_SCROLL_BAR_HEIGHT);
@@ -1129,8 +1217,10 @@ ProbeView::UpdateSizeLimits()
BRect bounds = Window()->Bounds();
float minWidth, maxWidth, minHeight, maxHeight;
Window()->GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight);
if (maxWidth < bounds.Width() || maxHeight < bounds.Height())
Window()->ResizeTo(MIN(maxWidth, bounds.Width()), MIN(maxHeight, bounds.Height()));
if (maxWidth < bounds.Width() || maxHeight < bounds.Height()) {
Window()->ResizeTo(MIN(maxWidth, bounds.Width()), MIN(maxHeight,
bounds.Height()));
}
#endif
}
@@ -1153,7 +1243,7 @@ ProbeView::DetachedFromWindow()
void
ProbeView::UpdateAttributesMenu(BMenu *menu)
ProbeView::_UpdateAttributesMenu(BMenu *menu)
{
// remove old contents
@@ -1206,10 +1296,10 @@ ProbeView::UpdateAttributesMenu(BMenu *menu)
void
ProbeView::AddSaveMenuItems(BMenu *menu, int32 index)
ProbeView::AddSaveMenuItems(BMenu* menu, int32 index)
{
menu->AddItem(fSaveMenuItem = new BMenuItem("Save", new BMessage(B_SAVE_REQUESTED),
'S', B_COMMAND_KEY), index);
menu->AddItem(fSaveMenuItem = new BMenuItem("Save",
new BMessage(B_SAVE_REQUESTED), 'S'), index);
fSaveMenuItem->SetTarget(this);
fSaveMenuItem->SetEnabled(false);
//menu->AddItem(new BMenuItem("Save As" B_UTF8_ELLIPSIS, NULL), index);
@@ -1217,22 +1307,63 @@ ProbeView::AddSaveMenuItems(BMenu *menu, int32 index)
void
ProbeView::AddPrintMenuItems(BMenu *menu, int32 index)
ProbeView::AddPrintMenuItems(BMenu* menu, int32 index)
{
BMenuItem *item;
menu->AddItem(item = new BMenuItem("Page Setup" B_UTF8_ELLIPSIS,
new BMessage(kMsgPageSetup)), index++);
new BMessage(kMsgPageSetup)), index++);
item->SetTarget(this);
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);
}
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
ProbeView::AttachedToWindow()
{
fEditorLooper = new EditorLooper(fEditor.Ref().name, fEditor, BMessenger(fDataView));
fEditorLooper = new EditorLooper(fEditor.Ref().name, fEditor,
BMessenger(fDataView));
fEditorLooper->Run();
fEditor.StartWatching(this);
@@ -1252,13 +1383,15 @@ ProbeView::AttachedToWindow()
MoveBy(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);
menu->AddSeparatorItem();
AddPrintMenuItems(menu, menu->CountItems());
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);
}
@@ -1266,26 +1399,30 @@ ProbeView::AttachedToWindow()
BMenu *menu = new BMenu("Edit");
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->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->SetTarget(fDataView);
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());
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());
CheckClipboard();
menu->AddItem(item = new BMenuItem("Select All", new BMessage(B_SELECT_ALL), 'A', B_COMMAND_KEY));
_CheckClipboard();
menu->AddItem(item = new BMenuItem("Select All", new BMessage(B_SELECT_ALL),
'A'));
item->SetTarget(NULL, Window());
menu->AddSeparatorItem();
menu->AddItem(item = new BMenuItem("Find" B_UTF8_ELLIPSIS, new BMessage(kMsgOpenFindWindow),
'F', B_COMMAND_KEY));
menu->AddItem(item = new BMenuItem("Find" B_UTF8_ELLIPSIS,
new BMessage(kMsgOpenFindWindow), 'F'));
item->SetTarget(this);
menu->AddItem(fFindAgainMenuItem = new BMenuItem("Find Again", new BMessage(kMsgFind),
'G', B_COMMAND_KEY));
menu->AddItem(fFindAgainMenuItem = new BMenuItem("Find Again",
new BMessage(kMsgFind), 'G'));
fFindAgainMenuItem->SetEnabled(false);
fFindAgainMenuItem->SetTarget(this);
bar->AddItem(menu);
@@ -1295,30 +1432,31 @@ ProbeView::AttachedToWindow()
menu = new BMenu("Block");
BMessage *message = new BMessage(kMsgPositionUpdate);
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);
message = new BMessage(kMsgPositionUpdate);
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);
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);
BMenu *subMenu = new BMenu("Selection");
message = new BMessage(kMsgPositionUpdate);
message->AddInt64("block", 0);
subMenu->AddItem(fNativeMenuItem = new BMenuItem("", message, 'K', B_COMMAND_KEY));
subMenu->AddItem(fNativeMenuItem = new BMenuItem("", message, 'K'));
fNativeMenuItem->SetTarget(fHeaderView);
message = new BMessage(*message);
subMenu->AddItem(fSwappedMenuItem = new BMenuItem("", message, 'L', B_COMMAND_KEY));
subMenu->AddItem(fSwappedMenuItem = new BMenuItem("", message, 'L'));
fSwappedMenuItem->SetTarget(fHeaderView);
menu->AddItem(new BMenuItem(subMenu));
UpdateSelectionMenuItems(0, 0);
_UpdateSelectionMenuItems(0, 0);
menu->AddSeparatorItem();
fBookmarkMenu = new BMenu("Bookmarks");
fBookmarkMenu->AddItem(item = new BMenuItem("Add", new BMessage(kMsgAddBookmark),
'B', B_COMMAND_KEY));
fBookmarkMenu->AddItem(item = new BMenuItem("Add",
new BMessage(kMsgAddBookmark), 'B'));
item->SetTarget(this);
menu->AddItem(new BMenuItem(fBookmarkMenu));
bar->AddItem(menu);
@@ -1328,15 +1466,16 @@ ProbeView::AttachedToWindow()
BDirectory directory;
BVolume volume;
if (directory.SetTo(&fEditor.AttributeRef()) == B_OK && directory.IsRootDirectory())
if (directory.SetTo(&fEditor.AttributeRef()) == B_OK
&& directory.IsRootDirectory())
directory.GetVolume(&volume);
else
fEditor.File().GetVolume(&volume);
if (!fEditor.IsAttribute()
&& volume.InitCheck() == B_OK && (volume.KnowsMime() || volume.KnowsAttr())) {
if (!fEditor.IsAttribute() && volume.InitCheck() == B_OK
&& (volume.KnowsMime() || volume.KnowsAttr())) {
bar->AddItem(menu = new BMenu("Attributes"));
UpdateAttributesMenu(menu);
_UpdateAttributesMenu(menu);
}
// "View" menu
@@ -1348,14 +1487,14 @@ ProbeView::AttachedToWindow()
subMenu = new BMenu("Base");
message = new BMessage(kMsgBaseType);
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);
if (fHeaderView->Base() == kDecimalBase)
item->SetMarked(true);
message = new BMessage(kMsgBaseType);
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);
if (fHeaderView->Base() == kHexBase)
item->SetMarked(true);
@@ -1371,8 +1510,10 @@ ProbeView::AttachedToWindow()
for (uint32 i = 0; i < sizeof(blockSizes) / sizeof(blockSizes[0]); i++) {
char buffer[32];
snprintf(buffer, sizeof(buffer), "%ld%s", blockSizes[i],
fEditor.IsDevice() && fEditor.BlockSize() == blockSizes[i] ? " (native)" : "");
subMenu->AddItem(item = new BMenuItem(buffer, message = new BMessage(kMsgBlockSize)));
fEditor.IsDevice() && fEditor.BlockSize() == blockSizes[i]
? " (native)" : "");
subMenu->AddItem(item = new BMenuItem(buffer,
message = new BMessage(kMsgBlockSize)));
message->AddInt32("block_size", blockSizes[i]);
if (fEditor.BlockSize() == blockSizes[i])
item->SetMarked(true);
@@ -1381,7 +1522,8 @@ ProbeView::AttachedToWindow()
// if the device has some weird block size, we'll add it here, too
char buffer[32];
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());
item->SetMarked(true);
}
@@ -1400,13 +1542,15 @@ ProbeView::AttachedToWindow()
for (uint32 i = 0; i < sizeof(fontSizes) / sizeof(fontSizes[0]); i++) {
char buffer[16];
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]);
if (fontSizes[i] == fontSize)
item->SetMarked(true);
}
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);
if (fontSize == 0)
item->SetMarked(true);
@@ -1441,7 +1585,7 @@ ProbeView::WindowActivated(bool active)
void
ProbeView::UpdateSelectionMenuItems(int64 start, int64 end)
ProbeView::_UpdateSelectionMenuItems(int64 start, int64 end)
{
int64 position = 0;
const uint8 *data = fDataView->DataAt(start);
@@ -1489,7 +1633,7 @@ ProbeView::UpdateSelectionMenuItems(int64 start, int64 end)
void
ProbeView::UpdateBookmarkMenuItems()
ProbeView::_UpdateBookmarkMenuItems()
{
for (int32 i = 2; i < fBookmarkMenu->CountItems(); i++) {
BMenuItem *item = fBookmarkMenu->ItemAt(i);
@@ -1514,7 +1658,7 @@ ProbeView::UpdateBookmarkMenuItems()
void
ProbeView::AddBookmark(off_t position)
ProbeView::_AddBookmark(off_t position)
{
int32 count = fBookmarkMenu->CountItems();
@@ -1560,7 +1704,50 @@ ProbeView::AddBookmark(off_t position)
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())
return;
@@ -1582,7 +1769,7 @@ ProbeView::CheckClipboard()
status_t
ProbeView::PageSetup()
ProbeView::_PageSetup()
{
BPrintJob printJob(Window()->Title());
if (fPrintSettings != NULL)
@@ -1600,9 +1787,9 @@ ProbeView::PageSetup()
void
ProbeView::Print()
ProbeView::_Print()
{
if (fPrintSettings == NULL && PageSetup() != B_OK)
if (fPrintSettings == NULL && _PageSetup() != B_OK)
return;
BPrintJob printJob(Window()->Title());
@@ -1627,7 +1814,7 @@ ProbeView::Print()
status_t
ProbeView::Save()
ProbeView::_Save()
{
status_t status = fEditor.Save();
if (status == B_OK)
@@ -1665,7 +1852,7 @@ ProbeView::QuitRequested()
if (chosen == 1)
return false;
return Save() == B_OK;
return _Save() == B_OK;
}
@@ -1674,7 +1861,7 @@ ProbeView::MessageReceived(BMessage *message)
{
switch (message->what) {
case B_SAVE_REQUESTED:
Save();
_Save();
break;
case B_OBSERVER_NOTICE_CHANGE: {
@@ -1688,7 +1875,7 @@ ProbeView::MessageReceived(BMessage *message)
int64 start, end;
if (message->FindInt64("start", &start) == B_OK
&& message->FindInt64("end", &end) == B_OK)
UpdateSelectionMenuItems(start, end);
_UpdateSelectionMenuItems(start, end);
break;
}
case kDataViewPreferredSize:
@@ -1710,9 +1897,9 @@ ProbeView::MessageReceived(BMessage *message)
// The selection menu items depend on the base type as well
int32 start, end;
fDataView->GetSelection(start, end);
UpdateSelectionMenuItems(start, end);
_UpdateSelectionMenuItems(start, end);
UpdateBookmarkMenuItems();
_UpdateBookmarkMenuItems();
// update the application's settings
BMessage update(*message);
@@ -1750,16 +1937,26 @@ ProbeView::MessageReceived(BMessage *message)
break;
}
case kMsgViewAs:
{
int32 index;
if (message->FindInt32("editor index", &index) != B_OK)
index = -1;
_SetTypeEditor(index);
break;
}
case kMsgAddBookmark:
AddBookmark(fHeaderView->Position());
_AddBookmark(fHeaderView->Position());
break;
case kMsgPrint:
Print();
_Print();
break;
case kMsgPageSetup:
PageSetup();
_PageSetup();
break;
case kMsgOpenFindWindow:
@@ -1827,7 +2024,7 @@ ProbeView::MessageReceived(BMessage *message)
if (bar != NULL) {
BMenuItem *item = bar->FindItem("Attributes");
if (item != NULL && item->Submenu() != NULL)
UpdateAttributesMenu(item->Submenu());
_UpdateAttributesMenu(item->Submenu());
}
}
@@ -1844,7 +2041,7 @@ ProbeView::MessageReceived(BMessage *message)
}
case B_CLIPBOARD_CHANGED:
CheckClipboard();
_CheckClipboard();
break;
case kMsgDataEditorStateChange:
+33 -27
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.
*/
#ifndef PROBE_VIEW_H
@@ -24,48 +24,54 @@ class EditorLooper;
class ProbeView : public BView {
public:
ProbeView(BRect rect, entry_ref *ref, const char *attribute = NULL,
const BMessage *settings = NULL);
ProbeView(BRect rect, entry_ref* ref, const char* attribute = NULL,
const BMessage* settings = NULL);
virtual ~ProbeView();
virtual void DetachedFromWindow();
virtual void AttachedToWindow();
virtual void AllAttached();
virtual void WindowActivated(bool active);
virtual void MessageReceived(BMessage *message);
virtual void MessageReceived(BMessage* message);
void AddSaveMenuItems(BMenu *menu, int32 index);
void AddPrintMenuItems(BMenu *menu, int32 index);
void AddSaveMenuItems(BMenu* menu, int32 index);
void AddPrintMenuItems(BMenu* menu, int32 index);
void AddViewAsMenuItems();
void UpdateSizeLimits();
bool QuitRequested();
DataEditor &Editor() { return fEditor; }
DataEditor& Editor() { return fEditor; }
private:
void UpdateAttributesMenu(BMenu *menu);
void UpdateSelectionMenuItems(int64 start, int64 end);
void UpdateBookmarkMenuItems();
void AddBookmark(off_t position);
void CheckClipboard();
status_t PageSetup();
void Print();
status_t Save();
void _UpdateAttributesMenu(BMenu* menu);
void _UpdateSelectionMenuItems(int64 start, int64 end);
void _UpdateBookmarkMenuItems();
void _AddBookmark(off_t position);
void _RemoveTypeEditor();
void _SetTypeEditor(int32 index);
void _CheckClipboard();
status_t _PageSetup();
void _Print();
status_t _Save();
DataEditor fEditor;
EditorLooper *fEditorLooper;
HeaderView *fHeaderView;
DataView *fDataView;
BScrollView *fScrollView;
BMenuItem *fPasteMenuItem;
BMenuItem *fUndoMenuItem, *fRedoMenuItem;
BMenuItem *fNativeMenuItem, *fSwappedMenuItem;
BMenuItem *fSaveMenuItem;
BMessage *fPrintSettings;
BMenu *fBookmarkMenu;
EditorLooper* fEditorLooper;
HeaderView* fHeaderView;
DataView* fDataView;
BScrollView* fScrollView;
BMenuItem* fPasteMenuItem;
BMenuItem* fUndoMenuItem;
BMenuItem* fRedoMenuItem;
BMenuItem* fNativeMenuItem;
BMenuItem* fSwappedMenuItem;
BMenuItem* fSaveMenuItem;
BMessage* fPrintSettings;
BMenu* fBookmarkMenu;
BView* fTypeView;
BMenuItem *fFindAgainMenuItem;
const uint8 *fLastSearch;
BMenuItem* fFindAgainMenuItem;
const uint8* fLastSearch;
size_t fLastSearchSize;
};
+214 -126
View File
@@ -37,77 +37,79 @@ static const uint32 kMimeTypeItem = 'miti';
class StringEditor : public TypeEditorView {
public:
StringEditor(BRect rect, DataEditor &editor);
StringEditor(BRect rect, DataEditor& editor);
virtual void AttachedToWindow();
virtual void DetachedFromWindow();
virtual void MessageReceived(BMessage *message);
virtual void MessageReceived(BMessage* message);
void UpdateText();
virtual void CommitChanges();
private:
DataEditor &fEditor;
BTextView *fTextView;
BString fPreviousText;
void _UpdateText();
BTextView* fTextView;
BString fPreviousText;
};
class MimeTypeEditor : public TypeEditorView {
public:
MimeTypeEditor(BRect rect, DataEditor &editor);
MimeTypeEditor(BRect rect, DataEditor& editor);
virtual void AttachedToWindow();
virtual void DetachedFromWindow();
virtual void MessageReceived(BMessage *message);
virtual void MessageReceived(BMessage* message);
void UpdateText();
virtual void CommitChanges();
virtual bool TypeMatches();
private:
DataEditor &fEditor;
BTextControl *fTextControl;
void _UpdateText();
BTextControl* fTextControl;
BString fPreviousText;
};
class NumberEditor : public TypeEditorView {
public:
NumberEditor(BRect rect, DataEditor &editor);
NumberEditor(BRect rect, DataEditor& editor);
virtual void AttachedToWindow();
virtual void DetachedFromWindow();
virtual void MessageReceived(BMessage *message);
virtual void MessageReceived(BMessage* message);
void UpdateText();
virtual void CommitChanges();
virtual bool TypeMatches();
private:
const char *TypeLabel();
status_t Format(char *buffer);
size_t Size();
void _UpdateText();
const char* _TypeLabel();
status_t _Format(char* buffer);
size_t _Size();
DataEditor &fEditor;
BTextControl *fTextControl;
BTextControl* fTextControl;
BString fPreviousText;
};
class BooleanEditor : public TypeEditorView {
public:
BooleanEditor(BRect rect, DataEditor &editor);
BooleanEditor(BRect rect, DataEditor& editor);
virtual void AttachedToWindow();
virtual void DetachedFromWindow();
virtual void MessageReceived(BMessage *message);
virtual void MessageReceived(BMessage* message);
void UpdateMenuField();
virtual void CommitChanges();
virtual bool TypeMatches();
private:
DataEditor &fEditor;
BMenuItem *fFalseMenuItem;
BMenuItem *fTrueMenuItem;
void _UpdateMenuField();
BMenuItem* fFalseMenuItem;
BMenuItem* fTrueMenuItem;
};
@@ -121,14 +123,12 @@ class ImageView : public TypeEditorView {
virtual void MessageReceived(BMessage *message);
virtual void Draw(BRect updateRect);
void UpdateImage();
virtual void CommitChanges();
private:
DataEditor &fEditor;
BBitmap *fBitmap;
BStringView *fDescriptionView;
BSlider *fScaleSlider;
void _UpdateImage();
BBitmap* fBitmap;
BStringView* fDescriptionView;
BSlider* fScaleSlider;
};
@@ -141,25 +141,56 @@ class MessageView : public TypeEditorView {
virtual void DetachedFromWindow();
virtual void MessageReceived(BMessage* message);
virtual void CommitChanges();
void SetTo(BMessage& message);
private:
BString _TypeToString(type_code type);
void _UpdateMessage();
DataEditor& fEditor;
BTextView* fTextView;
BTextView* fTextView;
};
//-----------------
// #pragma mark - TypeEditorView
StringEditor::StringEditor(BRect rect, DataEditor &editor)
: TypeEditorView(rect, "String Editor", B_FOLLOW_ALL, 0),
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)
: TypeEditorView(rect, "String Editor", B_FOLLOW_ALL, 0, editor)
{
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
@@ -177,24 +208,14 @@ StringEditor::StringEditor(BRect rect, DataEditor &editor)
rect.OffsetToCopy(B_ORIGIN).InsetByCopy(5, 5),
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);
AddChild(scrollView);
}
void
StringEditor::UpdateText()
StringEditor::_UpdateText()
{
BAutolock locker(fEditor);
@@ -214,7 +235,7 @@ StringEditor::UpdateText()
}
void
void
StringEditor::CommitChanges()
{
if (fPreviousText != fTextView->Text()) {
@@ -229,7 +250,7 @@ StringEditor::AttachedToWindow()
{
fEditor.StartWatching(this);
UpdateText();
_UpdateText();
}
@@ -249,17 +270,16 @@ StringEditor::MessageReceived(BMessage *message)
}
// #pragma mark -
// #pragma mark - MimeTypeEditor
MimeTypeEditor::MimeTypeEditor(BRect rect, DataEditor &editor)
: TypeEditorView(rect, "MIME Type Editor", B_FOLLOW_LEFT_RIGHT, 0),
fEditor(editor)
MimeTypeEditor::MimeTypeEditor(BRect rect, DataEditor& editor)
: TypeEditorView(rect, "MIME Type Editor", B_FOLLOW_LEFT_RIGHT, 0, editor)
{
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
fTextControl = new BTextControl(rect.InsetByCopy(5, 5), B_EMPTY_STRING, "MIME Type:", NULL,
new BMessage(kMsgValueChanged), B_FOLLOW_ALL);
fTextControl = new BTextControl(rect.InsetByCopy(5, 5), B_EMPTY_STRING,
"MIME Type:", NULL, new BMessage(kMsgValueChanged), B_FOLLOW_ALL);
fTextControl->SetDivider(StringWidth(fTextControl->Label()) + 8);
float width, height;
@@ -273,11 +293,11 @@ MimeTypeEditor::MimeTypeEditor(BRect rect, DataEditor &editor)
void
MimeTypeEditor::UpdateText()
MimeTypeEditor::_UpdateText()
{
BAutolock locker(fEditor);
const char *mimeType;
const char* mimeType;
if (fEditor.GetViewBuffer((const uint8 **)&mimeType) == B_OK) {
fTextControl->SetText(mimeType);
fPreviousText.SetTo(mimeType);
@@ -289,19 +309,27 @@ void
MimeTypeEditor::CommitChanges()
{
if (fPreviousText != fTextControl->Text()) {
fEditor.Replace(0, (const uint8 *)fTextControl->Text(),
fEditor.Replace(0, (const uint8*)fTextControl->Text(),
strlen(fTextControl->Text()) + 1);
}
}
bool
MimeTypeEditor::TypeMatches()
{
// TODO: check contents?
return fEditor.FileSize() <= B_MIME_TYPE_LENGTH;
}
void
MimeTypeEditor::AttachedToWindow()
{
fTextControl->SetTarget(this);
fEditor.StartWatching(this);
UpdateText();
_UpdateText();
}
@@ -324,7 +352,7 @@ MimeTypeEditor::MessageReceived(BMessage *message)
break;
case kMsgDataEditorUpdate:
UpdateText();
_UpdateText();
break;
default:
@@ -333,17 +361,16 @@ MimeTypeEditor::MessageReceived(BMessage *message)
}
// #pragma mark -
// #pragma mark - NumberEditor
NumberEditor::NumberEditor(BRect rect, DataEditor &editor)
: TypeEditorView(rect, "Number Editor", B_FOLLOW_LEFT_RIGHT, 0),
fEditor(editor)
: TypeEditorView(rect, "Number Editor", B_FOLLOW_LEFT_RIGHT, 0, editor)
{
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
fTextControl = new BTextControl(rect.InsetByCopy(5, 5), B_EMPTY_STRING, TypeLabel(), NULL,
new BMessage(kMsgValueChanged), B_FOLLOW_ALL);
fTextControl = new BTextControl(rect.InsetByCopy(5, 5), B_EMPTY_STRING,
_TypeLabel(), NULL, new BMessage(kMsgValueChanged), B_FOLLOW_ALL);
fTextControl->SetDivider(StringWidth(fTextControl->Label()) + 8);
fTextControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_RIGHT);
ResizeTo(rect.Width(), 30);
@@ -353,17 +380,17 @@ NumberEditor::NumberEditor(BRect rect, DataEditor &editor)
void
NumberEditor::UpdateText()
NumberEditor::_UpdateText()
{
if (fEditor.Lock()) {
const char *number;
if (fEditor.GetViewBuffer((const uint8 **)&number) == B_OK) {
const char* number;
if (fEditor.GetViewBuffer((const uint8**)&number) == B_OK) {
char buffer[64];
char format[16];
switch (fEditor.Type()) {
case B_FLOAT_TYPE:
{
float value = *(float *)number;
float value = *(float*)number;
snprintf(buffer, sizeof(buffer), "%g", value);
break;
}
@@ -380,8 +407,8 @@ NumberEditor::UpdateText()
case B_INT64_TYPE:
case B_OFF_T_TYPE:
{
Format(format);
switch (Size()) {
_Format(format);
switch (_Size()) {
case 1:
{
int8 value = *(int8 *)number;
@@ -409,10 +436,11 @@ NumberEditor::UpdateText()
}
break;
}
default:
{
Format(format);
switch (Size()) {
_Format(format);
switch (_Size()) {
case 1:
{
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
NumberEditor::CommitChanges()
{
@@ -546,13 +582,13 @@ NumberEditor::CommitChanges()
return;
}
fEditor.Replace(0, buffer, Size());
fEditor.Replace(0, buffer, _Size());
fPreviousText.SetTo((char *)buffer);
}
const char *
NumberEditor::TypeLabel()
const char*
NumberEditor::_TypeLabel()
{
switch (fEditor.Type()) {
case B_INT8_TYPE:
@@ -590,33 +626,30 @@ NumberEditor::TypeLabel()
size_t
NumberEditor::Size()
NumberEditor::_Size()
{
switch (fEditor.Type()) {
case B_INT8_TYPE:
return 1;
case B_UINT8_TYPE:
return 1;
case B_INT16_TYPE:
return 2;
case B_UINT16_TYPE:
return 2;
case B_SSIZE_T_TYPE:
case B_INT32_TYPE:
return 4;
case B_SIZE_T_TYPE:
case B_POINTER_TYPE:
case B_UINT32_TYPE:
return 4;
case B_INT64_TYPE:
case B_OFF_T_TYPE:
return 8;
case B_UINT64_TYPE:
return 8;
case B_FLOAT_TYPE:
return 4;
case B_DOUBLE_TYPE:
return 8;
default:
return 0;
}
@@ -624,7 +657,7 @@ NumberEditor::Size()
status_t
NumberEditor::Format(char *buffer)
NumberEditor::_Format(char *buffer)
{
switch (fEditor.Type()) {
case B_INT8_TYPE:
@@ -674,7 +707,7 @@ NumberEditor::AttachedToWindow()
fTextControl->SetTarget(this);
fEditor.StartWatching(this);
UpdateText();
_UpdateText();
}
@@ -695,7 +728,7 @@ NumberEditor::MessageReceived(BMessage *message)
CommitChanges();
break;
case kMsgDataEditorUpdate:
UpdateText();
_UpdateText();
break;
default:
@@ -704,36 +737,49 @@ NumberEditor::MessageReceived(BMessage *message)
}
// #pragma mark -
// #pragma mark - BooleanEditor
BooleanEditor::BooleanEditor(BRect rect, DataEditor &editor)
: TypeEditorView(rect, "Boolean Editor", B_FOLLOW_NONE, 0),
fEditor(editor)
: TypeEditorView(rect, "Boolean Editor", B_FOLLOW_NONE, 0, editor)
{
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
BPopUpMenu *menu = new BPopUpMenu("bool");
BMessage *message;
menu->AddItem(fFalseMenuItem = new BMenuItem("false", new BMessage(kMsgValueChanged)));
menu->AddItem(fTrueMenuItem = new BMenuItem("true", message = new BMessage(kMsgValueChanged)));
menu->AddItem(fFalseMenuItem = new BMenuItem("false",
new BMessage(kMsgValueChanged)));
menu->AddItem(fTrueMenuItem = new BMenuItem("true",
message = new BMessage(kMsgValueChanged)));
message->AddInt8("value", 1);
BMenuField *menuField = new BMenuField(rect.InsetByCopy(5, 5), B_EMPTY_STRING,
"Boolean Value:", menu, B_FOLLOW_LEFT_RIGHT);
BMenuField *menuField = new BMenuField(rect.InsetByCopy(5, 5),
B_EMPTY_STRING, "Boolean Value:", menu, B_FOLLOW_LEFT_RIGHT);
menuField->SetDivider(StringWidth(menuField->Label()) + 8);
menuField->ResizeToPreferred();
ResizeTo(menuField->Bounds().Width() + 10, menuField->Bounds().Height() + 10);
ResizeTo(menuField->Bounds().Width() + 10,
menuField->Bounds().Height() + 10);
UpdateMenuField();
_UpdateMenuField();
AddChild(menuField);
}
void
BooleanEditor::UpdateMenuField()
bool
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()) {
const char *buffer;
if (fEditor.GetViewBuffer((const uint8 **)&buffer) == B_OK)
@@ -779,7 +825,7 @@ BooleanEditor::MessageReceived(BMessage *message)
break;
}
case kMsgDataEditorUpdate:
UpdateMenuField();
_UpdateMenuField();
break;
default:
@@ -788,12 +834,11 @@ BooleanEditor::MessageReceived(BMessage *message)
}
// #pragma mark -
// #pragma mark - ImageView
ImageView::ImageView(BRect rect, DataEditor &editor)
: TypeEditorView(rect, "Image View", B_FOLLOW_NONE, B_WILL_DRAW),
fEditor(editor),
: TypeEditorView(rect, "Image View", B_FOLLOW_NONE, B_WILL_DRAW, editor),
fBitmap(NULL),
fScaleSlider(NULL)
{
@@ -843,7 +888,7 @@ ImageView::AttachedToWindow()
if (fScaleSlider != NULL)
fScaleSlider->SetTarget(this);
UpdateImage();
_UpdateImage();
}
@@ -859,11 +904,11 @@ ImageView::MessageReceived(BMessage *message)
{
switch (message->what) {
case kMsgDataEditorUpdate:
UpdateImage();
_UpdateImage();
break;
case kMsgScaleChanged:
UpdateImage();
_UpdateImage();
break;
default:
@@ -884,7 +929,7 @@ ImageView::Draw(BRect updateRect)
void
ImageView::UpdateImage()
ImageView::_UpdateImage()
{
// ToDo: add scroller if necessary?!
@@ -903,7 +948,8 @@ ImageView::UpdateImage()
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...
fBitmap->SetBits(data, fEditor.FileSize(), 0, B_CMAP8);
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
MessageView::MessageView(BRect rect, DataEditor &editor)
: TypeEditorView(rect, "Message View", B_FOLLOW_ALL, 0),
fEditor(editor)
: TypeEditorView(rect, "Message View", B_FOLLOW_ALL, 0, editor)
{
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
@@ -1256,18 +1294,11 @@ MessageView::MessageReceived(BMessage* message)
}
void
MessageView::CommitChanges()
{
// we're not an editor, we're just displaying something
}
// #pragma mark -
TypeEditorView *
GetTypeEditorFor(BRect rect, DataEditor &editor)
TypeEditorView*
GetTypeEditorFor(BRect rect, DataEditor& editor)
{
switch (editor.Type()) {
case B_STRING_TYPE:
@@ -1306,3 +1337,60 @@ GetTypeEditorFor(BRect rect, DataEditor &editor)
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;
}
+12 -6
View File
@@ -13,14 +13,20 @@ class DataEditor;
class TypeEditorView : public BView {
public:
TypeEditorView(BRect rect, const char *name, uint32 resizingMode, uint32 flags)
: BView(rect, name, resizingMode, flags)
{
}
TypeEditorView(BRect rect, const char* name, uint32 resizingMode,
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 */