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 <MenuItem.h> 38 #include <Mime.h> 39 #include <InterfaceDefs.h> 40 #include <VolumeRoster.h> 41 #include <Volume.h> 42 #include <fs_info.h> 43 44 #include "AutoMounter.h" 45 #include "Commands.h" 46 #include "MountMenu.h" 47 #include "IconMenuItem.h" 48 #include "Tracker.h" 49 #include "Bitmaps.h" 50 51 #ifdef __HAIKU__ 52 # include <DiskDevice.h> 53 # include <DiskDeviceList.h> 54 #else 55 # include "DeviceMap.h" 56 #endif 57 58 #define SHOW_NETWORK_VOLUMES 59 60 61 #ifdef __HAIKU__ 62 // #pragma mark - Haiku Disk Device API 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 AddMenuItemVisitor::AddMenuItemVisitor(BMenu* menu) 79 : 80 fMenu(menu) 81 { 82 } 83 84 85 AddMenuItemVisitor::~AddMenuItemVisitor() 86 { 87 } 88 89 90 bool 91 AddMenuItemVisitor::Visit(BDiskDevice *device) 92 { 93 return Visit(device, 0); 94 } 95 96 97 bool 98 AddMenuItemVisitor::Visit(BPartition *partition, int32 level) 99 { 100 if (!partition->ContainsFileSystem()) 101 return NULL; 102 103 // get name (and eventually the type) 104 BString name = partition->ContentName(); 105 if (name.Length() == 0) { 106 name = partition->Name(); 107 if (name.Length() == 0) { 108 const char *type = partition->ContentType(); 109 if (type == NULL) 110 return NULL; 111 112 name = "(unnamed "; 113 name << type; 114 name << ")"; 115 } 116 } 117 118 // get icon 119 BBitmap *icon = new BBitmap(BRect(0, 0, B_MINI_ICON - 1, B_MINI_ICON - 1), 120 B_CMAP8); 121 if (partition->GetIcon(icon, B_MINI_ICON) != B_OK) { 122 delete icon; 123 icon = NULL; 124 } 125 126 BMessage *message = new BMessage(partition->IsMounted() ? 127 kUnmountVolume : kMountVolume); 128 message->AddInt32("id", partition->ID()); 129 130 // TODO: for now, until we actually have disk device icons 131 BMenuItem *item; 132 if (icon != NULL) 133 item = new IconMenuItem(name.String(), message, icon); 134 else 135 item = new BMenuItem(name.String(), message); 136 if (partition->IsMounted()) { 137 item->SetMarked(true); 138 139 BVolume volume; 140 if (partition->GetVolume(&volume) == B_OK) { 141 BVolume bootVolume; 142 BVolumeRoster().GetBootVolume(&bootVolume); 143 if (volume == bootVolume) 144 item->SetEnabled(false); 145 } 146 } 147 148 fMenu->AddItem(item); 149 return false; 150 } 151 152 #else // !__HAIKU__ 153 // #pragma mark - R5 DeviceMap API 154 155 156 struct AddOneAsMenuItemParams { 157 BMenu *mountMenu; 158 }; 159 160 161 static Partition * 162 AddOnePartitionAsMenuItem(Partition *partition, void *castToParams) 163 { 164 if (partition->Hidden()) 165 return NULL; 166 167 AddOneAsMenuItemParams *params = (AddOneAsMenuItemParams *)castToParams; 168 BBitmap *icon = new BBitmap(BRect(0, 0, B_MINI_ICON - 1, B_MINI_ICON - 1), 169 B_CMAP8); 170 get_device_icon(partition->GetDevice()->Name(), icon->Bits(), B_MINI_ICON); 171 172 173 const char *name = partition->GetDevice()->DisplayName(); 174 175 if (!partition->GetDevice()->IsFloppy() || 176 partition->Mounted() == kMounted) { 177 if (*partition->VolumeName()) 178 name = partition->VolumeName(); 179 else if (*partition->Type()) 180 name = partition->Type(); 181 } 182 183 BMessage *message = new BMessage; 184 185 if (partition->Mounted() == kMounted) { 186 message->what = kUnmountVolume; 187 message->AddInt32("device_id", partition->VolumeDeviceID()); 188 } else { 189 message->what = kMountVolume; 190 191 // 192 // Floppies have an ID of -1, because they don't have 193 // partition (and hence no parititon ID). 194 // 195 if (partition->GetDevice()->IsFloppy()) 196 message->AddInt32("id", kFloppyID); 197 else 198 message->AddInt32("id", partition->UniqueID()); 199 } 200 201 BMenuItem *item = new IconMenuItem(name, message, icon); 202 if (partition->Mounted() == kMounted) 203 item->SetMarked(true); 204 205 if (partition->Mounted() == kMounted) { 206 BVolume partVolume(partition->VolumeDeviceID()); 207 208 BVolume bootVolume; 209 BVolumeRoster().GetBootVolume(&bootVolume); 210 if (partVolume == bootVolume) 211 item->SetEnabled(false); 212 } 213 214 params->mountMenu->AddItem(item); 215 216 return NULL; 217 } 218 #endif // !__HAIKU__ 219 220 221 // #pragma mark - 222 223 224 MountMenu::MountMenu(const char *name) 225 : BMenu(name) 226 { 227 SetFont(be_plain_font); 228 } 229 230 231 bool 232 MountMenu::AddDynamicItem(add_state) 233 { 234 // remove old items 235 for (;;) { 236 BMenuItem *item = RemoveItem(0L); 237 if (item == NULL) 238 break; 239 delete item; 240 } 241 242 #ifdef __HAIKU__ 243 BDiskDeviceList devices; 244 status_t status = devices.Fetch(); 245 if (status == B_OK) { 246 AddMenuItemVisitor visitor(this); 247 devices.VisitEachPartition(&visitor); 248 } 249 #else 250 AddOneAsMenuItemParams params; 251 params.mountMenu = this; 252 253 AutoMounter *autoMounter = dynamic_cast<TTracker *>(be_app)-> 254 AutoMounterLoop(); 255 256 autoMounter->CheckVolumesNow(); 257 autoMounter->EachPartition(&AddOnePartitionAsMenuItem, ¶ms); 258 #endif 259 260 #ifdef SHOW_NETWORK_VOLUMES 261 // iterate the volume roster and look for volumes with the 262 // 'shared' attributes -- these same volumes will not be returned 263 // by the autoMounter because they do not show up in the /dev tree 264 BVolumeRoster volumeRoster; 265 BVolume volume; 266 bool needSeparator = false; 267 while (volumeRoster.GetNextVolume(&volume) == B_OK) { 268 if (volume.IsShared()) { 269 needSeparator = true; 270 BBitmap *icon = new BBitmap(BRect(0, 0, 15, 15), B_CMAP8); 271 fs_info info; 272 if (fs_stat_dev(volume.Device(), &info) != B_OK) { 273 PRINT(("Cannot get mount menu item icon; bad device ID\n")); 274 delete icon; 275 continue; 276 } 277 // Use the shared icon instead of the device icon 278 if (get_device_icon(info.device_name, icon->Bits(), B_MINI_ICON) != B_OK) 279 GetTrackerResources()->GetIconResource(kResShareIcon, B_MINI_ICON, icon); 280 281 BMessage *message = new BMessage(kUnmountVolume); 282 message->AddInt32("device_id", volume.Device()); 283 char volumeName[B_FILE_NAME_LENGTH]; 284 volume.GetName(volumeName); 285 286 BMenuItem *item = new IconMenuItem(volumeName, message, icon); 287 item->SetMarked(true); 288 AddItem(item); 289 } 290 } 291 #endif // SHOW_NETWORK_VOLUMES 292 293 AddSeparatorItem(); 294 295 #ifndef __HAIKU__ 296 // add an option to rescan the scsii bus, etc. 297 BMenuItem *rescanItem = NULL; 298 if (modifiers() & B_SHIFT_KEY) { 299 rescanItem = new BMenuItem("Rescan Devices", new BMessage(kAutomounterRescan)); 300 AddItem(rescanItem); 301 } 302 #endif 303 304 BMenuItem *mountAll = new BMenuItem("Mount All", new BMessage(kMountAllNow)); 305 AddItem(mountAll); 306 BMenuItem *mountSettings = new BMenuItem("Settings"B_UTF8_ELLIPSIS, 307 new BMessage(kRunAutomounterSettings)); 308 AddItem(mountSettings); 309 310 SetTargetForItems(be_app); 311 312 #ifndef __HAIKU__ 313 if (rescanItem) 314 rescanItem->SetTarget(autoMounter); 315 #endif 316 317 return false; 318 } 319