xref: /haiku/src/apps/diskprobe/OpenWindow.cpp (revision d3d8b26997fac34a84981e6d2b649521de2cc45a)
1 /*
2  * Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "OpenWindow.h"
8 #include "DiskProbe.h"
9 
10 #include <Application.h>
11 #include <Screen.h>
12 #include <MenuField.h>
13 #include <PopUpMenu.h>
14 #include <MenuItem.h>
15 #include <Button.h>
16 #include <Directory.h>
17 #include <Entry.h>
18 #include <Path.h>
19 
20 
21 static const uint32 kMsgProbeFile = 'prDv';
22 static const uint32 kMsgProbeDevice = 'prFl';
23 
24 
25 OpenWindow::OpenWindow()
26 	: BWindow(BRect(0, 0, 35, 10), "DiskProbe", B_TITLED_WINDOW,
27 			B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS)
28 {
29 	BView *view = new BView(Bounds(), B_EMPTY_STRING, B_FOLLOW_ALL, B_WILL_DRAW);
30 	view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
31 	AddChild(view);
32 
33 	fDevicesMenu = new BPopUpMenu("devices");
34 	CollectDevices(fDevicesMenu);
35 	if (BMenuItem *item = fDevicesMenu->ItemAt(0))
36 		item->SetMarked(true);
37 
38 	BRect rect = Bounds().InsetByCopy(8, 8);
39 	BMenuField *field = new BMenuField(rect, "devices", "Examine Device:", fDevicesMenu);
40 	field->ResizeToPreferred();
41 	field->SetDivider(field->StringWidth(field->Label()) + 8);
42 	view->AddChild(field);
43 
44 	BButton *probeDeviceButton = new BButton(BRect(10, 10, 20, 20), "file", "Probe Device",
45 		new BMessage(kMsgProbeDevice), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
46 	probeDeviceButton->ResizeToPreferred();
47 	rect = probeDeviceButton->Bounds();
48 	probeDeviceButton->MoveTo(Bounds().Width() - 8 - rect.Width(),
49 		Bounds().Height() - 8 - rect.Height());
50 	view->AddChild(probeDeviceButton);
51 
52 	// MakeDefault() may change the size and location of the button
53 	rect = probeDeviceButton->Frame();
54 	float width = rect.Width() + 58.0f;
55 	probeDeviceButton->MakeDefault(true);
56 
57 	BButton *button = new BButton(rect, "file", "Probe File" B_UTF8_ELLIPSIS,
58 		new BMessage(kMsgProbeFile), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
59 	button->ResizeToPreferred();
60 	button->MoveBy(-button->Bounds().Width() - 8, 0);
61 	view->AddChild(button);
62 	width += button->Bounds().Width();
63 
64 	button = new BButton(button->Frame(), "cancel", "Cancel",
65 		new BMessage(B_QUIT_REQUESTED), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
66 	button->ResizeToPreferred();
67 	button->MoveBy(-button->Bounds().Width() - 8, 0);
68 	view->AddChild(button);
69 	width += button->Bounds().Width();
70 
71 	// make sure the window is large enough
72 
73 	if (width < Bounds().Width())
74 		width = Bounds().Width();
75 	float height = button->Bounds().Height() + 24.0f + field->Frame().bottom;
76 	if (height < Bounds().Height())
77 		height = Bounds().Height();
78 
79 	ResizeTo(width, height);
80 
81 	BScreen screen(this);
82 	MoveTo(screen.Frame().left + (screen.Frame().Width() - Frame().Width()) / 2,
83 		screen.Frame().top + (screen.Frame().Height() - Frame().Height()) / 2);
84 }
85 
86 
87 OpenWindow::~OpenWindow()
88 {
89 }
90 
91 
92 void
93 OpenWindow::MessageReceived(BMessage *message)
94 {
95 	switch (message->what) {
96 		case kMsgProbeDevice: {
97 			BMenuItem *item = fDevicesMenu->FindMarked();
98 			if (item == NULL)
99 				break;
100 
101 			be_app_messenger.SendMessage(item->Message());
102 			PostMessage(B_QUIT_REQUESTED);
103 			break;
104 		}
105 
106 		case kMsgProbeFile:
107 			be_app_messenger.SendMessage(kMsgOpenFilePanel);
108 			PostMessage(B_QUIT_REQUESTED);
109 			break;
110 
111 		case B_SIMPLE_DATA: {
112 			// if it's a file drop, open it
113 			entry_ref ref;
114 			if (message->FindRef("refs", 0, &ref) == B_OK) {
115 				BMessage openMessage(*message);
116 				openMessage.what = B_REFS_RECEIVED;
117 
118 				be_app_messenger.SendMessage(&openMessage);
119 				PostMessage(B_QUIT_REQUESTED);
120 			}
121 			break;
122 		}
123 
124 		default:
125 			BWindow::MessageReceived(message);
126 			break;
127 	}
128 }
129 
130 
131 bool
132 OpenWindow::QuitRequested()
133 {
134 	be_app_messenger.SendMessage(kMsgOpenWindowClosed);
135 	return true;
136 }
137 
138 
139 void
140 OpenWindow::CollectDevices(BMenu *menu, BEntry *startEntry)
141 {
142 	BDirectory directory;
143 	if (startEntry != NULL)
144 		directory.SetTo(startEntry);
145 	else
146 		directory.SetTo("/dev/disk");
147 
148 	BEntry entry;
149 	while (directory.GetNextEntry(&entry) == B_OK) {
150 		if (entry.IsDirectory()) {
151 			CollectDevices(menu, &entry);
152 			continue;
153 		}
154 
155 		entry_ref ref;
156 		if (entry.GetRef(&ref) != B_OK)
157 			continue;
158 
159 		BPath path;
160 		if (entry.GetPath(&path) != B_OK)
161 			continue;
162 
163 		BMessage *message = new BMessage(B_REFS_RECEIVED);
164 		message->AddRef("refs", &ref);
165 
166 		menu->AddItem(new BMenuItem(path.Path(), message));
167 	}
168 }
169 
170