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