Implemented initial attribute support.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6712 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2004-02-24 07:21:11 +00:00
parent 32069a88fa
commit 595bb3098e
2 changed files with 177 additions and 5 deletions

View File

@ -10,6 +10,7 @@
#define BEOS_R5_COMPATIBLE #define BEOS_R5_COMPATIBLE
// for SetLimits() // for SetLimits()
#include <Application.h>
#include <Window.h> #include <Window.h>
#include <Clipboard.h> #include <Clipboard.h>
#include <Autolock.h> #include <Autolock.h>
@ -28,6 +29,8 @@
#include <NodeInfo.h> #include <NodeInfo.h>
#include <Node.h> #include <Node.h>
#include <NodeMonitor.h> #include <NodeMonitor.h>
#include <Volume.h>
#include <fs_attr.h>
#include <stdio.h> #include <stdio.h>
@ -116,6 +119,7 @@ class HeaderView : public BView, public BInvoker {
off_t fPosition; off_t fPosition;
off_t fLastPosition; off_t fLastPosition;
BTextControl *fTypeControl;
BTextControl *fPositionControl; BTextControl *fPositionControl;
BStringView *fPathView; BStringView *fPathView;
BStringView *fSizeView; BStringView *fSizeView;
@ -126,6 +130,18 @@ class HeaderView : public BView, public BInvoker {
}; };
class TypeMenuItem : public BMenuItem {
public:
TypeMenuItem(const char *name, const char *type, BMessage *message);
virtual void GetContentSize(float *_width, float *_height);
virtual void DrawContent();
private:
BString fType;
};
class UpdateLooper : public BLooper { class UpdateLooper : public BLooper {
public: public:
UpdateLooper(const char *name, DataEditor &editor, BMessenger messenger); UpdateLooper(const char *name, DataEditor &editor, BMessenger messenger);
@ -142,6 +158,23 @@ class UpdateLooper : public BLooper {
//---------------------- //----------------------
static void
get_type_string(char *buffer, size_t bufferSize, type_code type)
{
for (int32 i = 0; i < 4; i++) {
buffer[i] = type >> (24 - 8 * i);
if (buffer[i] < ' ' || buffer[i] == 0x7f) {
snprintf(buffer, bufferSize, "0x%04lx", type);
break;
} else if (i == 3)
buffer[4] = '\0';
}
}
// #pragma mark -
IconView::IconView(BRect rect, entry_ref *ref, bool isDevice) IconView::IconView(BRect rect, entry_ref *ref, bool isDevice)
: BView(rect, NULL, B_FOLLOW_NONE, B_WILL_DRAW), : BView(rect, NULL, B_FOLLOW_NONE, B_WILL_DRAW),
fRef(*ref), fRef(*ref),
@ -384,7 +417,35 @@ HeaderView::HeaderView(BRect frame, entry_ref *ref, DataEditor &editor)
fPathView->SetFont(&plainFont); fPathView->SetFont(&plainFont);
AddChild(fPathView); AddChild(fPathView);
stringView = new BStringView(BRect(50, 27, frame.right, 50), B_EMPTY_STRING, "Block: "); float top = 27;
if (editor.IsAttribute()) {
top += 3;
stringView = new BStringView(BRect(50, top, frame.right, top + 15), B_EMPTY_STRING, "Attribute Type: ");
stringView->SetFont(&boldFont);
stringView->ResizeToPreferred();
AddChild(stringView);
rect = stringView->Frame();
rect.left = rect.right;
rect.right += 100;
rect.OffsetBy(0, -2);
// BTextControl oddities
char buffer[16];
get_type_string(buffer, sizeof(buffer), editor.Type());
fTypeControl = new BTextControl(rect, B_EMPTY_STRING, NULL, buffer, new BMessage(kMsgPositionUpdate));
fTypeControl->SetDivider(0.0);
fTypeControl->SetFont(&plainFont);
fTypeControl->TextView()->SetFontAndColor(&plainFont);
fTypeControl->SetEnabled(false);
// ToDo: for now
AddChild(fTypeControl);
top += 24;
} else
fTypeControl = NULL;
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);
@ -441,8 +502,8 @@ HeaderView::HeaderView(BRect frame, entry_ref *ref, DataEditor &editor)
rect = Bounds(); rect = Bounds();
rect.InsetBy(3, 0); rect.InsetBy(3, 0);
rect.top = 48; rect.top = top + 21;
rect.bottom = 60; rect.bottom = rect.top + 12;
fPositionSlider = new PositionSlider(rect, "slider", new BMessage(kMsgSliderUpdate), fPositionSlider = new PositionSlider(rect, "slider", new BMessage(kMsgSliderUpdate),
editor.FileSize(), editor.BlockSize()); editor.FileSize(), editor.BlockSize());
fPositionSlider->SetModificationMessage(new BMessage(kMsgSliderUpdate)); fPositionSlider->SetModificationMessage(new BMessage(kMsgSliderUpdate));
@ -655,6 +716,45 @@ HeaderView::MessageReceived(BMessage *message)
// #pragma mark - // #pragma mark -
/** 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)
{
}
void
TypeMenuItem::GetContentSize(float *_width, float *_height)
{
BMenuItem::GetContentSize(_width, _height);
if (_width)
*_width += Menu()->StringWidth(fType.String());
}
void
TypeMenuItem::DrawContent()
{
// draw the label
BMenuItem::DrawContent();
// draw the type
BPoint point = Menu()->PenLocation();
point.x = Frame().right - 4 - Menu()->StringWidth(fType.String());
Menu()->DrawString(fType.String(), point);
}
// #pragma mark -
/** 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 the main window looper. * loading from the main window looper.
* It will listen to the offset changes of the editor, let * It will listen to the offset changes of the editor, let
@ -788,6 +888,59 @@ ProbeView::DetachedFromWindow()
} }
void
ProbeView::UpdateAttributesMenu(BMenu *menu)
{
// remove old contents
for (int32 i = menu->CountItems(); i-- > 0;) {
delete menu->RemoveItem(i);
}
// add new items (sorted)
BNode node(&fEditor.Ref());
if (node.InitCheck() == B_OK) {
char attribute[B_ATTR_NAME_LENGTH];
node.RewindAttrs();
while (node.GetNextAttrName(attribute) == B_OK) {
attr_info info;
if (node.GetAttrInfo(attribute, &info) != B_OK)
continue;
char type[16];
type[0] = '[';
get_type_string(type + 1, sizeof(type) - 2, info.type);
strcat(type, "]");
// find where to insert
int32 i;
for (i = 0; i < menu->CountItems(); i++) {
if (strcasecmp(menu->ItemAt(i)->Label(), attribute) > 0)
break;
}
BMessage *message = new BMessage(B_REFS_RECEIVED);
message->AddRef("refs", &fEditor.Ref());
message->AddString("attributes", attribute);
menu->AddItem(new TypeMenuItem(attribute, type, message), i);
}
}
if (menu->CountItems() == 0) {
// if there are no attributes, add an item to the menu
// that says so
BMenuItem *item = new BMenuItem("none", NULL);
item->SetEnabled(false);
menu->AddItem(item);
}
menu->SetTargetForItems(be_app);
}
void void
ProbeView::AddFileMenuItems(BMenu *menu, int32 index) ProbeView::AddFileMenuItems(BMenu *menu, int32 index)
{ {
@ -825,10 +978,12 @@ ProbeView::AttachedToWindow()
AddFileMenuItems(menu, 0); AddFileMenuItems(menu, 0);
menu->AddSeparatorItem(); menu->AddSeparatorItem();
menu->AddItem(new BMenuItem("Close", new BMessage(B_QUIT_REQUESTED), 'W', B_COMMAND_KEY)); menu->AddItem(new BMenuItem("Close", new BMessage(B_CLOSE_REQUESTED), 'W', B_COMMAND_KEY));
bar->AddItem(menu); bar->AddItem(menu);
} }
// "Edit" menu
BMenu *menu = new BMenu("Edit"); BMenu *menu = new BMenu("Edit");
BMenuItem *item; BMenuItem *item;
menu->AddItem(new BMenuItem("Undo", NULL, 'Z', B_COMMAND_KEY)); menu->AddItem(new BMenuItem("Undo", NULL, 'Z', B_COMMAND_KEY));
@ -846,6 +1001,8 @@ ProbeView::AttachedToWindow()
menu->AddItem(new BMenuItem("Find Again", NULL, 'G', B_COMMAND_KEY)); menu->AddItem(new BMenuItem("Find Again", NULL, 'G', B_COMMAND_KEY));
bar->AddItem(menu); bar->AddItem(menu);
// "Block" menu
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);
@ -870,9 +1027,23 @@ ProbeView::AttachedToWindow()
menu->AddItem(new BMenuItem(subMenu)); menu->AddItem(new BMenuItem(subMenu));
bar->AddItem(menu); bar->AddItem(menu);
// Number Base (hex/decimal) // "Attributes" menu (it's only visible if the underlying
// file system actually supports attributes)
BVolume volume;
if (!fEditor.IsAttribute()
&& fEditor.File().GetVolume(&volume) == B_OK
&& (volume.KnowsMime() || volume.KnowsAttr())) {
bar->AddItem(menu = new BMenu("Attributes"));
UpdateAttributesMenu(menu);
}
// "View" menu
menu = new BMenu("View"); menu = new BMenu("View");
// Number Base (hex/decimal)
subMenu = new BMenu("Base"); subMenu = new BMenu("Base");
message = new BMessage(kMsgBaseType); message = new BMessage(kMsgBaseType);
message->AddInt32("base", kDecimalBase); message->AddInt32("base", kDecimalBase);

View File

@ -37,6 +37,7 @@ class ProbeView : public BView {
void UpdateSizeLimits(); void UpdateSizeLimits();
private: private:
void UpdateAttributesMenu(BMenu *menu);
void CheckClipboard(); void CheckClipboard();
DataEditor fEditor; DataEditor fEditor;