#include "MountMenu.h"
#include <Catalog.h>
#include <ControlLook.h>
#include <Debug.h>
#include <Locale.h>
#include <MenuItem.h>
#include <Mime.h>
#include <InterfaceDefs.h>
#include <VolumeRoster.h>
#include <Volume.h>
#include <fs_info.h>
#include "Commands.h"
#include "IconMenuItem.h"
#include "Tracker.h"
#include "Bitmaps.h"
#include <DiskDevice.h>
#include <DiskDeviceList.h>
#define SHOW_NETWORK_VOLUMES
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "MountMenu"
class AddMenuItemVisitor : public BDiskDeviceVisitor {
public:
AddMenuItemVisitor(BMenu* menu);
virtual ~AddMenuItemVisitor();
virtual bool Visit(BDiskDevice* device);
virtual bool Visit(BPartition* partition, int32 level);
private:
BMenu* fMenu;
};
AddMenuItemVisitor::AddMenuItemVisitor(BMenu* menu)
:
fMenu(menu)
{
}
AddMenuItemVisitor::~AddMenuItemVisitor()
{
}
bool
AddMenuItemVisitor::Visit(BDiskDevice* device)
{
return Visit(device, 0);
}
bool
AddMenuItemVisitor::Visit(BPartition* partition, int32 level)
{
if (!partition->ContainsFileSystem())
return false;
BString name = partition->ContentName();
if (name.Length() == 0) {
name = partition->Name();
if (name.Length() == 0) {
const char* type = partition->ContentType();
if (type == NULL)
return false;
uint32 divisor = 1UL << 30;
char unit = 'G';
if (partition->Size() < divisor) {
divisor = 1UL << 20;
unit = 'M';
}
name.SetToFormat("(%.1f %cB %s)",
1.0 * partition->Size() / divisor, unit, type);
}
}
BBitmap* icon = new BBitmap(BRect(BPoint(0, 0), be_control_look->ComposeIconSize(B_MINI_ICON)),
B_RGBA32);
if (partition->GetIcon(icon, B_MINI_ICON) != B_OK) {
delete icon;
icon = NULL;
}
BMessage* message = new BMessage(partition->IsMounted() ?
kUnmountVolume : kMountVolume);
message->AddInt32("id", partition->ID());
BMenuItem* item;
if (icon != NULL)
item = new IconMenuItem(name.String(), message, icon);
else
item = new BMenuItem(name.String(), message);
if (partition->IsMounted()) {
item->SetMarked(true);
BVolume volume;
if (partition->GetVolume(&volume) == B_OK) {
BVolume bootVolume;
BVolumeRoster().GetBootVolume(&bootVolume);
if (volume == bootVolume)
item->SetEnabled(false);
}
}
fMenu->AddItem(item);
return false;
}
MountMenu::MountMenu(const char* name)
: BMenu(name)
{
}
bool
MountMenu::AddDynamicItem(add_state)
{
for (;;) {
BMenuItem* item = RemoveItem((int32)0);
if (item == NULL)
break;
delete item;
}
BDiskDeviceList devices;
status_t status = devices.Fetch();
if (status == B_OK) {
AddMenuItemVisitor visitor(this);
devices.VisitEachPartition(&visitor);
}
#ifdef SHOW_NETWORK_VOLUMES
BVolumeRoster volumeRoster;
BVolume volume;
while (volumeRoster.GetNextVolume(&volume) == B_OK) {
if (volume.IsShared()) {
BBitmap* icon = new BBitmap(BRect(0, 0, 15, 15), B_CMAP8);
fs_info info;
if (fs_stat_dev(volume.Device(), &info) != B_OK) {
PRINT(("Cannot get mount menu item icon; bad device ID\n"));
delete icon;
continue;
}
if (get_device_icon(info.device_name, icon, B_MINI_ICON)
!= B_OK) {
GetTrackerResources()->GetIconResource(R_ShareIcon,
B_MINI_ICON, icon);
}
BMessage* message = new BMessage(kUnmountVolume);
message->AddInt32("device_id", volume.Device());
char volumeName[B_FILE_NAME_LENGTH];
volume.GetName(volumeName);
BMenuItem* item = new IconMenuItem(volumeName, message, icon);
item->SetMarked(true);
AddItem(item);
}
}
#endif
AddSeparatorItem();
BMenuItem* mountAll = new BMenuItem(B_TRANSLATE("Mount all"),
new BMessage(kMountAllNow));
AddItem(mountAll);
BMenuItem* mountSettings = new BMenuItem(
B_TRANSLATE("Settings" B_UTF8_ELLIPSIS),
new BMessage(kRunAutomounterSettings));
AddItem(mountSettings);
SetTargetForItems(be_app);
return false;
}