xref: /haiku/src/kits/tracker/MountMenu.cpp (revision ed24eb5ff12640d052171c6a7feba37fab8a75d1)
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 
38 #include "MountMenu.h"
39 
40 #include <Catalog.h>
41 #include <ControlLook.h>
42 #include <Debug.h>
43 #include <Locale.h>
44 #include <MenuItem.h>
45 #include <Mime.h>
46 #include <InterfaceDefs.h>
47 #include <VolumeRoster.h>
48 #include <Volume.h>
49 
50 #include <fs_info.h>
51 
52 #include "Commands.h"
53 #include "IconMenuItem.h"
54 #include "Tracker.h"
55 #include "Bitmaps.h"
56 
57 #include <DiskDevice.h>
58 #include <DiskDeviceList.h>
59 
60 #define SHOW_NETWORK_VOLUMES
61 
62 #undef B_TRANSLATION_CONTEXT
63 #define B_TRANSLATION_CONTEXT "MountMenu"
64 
65 
66 class AddMenuItemVisitor : public BDiskDeviceVisitor {
67 public:
68 	AddMenuItemVisitor(BMenu* menu);
69 	virtual ~AddMenuItemVisitor();
70 
71 	virtual bool Visit(BDiskDevice* device);
72 	virtual bool Visit(BPartition* partition, int32 level);
73 
74 private:
75 	BMenu* fMenu;
76 };
77 
78 
79 //	#pragma mark - AddMenuItemVisitor
80 
81 
82 AddMenuItemVisitor::AddMenuItemVisitor(BMenu* menu)
83 	:
84 	fMenu(menu)
85 {
86 }
87 
88 
89 AddMenuItemVisitor::~AddMenuItemVisitor()
90 {
91 }
92 
93 
94 bool
95 AddMenuItemVisitor::Visit(BDiskDevice* device)
96 {
97 	return Visit(device, 0);
98 }
99 
100 
101 bool
102 AddMenuItemVisitor::Visit(BPartition* partition, int32 level)
103 {
104 	if (!partition->ContainsFileSystem())
105 		return false;
106 
107 	// get name (and eventually the type)
108 	BString name = partition->ContentName();
109 	if (name.Length() == 0) {
110 		name = partition->Name();
111 		if (name.Length() == 0) {
112 			const char* type = partition->ContentType();
113 			if (type == NULL)
114 				return false;
115 
116 			uint32 divisor = 1UL << 30;
117 			char unit = 'G';
118 			if (partition->Size() < divisor) {
119 				divisor = 1UL << 20;
120 				unit = 'M';
121 			}
122 
123 			name.SetToFormat("(%.1f %cB %s)",
124 				1.0 * partition->Size() / divisor, unit, type);
125 		}
126 	}
127 
128 	// get icon
129 	BBitmap* icon = new BBitmap(BRect(BPoint(0, 0), be_control_look->ComposeIconSize(B_MINI_ICON)),
130 		B_RGBA32);
131 	if (partition->GetIcon(icon, B_MINI_ICON) != B_OK) {
132 		delete icon;
133 		icon = NULL;
134 	}
135 
136 	BMessage* message = new BMessage(partition->IsMounted() ?
137 		kUnmountVolume : kMountVolume);
138 	message->AddInt32("id", partition->ID());
139 
140 	// TODO: for now, until we actually have disk device icons
141 	BMenuItem* item;
142 	if (icon != NULL)
143 		item = new IconMenuItem(name.String(), message, icon);
144 	else
145 		item = new BMenuItem(name.String(), message);
146 	if (partition->IsMounted()) {
147 		item->SetMarked(true);
148 
149 		BVolume volume;
150 		if (partition->GetVolume(&volume) == B_OK) {
151 			BVolume bootVolume;
152 			BVolumeRoster().GetBootVolume(&bootVolume);
153 			if (volume == bootVolume)
154 				item->SetEnabled(false);
155 		}
156 	}
157 
158 	fMenu->AddItem(item);
159 	return false;
160 }
161 
162 
163 //	#pragma mark - MountMenu
164 
165 
166 MountMenu::MountMenu(const char* name)
167 	: BMenu(name)
168 {
169 }
170 
171 
172 bool
173 MountMenu::AddDynamicItem(add_state)
174 {
175 	// remove old items
176 	for (;;) {
177 		BMenuItem* item = RemoveItem((int32)0);
178 		if (item == NULL)
179 			break;
180 		delete item;
181 	}
182 
183 	BDiskDeviceList devices;
184 	status_t status = devices.Fetch();
185 	if (status == B_OK) {
186 		AddMenuItemVisitor visitor(this);
187 		devices.VisitEachPartition(&visitor);
188 	}
189 
190 #ifdef SHOW_NETWORK_VOLUMES
191 	// iterate the volume roster and look for volumes with the
192 	// 'shared' attributes -- these same volumes will not be returned
193 	// by the autoMounter because they do not show up in the /dev tree
194 	BVolumeRoster volumeRoster;
195 	BVolume volume;
196 	while (volumeRoster.GetNextVolume(&volume) == B_OK) {
197 		if (volume.IsShared()) {
198 			BBitmap* icon = new BBitmap(BRect(0, 0, 15, 15), B_CMAP8);
199 			fs_info info;
200 			if (fs_stat_dev(volume.Device(), &info) != B_OK) {
201 				PRINT(("Cannot get mount menu item icon; bad device ID\n"));
202 				delete icon;
203 				continue;
204 			}
205 			// Use the shared icon instead of the device icon
206 			if (get_device_icon(info.device_name, icon, B_MINI_ICON)
207 					!= B_OK) {
208 				GetTrackerResources()->GetIconResource(R_ShareIcon,
209 					B_MINI_ICON, icon);
210 			}
211 
212 			BMessage* message = new BMessage(kUnmountVolume);
213 			message->AddInt32("device_id", volume.Device());
214 			char volumeName[B_FILE_NAME_LENGTH];
215 			volume.GetName(volumeName);
216 
217 			BMenuItem* item = new IconMenuItem(volumeName, message, icon);
218 			item->SetMarked(true);
219 			AddItem(item);
220 		}
221 	}
222 #endif	// SHOW_NETWORK_VOLUMES
223 
224 	AddSeparatorItem();
225 
226 	BMenuItem* mountAll = new BMenuItem(B_TRANSLATE("Mount all"),
227 		new BMessage(kMountAllNow));
228 	AddItem(mountAll);
229 	BMenuItem* mountSettings = new BMenuItem(
230 		B_TRANSLATE("Settings" B_UTF8_ELLIPSIS),
231 		new BMessage(kRunAutomounterSettings));
232 	AddItem(mountSettings);
233 
234 	SetTargetForItems(be_app);
235 
236 	return false;
237 }
238