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