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