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