102be5353SAxel Dörfler/*
202be5353SAxel DörflerOpen Tracker License
302be5353SAxel Dörfler
402be5353SAxel DörflerTerms and Conditions
502be5353SAxel Dörfler
602be5353SAxel DörflerCopyright (c) 1991-2000, Be Incorporated. All rights reserved.
702be5353SAxel Dörfler
802be5353SAxel DörflerPermission is hereby granted, free of charge, to any person obtaining a copy of
902be5353SAxel Dörflerthis software and associated documentation files (the "Software"), to deal in
1002be5353SAxel Dörflerthe Software without restriction, including without limitation the rights to
1102be5353SAxel Dörfleruse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
1202be5353SAxel Dörflerof the Software, and to permit persons to whom the Software is furnished to do
1302be5353SAxel Dörflerso, subject to the following conditions:
1402be5353SAxel Dörfler
1502be5353SAxel DörflerThe above copyright notice and this permission notice applies to all licensees
1602be5353SAxel Dörflerand shall be included in all copies or substantial portions of the Software.
1702be5353SAxel Dörfler
1802be5353SAxel DörflerTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1902be5353SAxel DörflerIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
2002be5353SAxel DörflerFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
2102be5353SAxel DörflerBE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2202be5353SAxel DörflerAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
2302be5353SAxel DörflerWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2402be5353SAxel Dörfler
2502be5353SAxel DörflerExcept as contained in this notice, the name of Be Incorporated shall not be
2602be5353SAxel Dörflerused in advertising or otherwise to promote the sale, use or other dealings in
2702be5353SAxel Dörflerthis Software without prior written authorization from Be Incorporated.
2802be5353SAxel Dörfler
2902be5353SAxel DörflerTracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
3002be5353SAxel Dörflerof Be Incorporated in the United States and other countries. Other brand product
3102be5353SAxel Dörflernames are registered trademarks or trademarks of their respective holders.
3202be5353SAxel DörflerAll rights reserved.
3302be5353SAxel Dörfler*/
3402be5353SAxel Dörfler
3502be5353SAxel Dörfler// MountMenu implements a context menu used for mounting/unmounting volumes
3602be5353SAxel Dörfler
37dbe62cc7SJohn Scipione
38dbe62cc7SJohn Scipione#include "MountMenu.h"
39dbe62cc7SJohn Scipione
404ed28a57SAlexandre Deckner#include <Catalog.h>
414fba3522SIngo Weinhold#include <Debug.h>
424ed28a57SAlexandre Deckner#include <Locale.h>
4302be5353SAxel Dörfler#include <MenuItem.h>
4402be5353SAxel Dörfler#include <Mime.h>
4502be5353SAxel Dörfler#include <InterfaceDefs.h>
4602be5353SAxel Dörfler#include <VolumeRoster.h>
4702be5353SAxel Dörfler#include <Volume.h>
48dbe62cc7SJohn Scipione
4902be5353SAxel Dörfler#include <fs_info.h>
5002be5353SAxel Dörfler
5102be5353SAxel Dörfler#include "Commands.h"
5202be5353SAxel Dörfler#include "IconMenuItem.h"
5302be5353SAxel Dörfler#include "Tracker.h"
5402be5353SAxel Dörfler#include "Bitmaps.h"
5502be5353SAxel Dörfler
56c1b274fdSStephan Aßmus#include <DiskDevice.h>
57c1b274fdSStephan Aßmus#include <DiskDeviceList.h>
5802be5353SAxel Dörfler
5902be5353SAxel Dörfler#define SHOW_NETWORK_VOLUMES
6002be5353SAxel Dörfler
61dbe62cc7SJohn Scipione#undef B_TRANSLATION_CONTEXT
62dbe62cc7SJohn Scipione#define B_TRANSLATION_CONTEXT "MountMenu"
63dbe62cc7SJohn Scipione
6477187226SAxel Dörfler
6564866164SAxel Dörflerclass AddMenuItemVisitor : public BDiskDeviceVisitor {
66dbe62cc7SJohn Scipionepublic:
67dbe62cc7SJohn Scipione	AddMenuItemVisitor(BMenu* menu);
68dbe62cc7SJohn Scipione	virtual ~AddMenuItemVisitor();
6964866164SAxel Dörfler
70dbe62cc7SJohn Scipione	virtual bool Visit(BDiskDevice* device);
71dbe62cc7SJohn Scipione	virtual bool Visit(BPartition* partition, int32 level);
7264866164SAxel Dörfler
73dbe62cc7SJohn Scipioneprivate:
74dbe62cc7SJohn Scipione	BMenu* fMenu;
7564866164SAxel Dörfler};
7664866164SAxel Dörfler
7764866164SAxel Dörfler
78dbe62cc7SJohn Scipione//	#pragma mark - AddMenuItemVisitor
79dbe62cc7SJohn Scipione
80dbe62cc7SJohn Scipione
8164866164SAxel DörflerAddMenuItemVisitor::AddMenuItemVisitor(BMenu* menu)
8264866164SAxel Dörfler	:
8364866164SAxel Dörfler	fMenu(menu)
8402be5353SAxel Dörfler{
8502be5353SAxel Dörfler}
8602be5353SAxel Dörfler
8702be5353SAxel Dörfler
8864866164SAxel DörflerAddMenuItemVisitor::~AddMenuItemVisitor()
8964866164SAxel Dörfler{
9064866164SAxel Dörfler}
9164866164SAxel Dörfler
9264866164SAxel Dörfler
9364866164SAxel Dörflerbool
94b05aa8b5SJohn ScipioneAddMenuItemVisitor::Visit(BDiskDevice* device)
9564866164SAxel Dörfler{
9664866164SAxel Dörfler	return Visit(device, 0);
9764866164SAxel Dörfler}
9864866164SAxel Dörfler
9964866164SAxel Dörfler
10064866164SAxel Dörflerbool
101b05aa8b5SJohn ScipioneAddMenuItemVisitor::Visit(BPartition* partition, int32 level)
10264866164SAxel Dörfler{
10364866164SAxel Dörfler	if (!partition->ContainsFileSystem())
10447908b9aSStefano Ceccherini		return false;
10564866164SAxel Dörfler
10664866164SAxel Dörfler	// get name (and eventually the type)
10764866164SAxel Dörfler	BString name = partition->ContentName();
10864866164SAxel Dörfler	if (name.Length() == 0) {
10964866164SAxel Dörfler		name = partition->Name();
11064866164SAxel Dörfler		if (name.Length() == 0) {
111b05aa8b5SJohn Scipione			const char* type = partition->ContentType();
11264866164SAxel Dörfler			if (type == NULL)
11347908b9aSStefano Ceccherini				return false;
11464866164SAxel Dörfler
115dcdf3137SAxel Dörfler			uint32 divisor = 1UL << 30;
116dcdf3137SAxel Dörfler			char unit = 'G';
117dcdf3137SAxel Dörfler			if (partition->Size() < divisor) {
118dcdf3137SAxel Dörfler				divisor = 1UL << 20;
119dcdf3137SAxel Dörfler				unit = 'M';
120dcdf3137SAxel Dörfler			}
121dcdf3137SAxel Dörfler
122dcdf3137SAxel Dörfler			char* buffer = name.LockBuffer(256);
123dcdf3137SAxel Dörfler			snprintf(buffer, 256, "(%.1f %cB %s)",
124dcdf3137SAxel Dörfler				1.0 * partition->Size() / divisor, unit, type);
125dcdf3137SAxel Dörfler
126dcdf3137SAxel Dörfler			name.UnlockBuffer();
12764866164SAxel Dörfler		}
12864866164SAxel Dörfler	}
12964866164SAxel Dörfler
13064866164SAxel Dörfler	// get icon
131b05aa8b5SJohn Scipione	BBitmap* icon = new BBitmap(BRect(0, 0, B_MINI_ICON - 1, B_MINI_ICON - 1),
13206ba3f0aSAxel Dörfler		B_RGBA32);
13364866164SAxel Dörfler	if (partition->GetIcon(icon, B_MINI_ICON) != B_OK) {
13464866164SAxel Dörfler		delete icon;
13564866164SAxel Dörfler		icon = NULL;
13664866164SAxel Dörfler	}
13764866164SAxel Dörfler
138b05aa8b5SJohn Scipione	BMessage* message = new BMessage(partition->IsMounted() ?
13964866164SAxel Dörfler		kUnmountVolume : kMountVolume);
14064866164SAxel Dörfler	message->AddInt32("id", partition->ID());
14164866164SAxel Dörfler
14264866164SAxel Dörfler	// TODO: for now, until we actually have disk device icons
143b05aa8b5SJohn Scipione	BMenuItem* item;
14464866164SAxel Dörfler	if (icon != NULL)
14564866164SAxel Dörfler		item = new IconMenuItem(name.String(), message, icon);
14664866164SAxel Dörfler	else
14764866164SAxel Dörfler		item = new BMenuItem(name.String(), message);
14864866164SAxel Dörfler	if (partition->IsMounted()) {
14964866164SAxel Dörfler		item->SetMarked(true);
15064866164SAxel Dörfler
15164866164SAxel Dörfler		BVolume volume;
15264866164SAxel Dörfler		if (partition->GetVolume(&volume) == B_OK) {
15364866164SAxel Dörfler			BVolume bootVolume;
15464866164SAxel Dörfler			BVolumeRoster().GetBootVolume(&bootVolume);
15564866164SAxel Dörfler			if (volume == bootVolume)
15664866164SAxel Dörfler				item->SetEnabled(false);
15764866164SAxel Dörfler		}
15864866164SAxel Dörfler	}
15964866164SAxel Dörfler
16064866164SAxel Dörfler	fMenu->AddItem(item);
16164866164SAxel Dörfler	return false;
16264866164SAxel Dörfler}
16364866164SAxel Dörfler
16464866164SAxel Dörfler
165dbe62cc7SJohn Scipione//	#pragma mark - MountMenu
16664866164SAxel Dörfler
16764866164SAxel Dörfler
168b05aa8b5SJohn ScipioneMountMenu::MountMenu(const char* name)
16964866164SAxel Dörfler	: BMenu(name)
17064866164SAxel Dörfler{
17164866164SAxel Dörfler	SetFont(be_plain_font);
17264866164SAxel Dörfler}
17302be5353SAxel Dörfler
17402be5353SAxel Dörfler
17502be5353SAxel Dörflerbool
17602be5353SAxel DörflerMountMenu::AddDynamicItem(add_state)
17702be5353SAxel Dörfler{
17864866164SAxel Dörfler	// remove old items
17902be5353SAxel Dörfler	for (;;) {
180adf8818eSAlex Smith		BMenuItem* item = RemoveItem((int32)0);
18102be5353SAxel Dörfler		if (item == NULL)
18202be5353SAxel Dörfler			break;
18302be5353SAxel Dörfler		delete item;
18402be5353SAxel Dörfler	}
18502be5353SAxel Dörfler
18664866164SAxel Dörfler	BDiskDeviceList devices;
18764866164SAxel Dörfler	status_t status = devices.Fetch();
18864866164SAxel Dörfler	if (status == B_OK) {
18964866164SAxel Dörfler		AddMenuItemVisitor visitor(this);
19064866164SAxel Dörfler		devices.VisitEachPartition(&visitor);
19164866164SAxel Dörfler	}
19202be5353SAxel Dörfler
19302be5353SAxel Dörfler#ifdef SHOW_NETWORK_VOLUMES
19402be5353SAxel Dörfler	// iterate the volume roster and look for volumes with the
19502be5353SAxel Dörfler	// 'shared' attributes -- these same volumes will not be returned
19602be5353SAxel Dörfler	// by the autoMounter because they do not show up in the /dev tree
19702be5353SAxel Dörfler	BVolumeRoster volumeRoster;
19802be5353SAxel Dörfler	BVolume volume;
19902be5353SAxel Dörfler	while (volumeRoster.GetNextVolume(&volume) == B_OK) {
20002be5353SAxel Dörfler		if (volume.IsShared()) {
201b05aa8b5SJohn Scipione			BBitmap* icon = new BBitmap(BRect(0, 0, 15, 15), B_CMAP8);
20202be5353SAxel Dörfler			fs_info info;
20302be5353SAxel Dörfler			if (fs_stat_dev(volume.Device(), &info) != B_OK) {
20402be5353SAxel Dörfler				PRINT(("Cannot get mount menu item icon; bad device ID\n"));
20502be5353SAxel Dörfler				delete icon;
20602be5353SAxel Dörfler				continue;
20702be5353SAxel Dörfler			}
20802be5353SAxel Dörfler			// Use the shared icon instead of the device icon
209dbe62cc7SJohn Scipione			if (get_device_icon(info.device_name, icon->Bits(), B_MINI_ICON)
210dbe62cc7SJohn Scipione					!= B_OK) {
211dbe62cc7SJohn Scipione				GetTrackerResources()->GetIconResource(R_ShareIcon,
212dbe62cc7SJohn Scipione					B_MINI_ICON, icon);
213dbe62cc7SJohn Scipione			}
214dcdf3137SAxel Dörfler
215b05aa8b5SJohn Scipione			BMessage* message = new BMessage(kUnmountVolume);
21602be5353SAxel Dörfler			message->AddInt32("device_id", volume.Device());
21702be5353SAxel Dörfler			char volumeName[B_FILE_NAME_LENGTH];
21802be5353SAxel Dörfler			volume.GetName(volumeName);
219dcdf3137SAxel Dörfler
220b05aa8b5SJohn Scipione			BMenuItem* item = new IconMenuItem(volumeName, message, icon);
22102be5353SAxel Dörfler			item->SetMarked(true);
22202be5353SAxel Dörfler			AddItem(item);
22302be5353SAxel Dörfler		}
22402be5353SAxel Dörfler	}
22577187226SAxel Dörfler#endif	// SHOW_NETWORK_VOLUMES
22602be5353SAxel Dörfler
22702be5353SAxel Dörfler	AddSeparatorItem();
22802be5353SAxel Dörfler
2294ed28a57SAlexandre Deckner	BMenuItem* mountAll = new BMenuItem(B_TRANSLATE("Mount all"),
230c1b274fdSStephan Aßmus		new BMessage(kMountAllNow));
23102be5353SAxel Dörfler	AddItem(mountAll);
2324ed28a57SAlexandre Deckner	BMenuItem* mountSettings = new BMenuItem(
2334ed28a57SAlexandre Deckner		B_TRANSLATE("Settings" B_UTF8_ELLIPSIS),
23402be5353SAxel Dörfler		new BMessage(kRunAutomounterSettings));
23502be5353SAxel Dörfler	AddItem(mountSettings);
23602be5353SAxel Dörfler
23702be5353SAxel Dörfler	SetTargetForItems(be_app);
238dcdf3137SAxel Dörfler
23902be5353SAxel Dörfler	return false;
24002be5353SAxel Dörfler}
241