1/*
2Open Tracker License
3
4Terms and Conditions
5
6Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
7
8Permission is hereby granted, free of charge, to any person obtaining a copy of
9this software and associated documentation files (the "Software"), to deal in
10the Software without restriction, including without limitation the rights to
11use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12of the Software, and to permit persons to whom the Software is furnished to do
13so, subject to the following conditions:
14
15The above copyright notice and this permission notice applies to all licensees
16and shall be included in all copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25Except as contained in this notice, the name of Be Incorporated shall not be
26used in advertising or otherwise to promote the sale, use or other dealings in
27this Software without prior written authorization from Be Incorporated.
28
29Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
30of Be Incorporated in the United States and other countries. Other brand product
31names are registered trademarks or trademarks of their respective holders.
32All rights reserved.
33*/
34
35// Implementation for the public FilePanel object.
36
37
38#include <sys/resource.h>
39
40#include <BeBuild.h>
41#include <Debug.h>
42#include <FilePanel.h>
43#include <Looper.h>
44#include <Screen.h>
45#include <Window.h>
46
47#include "AutoLock.h"
48#include "Commands.h"
49#include "FilePanelPriv.h"
50
51
52// prototypes for some private kernel calls that will some day be public
53#ifndef _IMPEXP_ROOT
54#	define _IMPEXP_ROOT
55#endif
56
57
58//	#pragma mark - BFilePanel
59
60
61BFilePanel::BFilePanel(file_panel_mode mode, BMessenger* target,
62	const entry_ref* ref, uint32 nodeFlavors, bool multipleSelection,
63	BMessage* message, BRefFilter* filter, bool modal,
64	bool hideWhenDone)
65{
66	// boost file descriptor limit so file panels in other apps don't have
67	// problems
68	struct rlimit rl;
69	rl.rlim_cur = 512;
70	rl.rlim_max = RLIM_SAVED_MAX;
71	setrlimit(RLIMIT_NOFILE, &rl);
72
73	BEntry startDir(ref);
74	fWindow = new TFilePanel(mode, target, &startDir, nodeFlavors,
75		multipleSelection, message, filter, 0, B_DOCUMENT_WINDOW_LOOK,
76		(modal ? B_MODAL_APP_WINDOW_FEEL : B_NORMAL_WINDOW_FEEL),
77		B_CURRENT_WORKSPACE, 0, hideWhenDone);
78
79	static_cast<TFilePanel*>(fWindow)->SetClientObject(this);
80
81	fWindow->SetIsFilePanel(true);
82}
83
84
85BFilePanel::~BFilePanel()
86{
87	if (fWindow->Lock())
88		fWindow->Quit();
89}
90
91
92void
93BFilePanel::Show()
94{
95	AutoLock<BWindow> lock(fWindow);
96	if (!lock)
97		return;
98
99	// if the window is already showing, don't jerk the workspaces around,
100	// just pull it to us
101	uint32 workspace = 1UL << (uint32)current_workspace();
102	uint32 windowWorkspaces = fWindow->Workspaces();
103	if (!(windowWorkspaces & workspace)) {
104		// window in a different workspace, reopen in current
105		fWindow->SetWorkspaces(workspace);
106	}
107
108	// Position like an alert, unless the parent is NULL and a position was
109	// already restored from saved settings.
110	BWindow* parent = dynamic_cast<BWindow*>(
111		BLooper::LooperForThread(find_thread(NULL)));
112	if (parent != NULL)
113		fWindow->MoveTo(fWindow->AlertPosition(parent->Frame()));
114	else {
115		if (!static_cast<TFilePanel*>(fWindow)->DefaultStateRestored())
116			fWindow->MoveTo(fWindow->AlertPosition(BScreen(fWindow).Frame()));
117	}
118
119	if (!IsShowing())
120		fWindow->Show();
121
122	fWindow->Activate();
123
124#if 1
125	// The Be Book gives the names for some of the child views so that apps
126	// could move them around if they needed to, but we have most in layouts,
127	// so once the window has been opened, we have to forcibly resize "PoseView"
128	// (fBackView) to fully invalidate its layout in case any of the controls
129	// in it have been moved.
130	fWindow->FindView("PoseView")->ResizeBy(1, 1);
131	fWindow->FindView("PoseView")->ResizeBy(-1, -1);
132#endif
133}
134
135
136void
137BFilePanel::Hide()
138{
139	AutoLock<BWindow> lock(fWindow);
140	if (!lock)
141		return;
142
143	if (!fWindow->IsHidden())
144		fWindow->QuitRequested();
145}
146
147
148bool
149BFilePanel::IsShowing() const
150{
151	AutoLock<BWindow> lock(fWindow);
152	if (!lock)
153		return false;
154
155	return !fWindow->IsHidden();
156}
157
158
159void
160BFilePanel::SendMessage(const BMessenger* messenger, BMessage* message)
161{
162	messenger->SendMessage(message);
163}
164
165
166file_panel_mode
167BFilePanel::PanelMode() const
168{
169	AutoLock<BWindow> lock(fWindow);
170	if (!lock)
171		return B_OPEN_PANEL;
172
173	if (static_cast<TFilePanel*>(fWindow)->IsSavePanel())
174		return B_SAVE_PANEL;
175
176	return B_OPEN_PANEL;
177}
178
179
180BMessenger
181BFilePanel::Messenger() const
182{
183	BMessenger target;
184
185	AutoLock<BWindow> lock(fWindow);
186	if (!lock)
187		return target;
188
189	return *static_cast<TFilePanel*>(fWindow)->Target();
190}
191
192
193void
194BFilePanel::SetTarget(BMessenger target)
195{
196	AutoLock<BWindow> lock(fWindow);
197	if (!lock)
198		return;
199
200	static_cast<TFilePanel*>(fWindow)->SetTarget(target);
201}
202
203
204void
205BFilePanel::SetMessage(BMessage* message)
206{
207	AutoLock<BWindow> lock(fWindow);
208	if (!lock)
209		return;
210
211	static_cast<TFilePanel*>(fWindow)->SetMessage(message);
212}
213
214
215void
216BFilePanel::Refresh()
217{
218	AutoLock<BWindow> lock(fWindow);
219	if (!lock)
220		return;
221
222	static_cast<TFilePanel*>(fWindow)->Refresh();
223}
224
225
226BRefFilter*
227BFilePanel::RefFilter() const
228{
229	AutoLock<BWindow> lock(fWindow);
230	if (!lock)
231		return 0;
232
233	return static_cast<TFilePanel*>(fWindow)->Filter();
234}
235
236
237void
238BFilePanel::SetRefFilter(BRefFilter* filter)
239{
240	AutoLock<BWindow> lock(fWindow);
241	if (!lock)
242		return;
243
244	static_cast<TFilePanel*>(fWindow)->SetRefFilter(filter);
245}
246
247
248void
249BFilePanel::SetButtonLabel(file_panel_button button, const char* text)
250{
251	AutoLock<BWindow> lock(fWindow);
252	if (!lock)
253		return;
254
255	static_cast<TFilePanel*>(fWindow)->SetButtonLabel(button, text);
256}
257
258
259void
260BFilePanel::SetNodeFlavors(uint32 flavors)
261{
262	AutoLock<BWindow> lock(fWindow);
263	if (!lock)
264		return;
265
266	static_cast<TFilePanel*>(fWindow)->SetNodeFlavors(flavors);
267}
268
269
270void
271BFilePanel::GetPanelDirectory(entry_ref* ref) const
272{
273	AutoLock<BWindow> lock(fWindow);
274	if (!lock)
275		return;
276
277	*ref = *static_cast<TFilePanel*>(fWindow)->TargetModel()->EntryRef();
278}
279
280
281void
282BFilePanel::SetSaveText(const char* text)
283{
284	AutoLock<BWindow> lock(fWindow);
285	if (!lock)
286		return;
287
288	static_cast<TFilePanel*>(fWindow)->SetSaveText(text);
289}
290
291
292void
293BFilePanel::SetPanelDirectory(const entry_ref* ref)
294{
295	AutoLock<BWindow> lock(fWindow);
296	if (!lock)
297		return;
298
299	static_cast<TFilePanel*>(fWindow)->SetTo(ref);
300}
301
302
303void
304BFilePanel::SetPanelDirectory(const char* path)
305{
306	entry_ref ref;
307	status_t err = get_ref_for_path(path, &ref);
308	if (err < B_OK)
309	  return;
310
311	AutoLock<BWindow> lock(fWindow);
312	if (!lock)
313		return;
314
315	static_cast<TFilePanel*>(fWindow)->SetTo(&ref);
316}
317
318
319void
320BFilePanel::SetPanelDirectory(const BEntry* entry)
321{
322	entry_ref ref;
323
324	if (entry && entry->GetRef(&ref) == B_OK)
325		SetPanelDirectory(&ref);
326}
327
328
329void
330BFilePanel::SetPanelDirectory(const BDirectory* dir)
331{
332	BEntry entry;
333
334	if (dir && (dir->GetEntry(&entry) == B_OK))
335		SetPanelDirectory(&entry);
336}
337
338
339BWindow*
340BFilePanel::Window() const
341{
342	return fWindow;
343}
344
345
346void
347BFilePanel::Rewind()
348{
349	AutoLock<BWindow> lock(fWindow);
350	if (!lock)
351		return;
352
353	static_cast<TFilePanel*>(fWindow)->Rewind();
354}
355
356
357status_t
358BFilePanel::GetNextSelectedRef(entry_ref* ref)
359{
360	AutoLock<BWindow> lock(fWindow);
361	if (!lock)
362		return B_ERROR;
363
364	return static_cast<TFilePanel*>(fWindow)->GetNextEntryRef(ref);
365
366}
367
368
369void
370BFilePanel::SetHideWhenDone(bool on)
371{
372	AutoLock<BWindow> lock(fWindow);
373	if (!lock)
374		return;
375
376	static_cast<TFilePanel*>(fWindow)->SetHideWhenDone(on);
377}
378
379
380bool
381BFilePanel::HidesWhenDone(void) const
382{
383	AutoLock<BWindow> lock(fWindow);
384	if (!lock)
385		return false;
386
387	return static_cast<TFilePanel*>(fWindow)->HidesWhenDone();
388}
389
390
391void
392BFilePanel::WasHidden()
393{
394	// hook function
395}
396
397
398void
399BFilePanel::SelectionChanged()
400{
401	// hook function
402}
403