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 // DesktopPoseView adds support for displaying integrated desktops 36 // from multiple volumes to BPoseView 37 // 38 // Used by the Desktop window and by the root view in file panels 39 40 #include "DesktopPoseView.h" 41 42 #include <NodeMonitor.h> 43 #include <Path.h> 44 #include <Volume.h> 45 #include <VolumeRoster.h> 46 47 #include "Commands.h" 48 #include "FSUtils.h" 49 #include "PoseList.h" 50 #include "Tracker.h" 51 #include "TrackerSettings.h" 52 #include "TrackerString.h" 53 54 55 // #pragma mark - 56 57 58 DesktopPoseView::DesktopPoseView(Model* model, BRect frame, uint32 viewMode, 59 uint32 resizeMask) 60 : 61 BPoseView(model, frame, viewMode, resizeMask) 62 { 63 SetFlags(Flags() | B_DRAW_ON_CHILDREN); 64 } 65 66 67 EntryListBase* 68 DesktopPoseView::InitDesktopDirentIterator(BPoseView* nodeMonitoringTarget, 69 const entry_ref* ref) 70 { 71 // the desktop dirent iterator knows how to iterate over all the volumes, 72 // integrated onto the desktop 73 74 Model sourceModel(ref, false, true); 75 if (sourceModel.InitCheck() != B_OK) 76 return NULL; 77 78 CachedEntryIteratorList* result = new CachedEntryIteratorList(); 79 80 ASSERT(!sourceModel.IsQuery()); 81 ASSERT(!sourceModel.IsVirtualDirectory()); 82 ASSERT(sourceModel.Node()); 83 BDirectory* sourceDirectory 84 = dynamic_cast<BDirectory*>(sourceModel.Node()); 85 86 ASSERT(sourceDirectory); 87 88 // build an iterator list, start with boot 89 EntryListBase* perDesktopIterator 90 = new CachedDirectoryEntryList(*sourceDirectory); 91 92 result->AddItem(perDesktopIterator); 93 if (nodeMonitoringTarget) { 94 TTracker::WatchNode(sourceModel.NodeRef(), 95 B_WATCH_DIRECTORY | B_WATCH_NAME | B_WATCH_STAT | B_WATCH_ATTR, 96 nodeMonitoringTarget); 97 } 98 99 if (result->Rewind() != B_OK) { 100 delete result; 101 if (nodeMonitoringTarget) 102 nodeMonitoringTarget->HideBarberPole(); 103 104 return NULL; 105 } 106 107 return result; 108 } 109 110 111 EntryListBase* 112 DesktopPoseView::InitDirentIterator(const entry_ref* ref) 113 { 114 return InitDesktopDirentIterator(this, ref); 115 } 116 117 118 bool 119 DesktopPoseView::FSNotification(const BMessage* message) 120 { 121 switch (message->FindInt32("opcode")) { 122 case B_DEVICE_MOUNTED: 123 { 124 dev_t device; 125 if (message->FindInt32("new device", &device) != B_OK) 126 break; 127 128 ASSERT(TargetModel()); 129 TrackerSettings settings; 130 131 BVolume volume(device); 132 if (volume.InitCheck() != B_OK) 133 break; 134 135 if (settings.MountVolumesOntoDesktop() 136 && (!volume.IsShared() 137 || settings.MountSharedVolumesOntoDesktop())) { 138 // place an icon for the volume onto the desktop 139 CreateVolumePose(&volume, true); 140 } 141 } 142 break; 143 } 144 145 return _inherited::FSNotification(message); 146 } 147 148 149 bool 150 DesktopPoseView::AddPosesThreadValid(const entry_ref*) const 151 { 152 return true; 153 } 154 155 156 void 157 DesktopPoseView::AddPosesCompleted() 158 { 159 _inherited::AddPosesCompleted(); 160 CreateTrashPose(); 161 } 162 163 164 bool 165 DesktopPoseView::Represents(const node_ref* ref) const 166 { 167 // When the Tracker is set up to integrate non-boot beos volumes, 168 // it represents the home/Desktop folders of all beos volumes 169 170 return _inherited::Represents(ref); 171 } 172 173 174 bool 175 DesktopPoseView::Represents(const entry_ref* ref) const 176 { 177 BEntry entry(ref); 178 node_ref nref; 179 entry.GetNodeRef(&nref); 180 return Represents(&nref); 181 } 182 183 184 void 185 DesktopPoseView::ShowVolumes(bool visible, bool showShared) 186 { 187 if (LockLooper()) { 188 SavePoseLocations(); 189 if (!visible) 190 RemoveRootPoses(); 191 else 192 AddRootPoses(true, showShared); 193 UnlockLooper(); 194 } 195 } 196 197 198 void 199 DesktopPoseView::StartSettingsWatch() 200 { 201 be_app->LockLooper(); 202 be_app->StartWatching(this, kShowDisksIconChanged); 203 be_app->StartWatching(this, kVolumesOnDesktopChanged); 204 be_app->StartWatching(this, kDesktopIntegrationChanged); 205 be_app->UnlockLooper(); 206 } 207 208 209 void 210 DesktopPoseView::StopSettingsWatch() 211 { 212 be_app->LockLooper(); 213 be_app->StopWatching(this, kShowDisksIconChanged); 214 be_app->StopWatching(this, kVolumesOnDesktopChanged); 215 be_app->StopWatching(this, kDesktopIntegrationChanged); 216 be_app->UnlockLooper(); 217 } 218 219 220 void 221 DesktopPoseView::AdaptToVolumeChange(BMessage* message) 222 { 223 TTracker* tracker = dynamic_cast<TTracker*>(be_app); 224 if (!tracker) 225 return; 226 227 bool showDisksIcon = false; 228 bool mountVolumesOnDesktop = true; 229 bool mountSharedVolumesOntoDesktop = false; 230 231 message->FindBool("ShowDisksIcon", &showDisksIcon); 232 message->FindBool("MountVolumesOntoDesktop", &mountVolumesOnDesktop); 233 message->FindBool("MountSharedVolumesOntoDesktop", 234 &mountSharedVolumesOntoDesktop); 235 236 BEntry entry("/"); 237 Model model(&entry); 238 if (model.InitCheck() == B_OK) { 239 BMessage entryMessage; 240 entryMessage.what = B_NODE_MONITOR; 241 242 if (showDisksIcon) 243 entryMessage.AddInt32("opcode", B_ENTRY_CREATED); 244 else { 245 entryMessage.AddInt32("opcode", B_ENTRY_REMOVED); 246 entry_ref ref; 247 if (entry.GetRef(&ref) == B_OK) { 248 BContainerWindow* disksWindow 249 = tracker->FindContainerWindow(&ref); 250 if (disksWindow) { 251 disksWindow->Lock(); 252 disksWindow->Close(); 253 } 254 } 255 } 256 entryMessage.AddInt32("device", model.NodeRef()->device); 257 entryMessage.AddInt64("node", model.NodeRef()->node); 258 entryMessage.AddInt64("directory", model.EntryRef()->directory); 259 entryMessage.AddString("name", model.EntryRef()->name); 260 BContainerWindow* deskWindow 261 = dynamic_cast<BContainerWindow*>(Window()); 262 if (deskWindow) 263 deskWindow->PostMessage(&entryMessage, deskWindow->PoseView()); 264 } 265 266 ShowVolumes(mountVolumesOnDesktop, mountSharedVolumesOntoDesktop); 267 } 268 269 270 void 271 DesktopPoseView::AdaptToDesktopIntegrationChange(BMessage* message) 272 { 273 bool mountVolumesOnDesktop = true; 274 bool mountSharedVolumesOntoDesktop = true; 275 276 message->FindBool("MountVolumesOntoDesktop", &mountVolumesOnDesktop); 277 message->FindBool("MountSharedVolumesOntoDesktop", 278 &mountSharedVolumesOntoDesktop); 279 280 ShowVolumes(false, mountSharedVolumesOntoDesktop); 281 ShowVolumes(mountVolumesOnDesktop, mountSharedVolumesOntoDesktop); 282 } 283