xref: /haiku/src/apps/diskprobe/AttributeWindow.cpp (revision 527b14e9d548c05336910cdee47c2e5218c06885)
1d11ec082SAxel Dörfler /*
2*527b14e9SAxel Dörfler  * Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
386daa6f2SAxel Dörfler  * Distributed under the terms of the MIT License.
4d11ec082SAxel Dörfler  */
5d11ec082SAxel Dörfler 
6d11ec082SAxel Dörfler 
7d11ec082SAxel Dörfler #include "AttributeWindow.h"
8d11ec082SAxel Dörfler #include "ProbeView.h"
9*527b14e9SAxel Dörfler #include "TypeEditors.h"
10d11ec082SAxel Dörfler 
11d11ec082SAxel Dörfler #include <MenuBar.h>
12d11ec082SAxel Dörfler #include <MenuItem.h>
137d7f16acSAxel Dörfler #include <TabView.h>
147d7f16acSAxel Dörfler #include <StringView.h>
1536a79516SAxel Dörfler #include <Alert.h>
1686daa6f2SAxel Dörfler #include <Directory.h>
1786daa6f2SAxel Dörfler #include <Volume.h>
18d11ec082SAxel Dörfler 
19d11ec082SAxel Dörfler 
2036a79516SAxel Dörfler static const uint32 kMsgRemoveAttribute = 'rmat';
217d7f16acSAxel Dörfler 
227d7f16acSAxel Dörfler 
237d7f16acSAxel Dörfler class EditorTabView : public BTabView {
247d7f16acSAxel Dörfler 	public:
257d7f16acSAxel Dörfler 		EditorTabView(BRect frame, const char *name, button_width width = B_WIDTH_AS_USUAL,
267d7f16acSAxel Dörfler 			uint32 resizingMode = B_FOLLOW_ALL, uint32 flags = B_WILL_DRAW | B_FRAME_EVENTS);
277d7f16acSAxel Dörfler 
287d7f16acSAxel Dörfler 		virtual void FrameResized(float width, float height);
297d7f16acSAxel Dörfler 		virtual void Select(int32 tab);
307d7f16acSAxel Dörfler 
317d7f16acSAxel Dörfler 		void AddRawEditorTab(BView *view);
327d7f16acSAxel Dörfler 		void SetTypeEditorTab(BView *view);
337d7f16acSAxel Dörfler 
347d7f16acSAxel Dörfler 	private:
357d7f16acSAxel Dörfler 		BView		*fRawEditorView;
367d7f16acSAxel Dörfler 		BView		*fTypeEditorView;
377d7f16acSAxel Dörfler 		BStringView	*fNoEditorView;
387d7f16acSAxel Dörfler 		int32		fRawTab;
397d7f16acSAxel Dörfler };
407d7f16acSAxel Dörfler 
417d7f16acSAxel Dörfler 
427d7f16acSAxel Dörfler //-----------------
437d7f16acSAxel Dörfler 
447d7f16acSAxel Dörfler 
457d7f16acSAxel Dörfler EditorTabView::EditorTabView(BRect frame, const char *name, button_width width,
467d7f16acSAxel Dörfler 	uint32 resizingMode, uint32 flags)
477d7f16acSAxel Dörfler 	: BTabView(frame, name, width, resizingMode, flags),
487d7f16acSAxel Dörfler 	fRawEditorView(NULL),
497d7f16acSAxel Dörfler 	fRawTab(-1)
507d7f16acSAxel Dörfler {
517d7f16acSAxel Dörfler 	ContainerView()->MoveBy(-ContainerView()->Frame().left,
527d7f16acSAxel Dörfler 						TabHeight() + 1 - ContainerView()->Frame().top);
537d7f16acSAxel Dörfler 	fNoEditorView = new BStringView(ContainerView()->Bounds(), "Type Editor",
547d7f16acSAxel Dörfler 							"No type editor available", B_FOLLOW_NONE);
557d7f16acSAxel Dörfler 	fNoEditorView->ResizeToPreferred();
567d7f16acSAxel Dörfler 	fNoEditorView->SetAlignment(B_ALIGN_CENTER);
577d7f16acSAxel Dörfler 	fTypeEditorView = fNoEditorView;
587d7f16acSAxel Dörfler 
597d7f16acSAxel Dörfler 	FrameResized(0, 0);
607d7f16acSAxel Dörfler 
617d7f16acSAxel Dörfler 	SetTypeEditorTab(NULL);
627d7f16acSAxel Dörfler }
637d7f16acSAxel Dörfler 
647d7f16acSAxel Dörfler 
657d7f16acSAxel Dörfler void
667d7f16acSAxel Dörfler EditorTabView::FrameResized(float width, float height)
677d7f16acSAxel Dörfler {
687d7f16acSAxel Dörfler 	BRect rect = Bounds();
697d7f16acSAxel Dörfler 	rect.top = ContainerView()->Frame().top;
707d7f16acSAxel Dörfler 
717d7f16acSAxel Dörfler 	ContainerView()->ResizeTo(rect.Width(), rect.Height());
727d7f16acSAxel Dörfler 
737d7f16acSAxel Dörfler 	BView *view = fTypeEditorView;
747d7f16acSAxel Dörfler 	if (view == NULL)
757d7f16acSAxel Dörfler 		view = fNoEditorView;
767d7f16acSAxel Dörfler 
777d7f16acSAxel Dörfler 	BPoint point = view->Frame().LeftTop();
787d7f16acSAxel Dörfler 	if ((view->ResizingMode() & B_FOLLOW_RIGHT) == 0)
797d7f16acSAxel Dörfler 		point.x = (rect.Width() - view->Bounds().Width()) / 2;
807d7f16acSAxel Dörfler 	if ((view->ResizingMode() & B_FOLLOW_BOTTOM) == 0)
817d7f16acSAxel Dörfler 		point.y = (rect.Height() - view->Bounds().Height()) / 2;
827d7f16acSAxel Dörfler 
837d7f16acSAxel Dörfler 	view->MoveTo(point);
847d7f16acSAxel Dörfler }
857d7f16acSAxel Dörfler 
867d7f16acSAxel Dörfler 
877d7f16acSAxel Dörfler void
887d7f16acSAxel Dörfler EditorTabView::Select(int32 tab)
897d7f16acSAxel Dörfler {
907d7f16acSAxel Dörfler 	if (tab != fRawTab && fRawEditorView != NULL && !fRawEditorView->IsHidden(fRawEditorView))
917d7f16acSAxel Dörfler 		fRawEditorView->Hide();
927d7f16acSAxel Dörfler 
937d7f16acSAxel Dörfler 	BTabView::Select(tab);
947d7f16acSAxel Dörfler 
957d7f16acSAxel Dörfler 	BView *view;
967d7f16acSAxel Dörfler 	if (tab == fRawTab && fRawEditorView != NULL) {
977d7f16acSAxel Dörfler 		if (fRawEditorView->IsHidden(fRawEditorView))
987d7f16acSAxel Dörfler 			fRawEditorView->Show();
997d7f16acSAxel Dörfler 		view = fRawEditorView;
1007d7f16acSAxel Dörfler 	} else
1017d7f16acSAxel Dörfler 		view = ViewForTab(Selection());
1027d7f16acSAxel Dörfler 
1037d7f16acSAxel Dörfler 	if (view != NULL && (view->ResizingMode() & (B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM)) != 0) {
1047d7f16acSAxel Dörfler 		BRect rect = ContainerView()->Bounds();
1057d7f16acSAxel Dörfler 
1067d7f16acSAxel Dörfler 		BRect frame = view->Frame();
1077d7f16acSAxel Dörfler 		rect.left = frame.left;
1087d7f16acSAxel Dörfler 		rect.top = frame.top;
1097d7f16acSAxel Dörfler 		if ((view->ResizingMode() & B_FOLLOW_RIGHT) == 0)
1107d7f16acSAxel Dörfler 			rect.right = frame.right;
1117d7f16acSAxel Dörfler 		if ((view->ResizingMode() & B_FOLLOW_BOTTOM) == 0)
1127d7f16acSAxel Dörfler 			rect.bottom = frame.bottom;
1137d7f16acSAxel Dörfler 
1147d7f16acSAxel Dörfler 		view->ResizeTo(rect.Width(), rect.Height());
1157d7f16acSAxel Dörfler 	}
1167d7f16acSAxel Dörfler }
1177d7f16acSAxel Dörfler 
1187d7f16acSAxel Dörfler 
1197d7f16acSAxel Dörfler void
1207d7f16acSAxel Dörfler EditorTabView::AddRawEditorTab(BView *view)
1217d7f16acSAxel Dörfler {
1227d7f16acSAxel Dörfler 	fRawEditorView = view;
1237d7f16acSAxel Dörfler 	if (view != NULL)
1247d7f16acSAxel Dörfler 		ContainerView()->AddChild(view);
1257d7f16acSAxel Dörfler 
1267d7f16acSAxel Dörfler 	fRawTab = CountTabs();
1277d7f16acSAxel Dörfler 
1287d7f16acSAxel Dörfler 	view = new BView(BRect(0, 0, 5, 5), "Raw Editor", B_FOLLOW_NONE, 0);
1297d7f16acSAxel Dörfler 	view->SetViewColor(ViewColor());
1307d7f16acSAxel Dörfler 	AddTab(view);
1317d7f16acSAxel Dörfler }
1327d7f16acSAxel Dörfler 
1337d7f16acSAxel Dörfler 
1347d7f16acSAxel Dörfler void
1357d7f16acSAxel Dörfler EditorTabView::SetTypeEditorTab(BView *view)
1367d7f16acSAxel Dörfler {
1377d7f16acSAxel Dörfler 	if (fTypeEditorView == view)
1387d7f16acSAxel Dörfler 		return;
1397d7f16acSAxel Dörfler 
1407d7f16acSAxel Dörfler 	BTab *tab = TabAt(0);
1417d7f16acSAxel Dörfler 	if (tab != NULL)
1427d7f16acSAxel Dörfler 		tab->SetView(NULL);
1437d7f16acSAxel Dörfler 
1447d7f16acSAxel Dörfler 	fTypeEditorView = view;
1457d7f16acSAxel Dörfler 
1467d7f16acSAxel Dörfler 	if (view == NULL)
1477d7f16acSAxel Dörfler 		view = fNoEditorView;
1487d7f16acSAxel Dörfler 
1497d7f16acSAxel Dörfler 	if (CountTabs() == 0)
1507d7f16acSAxel Dörfler 		AddTab(view);
1517d7f16acSAxel Dörfler 	else
1527d7f16acSAxel Dörfler 		tab->SetView(view);
1537d7f16acSAxel Dörfler 
1547d7f16acSAxel Dörfler 	FrameResized(0, 0);
155871fa04fSAxel Dörfler 
1566f850dfdSAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_BEOS
157871fa04fSAxel Dörfler 	if (Window() != NULL) {
158871fa04fSAxel Dörfler 		// With R5's BTabView, calling select without being
159871fa04fSAxel Dörfler 		// attached to a window crashes...
1607d7f16acSAxel Dörfler 		Select(0);
1617d7f16acSAxel Dörfler 	}
162871fa04fSAxel Dörfler #else
163871fa04fSAxel Dörfler 	Select(0);
164871fa04fSAxel Dörfler #endif
165871fa04fSAxel Dörfler }
1667d7f16acSAxel Dörfler 
1677d7f16acSAxel Dörfler 
1687d7f16acSAxel Dörfler //	#pragma mark -
1697d7f16acSAxel Dörfler 
1707d7f16acSAxel Dörfler 
171758b1d0eSIngo Weinhold AttributeWindow::AttributeWindow(BRect _rect, entry_ref *ref, const char *attribute,
1727fff3ed0SAxel Dörfler 	const BMessage *settings)
173758b1d0eSIngo Weinhold 	: ProbeWindow(_rect, ref),
174d11ec082SAxel Dörfler 	fAttribute(strdup(attribute))
175d11ec082SAxel Dörfler {
17686daa6f2SAxel Dörfler 	// Set alternative window title for devices
17786daa6f2SAxel Dörfler 
17886daa6f2SAxel Dörfler 	char name[B_FILE_NAME_LENGTH];
1796f850dfdSAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_BEOS
18086daa6f2SAxel Dörfler 	strncpy(name, ref->name, sizeof(name));
18186daa6f2SAxel Dörfler 	name[sizeof(name) - 1] = '\0';
18286daa6f2SAxel Dörfler #else
18386daa6f2SAxel Dörfler 	strlcpy(name, ref->name, sizeof(name));
18486daa6f2SAxel Dörfler #endif
18586daa6f2SAxel Dörfler 
18686daa6f2SAxel Dörfler 	BEntry entry(ref);
18786daa6f2SAxel Dörfler 	if (entry.IsDirectory()) {
18886daa6f2SAxel Dörfler 		BDirectory directory(&entry);
18986daa6f2SAxel Dörfler 		if (directory.InitCheck() == B_OK && directory.IsRootDirectory()) {
19086daa6f2SAxel Dörfler 			// use the volume name for root directories
19186daa6f2SAxel Dörfler 			BVolume volume;
19286daa6f2SAxel Dörfler 			if (directory.GetVolume(&volume) == B_OK)
19386daa6f2SAxel Dörfler 				volume.GetName(name);
19486daa6f2SAxel Dörfler 		}
19586daa6f2SAxel Dörfler 	}
19686daa6f2SAxel Dörfler 	char buffer[B_PATH_NAME_LENGTH];
19786daa6f2SAxel Dörfler 	snprintf(buffer, sizeof(buffer), "%s: %s", name, attribute);
198d11ec082SAxel Dörfler 	SetTitle(buffer);
199d11ec082SAxel Dörfler 
200d11ec082SAxel Dörfler 	// add the menu
201d11ec082SAxel Dörfler 
202d11ec082SAxel Dörfler 	BMenuBar *menuBar = new BMenuBar(BRect(0, 0, 0, 0), NULL);
203d11ec082SAxel Dörfler 	AddChild(menuBar);
204d11ec082SAxel Dörfler 
205d11ec082SAxel Dörfler 	BMenu *menu = new BMenu("Attribute");
206d11ec082SAxel Dörfler 
2076781cbdcSAxel Dörfler 	// the ProbeView save menu items will be inserted here
20836a79516SAxel Dörfler 	menu->AddItem(new BMenuItem("Remove from File", new BMessage(kMsgRemoveAttribute)));
20936a79516SAxel Dörfler 	menu->AddSeparatorItem();
21036a79516SAxel Dörfler 
2116781cbdcSAxel Dörfler 	// the ProbeView print menu items will be inserted here
212d11ec082SAxel Dörfler 	menu->AddSeparatorItem();
213d11ec082SAxel Dörfler 
214d11ec082SAxel Dörfler 	menu->AddItem(new BMenuItem("Close", new BMessage(B_CLOSE_REQUESTED), 'W', B_COMMAND_KEY));
215d11ec082SAxel Dörfler 	menu->SetTargetForItems(this);
216d11ec082SAxel Dörfler 	menuBar->AddItem(menu);
217d11ec082SAxel Dörfler 
218d11ec082SAxel Dörfler 	// add our interface widgets
219d11ec082SAxel Dörfler 
220d11ec082SAxel Dörfler 	BRect rect = Bounds();
221d11ec082SAxel Dörfler 	rect.top = menuBar->Bounds().Height() + 1;
222d11ec082SAxel Dörfler 
2237d7f16acSAxel Dörfler 	BView *view = new BView(rect, "main", B_FOLLOW_ALL, 0);
2247d7f16acSAxel Dörfler 	view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
2257d7f16acSAxel Dörfler 	AddChild(view);
2267d7f16acSAxel Dörfler 
2277d7f16acSAxel Dörfler 	rect = view->Bounds();
2287d7f16acSAxel Dörfler 	rect.top += 3;
2297d7f16acSAxel Dörfler 
2307d7f16acSAxel Dörfler 	EditorTabView *tabView = new EditorTabView(rect, "tabView");
2317d7f16acSAxel Dörfler 
2327d7f16acSAxel Dörfler 	rect = tabView->ContainerView()->Bounds();
2337d7f16acSAxel Dörfler 	rect.top += 3;
2347d7f16acSAxel Dörfler 	fProbeView = new ProbeView(rect, ref, attribute, settings);
2357d7f16acSAxel Dörfler 	tabView->AddRawEditorTab(fProbeView);
2367d7f16acSAxel Dörfler 
2377d7f16acSAxel Dörfler 	view->AddChild(tabView);
2387d7f16acSAxel Dörfler 
239fa78c88eSAxel Dörfler 	fTypeEditorView = GetTypeEditorFor(rect, fProbeView->Editor());
240fa78c88eSAxel Dörfler 	if (fTypeEditorView != NULL)
241fa78c88eSAxel Dörfler 		tabView->SetTypeEditorTab(fTypeEditorView);
2427d7f16acSAxel Dörfler 	else {
2437d7f16acSAxel Dörfler 		// show the raw editor if we don't have a specialised type editor
2447d7f16acSAxel Dörfler 		tabView->Select(1);
2457d7f16acSAxel Dörfler 	}
2467d7f16acSAxel Dörfler 
247c0ced84aSAxel Dörfler 	fProbeView->AddSaveMenuItems(menu, 0);
248c0ced84aSAxel Dörfler 	fProbeView->AddPrintMenuItems(menu, menu->CountItems() - 2);
249c0ced84aSAxel Dörfler 
2507d7f16acSAxel Dörfler 	fProbeView->UpdateSizeLimits();
251d11ec082SAxel Dörfler }
252d11ec082SAxel Dörfler 
253d11ec082SAxel Dörfler 
254d11ec082SAxel Dörfler AttributeWindow::~AttributeWindow()
255d11ec082SAxel Dörfler {
256d11ec082SAxel Dörfler 	free(fAttribute);
257d11ec082SAxel Dörfler }
258d11ec082SAxel Dörfler 
259d11ec082SAxel Dörfler 
26036a79516SAxel Dörfler void
26136a79516SAxel Dörfler AttributeWindow::MessageReceived(BMessage *message)
26236a79516SAxel Dörfler {
26336a79516SAxel Dörfler 	switch (message->what) {
26436a79516SAxel Dörfler 		case kMsgRemoveAttribute:
26536a79516SAxel Dörfler 		{
26636a79516SAxel Dörfler 			char buffer[1024];
26736a79516SAxel Dörfler 			snprintf(buffer, sizeof(buffer),
26836a79516SAxel Dörfler 				"Do you really want to remove the attribute \"%s\" from the file \"%s\"?\n\n"
269768673c6SAxel Dörfler 				"You cannot undo this action.",
27036a79516SAxel Dörfler 				fAttribute, Ref().name);
27136a79516SAxel Dörfler 
27236a79516SAxel Dörfler 			int32 chosen = (new BAlert("DiskProbe request",
273768673c6SAxel Dörfler 				buffer, "Cancel", "Remove", NULL,
27436a79516SAxel Dörfler 				B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go();
275768673c6SAxel Dörfler 			if (chosen == 1) {
27636a79516SAxel Dörfler 				BNode node(&Ref());
27736a79516SAxel Dörfler 				if (node.InitCheck() == B_OK)
27836a79516SAxel Dörfler 					node.RemoveAttr(fAttribute);
27936a79516SAxel Dörfler 
28036a79516SAxel Dörfler 				PostMessage(B_QUIT_REQUESTED);
28136a79516SAxel Dörfler 			}
28236a79516SAxel Dörfler 			break;
28336a79516SAxel Dörfler 		}
28436a79516SAxel Dörfler 
28536a79516SAxel Dörfler 		default:
28636a79516SAxel Dörfler 			ProbeWindow::MessageReceived(message);
28736a79516SAxel Dörfler 			break;
28836a79516SAxel Dörfler 	}
28936a79516SAxel Dörfler }
29036a79516SAxel Dörfler 
29136a79516SAxel Dörfler 
292d11ec082SAxel Dörfler bool
2930adaff85SAxel Dörfler AttributeWindow::QuitRequested()
2940adaff85SAxel Dörfler {
295c1381da9SAxel Dörfler 	if (fTypeEditorView != NULL)
296fa78c88eSAxel Dörfler 		fTypeEditorView->CommitChanges();
297fa78c88eSAxel Dörfler 
2980adaff85SAxel Dörfler 	bool quit = fProbeView->QuitRequested();
2990adaff85SAxel Dörfler 	if (!quit)
3000adaff85SAxel Dörfler 		return false;
3010adaff85SAxel Dörfler 
3020adaff85SAxel Dörfler 	return ProbeWindow::QuitRequested();
3030adaff85SAxel Dörfler }
3040adaff85SAxel Dörfler 
3050adaff85SAxel Dörfler 
3060adaff85SAxel Dörfler bool
307d11ec082SAxel Dörfler AttributeWindow::Contains(const entry_ref &ref, const char *attribute)
308d11ec082SAxel Dörfler {
309d11ec082SAxel Dörfler 	return ref == Ref() && attribute != NULL && !strcmp(attribute, fAttribute);
310d11ec082SAxel Dörfler }
311d11ec082SAxel Dörfler 
312