xref: /haiku/src/kits/tracker/MountMenu.cpp (revision 9760dcae2038d47442f4658c2575844c6cf92c40)
1 /*
2 Open Tracker License
3 
4 Terms and Conditions
5 
6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
7 
8 Permission is hereby granted, free of charge, to any person obtaining a copy of
9 this software and associated documentation files (the "Software"), to deal in
10 the Software without restriction, including without limitation the rights to
11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 of the Software, and to permit persons to whom the Software is furnished to do
13 so, subject to the following conditions:
14 
15 The above copyright notice and this permission notice applies to all licensees
16 and shall be included in all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 
25 Except as contained in this notice, the name of Be Incorporated shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings in
27 this Software without prior written authorization from Be Incorporated.
28 
29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
30 of Be Incorporated in the United States and other countries. Other brand product
31 names are registered trademarks or trademarks of their respective holders.
32 All rights reserved.
33 */
34 
35 // MountMenu implements a context menu used for mounting/unmounting volumes
36 
37 #include <Debug.h>
38 #include <MenuItem.h>
39 #include <Mime.h>
40 #include <InterfaceDefs.h>
41 #include <VolumeRoster.h>
42 #include <Volume.h>
43 #include <fs_info.h>
44 
45 #include "Commands.h"
46 #include "MountMenu.h"
47 #include "IconMenuItem.h"
48 #include "Tracker.h"
49 #include "Bitmaps.h"
50 
51 #include <DiskDevice.h>
52 #include <DiskDeviceList.h>
53 
54 #define SHOW_NETWORK_VOLUMES
55 
56 
57 class AddMenuItemVisitor : public BDiskDeviceVisitor {
58 	public:
59 		AddMenuItemVisitor(BMenu* menu);
60 		virtual ~AddMenuItemVisitor();
61 
62 		virtual bool Visit(BDiskDevice *device);
63 		virtual bool Visit(BPartition *partition, int32 level);
64 
65 	private:
66 		BMenu* fMenu;
67 };
68 
69 
70 AddMenuItemVisitor::AddMenuItemVisitor(BMenu* menu)
71 	:
72 	fMenu(menu)
73 {
74 }
75 
76 
77 AddMenuItemVisitor::~AddMenuItemVisitor()
78 {
79 }
80 
81 
82 bool
83 AddMenuItemVisitor::Visit(BDiskDevice *device)
84 {
85 	return Visit(device, 0);
86 }
87 
88 
89 bool
90 AddMenuItemVisitor::Visit(BPartition *partition, int32 level)
91 {
92 	if (!partition->ContainsFileSystem())
93 		return false;
94 
95 	// get name (and eventually the type)
96 	BString name = partition->ContentName();
97 	if (name.Length() == 0) {
98 		name = partition->Name();
99 		if (name.Length() == 0) {
100 			const char *type = partition->ContentType();
101 			if (type == NULL)
102 				return false;
103 
104 			uint32 divisor = 1UL << 30;
105 			char unit = 'G';
106 			if (partition->Size() < divisor) {
107 				divisor = 1UL << 20;
108 				unit = 'M';
109 			}
110 
111 			char* buffer = name.LockBuffer(256);
112 			snprintf(buffer, 256, "(%.1f %cB %s)",
113 				1.0 * partition->Size() / divisor, unit, type);
114 
115 			name.UnlockBuffer();
116 		}
117 	}
118 
119 	// get icon
120 	BBitmap *icon = new BBitmap(BRect(0, 0, B_MINI_ICON - 1, B_MINI_ICON - 1),
121 		B_RGBA32);
122 	if (partition->GetIcon(icon, B_MINI_ICON) != B_OK) {
123 		delete icon;
124 		icon = NULL;
125 	}
126 
127 	BMessage *message = new BMessage(partition->IsMounted() ?
128 		kUnmountVolume : kMountVolume);
129 	message->AddInt32("id", partition->ID());
130 
131 	// TODO: for now, until we actually have disk device icons
132 	BMenuItem *item;
133 	if (icon != NULL)
134 		item = new IconMenuItem(name.String(), message, icon);
135 	else
136 		item = new BMenuItem(name.String(), message);
137 	if (partition->IsMounted()) {
138 		item->SetMarked(true);
139 
140 		BVolume volume;
141 		if (partition->GetVolume(&volume) == B_OK) {
142 			BVolume bootVolume;
143 			BVolumeRoster().GetBootVolume(&bootVolume);
144 			if (volume == bootVolume)
145 				item->SetEnabled(false);
146 		}
147 	}
148 
149 	fMenu->AddItem(item);
150 	return false;
151 }
152 
153 
154 //	#pragma mark -
155 
156 
157 MountMenu::MountMenu(const char *name)
158 	: BMenu(name)
159 {
160 	SetFont(be_plain_font);
161 }
162 
163 
164 bool
165 MountMenu::AddDynamicItem(add_state)
166 {
167 	// remove old items
168 	for (;;) {
169 		BMenuItem *item = RemoveItem(0L);
170 		if (item == NULL)
171 			break;
172 		delete item;
173 	}
174 
175 	BDiskDeviceList devices;
176 	status_t status = devices.Fetch();
177 	if (status == B_OK) {
178 		AddMenuItemVisitor visitor(this);
179 		devices.VisitEachPartition(&visitor);
180 	}
181 
182 #ifdef SHOW_NETWORK_VOLUMES
183 	// iterate the volume roster and look for volumes with the
184 	// 'shared' attributes -- these same volumes will not be returned
185 	// by the autoMounter because they do not show up in the /dev tree
186 	BVolumeRoster volumeRoster;
187 	BVolume volume;
188 	bool needSeparator = false;
189 	while (volumeRoster.GetNextVolume(&volume) == B_OK) {
190 		if (volume.IsShared()) {
191 			needSeparator = true;
192 			BBitmap *icon = new BBitmap(BRect(0, 0, 15, 15), B_CMAP8);
193 			fs_info info;
194 			if (fs_stat_dev(volume.Device(), &info) != B_OK) {
195 				PRINT(("Cannot get mount menu item icon; bad device ID\n"));
196 				delete icon;
197 				continue;
198 			}
199 			// Use the shared icon instead of the device icon
200 			if (get_device_icon(info.device_name, icon->Bits(), B_MINI_ICON) != B_OK)
201 				GetTrackerResources()->GetIconResource(kResShareIcon, B_MINI_ICON, icon);
202 
203 			BMessage *message = new BMessage(kUnmountVolume);
204 			message->AddInt32("device_id", volume.Device());
205 			char volumeName[B_FILE_NAME_LENGTH];
206 			volume.GetName(volumeName);
207 
208 			BMenuItem *item = new IconMenuItem(volumeName, message, icon);
209 			item->SetMarked(true);
210 			AddItem(item);
211 		}
212 	}
213 #endif	// SHOW_NETWORK_VOLUMES
214 
215 	AddSeparatorItem();
216 
217 	BMenuItem *mountAll = new BMenuItem("Mount all",
218 		new BMessage(kMountAllNow));
219 	AddItem(mountAll);
220 	BMenuItem *mountSettings = new BMenuItem("Settings" B_UTF8_ELLIPSIS,
221 		new BMessage(kRunAutomounterSettings));
222 	AddItem(mountSettings);
223 
224 	SetTargetForItems(be_app);
225 
226 	return false;
227 }
228