xref: /haiku/src/kits/tracker/DesktopPoseView.cpp (revision 9522c1e4f21b0292084467c927e4169770db1329)
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