xref: /haiku/src/kits/tracker/MountMenu.cpp (revision 4a55cc230cf7566cadcbb23b1928eefff8aea9a2)
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 	SetFont(be_plain_font);
170 }
171 
172 
173 bool
174 MountMenu::AddDynamicItem(add_state)
175 {
176 	// remove old items
177 	for (;;) {
178 		BMenuItem* item = RemoveItem((int32)0);
179 		if (item == NULL)
180 			break;
181 		delete item;
182 	}
183 
184 	BDiskDeviceList devices;
185 	status_t status = devices.Fetch();
186 	if (status == B_OK) {
187 		AddMenuItemVisitor visitor(this);
188 		devices.VisitEachPartition(&visitor);
189 	}
190 
191 #ifdef SHOW_NETWORK_VOLUMES
192 	// iterate the volume roster and look for volumes with the
193 	// 'shared' attributes -- these same volumes will not be returned
194 	// by the autoMounter because they do not show up in the /dev tree
195 	BVolumeRoster volumeRoster;
196 	BVolume volume;
197 	while (volumeRoster.GetNextVolume(&volume) == B_OK) {
198 		if (volume.IsShared()) {
199 			BBitmap* icon = new BBitmap(BRect(0, 0, 15, 15), B_CMAP8);
200 			fs_info info;
201 			if (fs_stat_dev(volume.Device(), &info) != B_OK) {
202 				PRINT(("Cannot get mount menu item icon; bad device ID\n"));
203 				delete icon;
204 				continue;
205 			}
206 			// Use the shared icon instead of the device icon
207 			if (get_device_icon(info.device_name, icon, B_MINI_ICON)
208 					!= B_OK) {
209 				GetTrackerResources()->GetIconResource(R_ShareIcon,
210 					B_MINI_ICON, icon);
211 			}
212 
213 			BMessage* message = new BMessage(kUnmountVolume);
214 			message->AddInt32("device_id", volume.Device());
215 			char volumeName[B_FILE_NAME_LENGTH];
216 			volume.GetName(volumeName);
217 
218 			BMenuItem* item = new IconMenuItem(volumeName, message, icon);
219 			item->SetMarked(true);
220 			AddItem(item);
221 		}
222 	}
223 #endif	// SHOW_NETWORK_VOLUMES
224 
225 	AddSeparatorItem();
226 
227 	BMenuItem* mountAll = new BMenuItem(B_TRANSLATE("Mount all"),
228 		new BMessage(kMountAllNow));
229 	AddItem(mountAll);
230 	BMenuItem* mountSettings = new BMenuItem(
231 		B_TRANSLATE("Settings" B_UTF8_ELLIPSIS),
232 		new BMessage(kRunAutomounterSettings));
233 	AddItem(mountSettings);
234 
235 	SetTargetForItems(be_app);
236 
237 	return false;
238 }
239