xref: /haiku/src/apps/diskprobe/AttributeWindow.cpp (revision 7d7f16ac72b81c07046d33e9cb39dbe97888f619)
1d11ec082SAxel Dörfler /*
2d11ec082SAxel Dörfler ** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3d11ec082SAxel Dörfler ** Distributed under the terms of the OpenBeOS License.
4d11ec082SAxel Dörfler */
5d11ec082SAxel Dörfler 
6d11ec082SAxel Dörfler 
7d11ec082SAxel Dörfler #include "AttributeWindow.h"
8d11ec082SAxel Dörfler #include "ProbeView.h"
9d11ec082SAxel Dörfler 
10d11ec082SAxel Dörfler #include <MenuBar.h>
11d11ec082SAxel Dörfler #include <MenuItem.h>
12*7d7f16acSAxel Dörfler #include <TabView.h>
13*7d7f16acSAxel Dörfler #include <StringView.h>
14*7d7f16acSAxel Dörfler #include <TextControl.h>
15*7d7f16acSAxel Dörfler #include <TextView.h>
16*7d7f16acSAxel Dörfler #include <ScrollView.h>
17*7d7f16acSAxel Dörfler #include <MenuField.h>
18*7d7f16acSAxel Dörfler #include <PopUpMenu.h>
1936a79516SAxel Dörfler #include <Alert.h>
20*7d7f16acSAxel Dörfler #include <Autolock.h>
21*7d7f16acSAxel Dörfler #include <Mime.h>
22*7d7f16acSAxel Dörfler #include <fs_attr.h>
23d11ec082SAxel Dörfler 
24d11ec082SAxel Dörfler #include <stdio.h>
25d11ec082SAxel Dörfler 
26d11ec082SAxel Dörfler 
2736a79516SAxel Dörfler static const uint32 kMsgRemoveAttribute = 'rmat';
28*7d7f16acSAxel Dörfler static const uint32 kMsgValueChanged = 'vlch';
29*7d7f16acSAxel Dörfler static const uint32 kMimeTypeItem = 'miti';
30*7d7f16acSAxel Dörfler 
31*7d7f16acSAxel Dörfler 
32*7d7f16acSAxel Dörfler class EditorTabView : public BTabView {
33*7d7f16acSAxel Dörfler 	public:
34*7d7f16acSAxel Dörfler 		EditorTabView(BRect frame, const char *name, button_width width = B_WIDTH_AS_USUAL,
35*7d7f16acSAxel Dörfler 			uint32 resizingMode = B_FOLLOW_ALL, uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS);
36*7d7f16acSAxel Dörfler 
37*7d7f16acSAxel Dörfler 		virtual void FrameResized(float width, float height);
38*7d7f16acSAxel Dörfler 		virtual void Select(int32 tab);
39*7d7f16acSAxel Dörfler 
40*7d7f16acSAxel Dörfler 		void AddRawEditorTab(BView *view);
41*7d7f16acSAxel Dörfler 		void SetTypeEditorTab(BView *view);
42*7d7f16acSAxel Dörfler 
43*7d7f16acSAxel Dörfler 	private:
44*7d7f16acSAxel Dörfler 		BView		*fRawEditorView;
45*7d7f16acSAxel Dörfler 		BView		*fTypeEditorView;
46*7d7f16acSAxel Dörfler 		BStringView	*fNoEditorView;
47*7d7f16acSAxel Dörfler 		int32		fRawTab;
48*7d7f16acSAxel Dörfler };
49*7d7f16acSAxel Dörfler 
50*7d7f16acSAxel Dörfler 
51*7d7f16acSAxel Dörfler class StringEditor : public BView {
52*7d7f16acSAxel Dörfler 	public:
53*7d7f16acSAxel Dörfler 		StringEditor(BRect rect, DataEditor &editor);
54*7d7f16acSAxel Dörfler 
55*7d7f16acSAxel Dörfler 		virtual void AttachedToWindow();
56*7d7f16acSAxel Dörfler 		virtual void DetachedFromWindow();
57*7d7f16acSAxel Dörfler 		virtual void MessageReceived(BMessage *message);
58*7d7f16acSAxel Dörfler 
59*7d7f16acSAxel Dörfler 	private:
60*7d7f16acSAxel Dörfler 		DataEditor	&fEditor;
61*7d7f16acSAxel Dörfler 		BTextView	*fTextView;
62*7d7f16acSAxel Dörfler };
63*7d7f16acSAxel Dörfler 
64*7d7f16acSAxel Dörfler 
65*7d7f16acSAxel Dörfler class MimeTypeEditor : public BView {
66*7d7f16acSAxel Dörfler 	public:
67*7d7f16acSAxel Dörfler 		MimeTypeEditor(BRect rect, DataEditor &editor);
68*7d7f16acSAxel Dörfler 
69*7d7f16acSAxel Dörfler 		virtual void AttachedToWindow();
70*7d7f16acSAxel Dörfler 		virtual void DetachedFromWindow();
71*7d7f16acSAxel Dörfler 		virtual void MessageReceived(BMessage *message);
72*7d7f16acSAxel Dörfler 
73*7d7f16acSAxel Dörfler 		void UpdateText();
74*7d7f16acSAxel Dörfler 
75*7d7f16acSAxel Dörfler 	private:
76*7d7f16acSAxel Dörfler 		void AddMimeTypesToMenu();
77*7d7f16acSAxel Dörfler 
78*7d7f16acSAxel Dörfler 		DataEditor		&fEditor;
79*7d7f16acSAxel Dörfler 		BMenu			*fMimeTypeMenu;
80*7d7f16acSAxel Dörfler 		BTextControl	*fTextControl;
81*7d7f16acSAxel Dörfler 		BString			fPreviousText;
82*7d7f16acSAxel Dörfler };
83*7d7f16acSAxel Dörfler 
84*7d7f16acSAxel Dörfler 
85*7d7f16acSAxel Dörfler class NumberEditor : public BView {
86*7d7f16acSAxel Dörfler 	public:
87*7d7f16acSAxel Dörfler 		NumberEditor(BRect rect, DataEditor &editor);
88*7d7f16acSAxel Dörfler 
89*7d7f16acSAxel Dörfler 		virtual void AttachedToWindow();
90*7d7f16acSAxel Dörfler 		virtual void DetachedFromWindow();
91*7d7f16acSAxel Dörfler 		virtual void MessageReceived(BMessage *message);
92*7d7f16acSAxel Dörfler 
93*7d7f16acSAxel Dörfler 		void UpdateText();
94*7d7f16acSAxel Dörfler 		void UpdateNumber();
95*7d7f16acSAxel Dörfler 
96*7d7f16acSAxel Dörfler 	private:
97*7d7f16acSAxel Dörfler 		const char *TypeLabel();
98*7d7f16acSAxel Dörfler 		status_t Format(char *buffer);
99*7d7f16acSAxel Dörfler 		size_t Size();
100*7d7f16acSAxel Dörfler 
101*7d7f16acSAxel Dörfler 		DataEditor		&fEditor;
102*7d7f16acSAxel Dörfler 		BTextControl	*fTextControl;
103*7d7f16acSAxel Dörfler 		BString			fPreviousText;
104*7d7f16acSAxel Dörfler };
105*7d7f16acSAxel Dörfler 
106*7d7f16acSAxel Dörfler 
107*7d7f16acSAxel Dörfler class BooleanEditor : public BView {
108*7d7f16acSAxel Dörfler 	public:
109*7d7f16acSAxel Dörfler 		BooleanEditor(BRect rect, DataEditor &editor);
110*7d7f16acSAxel Dörfler 
111*7d7f16acSAxel Dörfler 		virtual void AttachedToWindow();
112*7d7f16acSAxel Dörfler 		virtual void DetachedFromWindow();
113*7d7f16acSAxel Dörfler 		virtual void MessageReceived(BMessage *message);
114*7d7f16acSAxel Dörfler 
115*7d7f16acSAxel Dörfler 		void UpdateMenuField();
116*7d7f16acSAxel Dörfler 
117*7d7f16acSAxel Dörfler 	private:
118*7d7f16acSAxel Dörfler 		DataEditor	&fEditor;
119*7d7f16acSAxel Dörfler 		BMenuItem	*fFalseMenuItem;
120*7d7f16acSAxel Dörfler 		BMenuItem	*fTrueMenuItem;
121*7d7f16acSAxel Dörfler };
122*7d7f16acSAxel Dörfler 
123*7d7f16acSAxel Dörfler 
124*7d7f16acSAxel Dörfler //-----------------
125*7d7f16acSAxel Dörfler 
126*7d7f16acSAxel Dörfler 
127*7d7f16acSAxel Dörfler static BView *
128*7d7f16acSAxel Dörfler GetTypeEditorFor(BRect rect, DataEditor &editor)
129*7d7f16acSAxel Dörfler {
130*7d7f16acSAxel Dörfler 	switch (editor.Type()) {
131*7d7f16acSAxel Dörfler 		case B_STRING_TYPE:
132*7d7f16acSAxel Dörfler 			return new StringEditor(rect, editor);
133*7d7f16acSAxel Dörfler 		case B_MIME_STRING_TYPE:
134*7d7f16acSAxel Dörfler 			return new MimeTypeEditor(rect, editor);
135*7d7f16acSAxel Dörfler 		case B_BOOL_TYPE:
136*7d7f16acSAxel Dörfler 			return new BooleanEditor(rect, editor);
137*7d7f16acSAxel Dörfler 		case B_INT8_TYPE:
138*7d7f16acSAxel Dörfler 		case B_UINT8_TYPE:
139*7d7f16acSAxel Dörfler 		case B_INT16_TYPE:
140*7d7f16acSAxel Dörfler 		case B_UINT16_TYPE:
141*7d7f16acSAxel Dörfler 		case B_INT32_TYPE:
142*7d7f16acSAxel Dörfler 		case B_UINT32_TYPE:
143*7d7f16acSAxel Dörfler 		case B_INT64_TYPE:
144*7d7f16acSAxel Dörfler 		case B_UINT64_TYPE:
145*7d7f16acSAxel Dörfler 		case B_FLOAT_TYPE:
146*7d7f16acSAxel Dörfler 		case B_DOUBLE_TYPE:
147*7d7f16acSAxel Dörfler 		case B_SSIZE_T_TYPE:
148*7d7f16acSAxel Dörfler 		case B_SIZE_T_TYPE:
149*7d7f16acSAxel Dörfler 		case B_OFF_T_TYPE:
150*7d7f16acSAxel Dörfler 		case B_POINTER_TYPE:
151*7d7f16acSAxel Dörfler 			return new NumberEditor(rect, editor);
152*7d7f16acSAxel Dörfler 	}
153*7d7f16acSAxel Dörfler 
154*7d7f16acSAxel Dörfler 	return NULL;
155*7d7f16acSAxel Dörfler }
156*7d7f16acSAxel Dörfler 
157*7d7f16acSAxel Dörfler 
158*7d7f16acSAxel Dörfler //	#pragma mark -
159*7d7f16acSAxel Dörfler 
160*7d7f16acSAxel Dörfler 
161*7d7f16acSAxel Dörfler EditorTabView::EditorTabView(BRect frame, const char *name, button_width width,
162*7d7f16acSAxel Dörfler 	uint32 resizingMode, uint32 flags)
163*7d7f16acSAxel Dörfler 	: BTabView(frame, name, width, resizingMode, flags),
164*7d7f16acSAxel Dörfler 	fRawEditorView(NULL),
165*7d7f16acSAxel Dörfler 	fRawTab(-1)
166*7d7f16acSAxel Dörfler {
167*7d7f16acSAxel Dörfler 	ContainerView()->MoveBy(-ContainerView()->Frame().left,
168*7d7f16acSAxel Dörfler 						TabHeight() + 1 - ContainerView()->Frame().top);
169*7d7f16acSAxel Dörfler 	fNoEditorView = new BStringView(ContainerView()->Bounds(), "Type Editor",
170*7d7f16acSAxel Dörfler 							"No type editor available", B_FOLLOW_NONE);
171*7d7f16acSAxel Dörfler 	fNoEditorView->ResizeToPreferred();
172*7d7f16acSAxel Dörfler 	fNoEditorView->SetAlignment(B_ALIGN_CENTER);
173*7d7f16acSAxel Dörfler 	fTypeEditorView = fNoEditorView;
174*7d7f16acSAxel Dörfler 
175*7d7f16acSAxel Dörfler 	FrameResized(0, 0);
176*7d7f16acSAxel Dörfler 
177*7d7f16acSAxel Dörfler 	SetTypeEditorTab(NULL);
178*7d7f16acSAxel Dörfler }
179*7d7f16acSAxel Dörfler 
180*7d7f16acSAxel Dörfler 
181*7d7f16acSAxel Dörfler void
182*7d7f16acSAxel Dörfler EditorTabView::FrameResized(float width, float height)
183*7d7f16acSAxel Dörfler {
184*7d7f16acSAxel Dörfler 	BRect rect = Bounds();
185*7d7f16acSAxel Dörfler 	rect.top = ContainerView()->Frame().top;
186*7d7f16acSAxel Dörfler 
187*7d7f16acSAxel Dörfler 	ContainerView()->ResizeTo(rect.Width(), rect.Height());
188*7d7f16acSAxel Dörfler 
189*7d7f16acSAxel Dörfler 	BView *view = fTypeEditorView;
190*7d7f16acSAxel Dörfler 	if (view == NULL)
191*7d7f16acSAxel Dörfler 		view = fNoEditorView;
192*7d7f16acSAxel Dörfler 
193*7d7f16acSAxel Dörfler 	BPoint point = view->Frame().LeftTop();
194*7d7f16acSAxel Dörfler 	if ((view->ResizingMode() & B_FOLLOW_RIGHT) == 0)
195*7d7f16acSAxel Dörfler 		point.x = (rect.Width() - view->Bounds().Width()) / 2;
196*7d7f16acSAxel Dörfler 	if ((view->ResizingMode() & B_FOLLOW_BOTTOM) == 0)
197*7d7f16acSAxel Dörfler 		point.y = (rect.Height() - view->Bounds().Height()) / 2;
198*7d7f16acSAxel Dörfler 
199*7d7f16acSAxel Dörfler 	view->MoveTo(point);
200*7d7f16acSAxel Dörfler }
201*7d7f16acSAxel Dörfler 
202*7d7f16acSAxel Dörfler 
203*7d7f16acSAxel Dörfler void
204*7d7f16acSAxel Dörfler EditorTabView::Select(int32 tab)
205*7d7f16acSAxel Dörfler {
206*7d7f16acSAxel Dörfler 	if (tab != fRawTab && fRawEditorView != NULL && !fRawEditorView->IsHidden(fRawEditorView))
207*7d7f16acSAxel Dörfler 		fRawEditorView->Hide();
208*7d7f16acSAxel Dörfler 
209*7d7f16acSAxel Dörfler 	BTabView::Select(tab);
210*7d7f16acSAxel Dörfler 
211*7d7f16acSAxel Dörfler 	BView *view;
212*7d7f16acSAxel Dörfler 	if (tab == fRawTab && fRawEditorView != NULL) {
213*7d7f16acSAxel Dörfler 		if (fRawEditorView->IsHidden(fRawEditorView))
214*7d7f16acSAxel Dörfler 			fRawEditorView->Show();
215*7d7f16acSAxel Dörfler 		view = fRawEditorView;
216*7d7f16acSAxel Dörfler 	} else
217*7d7f16acSAxel Dörfler 		view = ViewForTab(Selection());
218*7d7f16acSAxel Dörfler 
219*7d7f16acSAxel Dörfler 	if (view != NULL && (view->ResizingMode() & (B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM)) != 0) {
220*7d7f16acSAxel Dörfler 		BRect rect = ContainerView()->Bounds();
221*7d7f16acSAxel Dörfler 
222*7d7f16acSAxel Dörfler 		BRect frame = view->Frame();
223*7d7f16acSAxel Dörfler 		rect.left = frame.left;
224*7d7f16acSAxel Dörfler 		rect.top = frame.top;
225*7d7f16acSAxel Dörfler 		if ((view->ResizingMode() & B_FOLLOW_RIGHT) == 0)
226*7d7f16acSAxel Dörfler 			rect.right = frame.right;
227*7d7f16acSAxel Dörfler 		if ((view->ResizingMode() & B_FOLLOW_BOTTOM) == 0)
228*7d7f16acSAxel Dörfler 			rect.bottom = frame.bottom;
229*7d7f16acSAxel Dörfler 
230*7d7f16acSAxel Dörfler 		view->ResizeTo(rect.Width(), rect.Height());
231*7d7f16acSAxel Dörfler 	}
232*7d7f16acSAxel Dörfler }
233*7d7f16acSAxel Dörfler 
234*7d7f16acSAxel Dörfler 
235*7d7f16acSAxel Dörfler void
236*7d7f16acSAxel Dörfler EditorTabView::AddRawEditorTab(BView *view)
237*7d7f16acSAxel Dörfler {
238*7d7f16acSAxel Dörfler 	fRawEditorView = view;
239*7d7f16acSAxel Dörfler 	if (view != NULL)
240*7d7f16acSAxel Dörfler 		ContainerView()->AddChild(view);
241*7d7f16acSAxel Dörfler 
242*7d7f16acSAxel Dörfler 	fRawTab = CountTabs();
243*7d7f16acSAxel Dörfler 
244*7d7f16acSAxel Dörfler 	view = new BView(BRect(0, 0, 5, 5), "Raw Editor", B_FOLLOW_NONE, 0);
245*7d7f16acSAxel Dörfler 	view->SetViewColor(ViewColor());
246*7d7f16acSAxel Dörfler 	AddTab(view);
247*7d7f16acSAxel Dörfler }
248*7d7f16acSAxel Dörfler 
249*7d7f16acSAxel Dörfler 
250*7d7f16acSAxel Dörfler void
251*7d7f16acSAxel Dörfler EditorTabView::SetTypeEditorTab(BView *view)
252*7d7f16acSAxel Dörfler {
253*7d7f16acSAxel Dörfler 	if (fTypeEditorView == view)
254*7d7f16acSAxel Dörfler 		return;
255*7d7f16acSAxel Dörfler 
256*7d7f16acSAxel Dörfler 	BTab *tab = TabAt(0);
257*7d7f16acSAxel Dörfler 	if (tab != NULL)
258*7d7f16acSAxel Dörfler 		tab->SetView(NULL);
259*7d7f16acSAxel Dörfler 
260*7d7f16acSAxel Dörfler 	fTypeEditorView = view;
261*7d7f16acSAxel Dörfler 
262*7d7f16acSAxel Dörfler 	if (view == NULL)
263*7d7f16acSAxel Dörfler 		view = fNoEditorView;
264*7d7f16acSAxel Dörfler 
265*7d7f16acSAxel Dörfler 	if (CountTabs() == 0)
266*7d7f16acSAxel Dörfler 		AddTab(view);
267*7d7f16acSAxel Dörfler 	else
268*7d7f16acSAxel Dörfler 		tab->SetView(view);
269*7d7f16acSAxel Dörfler 
270*7d7f16acSAxel Dörfler 	FrameResized(0, 0);
271*7d7f16acSAxel Dörfler 	Select(0);
272*7d7f16acSAxel Dörfler }
273*7d7f16acSAxel Dörfler 
274*7d7f16acSAxel Dörfler 
275*7d7f16acSAxel Dörfler //	#pragma mark -
276*7d7f16acSAxel Dörfler 
277*7d7f16acSAxel Dörfler 
278*7d7f16acSAxel Dörfler StringEditor::StringEditor(BRect rect, DataEditor &editor)
279*7d7f16acSAxel Dörfler 	: BView(rect, "String Editor", B_FOLLOW_ALL, 0),
280*7d7f16acSAxel Dörfler 	fEditor(editor)
281*7d7f16acSAxel Dörfler {
282*7d7f16acSAxel Dörfler 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
283*7d7f16acSAxel Dörfler 
284*7d7f16acSAxel Dörfler 	BStringView *stringView = new BStringView(BRect(5, 5, rect.right, 20),
285*7d7f16acSAxel Dörfler 										B_EMPTY_STRING, "Contents:");
286*7d7f16acSAxel Dörfler 	stringView->ResizeToPreferred();
287*7d7f16acSAxel Dörfler 	AddChild(stringView);
288*7d7f16acSAxel Dörfler 
289*7d7f16acSAxel Dörfler 	rect = Bounds();
290*7d7f16acSAxel Dörfler 	rect.top = stringView->Frame().bottom + 5;
291*7d7f16acSAxel Dörfler 	rect.right -= B_V_SCROLL_BAR_WIDTH;
292*7d7f16acSAxel Dörfler 	rect.bottom -= B_H_SCROLL_BAR_HEIGHT;
293*7d7f16acSAxel Dörfler 
294*7d7f16acSAxel Dörfler 	fTextView = new BTextView(rect, B_EMPTY_STRING, rect.OffsetToCopy(B_ORIGIN).InsetByCopy(5, 5),
295*7d7f16acSAxel Dörfler 						B_FOLLOW_ALL, B_WILL_DRAW);
296*7d7f16acSAxel Dörfler 
297*7d7f16acSAxel Dörfler 	if (fEditor.Lock()) {
298*7d7f16acSAxel Dörfler 		size_t viewSize = fEditor.ViewSize();
299*7d7f16acSAxel Dörfler 		// that may need some more memory...
300*7d7f16acSAxel Dörfler 		if (viewSize < fEditor.FileSize())
301*7d7f16acSAxel Dörfler 			fEditor.SetViewSize(fEditor.FileSize());
302*7d7f16acSAxel Dörfler 
303*7d7f16acSAxel Dörfler 		const char *buffer;
304*7d7f16acSAxel Dörfler 		if (fEditor.GetViewBuffer((const uint8 **)&buffer) == B_OK)
305*7d7f16acSAxel Dörfler 			fTextView->SetText(buffer);
306*7d7f16acSAxel Dörfler 
307*7d7f16acSAxel Dörfler 		// restore old view size
308*7d7f16acSAxel Dörfler 		fEditor.SetViewSize(viewSize);
309*7d7f16acSAxel Dörfler 
310*7d7f16acSAxel Dörfler 		fEditor.Unlock();
311*7d7f16acSAxel Dörfler 	}
312*7d7f16acSAxel Dörfler #if 0
313*7d7f16acSAxel Dörfler 	char *data = (char *)malloc(info.size);
314*7d7f16acSAxel Dörfler 	if (data != NULL) {
315*7d7f16acSAxel Dörfler 		if (fNode.ReadAttr(attribute, info.type, 0LL, data, info.size) >= B_OK)
316*7d7f16acSAxel Dörfler 			fTextView->SetText(data);
317*7d7f16acSAxel Dörfler 
318*7d7f16acSAxel Dörfler 		free(data);
319*7d7f16acSAxel Dörfler 	}
320*7d7f16acSAxel Dörfler #endif
321*7d7f16acSAxel Dörfler 
322*7d7f16acSAxel Dörfler 	BScrollView *scrollView = new BScrollView("scroller", fTextView, B_FOLLOW_ALL, B_WILL_DRAW, true, true);
323*7d7f16acSAxel Dörfler 	AddChild(scrollView);
324*7d7f16acSAxel Dörfler }
325*7d7f16acSAxel Dörfler 
326*7d7f16acSAxel Dörfler 
327*7d7f16acSAxel Dörfler void
328*7d7f16acSAxel Dörfler StringEditor::AttachedToWindow()
329*7d7f16acSAxel Dörfler {
330*7d7f16acSAxel Dörfler 	fEditor.StartWatching(this);
331*7d7f16acSAxel Dörfler }
332*7d7f16acSAxel Dörfler 
333*7d7f16acSAxel Dörfler 
334*7d7f16acSAxel Dörfler void
335*7d7f16acSAxel Dörfler StringEditor::DetachedFromWindow()
336*7d7f16acSAxel Dörfler {
337*7d7f16acSAxel Dörfler 	fEditor.StopWatching(this);
338*7d7f16acSAxel Dörfler }
339*7d7f16acSAxel Dörfler 
340*7d7f16acSAxel Dörfler 
341*7d7f16acSAxel Dörfler void
342*7d7f16acSAxel Dörfler StringEditor::MessageReceived(BMessage *message)
343*7d7f16acSAxel Dörfler {
344*7d7f16acSAxel Dörfler 	BView::MessageReceived(message);
345*7d7f16acSAxel Dörfler }
346*7d7f16acSAxel Dörfler 
347*7d7f16acSAxel Dörfler 
348*7d7f16acSAxel Dörfler //	#pragma mark -
349*7d7f16acSAxel Dörfler 
350*7d7f16acSAxel Dörfler 
351*7d7f16acSAxel Dörfler MimeTypeEditor::MimeTypeEditor(BRect rect, DataEditor &editor)
352*7d7f16acSAxel Dörfler 	: BView(rect, "MIME Type Editor", B_FOLLOW_NONE, 0),
353*7d7f16acSAxel Dörfler 	fEditor(editor)
354*7d7f16acSAxel Dörfler {
355*7d7f16acSAxel Dörfler 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
356*7d7f16acSAxel Dörfler 
357*7d7f16acSAxel Dörfler 	rect.right -= 100;
358*7d7f16acSAxel Dörfler 	fTextControl = new BTextControl(rect.InsetByCopy(5, 5), B_EMPTY_STRING, "MIME Type:", NULL,
359*7d7f16acSAxel Dörfler 							new BMessage(kMsgValueChanged), B_FOLLOW_ALL);
360*7d7f16acSAxel Dörfler 	fTextControl->SetDivider(StringWidth(fTextControl->Label()) + 8);
361*7d7f16acSAxel Dörfler 
362*7d7f16acSAxel Dörfler 	fMimeTypeMenu = new BMenu(B_EMPTY_STRING);
363*7d7f16acSAxel Dörfler 	rect = fTextControl->Frame();
364*7d7f16acSAxel Dörfler 	rect.left = rect.right + 5;
365*7d7f16acSAxel Dörfler 	rect.right = Bounds().right;
366*7d7f16acSAxel Dörfler 	//rect.top++;
367*7d7f16acSAxel Dörfler 	BMenuField *menuField = new BMenuField(rect, NULL, NULL, fMimeTypeMenu);
368*7d7f16acSAxel Dörfler 	menuField->SetDivider(0);
369*7d7f16acSAxel Dörfler 	menuField->ResizeToPreferred();
370*7d7f16acSAxel Dörfler 	AddChild(menuField);
371*7d7f16acSAxel Dörfler 
372*7d7f16acSAxel Dörfler 	ResizeTo(fTextControl->Bounds().Width() + menuField->Bounds().Width() + 10,
373*7d7f16acSAxel Dörfler 		menuField->Bounds().Height() + 10);
374*7d7f16acSAxel Dörfler 
375*7d7f16acSAxel Dörfler 	AddChild(fTextControl);
376*7d7f16acSAxel Dörfler }
377*7d7f16acSAxel Dörfler 
378*7d7f16acSAxel Dörfler 
379*7d7f16acSAxel Dörfler void
380*7d7f16acSAxel Dörfler MimeTypeEditor::UpdateText()
381*7d7f16acSAxel Dörfler {
382*7d7f16acSAxel Dörfler 	if (fEditor.Lock()) {
383*7d7f16acSAxel Dörfler 		const char *mimeType;
384*7d7f16acSAxel Dörfler 		if (fEditor.GetViewBuffer((const uint8 **)&mimeType) == B_OK) {
385*7d7f16acSAxel Dörfler 			fTextControl->SetText(mimeType);
386*7d7f16acSAxel Dörfler 			fPreviousText.SetTo(mimeType);
387*7d7f16acSAxel Dörfler 		}
388*7d7f16acSAxel Dörfler 
389*7d7f16acSAxel Dörfler 		fEditor.Unlock();
390*7d7f16acSAxel Dörfler 	}
391*7d7f16acSAxel Dörfler }
392*7d7f16acSAxel Dörfler 
393*7d7f16acSAxel Dörfler 
394*7d7f16acSAxel Dörfler void
395*7d7f16acSAxel Dörfler MimeTypeEditor::AttachedToWindow()
396*7d7f16acSAxel Dörfler {
397*7d7f16acSAxel Dörfler 	fTextControl->SetTarget(this);
398*7d7f16acSAxel Dörfler 	fEditor.StartWatching(this);
399*7d7f16acSAxel Dörfler 
400*7d7f16acSAxel Dörfler 	AddMimeTypesToMenu();
401*7d7f16acSAxel Dörfler 	UpdateText();
402*7d7f16acSAxel Dörfler }
403*7d7f16acSAxel Dörfler 
404*7d7f16acSAxel Dörfler 
405*7d7f16acSAxel Dörfler void
406*7d7f16acSAxel Dörfler MimeTypeEditor::DetachedFromWindow()
407*7d7f16acSAxel Dörfler {
408*7d7f16acSAxel Dörfler 	fEditor.StopWatching(this);
409*7d7f16acSAxel Dörfler 
410*7d7f16acSAxel Dörfler 	if (fPreviousText != fTextControl->Text()) {
411*7d7f16acSAxel Dörfler 		BAutolock locker(fEditor);
412*7d7f16acSAxel Dörfler 		fEditor.Replace(0, (const uint8 *)fTextControl->Text(),
413*7d7f16acSAxel Dörfler 			strlen(fTextControl->Text()) + 1);
414*7d7f16acSAxel Dörfler 	}
415*7d7f16acSAxel Dörfler }
416*7d7f16acSAxel Dörfler 
417*7d7f16acSAxel Dörfler 
418*7d7f16acSAxel Dörfler void
419*7d7f16acSAxel Dörfler MimeTypeEditor::MessageReceived(BMessage *message)
420*7d7f16acSAxel Dörfler {
421*7d7f16acSAxel Dörfler 	switch (message->what) {
422*7d7f16acSAxel Dörfler 		case kMsgValueChanged:
423*7d7f16acSAxel Dörfler 		{
424*7d7f16acSAxel Dörfler 			BAutolock locker(fEditor);
425*7d7f16acSAxel Dörfler 			fEditor.Replace(0, (const uint8 *)fTextControl->Text(),
426*7d7f16acSAxel Dörfler 				strlen(fTextControl->Text()) + 1);
427*7d7f16acSAxel Dörfler 			break;
428*7d7f16acSAxel Dörfler 		}
429*7d7f16acSAxel Dörfler 
430*7d7f16acSAxel Dörfler 		case kMsgDataEditorUpdate:
431*7d7f16acSAxel Dörfler 			UpdateText();
432*7d7f16acSAxel Dörfler 			break;
433*7d7f16acSAxel Dörfler 
434*7d7f16acSAxel Dörfler 		default:
435*7d7f16acSAxel Dörfler 			BView::MessageReceived(message);
436*7d7f16acSAxel Dörfler 	}
437*7d7f16acSAxel Dörfler }
438*7d7f16acSAxel Dörfler 
439*7d7f16acSAxel Dörfler 
440*7d7f16acSAxel Dörfler void
441*7d7f16acSAxel Dörfler MimeTypeEditor::AddMimeTypesToMenu()
442*7d7f16acSAxel Dörfler {
443*7d7f16acSAxel Dörfler 	// add MIME type tree list
444*7d7f16acSAxel Dörfler 
445*7d7f16acSAxel Dörfler 	BMessage types;
446*7d7f16acSAxel Dörfler 	if (BMimeType::GetInstalledSupertypes(&types) == B_OK) {
447*7d7f16acSAxel Dörfler 		const char *superType;
448*7d7f16acSAxel Dörfler 		int32 index = 0;
449*7d7f16acSAxel Dörfler 
450*7d7f16acSAxel Dörfler 		while (types.FindString("super_types", index++, &superType) == B_OK) {
451*7d7f16acSAxel Dörfler 			BMenu *superMenu = new BMenu(superType);
452*7d7f16acSAxel Dörfler 
453*7d7f16acSAxel Dörfler 			// ToDo: there are way too many "application" types... (need to lay off to another thread)
454*7d7f16acSAxel Dörfler 			if (!strcmp(superType, "application"))
455*7d7f16acSAxel Dörfler 				continue;
456*7d7f16acSAxel Dörfler 
457*7d7f16acSAxel Dörfler 			BMessage subTypes;
458*7d7f16acSAxel Dörfler 			if (BMimeType::GetInstalledTypes(superType, &subTypes) == B_OK) {
459*7d7f16acSAxel Dörfler 				const char *type;
460*7d7f16acSAxel Dörfler 				int32 subIndex = 0;
461*7d7f16acSAxel Dörfler 				while (subTypes.FindString("types", subIndex++, &type) == B_OK) {
462*7d7f16acSAxel Dörfler 					BMessage *message = new BMessage(kMimeTypeItem);
463*7d7f16acSAxel Dörfler 					message->AddString("super_type", superType);
464*7d7f16acSAxel Dörfler 					message->AddString("mime_type", type);
465*7d7f16acSAxel Dörfler 					superMenu->AddItem(new BMenuItem(strchr(type, '/') + 1, message));
466*7d7f16acSAxel Dörfler 				}
467*7d7f16acSAxel Dörfler 		 	}
468*7d7f16acSAxel Dörfler 		 	if (superMenu->CountItems() != 0) {
469*7d7f16acSAxel Dörfler 				fMimeTypeMenu->AddItem(new BMenuItem(superMenu));
470*7d7f16acSAxel Dörfler 
471*7d7f16acSAxel Dörfler 				// the MimeTypeMenu's font is not correct at this time
472*7d7f16acSAxel Dörfler 				superMenu->SetFont(be_plain_font);
473*7d7f16acSAxel Dörfler 				superMenu->SetTargetForItems(this);
474*7d7f16acSAxel Dörfler 			} else
475*7d7f16acSAxel Dörfler 				delete superMenu;
476*7d7f16acSAxel Dörfler 
477*7d7f16acSAxel Dörfler 		}
478*7d7f16acSAxel Dörfler 	}
479*7d7f16acSAxel Dörfler }
480*7d7f16acSAxel Dörfler 
481*7d7f16acSAxel Dörfler 
482*7d7f16acSAxel Dörfler //	#pragma mark -
483*7d7f16acSAxel Dörfler 
484*7d7f16acSAxel Dörfler 
485*7d7f16acSAxel Dörfler NumberEditor::NumberEditor(BRect rect, DataEditor &editor)
486*7d7f16acSAxel Dörfler 	: BView(rect, "Number Editor", B_FOLLOW_LEFT_RIGHT, 0),
487*7d7f16acSAxel Dörfler 	fEditor(editor)
488*7d7f16acSAxel Dörfler {
489*7d7f16acSAxel Dörfler 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
490*7d7f16acSAxel Dörfler 
491*7d7f16acSAxel Dörfler 	fTextControl = new BTextControl(rect.InsetByCopy(5, 5), B_EMPTY_STRING, TypeLabel(), NULL,
492*7d7f16acSAxel Dörfler 							new BMessage(kMsgValueChanged), B_FOLLOW_ALL);
493*7d7f16acSAxel Dörfler 	fTextControl->SetDivider(StringWidth(fTextControl->Label()) + 8);
494*7d7f16acSAxel Dörfler 	fTextControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_RIGHT);
495*7d7f16acSAxel Dörfler 	ResizeTo(rect.Width(), 30);
496*7d7f16acSAxel Dörfler 
497*7d7f16acSAxel Dörfler 	AddChild(fTextControl);
498*7d7f16acSAxel Dörfler }
499*7d7f16acSAxel Dörfler 
500*7d7f16acSAxel Dörfler 
501*7d7f16acSAxel Dörfler void
502*7d7f16acSAxel Dörfler NumberEditor::UpdateText()
503*7d7f16acSAxel Dörfler {
504*7d7f16acSAxel Dörfler 	if (fEditor.Lock()) {
505*7d7f16acSAxel Dörfler 		const char *number;
506*7d7f16acSAxel Dörfler 		if (fEditor.GetViewBuffer((const uint8 **)&number) == B_OK) {
507*7d7f16acSAxel Dörfler 			char buffer[64];
508*7d7f16acSAxel Dörfler 			char format[16];
509*7d7f16acSAxel Dörfler 			switch (fEditor.Type()) {
510*7d7f16acSAxel Dörfler 				case B_FLOAT_TYPE:
511*7d7f16acSAxel Dörfler 				{
512*7d7f16acSAxel Dörfler 					float value = *(float *)number;
513*7d7f16acSAxel Dörfler 					snprintf(buffer, sizeof(buffer), "%g", value);
514*7d7f16acSAxel Dörfler 					break;
515*7d7f16acSAxel Dörfler 				}
516*7d7f16acSAxel Dörfler 				case B_DOUBLE_TYPE:
517*7d7f16acSAxel Dörfler 				{
518*7d7f16acSAxel Dörfler 					double value = *(double *)number;
519*7d7f16acSAxel Dörfler 					snprintf(buffer, sizeof(buffer), "%g", value);
520*7d7f16acSAxel Dörfler 					break;
521*7d7f16acSAxel Dörfler 				}
522*7d7f16acSAxel Dörfler 				case B_SSIZE_T_TYPE:
523*7d7f16acSAxel Dörfler 				case B_INT8_TYPE:
524*7d7f16acSAxel Dörfler 				case B_INT16_TYPE:
525*7d7f16acSAxel Dörfler 				case B_INT32_TYPE:
526*7d7f16acSAxel Dörfler 				case B_INT64_TYPE:
527*7d7f16acSAxel Dörfler 				case B_OFF_T_TYPE:
528*7d7f16acSAxel Dörfler 				{
529*7d7f16acSAxel Dörfler 					Format(format);
530*7d7f16acSAxel Dörfler 					switch (Size()) {
531*7d7f16acSAxel Dörfler 						case 1:
532*7d7f16acSAxel Dörfler 						{
533*7d7f16acSAxel Dörfler 							int8 value = *(int8 *)number;
534*7d7f16acSAxel Dörfler 							snprintf(buffer, sizeof(buffer), format, value);
535*7d7f16acSAxel Dörfler 							break;
536*7d7f16acSAxel Dörfler 						}
537*7d7f16acSAxel Dörfler 						case 2:
538*7d7f16acSAxel Dörfler 						{
539*7d7f16acSAxel Dörfler 							int16 value = *(int16 *)number;
540*7d7f16acSAxel Dörfler 							snprintf(buffer, sizeof(buffer), format, value);
541*7d7f16acSAxel Dörfler 							break;
542*7d7f16acSAxel Dörfler 						}
543*7d7f16acSAxel Dörfler 						case 4:
544*7d7f16acSAxel Dörfler 						{
545*7d7f16acSAxel Dörfler 							int32 value = *(int32 *)number;
546*7d7f16acSAxel Dörfler 							snprintf(buffer, sizeof(buffer), format, value);
547*7d7f16acSAxel Dörfler 							break;
548*7d7f16acSAxel Dörfler 						}
549*7d7f16acSAxel Dörfler 						case 8:
550*7d7f16acSAxel Dörfler 						{
551*7d7f16acSAxel Dörfler 							int64 value = *(int64 *)number;
552*7d7f16acSAxel Dörfler 							snprintf(buffer, sizeof(buffer), format, value);
553*7d7f16acSAxel Dörfler 							break;
554*7d7f16acSAxel Dörfler 						}
555*7d7f16acSAxel Dörfler 					}
556*7d7f16acSAxel Dörfler 					break;
557*7d7f16acSAxel Dörfler 				}
558*7d7f16acSAxel Dörfler 				default:
559*7d7f16acSAxel Dörfler 				{
560*7d7f16acSAxel Dörfler 					Format(format);
561*7d7f16acSAxel Dörfler 					switch (Size()) {
562*7d7f16acSAxel Dörfler 						case 1:
563*7d7f16acSAxel Dörfler 						{
564*7d7f16acSAxel Dörfler 							uint8 value = *(uint8 *)number;
565*7d7f16acSAxel Dörfler 							snprintf(buffer, sizeof(buffer), format, value);
566*7d7f16acSAxel Dörfler 							break;
567*7d7f16acSAxel Dörfler 						}
568*7d7f16acSAxel Dörfler 						case 2:
569*7d7f16acSAxel Dörfler 						{
570*7d7f16acSAxel Dörfler 							uint16 value = *(uint16 *)number;
571*7d7f16acSAxel Dörfler 							snprintf(buffer, sizeof(buffer), format, value);
572*7d7f16acSAxel Dörfler 							break;
573*7d7f16acSAxel Dörfler 						}
574*7d7f16acSAxel Dörfler 						case 4:
575*7d7f16acSAxel Dörfler 						{
576*7d7f16acSAxel Dörfler 							uint32 value = *(uint32 *)number;
577*7d7f16acSAxel Dörfler 							snprintf(buffer, sizeof(buffer), format, value);
578*7d7f16acSAxel Dörfler 							break;
579*7d7f16acSAxel Dörfler 						}
580*7d7f16acSAxel Dörfler 						case 8:
581*7d7f16acSAxel Dörfler 						{
582*7d7f16acSAxel Dörfler 							uint64 value = *(uint64 *)number;
583*7d7f16acSAxel Dörfler 							snprintf(buffer, sizeof(buffer), format, value);
584*7d7f16acSAxel Dörfler 							break;
585*7d7f16acSAxel Dörfler 						}
586*7d7f16acSAxel Dörfler 					}
587*7d7f16acSAxel Dörfler 					break;
588*7d7f16acSAxel Dörfler 				}
589*7d7f16acSAxel Dörfler 			}
590*7d7f16acSAxel Dörfler 			fTextControl->SetText(buffer);
591*7d7f16acSAxel Dörfler 			fPreviousText.SetTo(buffer);
592*7d7f16acSAxel Dörfler 		}
593*7d7f16acSAxel Dörfler 
594*7d7f16acSAxel Dörfler 		fEditor.Unlock();
595*7d7f16acSAxel Dörfler 	}
596*7d7f16acSAxel Dörfler }
597*7d7f16acSAxel Dörfler 
598*7d7f16acSAxel Dörfler 
599*7d7f16acSAxel Dörfler void
600*7d7f16acSAxel Dörfler NumberEditor::UpdateNumber()
601*7d7f16acSAxel Dörfler {
602*7d7f16acSAxel Dörfler 	const char *number = fTextControl->Text();
603*7d7f16acSAxel Dörfler 	uint8 buffer[8];
604*7d7f16acSAxel Dörfler 
605*7d7f16acSAxel Dörfler 	switch (fEditor.Type()) {
606*7d7f16acSAxel Dörfler 		case B_FLOAT_TYPE:
607*7d7f16acSAxel Dörfler 		{
608*7d7f16acSAxel Dörfler 			float value = strtod(number, NULL);
609*7d7f16acSAxel Dörfler 			*(float *)buffer = value;
610*7d7f16acSAxel Dörfler 			break;
611*7d7f16acSAxel Dörfler 		}
612*7d7f16acSAxel Dörfler 		case B_DOUBLE_TYPE:
613*7d7f16acSAxel Dörfler 		{
614*7d7f16acSAxel Dörfler 			double value = strtod(number, NULL);
615*7d7f16acSAxel Dörfler 			*(double *)buffer = value;
616*7d7f16acSAxel Dörfler 			break;
617*7d7f16acSAxel Dörfler 		}
618*7d7f16acSAxel Dörfler 		case B_INT8_TYPE:
619*7d7f16acSAxel Dörfler 		{
620*7d7f16acSAxel Dörfler 			int64 value = strtoll(number, NULL, 0);
621*7d7f16acSAxel Dörfler 			if (value > CHAR_MAX)
622*7d7f16acSAxel Dörfler 				value = CHAR_MAX;
623*7d7f16acSAxel Dörfler 			else if (value < CHAR_MIN)
624*7d7f16acSAxel Dörfler 				value = CHAR_MIN;
625*7d7f16acSAxel Dörfler 			*(int8 *)buffer = (int8)value;
626*7d7f16acSAxel Dörfler 			break;
627*7d7f16acSAxel Dörfler 		}
628*7d7f16acSAxel Dörfler 		case B_UINT8_TYPE:
629*7d7f16acSAxel Dörfler 		{
630*7d7f16acSAxel Dörfler 			int64 value = strtoull(number, NULL, 0);
631*7d7f16acSAxel Dörfler 			if (value > UCHAR_MAX)
632*7d7f16acSAxel Dörfler 				value = UCHAR_MAX;
633*7d7f16acSAxel Dörfler 			*(uint8 *)buffer = (uint8)value;
634*7d7f16acSAxel Dörfler 			break;
635*7d7f16acSAxel Dörfler 		}
636*7d7f16acSAxel Dörfler 		case B_INT16_TYPE:
637*7d7f16acSAxel Dörfler 		{
638*7d7f16acSAxel Dörfler 			int64 value = strtoll(number, NULL, 0);
639*7d7f16acSAxel Dörfler 			if (value > SHRT_MAX)
640*7d7f16acSAxel Dörfler 				value = SHRT_MAX;
641*7d7f16acSAxel Dörfler 			else if (value < SHRT_MIN)
642*7d7f16acSAxel Dörfler 				value = SHRT_MIN;
643*7d7f16acSAxel Dörfler 			*(int16 *)buffer = (int16)value;
644*7d7f16acSAxel Dörfler 			break;
645*7d7f16acSAxel Dörfler 		}
646*7d7f16acSAxel Dörfler 		case B_UINT16_TYPE:
647*7d7f16acSAxel Dörfler 		{
648*7d7f16acSAxel Dörfler 			int64 value = strtoull(number, NULL, 0);
649*7d7f16acSAxel Dörfler 			if (value > USHRT_MAX)
650*7d7f16acSAxel Dörfler 				value = USHRT_MAX;
651*7d7f16acSAxel Dörfler 			*(uint16 *)buffer = (uint16)value;
652*7d7f16acSAxel Dörfler 			break;
653*7d7f16acSAxel Dörfler 		}
654*7d7f16acSAxel Dörfler 		case B_INT32_TYPE:
655*7d7f16acSAxel Dörfler 		case B_SSIZE_T_TYPE:
656*7d7f16acSAxel Dörfler 		{
657*7d7f16acSAxel Dörfler 			int64 value = strtoll(number, NULL, 0);
658*7d7f16acSAxel Dörfler 			if (value > LONG_MAX)
659*7d7f16acSAxel Dörfler 				value = LONG_MAX;
660*7d7f16acSAxel Dörfler 			else if (value < LONG_MIN)
661*7d7f16acSAxel Dörfler 				value = LONG_MIN;
662*7d7f16acSAxel Dörfler 			*(int32 *)buffer = (int32)value;
663*7d7f16acSAxel Dörfler 			break;
664*7d7f16acSAxel Dörfler 		}
665*7d7f16acSAxel Dörfler 		case B_UINT32_TYPE:
666*7d7f16acSAxel Dörfler 		case B_SIZE_T_TYPE:
667*7d7f16acSAxel Dörfler 		case B_POINTER_TYPE:
668*7d7f16acSAxel Dörfler 		{
669*7d7f16acSAxel Dörfler 			uint64 value = strtoull(number, NULL, 0);
670*7d7f16acSAxel Dörfler 			if (value > ULONG_MAX)
671*7d7f16acSAxel Dörfler 				value = ULONG_MAX;
672*7d7f16acSAxel Dörfler 			*(uint32 *)buffer = (uint32)value;
673*7d7f16acSAxel Dörfler 			break;
674*7d7f16acSAxel Dörfler 		}
675*7d7f16acSAxel Dörfler 		case B_INT64_TYPE:
676*7d7f16acSAxel Dörfler 		case B_OFF_T_TYPE:
677*7d7f16acSAxel Dörfler 		{
678*7d7f16acSAxel Dörfler 			int64 value = strtoll(number, NULL, 0);
679*7d7f16acSAxel Dörfler 			*(int64 *)buffer = value;
680*7d7f16acSAxel Dörfler 			break;
681*7d7f16acSAxel Dörfler 		}
682*7d7f16acSAxel Dörfler 		case B_UINT64_TYPE:
683*7d7f16acSAxel Dörfler 		{
684*7d7f16acSAxel Dörfler 			uint64 value = strtoull(number, NULL, 0);
685*7d7f16acSAxel Dörfler 			*(uint64 *)buffer = value;
686*7d7f16acSAxel Dörfler 			break;
687*7d7f16acSAxel Dörfler 		}
688*7d7f16acSAxel Dörfler 		default:
689*7d7f16acSAxel Dörfler 			return;
690*7d7f16acSAxel Dörfler 	}
691*7d7f16acSAxel Dörfler 
692*7d7f16acSAxel Dörfler 	BAutolock locker(fEditor);
693*7d7f16acSAxel Dörfler 	fEditor.Replace(0, buffer, Size());
694*7d7f16acSAxel Dörfler }
695*7d7f16acSAxel Dörfler 
696*7d7f16acSAxel Dörfler 
697*7d7f16acSAxel Dörfler const char *
698*7d7f16acSAxel Dörfler NumberEditor::TypeLabel()
699*7d7f16acSAxel Dörfler {
700*7d7f16acSAxel Dörfler 	switch (fEditor.Type()) {
701*7d7f16acSAxel Dörfler 		case B_INT8_TYPE:
702*7d7f16acSAxel Dörfler 			return "8 Bit Signed Value:";
703*7d7f16acSAxel Dörfler 		case B_UINT8_TYPE:
704*7d7f16acSAxel Dörfler 			return "8 Bit Unsigned Value:";
705*7d7f16acSAxel Dörfler 		case B_INT16_TYPE:
706*7d7f16acSAxel Dörfler 			return "16 Bit Signed Value:";
707*7d7f16acSAxel Dörfler 		case B_UINT16_TYPE:
708*7d7f16acSAxel Dörfler 			return "16 Bit Unsigned Value:";
709*7d7f16acSAxel Dörfler 		case B_INT32_TYPE:
710*7d7f16acSAxel Dörfler 			return "32 Bit Signed Value:";
711*7d7f16acSAxel Dörfler 		case B_UINT32_TYPE:
712*7d7f16acSAxel Dörfler 			return "32 Bit Unsigned Value:";
713*7d7f16acSAxel Dörfler 		case B_INT64_TYPE:
714*7d7f16acSAxel Dörfler 			return "64 Bit Signed Value:";
715*7d7f16acSAxel Dörfler 		case B_UINT64_TYPE:
716*7d7f16acSAxel Dörfler 			return "64 Bit Unsigned Value:";
717*7d7f16acSAxel Dörfler 		case B_FLOAT_TYPE:
718*7d7f16acSAxel Dörfler 			return "Floating-Point Value:";
719*7d7f16acSAxel Dörfler 		case B_DOUBLE_TYPE:
720*7d7f16acSAxel Dörfler 			return "Double Precision Floating-Point Value:";
721*7d7f16acSAxel Dörfler 		case B_SSIZE_T_TYPE:
722*7d7f16acSAxel Dörfler 			return "32 Bit Size or Status:";
723*7d7f16acSAxel Dörfler 		case B_SIZE_T_TYPE:
724*7d7f16acSAxel Dörfler 			return "32 Bit Unsigned Size:";
725*7d7f16acSAxel Dörfler 		case B_OFF_T_TYPE:
726*7d7f16acSAxel Dörfler 			return "64 Bit Signed Offset:";
727*7d7f16acSAxel Dörfler 		case B_POINTER_TYPE:
728*7d7f16acSAxel Dörfler 			return "32 Bit Unsigned Pointer:";
729*7d7f16acSAxel Dörfler 		default:
730*7d7f16acSAxel Dörfler 			return "Number:";
731*7d7f16acSAxel Dörfler 	}
732*7d7f16acSAxel Dörfler }
733*7d7f16acSAxel Dörfler 
734*7d7f16acSAxel Dörfler 
735*7d7f16acSAxel Dörfler size_t
736*7d7f16acSAxel Dörfler NumberEditor::Size()
737*7d7f16acSAxel Dörfler {
738*7d7f16acSAxel Dörfler 	switch (fEditor.Type()) {
739*7d7f16acSAxel Dörfler 		case B_INT8_TYPE:
740*7d7f16acSAxel Dörfler 			return 1;
741*7d7f16acSAxel Dörfler 		case B_UINT8_TYPE:
742*7d7f16acSAxel Dörfler 			return 1;
743*7d7f16acSAxel Dörfler 		case B_INT16_TYPE:
744*7d7f16acSAxel Dörfler 			return 2;
745*7d7f16acSAxel Dörfler 		case B_UINT16_TYPE:
746*7d7f16acSAxel Dörfler 			return 2;
747*7d7f16acSAxel Dörfler 		case B_SSIZE_T_TYPE:
748*7d7f16acSAxel Dörfler 		case B_INT32_TYPE:
749*7d7f16acSAxel Dörfler 			return 4;
750*7d7f16acSAxel Dörfler 		case B_SIZE_T_TYPE:
751*7d7f16acSAxel Dörfler 		case B_POINTER_TYPE:
752*7d7f16acSAxel Dörfler 		case B_UINT32_TYPE:
753*7d7f16acSAxel Dörfler 			return 4;
754*7d7f16acSAxel Dörfler 		case B_INT64_TYPE:
755*7d7f16acSAxel Dörfler 		case B_OFF_T_TYPE:
756*7d7f16acSAxel Dörfler 			return 8;
757*7d7f16acSAxel Dörfler 		case B_UINT64_TYPE:
758*7d7f16acSAxel Dörfler 			return 8;
759*7d7f16acSAxel Dörfler 		case B_FLOAT_TYPE:
760*7d7f16acSAxel Dörfler 			return 4;
761*7d7f16acSAxel Dörfler 		case B_DOUBLE_TYPE:
762*7d7f16acSAxel Dörfler 			return 8;
763*7d7f16acSAxel Dörfler 		default:
764*7d7f16acSAxel Dörfler 			return 0;
765*7d7f16acSAxel Dörfler 	}
766*7d7f16acSAxel Dörfler }
767*7d7f16acSAxel Dörfler 
768*7d7f16acSAxel Dörfler 
769*7d7f16acSAxel Dörfler status_t
770*7d7f16acSAxel Dörfler NumberEditor::Format(char *buffer)
771*7d7f16acSAxel Dörfler {
772*7d7f16acSAxel Dörfler 	switch (fEditor.Type()) {
773*7d7f16acSAxel Dörfler 		case B_INT8_TYPE:
774*7d7f16acSAxel Dörfler 			strcpy(buffer, "%hd");
775*7d7f16acSAxel Dörfler 			return B_OK;
776*7d7f16acSAxel Dörfler 		case B_UINT8_TYPE:
777*7d7f16acSAxel Dörfler 			strcpy(buffer, "%hu");
778*7d7f16acSAxel Dörfler 			return B_OK;
779*7d7f16acSAxel Dörfler 		case B_INT16_TYPE:
780*7d7f16acSAxel Dörfler 			strcpy(buffer, "%hd");
781*7d7f16acSAxel Dörfler 			return B_OK;
782*7d7f16acSAxel Dörfler 		case B_UINT16_TYPE:
783*7d7f16acSAxel Dörfler 			strcpy(buffer, "%hu");
784*7d7f16acSAxel Dörfler 			return B_OK;
785*7d7f16acSAxel Dörfler 		case B_SSIZE_T_TYPE:
786*7d7f16acSAxel Dörfler 		case B_INT32_TYPE:
787*7d7f16acSAxel Dörfler 			strcpy(buffer, "%ld");
788*7d7f16acSAxel Dörfler 			return B_OK;
789*7d7f16acSAxel Dörfler 		case B_SIZE_T_TYPE:
790*7d7f16acSAxel Dörfler 		case B_POINTER_TYPE:
791*7d7f16acSAxel Dörfler 		case B_UINT32_TYPE:
792*7d7f16acSAxel Dörfler 			strcpy(buffer, "%lu");
793*7d7f16acSAxel Dörfler 			return B_OK;
794*7d7f16acSAxel Dörfler 		case B_INT64_TYPE:
795*7d7f16acSAxel Dörfler 		case B_OFF_T_TYPE:
796*7d7f16acSAxel Dörfler 			strcpy(buffer, "%Ld");
797*7d7f16acSAxel Dörfler 			return B_OK;
798*7d7f16acSAxel Dörfler 		case B_UINT64_TYPE:
799*7d7f16acSAxel Dörfler 			strcpy(buffer, "%Lu");
800*7d7f16acSAxel Dörfler 			return B_OK;
801*7d7f16acSAxel Dörfler 		case B_FLOAT_TYPE:
802*7d7f16acSAxel Dörfler 			strcpy(buffer, "%g");
803*7d7f16acSAxel Dörfler 			return B_OK;
804*7d7f16acSAxel Dörfler 		case B_DOUBLE_TYPE:
805*7d7f16acSAxel Dörfler 			strcpy(buffer, "%lg");
806*7d7f16acSAxel Dörfler 			return B_OK;
807*7d7f16acSAxel Dörfler 
808*7d7f16acSAxel Dörfler 		default:
809*7d7f16acSAxel Dörfler 			return B_ERROR;
810*7d7f16acSAxel Dörfler 	}
811*7d7f16acSAxel Dörfler }
812*7d7f16acSAxel Dörfler 
813*7d7f16acSAxel Dörfler 
814*7d7f16acSAxel Dörfler void
815*7d7f16acSAxel Dörfler NumberEditor::AttachedToWindow()
816*7d7f16acSAxel Dörfler {
817*7d7f16acSAxel Dörfler 	fTextControl->SetTarget(this);
818*7d7f16acSAxel Dörfler 	fEditor.StartWatching(this);
819*7d7f16acSAxel Dörfler 
820*7d7f16acSAxel Dörfler 	UpdateText();
821*7d7f16acSAxel Dörfler }
822*7d7f16acSAxel Dörfler 
823*7d7f16acSAxel Dörfler 
824*7d7f16acSAxel Dörfler void
825*7d7f16acSAxel Dörfler NumberEditor::DetachedFromWindow()
826*7d7f16acSAxel Dörfler {
827*7d7f16acSAxel Dörfler 	fEditor.StopWatching(this);
828*7d7f16acSAxel Dörfler 
829*7d7f16acSAxel Dörfler 	if (fPreviousText != fTextControl->Text())
830*7d7f16acSAxel Dörfler 		UpdateNumber();
831*7d7f16acSAxel Dörfler }
832*7d7f16acSAxel Dörfler 
833*7d7f16acSAxel Dörfler 
834*7d7f16acSAxel Dörfler void
835*7d7f16acSAxel Dörfler NumberEditor::MessageReceived(BMessage *message)
836*7d7f16acSAxel Dörfler {
837*7d7f16acSAxel Dörfler 	switch (message->what) {
838*7d7f16acSAxel Dörfler 		case kMsgValueChanged:
839*7d7f16acSAxel Dörfler 			UpdateNumber();
840*7d7f16acSAxel Dörfler 			break;
841*7d7f16acSAxel Dörfler 		case kMsgDataEditorUpdate:
842*7d7f16acSAxel Dörfler 			UpdateText();
843*7d7f16acSAxel Dörfler 			break;
844*7d7f16acSAxel Dörfler 
845*7d7f16acSAxel Dörfler 		default:
846*7d7f16acSAxel Dörfler 			BView::MessageReceived(message);
847*7d7f16acSAxel Dörfler 	}
848*7d7f16acSAxel Dörfler }
849*7d7f16acSAxel Dörfler 
850*7d7f16acSAxel Dörfler 
851*7d7f16acSAxel Dörfler //	#pragma mark -
852*7d7f16acSAxel Dörfler 
853*7d7f16acSAxel Dörfler 
854*7d7f16acSAxel Dörfler BooleanEditor::BooleanEditor(BRect rect, DataEditor &editor)
855*7d7f16acSAxel Dörfler 	: BView(rect, "Boolean Editor", B_FOLLOW_NONE, 0),
856*7d7f16acSAxel Dörfler 	fEditor(editor)
857*7d7f16acSAxel Dörfler {
858*7d7f16acSAxel Dörfler 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
859*7d7f16acSAxel Dörfler 
860*7d7f16acSAxel Dörfler 	BPopUpMenu *menu = new BPopUpMenu("bool");
861*7d7f16acSAxel Dörfler 	BMessage *message;
862*7d7f16acSAxel Dörfler 	menu->AddItem(fFalseMenuItem = new BMenuItem("false", new BMessage(kMsgValueChanged)));
863*7d7f16acSAxel Dörfler 	menu->AddItem(fTrueMenuItem = new BMenuItem("true", message = new BMessage(kMsgValueChanged)));
864*7d7f16acSAxel Dörfler 	message->AddInt8("value", 1);
865*7d7f16acSAxel Dörfler 
866*7d7f16acSAxel Dörfler 	BMenuField *menuField = new BMenuField(rect.InsetByCopy(5, 5), B_EMPTY_STRING,
867*7d7f16acSAxel Dörfler 						"Boolean Value:", menu, B_FOLLOW_LEFT_RIGHT);
868*7d7f16acSAxel Dörfler 	menuField->SetDivider(StringWidth(menuField->Label()) + 8);
869*7d7f16acSAxel Dörfler 	menuField->ResizeToPreferred();
870*7d7f16acSAxel Dörfler 	ResizeTo(menuField->Bounds().Width() + 10, menuField->Bounds().Height() + 10);
871*7d7f16acSAxel Dörfler 
872*7d7f16acSAxel Dörfler 	UpdateMenuField();
873*7d7f16acSAxel Dörfler 
874*7d7f16acSAxel Dörfler 	AddChild(menuField);
875*7d7f16acSAxel Dörfler }
876*7d7f16acSAxel Dörfler 
877*7d7f16acSAxel Dörfler 
878*7d7f16acSAxel Dörfler void
879*7d7f16acSAxel Dörfler BooleanEditor::UpdateMenuField()
880*7d7f16acSAxel Dörfler {
881*7d7f16acSAxel Dörfler 	if (fEditor.Lock()) {
882*7d7f16acSAxel Dörfler 		const char *buffer;
883*7d7f16acSAxel Dörfler 		if (fEditor.GetViewBuffer((const uint8 **)&buffer) == B_OK)
884*7d7f16acSAxel Dörfler 			(buffer[0] != 0 ? fTrueMenuItem : fFalseMenuItem)->SetMarked(true);
885*7d7f16acSAxel Dörfler 
886*7d7f16acSAxel Dörfler 		fEditor.Unlock();
887*7d7f16acSAxel Dörfler 	}
888*7d7f16acSAxel Dörfler 
889*7d7f16acSAxel Dörfler }
890*7d7f16acSAxel Dörfler 
891*7d7f16acSAxel Dörfler 
892*7d7f16acSAxel Dörfler void
893*7d7f16acSAxel Dörfler BooleanEditor::AttachedToWindow()
894*7d7f16acSAxel Dörfler {
895*7d7f16acSAxel Dörfler 	fTrueMenuItem->SetTarget(this);
896*7d7f16acSAxel Dörfler 	fFalseMenuItem->SetTarget(this);
897*7d7f16acSAxel Dörfler 
898*7d7f16acSAxel Dörfler 	fEditor.StartWatching(this);
899*7d7f16acSAxel Dörfler }
900*7d7f16acSAxel Dörfler 
901*7d7f16acSAxel Dörfler 
902*7d7f16acSAxel Dörfler void
903*7d7f16acSAxel Dörfler BooleanEditor::DetachedFromWindow()
904*7d7f16acSAxel Dörfler {
905*7d7f16acSAxel Dörfler 	fEditor.StopWatching(this);
906*7d7f16acSAxel Dörfler }
907*7d7f16acSAxel Dörfler 
908*7d7f16acSAxel Dörfler 
909*7d7f16acSAxel Dörfler void
910*7d7f16acSAxel Dörfler BooleanEditor::MessageReceived(BMessage *message)
911*7d7f16acSAxel Dörfler {
912*7d7f16acSAxel Dörfler 	switch (message->what) {
913*7d7f16acSAxel Dörfler 		case kMsgValueChanged:
914*7d7f16acSAxel Dörfler 		{
915*7d7f16acSAxel Dörfler 			BAutolock locker(fEditor);
916*7d7f16acSAxel Dörfler 			uint8 boolean = message->FindInt8("value");
917*7d7f16acSAxel Dörfler 			fEditor.Replace(0, (const uint8 *)&boolean, 1);
918*7d7f16acSAxel Dörfler 			break;
919*7d7f16acSAxel Dörfler 		}
920*7d7f16acSAxel Dörfler 		case kMsgDataEditorUpdate:
921*7d7f16acSAxel Dörfler 			UpdateMenuField();
922*7d7f16acSAxel Dörfler 			break;
923*7d7f16acSAxel Dörfler 
924*7d7f16acSAxel Dörfler 		default:
925*7d7f16acSAxel Dörfler 			BView::MessageReceived(message);
926*7d7f16acSAxel Dörfler 	}
927*7d7f16acSAxel Dörfler }
928*7d7f16acSAxel Dörfler 
929*7d7f16acSAxel Dörfler 
930*7d7f16acSAxel Dörfler //	#pragma mark -
93136a79516SAxel Dörfler 
93236a79516SAxel Dörfler 
9337fff3ed0SAxel Dörfler AttributeWindow::AttributeWindow(BRect rect, entry_ref *ref, const char *attribute,
9347fff3ed0SAxel Dörfler 	const BMessage *settings)
935d11ec082SAxel Dörfler 	: ProbeWindow(rect, ref),
936d11ec082SAxel Dörfler 	fAttribute(strdup(attribute))
937d11ec082SAxel Dörfler {
938d11ec082SAxel Dörfler 	char buffer[256];
939d11ec082SAxel Dörfler 	snprintf(buffer, sizeof(buffer), "%s: %s", ref->name, attribute);
940d11ec082SAxel Dörfler 	SetTitle(buffer);
941d11ec082SAxel Dörfler 
942d11ec082SAxel Dörfler 	// add the menu
943d11ec082SAxel Dörfler 
944d11ec082SAxel Dörfler 	BMenuBar *menuBar = new BMenuBar(BRect(0, 0, 0, 0), NULL);
945d11ec082SAxel Dörfler 	AddChild(menuBar);
946d11ec082SAxel Dörfler 
947d11ec082SAxel Dörfler 	BMenu *menu = new BMenu("Attribute");
948d11ec082SAxel Dörfler 
94936a79516SAxel Dörfler 	menu->AddItem(new BMenuItem("Save", NULL, 'S', B_COMMAND_KEY));
95036a79516SAxel Dörfler 	menu->AddItem(new BMenuItem("Remove from File", new BMessage(kMsgRemoveAttribute)));
95136a79516SAxel Dörfler 	menu->AddSeparatorItem();
95236a79516SAxel Dörfler 
953d11ec082SAxel Dörfler 	// the ProbeView file menu items will be inserted here
954d11ec082SAxel Dörfler 	menu->AddSeparatorItem();
955d11ec082SAxel Dörfler 
956d11ec082SAxel Dörfler 	menu->AddItem(new BMenuItem("Close", new BMessage(B_CLOSE_REQUESTED), 'W', B_COMMAND_KEY));
957d11ec082SAxel Dörfler 	menu->SetTargetForItems(this);
958d11ec082SAxel Dörfler 	menuBar->AddItem(menu);
959d11ec082SAxel Dörfler 
960d11ec082SAxel Dörfler 	// add our interface widgets
961d11ec082SAxel Dörfler 
962d11ec082SAxel Dörfler 	BRect rect = Bounds();
963d11ec082SAxel Dörfler 	rect.top = menuBar->Bounds().Height() + 1;
964d11ec082SAxel Dörfler 
965*7d7f16acSAxel Dörfler 	BView *view = new BView(rect, "main", B_FOLLOW_ALL, 0);
966*7d7f16acSAxel Dörfler 	view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
967*7d7f16acSAxel Dörfler 	AddChild(view);
968*7d7f16acSAxel Dörfler 
969*7d7f16acSAxel Dörfler 	rect = view->Bounds();
970*7d7f16acSAxel Dörfler 	rect.top += 3;
971*7d7f16acSAxel Dörfler 
972*7d7f16acSAxel Dörfler 	EditorTabView *tabView = new EditorTabView(rect, "tabView");
973*7d7f16acSAxel Dörfler 
974*7d7f16acSAxel Dörfler 	rect = tabView->ContainerView()->Bounds();
975*7d7f16acSAxel Dörfler 	rect.top += 3;
976*7d7f16acSAxel Dörfler 	fProbeView = new ProbeView(rect, ref, attribute, settings);
977*7d7f16acSAxel Dörfler 	fProbeView->AddFileMenuItems(menu, menu->CountItems() - 2);
978*7d7f16acSAxel Dörfler 	tabView->AddRawEditorTab(fProbeView);
979*7d7f16acSAxel Dörfler 
980*7d7f16acSAxel Dörfler 	view->AddChild(tabView);
981*7d7f16acSAxel Dörfler 
982*7d7f16acSAxel Dörfler 	BView *editor = GetTypeEditorFor(rect, fProbeView->Editor());
983*7d7f16acSAxel Dörfler 	if (editor != NULL)
984*7d7f16acSAxel Dörfler 		tabView->SetTypeEditorTab(editor);
985*7d7f16acSAxel Dörfler 	else {
986*7d7f16acSAxel Dörfler 		// show the raw editor if we don't have a specialised type editor
987*7d7f16acSAxel Dörfler 		tabView->Select(1);
988*7d7f16acSAxel Dörfler 	}
989*7d7f16acSAxel Dörfler 
990*7d7f16acSAxel Dörfler 	fProbeView->UpdateSizeLimits();
991d11ec082SAxel Dörfler }
992d11ec082SAxel Dörfler 
993d11ec082SAxel Dörfler 
994d11ec082SAxel Dörfler AttributeWindow::~AttributeWindow()
995d11ec082SAxel Dörfler {
996d11ec082SAxel Dörfler 	free(fAttribute);
997d11ec082SAxel Dörfler }
998d11ec082SAxel Dörfler 
999d11ec082SAxel Dörfler 
100036a79516SAxel Dörfler void
100136a79516SAxel Dörfler AttributeWindow::MessageReceived(BMessage *message)
100236a79516SAxel Dörfler {
100336a79516SAxel Dörfler 	switch (message->what) {
100436a79516SAxel Dörfler 		case kMsgRemoveAttribute:
100536a79516SAxel Dörfler 		{
100636a79516SAxel Dörfler 			char buffer[1024];
100736a79516SAxel Dörfler 			snprintf(buffer, sizeof(buffer),
100836a79516SAxel Dörfler 				"Do you really want to remove the attribute \"%s\" from the file \"%s\"?\n\n"
100936a79516SAxel Dörfler 				"The contents of the attribute will get lost if you click on \"Remove\".",
101036a79516SAxel Dörfler 				fAttribute, Ref().name);
101136a79516SAxel Dörfler 
101236a79516SAxel Dörfler 			int32 chosen = (new BAlert("DiskProbe request",
101336a79516SAxel Dörfler 				buffer, "Remove", "Cancel", NULL,
101436a79516SAxel Dörfler 				B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go();
101536a79516SAxel Dörfler 			if (chosen == 0) {
101636a79516SAxel Dörfler 				BNode node(&Ref());
101736a79516SAxel Dörfler 				if (node.InitCheck() == B_OK)
101836a79516SAxel Dörfler 					node.RemoveAttr(fAttribute);
101936a79516SAxel Dörfler 
102036a79516SAxel Dörfler 				PostMessage(B_QUIT_REQUESTED);
102136a79516SAxel Dörfler 			}
102236a79516SAxel Dörfler 			break;
102336a79516SAxel Dörfler 		}
102436a79516SAxel Dörfler 
102536a79516SAxel Dörfler 		default:
102636a79516SAxel Dörfler 			ProbeWindow::MessageReceived(message);
102736a79516SAxel Dörfler 			break;
102836a79516SAxel Dörfler 	}
102936a79516SAxel Dörfler }
103036a79516SAxel Dörfler 
103136a79516SAxel Dörfler 
1032d11ec082SAxel Dörfler bool
1033d11ec082SAxel Dörfler AttributeWindow::Contains(const entry_ref &ref, const char *attribute)
1034d11ec082SAxel Dörfler {
1035d11ec082SAxel Dörfler 	return ref == Ref() && attribute != NULL && !strcmp(attribute, fAttribute);
1036d11ec082SAxel Dörfler }
1037d11ec082SAxel Dörfler 
1038