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