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		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 the file panel like an alert
109	BWindow* parent = dynamic_cast<BWindow*>(
110		BLooper::LooperForThread(find_thread(NULL)));
111	const BRect frame = parent != NULL ? parent->Frame()
112		: BScreen(fWindow).Frame();
113
114	fWindow->MoveTo(fWindow->AlertPosition(frame));
115	if (!IsShowing())
116		fWindow->Show();
117
118	fWindow->Activate();
119}
120
121
122void
123BFilePanel::Hide()
124{
125	AutoLock<BWindow> lock(fWindow);
126	if (!lock)
127		return;
128
129	if (!fWindow->IsHidden())
130		fWindow->QuitRequested();
131}
132
133
134bool
135BFilePanel::IsShowing() const
136{
137	AutoLock<BWindow> lock(fWindow);
138	if (!lock)
139		return false;
140
141	return !fWindow->IsHidden();
142}
143
144
145void
146BFilePanel::SendMessage(const BMessenger* messenger, BMessage* message)
147{
148	messenger->SendMessage(message);
149}
150
151
152file_panel_mode
153BFilePanel::PanelMode() const
154{
155	AutoLock<BWindow> lock(fWindow);
156	if (!lock)
157		return B_OPEN_PANEL;
158
159	if (static_cast<TFilePanel*>(fWindow)->IsSavePanel())
160		return B_SAVE_PANEL;
161
162	return B_OPEN_PANEL;
163}
164
165
166BMessenger
167BFilePanel::Messenger() const
168{
169	BMessenger target;
170
171	AutoLock<BWindow> lock(fWindow);
172	if (!lock)
173		return target;
174
175	return *static_cast<TFilePanel*>(fWindow)->Target();
176}
177
178
179void
180BFilePanel::SetTarget(BMessenger target)
181{
182	AutoLock<BWindow> lock(fWindow);
183	if (!lock)
184		return;
185
186	static_cast<TFilePanel*>(fWindow)->SetTarget(target);
187}
188
189
190void
191BFilePanel::SetMessage(BMessage* message)
192{
193	AutoLock<BWindow> lock(fWindow);
194	if (!lock)
195		return;
196
197	static_cast<TFilePanel*>(fWindow)->SetMessage(message);
198}
199
200
201void
202BFilePanel::Refresh()
203{
204	AutoLock<BWindow> lock(fWindow);
205	if (!lock)
206		return;
207
208	static_cast<TFilePanel*>(fWindow)->Refresh();
209}
210
211
212BRefFilter*
213BFilePanel::RefFilter() const
214{
215	AutoLock<BWindow> lock(fWindow);
216	if (!lock)
217		return 0;
218
219	return static_cast<TFilePanel*>(fWindow)->Filter();
220}
221
222
223void
224BFilePanel::SetRefFilter(BRefFilter* filter)
225{
226	AutoLock<BWindow> lock(fWindow);
227	if (!lock)
228		return;
229
230	static_cast<TFilePanel*>(fWindow)->SetRefFilter(filter);
231}
232
233
234void
235BFilePanel::SetButtonLabel(file_panel_button button, const char* text)
236{
237	AutoLock<BWindow> lock(fWindow);
238	if (!lock)
239		return;
240
241	static_cast<TFilePanel*>(fWindow)->SetButtonLabel(button, text);
242}
243
244
245void
246BFilePanel::SetNodeFlavors(uint32 flavors)
247{
248	AutoLock<BWindow> lock(fWindow);
249	if (!lock)
250		return;
251
252	static_cast<TFilePanel*>(fWindow)->SetNodeFlavors(flavors);
253}
254
255
256void
257BFilePanel::GetPanelDirectory(entry_ref* ref) const
258{
259	AutoLock<BWindow> lock(fWindow);
260	if (!lock)
261		return;
262
263	*ref = *static_cast<TFilePanel*>(fWindow)->TargetModel()->EntryRef();
264}
265
266
267void
268BFilePanel::SetSaveText(const char* text)
269{
270	AutoLock<BWindow> lock(fWindow);
271	if (!lock)
272		return;
273
274	static_cast<TFilePanel*>(fWindow)->SetSaveText(text);
275}
276
277
278void
279BFilePanel::SetPanelDirectory(const entry_ref* ref)
280{
281	AutoLock<BWindow> lock(fWindow);
282	if (!lock)
283		return;
284
285	static_cast<TFilePanel*>(fWindow)->SetTo(ref);
286}
287
288
289void
290BFilePanel::SetPanelDirectory(const char* path)
291{
292	entry_ref ref;
293	status_t err = get_ref_for_path(path, &ref);
294	if (err < B_OK)
295	  return;
296
297	AutoLock<BWindow> lock(fWindow);
298	if (!lock)
299		return;
300
301	static_cast<TFilePanel*>(fWindow)->SetTo(&ref);
302}
303
304
305void
306BFilePanel::SetPanelDirectory(const BEntry* entry)
307{
308	entry_ref ref;
309
310	if (entry && entry->GetRef(&ref) == B_OK)
311		SetPanelDirectory(&ref);
312}
313
314
315void
316BFilePanel::SetPanelDirectory(const BDirectory* dir)
317{
318	BEntry	entry;
319
320	if (dir && (dir->GetEntry(&entry) == B_OK))
321		SetPanelDirectory(&entry);
322}
323
324
325BWindow*
326BFilePanel::Window() const
327{
328	return fWindow;
329}
330
331
332void
333BFilePanel::Rewind()
334{
335	AutoLock<BWindow> lock(fWindow);
336	if (!lock)
337		return;
338
339	static_cast<TFilePanel*>(fWindow)->Rewind();
340}
341
342
343status_t
344BFilePanel::GetNextSelectedRef(entry_ref* ref)
345{
346	AutoLock<BWindow> lock(fWindow);
347	if (!lock)
348		return B_ERROR;
349
350	return static_cast<TFilePanel*>(fWindow)->GetNextEntryRef(ref);
351
352}
353
354
355void
356BFilePanel::SetHideWhenDone(bool on)
357{
358	AutoLock<BWindow> lock(fWindow);
359	if (!lock)
360		return;
361
362	static_cast<TFilePanel*>(fWindow)->SetHideWhenDone(on);
363}
364
365
366bool
367BFilePanel::HidesWhenDone(void) const
368{
369	AutoLock<BWindow> lock(fWindow);
370	if (!lock)
371		return false;
372
373	return static_cast<TFilePanel*>(fWindow)->HidesWhenDone();
374}
375
376
377void
378BFilePanel::WasHidden()
379{
380	// hook function
381}
382
383
384void
385BFilePanel::SelectionChanged()
386{
387	// hook function
388}
389