xref: /haiku/src/apps/diskprobe/AttributeWindow.cpp (revision 67bce78b48ed6d01b5a8eef89f5694c372b7e0a1)
1 /*
2 ** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 ** Distributed under the terms of the OpenBeOS License.
4 */
5 
6 
7 #include "AttributeWindow.h"
8 #include "AttributeEditors.h"
9 #include "ProbeView.h"
10 
11 #include <MenuBar.h>
12 #include <MenuItem.h>
13 #include <TabView.h>
14 #include <StringView.h>
15 #include <Alert.h>
16 
17 
18 static const uint32 kMsgRemoveAttribute = 'rmat';
19 
20 
21 class EditorTabView : public BTabView {
22 	public:
23 		EditorTabView(BRect frame, const char *name, button_width width = B_WIDTH_AS_USUAL,
24 			uint32 resizingMode = B_FOLLOW_ALL, uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS);
25 
26 		virtual void FrameResized(float width, float height);
27 		virtual void Select(int32 tab);
28 
29 		void AddRawEditorTab(BView *view);
30 		void SetTypeEditorTab(BView *view);
31 
32 	private:
33 		BView		*fRawEditorView;
34 		BView		*fTypeEditorView;
35 		BStringView	*fNoEditorView;
36 		int32		fRawTab;
37 };
38 
39 
40 //-----------------
41 
42 
43 EditorTabView::EditorTabView(BRect frame, const char *name, button_width width,
44 	uint32 resizingMode, uint32 flags)
45 	: BTabView(frame, name, width, resizingMode, flags),
46 	fRawEditorView(NULL),
47 	fRawTab(-1)
48 {
49 	ContainerView()->MoveBy(-ContainerView()->Frame().left,
50 						TabHeight() + 1 - ContainerView()->Frame().top);
51 	fNoEditorView = new BStringView(ContainerView()->Bounds(), "Type Editor",
52 							"No type editor available", B_FOLLOW_NONE);
53 	fNoEditorView->ResizeToPreferred();
54 	fNoEditorView->SetAlignment(B_ALIGN_CENTER);
55 	fTypeEditorView = fNoEditorView;
56 
57 	FrameResized(0, 0);
58 
59 	SetTypeEditorTab(NULL);
60 }
61 
62 
63 void
64 EditorTabView::FrameResized(float width, float height)
65 {
66 	BRect rect = Bounds();
67 	rect.top = ContainerView()->Frame().top;
68 
69 	ContainerView()->ResizeTo(rect.Width(), rect.Height());
70 
71 	BView *view = fTypeEditorView;
72 	if (view == NULL)
73 		view = fNoEditorView;
74 
75 	BPoint point = view->Frame().LeftTop();
76 	if ((view->ResizingMode() & B_FOLLOW_RIGHT) == 0)
77 		point.x = (rect.Width() - view->Bounds().Width()) / 2;
78 	if ((view->ResizingMode() & B_FOLLOW_BOTTOM) == 0)
79 		point.y = (rect.Height() - view->Bounds().Height()) / 2;
80 
81 	view->MoveTo(point);
82 }
83 
84 
85 void
86 EditorTabView::Select(int32 tab)
87 {
88 	if (tab != fRawTab && fRawEditorView != NULL && !fRawEditorView->IsHidden(fRawEditorView))
89 		fRawEditorView->Hide();
90 
91 	BTabView::Select(tab);
92 
93 	BView *view;
94 	if (tab == fRawTab && fRawEditorView != NULL) {
95 		if (fRawEditorView->IsHidden(fRawEditorView))
96 			fRawEditorView->Show();
97 		view = fRawEditorView;
98 	} else
99 		view = ViewForTab(Selection());
100 
101 	if (view != NULL && (view->ResizingMode() & (B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM)) != 0) {
102 		BRect rect = ContainerView()->Bounds();
103 
104 		BRect frame = view->Frame();
105 		rect.left = frame.left;
106 		rect.top = frame.top;
107 		if ((view->ResizingMode() & B_FOLLOW_RIGHT) == 0)
108 			rect.right = frame.right;
109 		if ((view->ResizingMode() & B_FOLLOW_BOTTOM) == 0)
110 			rect.bottom = frame.bottom;
111 
112 		view->ResizeTo(rect.Width(), rect.Height());
113 	}
114 }
115 
116 
117 void
118 EditorTabView::AddRawEditorTab(BView *view)
119 {
120 	fRawEditorView = view;
121 	if (view != NULL)
122 		ContainerView()->AddChild(view);
123 
124 	fRawTab = CountTabs();
125 
126 	view = new BView(BRect(0, 0, 5, 5), "Raw Editor", B_FOLLOW_NONE, 0);
127 	view->SetViewColor(ViewColor());
128 	AddTab(view);
129 }
130 
131 
132 void
133 EditorTabView::SetTypeEditorTab(BView *view)
134 {
135 	if (fTypeEditorView == view)
136 		return;
137 
138 	BTab *tab = TabAt(0);
139 	if (tab != NULL)
140 		tab->SetView(NULL);
141 
142 	fTypeEditorView = view;
143 
144 	if (view == NULL)
145 		view = fNoEditorView;
146 
147 	if (CountTabs() == 0)
148 		AddTab(view);
149 	else
150 		tab->SetView(view);
151 
152 	FrameResized(0, 0);
153 
154 #ifdef COMPILE_FOR_R5
155 	if (Window() != NULL) {
156 		// With R5's BTabView, calling select without being
157 		// attached to a window crashes...
158 		Select(0);
159 	}
160 #else
161 	Select(0);
162 #endif
163 }
164 
165 
166 //	#pragma mark -
167 
168 
169 AttributeWindow::AttributeWindow(BRect rect, entry_ref *ref, const char *attribute,
170 	const BMessage *settings)
171 	: ProbeWindow(rect, ref),
172 	fAttribute(strdup(attribute))
173 {
174 	char buffer[256];
175 	snprintf(buffer, sizeof(buffer), "%s: %s", ref->name, attribute);
176 	SetTitle(buffer);
177 
178 	// add the menu
179 
180 	BMenuBar *menuBar = new BMenuBar(BRect(0, 0, 0, 0), NULL);
181 	AddChild(menuBar);
182 
183 	BMenu *menu = new BMenu("Attribute");
184 
185 	// the ProbeView save menu items will be inserted here
186 	menu->AddItem(new BMenuItem("Remove from File", new BMessage(kMsgRemoveAttribute)));
187 	menu->AddSeparatorItem();
188 
189 	// the ProbeView print menu items will be inserted here
190 	menu->AddSeparatorItem();
191 
192 	menu->AddItem(new BMenuItem("Close", new BMessage(B_CLOSE_REQUESTED), 'W', B_COMMAND_KEY));
193 	menu->SetTargetForItems(this);
194 	menuBar->AddItem(menu);
195 
196 	// add our interface widgets
197 
198 	BRect rect = Bounds();
199 	rect.top = menuBar->Bounds().Height() + 1;
200 
201 	BView *view = new BView(rect, "main", B_FOLLOW_ALL, 0);
202 	view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
203 	AddChild(view);
204 
205 	rect = view->Bounds();
206 	rect.top += 3;
207 
208 	EditorTabView *tabView = new EditorTabView(rect, "tabView");
209 
210 	rect = tabView->ContainerView()->Bounds();
211 	rect.top += 3;
212 	fProbeView = new ProbeView(rect, ref, attribute, settings);
213 	tabView->AddRawEditorTab(fProbeView);
214 
215 	view->AddChild(tabView);
216 
217 	fTypeEditorView = GetTypeEditorFor(rect, fProbeView->Editor());
218 	if (fTypeEditorView != NULL)
219 		tabView->SetTypeEditorTab(fTypeEditorView);
220 	else {
221 		// show the raw editor if we don't have a specialised type editor
222 		tabView->Select(1);
223 	}
224 
225 	fProbeView->AddSaveMenuItems(menu, 0);
226 	fProbeView->AddPrintMenuItems(menu, menu->CountItems() - 2);
227 
228 	fProbeView->UpdateSizeLimits();
229 }
230 
231 
232 AttributeWindow::~AttributeWindow()
233 {
234 	free(fAttribute);
235 }
236 
237 
238 void
239 AttributeWindow::MessageReceived(BMessage *message)
240 {
241 	switch (message->what) {
242 		case kMsgRemoveAttribute:
243 		{
244 			char buffer[1024];
245 			snprintf(buffer, sizeof(buffer),
246 				"Do you really want to remove the attribute \"%s\" from the file \"%s\"?\n\n"
247 				"You cannot undo this action.",
248 				fAttribute, Ref().name);
249 
250 			int32 chosen = (new BAlert("DiskProbe request",
251 				buffer, "Cancel", "Remove", NULL,
252 				B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go();
253 			if (chosen == 1) {
254 				BNode node(&Ref());
255 				if (node.InitCheck() == B_OK)
256 					node.RemoveAttr(fAttribute);
257 
258 				PostMessage(B_QUIT_REQUESTED);
259 			}
260 			break;
261 		}
262 
263 		default:
264 			ProbeWindow::MessageReceived(message);
265 			break;
266 	}
267 }
268 
269 
270 bool
271 AttributeWindow::QuitRequested()
272 {
273 	if (fTypeEditorView != NULL)
274 		fTypeEditorView->CommitChanges();
275 
276 	bool quit = fProbeView->QuitRequested();
277 	if (!quit)
278 		return false;
279 
280 	return ProbeWindow::QuitRequested();
281 }
282 
283 
284 bool
285 AttributeWindow::Contains(const entry_ref &ref, const char *attribute)
286 {
287 	return ref == Ref() && attribute != NULL && !strcmp(attribute, fAttribute);
288 }
289 
290