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