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#ifndef _OPEN_WITH_WINDOW_H
35#define _OPEN_WITH_WINDOW_H
36
37
38// OpenWithContainerWindow supports the Open With feature
39
40
41#include <String.h>
42
43#include "ContainerWindow.h"
44#include "EntryIterator.h"
45#include "NodeWalker.h"
46#include "PoseView.h"
47#include "Query.h"
48#include "SlowMenu.h"
49#include "Utilities.h"
50
51class BGroupView;
52
53namespace BPrivate {
54
55enum {
56	kUnknownRelation = -1,
57	kNoRelation = 0,
58	kSuperhandler,
59	kSupportsSupertype,
60	kSupportsType,
61	kPreferredForType,
62	kPreferredForFile
63};
64
65
66class OpenWithPoseView;
67
68// pass in a predicate; a query will search for matches
69// matches will be returned in iteration
70class SearchForSignatureEntryList : public EntryListBase {
71public:
72	SearchForSignatureEntryList(bool canAddAllApps);
73	virtual ~SearchForSignatureEntryList();
74
75	void PushUniqueSignature(const char*);
76		// add one signature to search for
77
78	// entry list iterators
79	virtual status_t GetNextEntry(BEntry* entry, bool traverse = false);
80	virtual status_t GetNextRef(entry_ref* ref);
81	virtual int32 GetNextDirents(struct dirent* buffer, size_t length,
82		int32 count = INT_MAX);
83
84	virtual status_t Rewind();
85	virtual int32 CountEntries();
86
87	bool GetPreferredApp(entry_ref* ref) const;
88		// gets the preferred app for all the files it was asked to
89		// find supporting apps for, returns false if no preferred app
90		// found or if more than one found
91	void TrySettingPreferredApp(const entry_ref*);
92	void TrySettingPreferredAppForFile(const entry_ref*);
93
94	int32 Relation(const BMessage* entriesToOpen, const Model*) const;
95		// returns the reason why an application is shown in
96		// Open With window
97	void RelationDescription(const BMessage* entriesToOpen, const Model*,
98		BString*) const;
99		// returns a string describing why application handles files
100		// to open
101
102	static int32 Relation(const BMessage* entriesToOpen,
103		const Model*, const entry_ref* preferredApp,
104		const entry_ref* preferredAppForFile);
105		// returns the reason why an application is shown in Open With
106		// window static version, needs the preferred app for preformance
107	static void RelationDescription(const BMessage* entriesToOpen,
108		const Model*, BString*, const entry_ref* preferredApp,
109		const entry_ref* preferredAppForFile);
110		// returns a string describing why application handles files
111		// to open
112
113	bool CanOpenWithFilter(const Model* appModel,
114		const BMessage* entriesToOpen, const entry_ref* preferredApp);
115
116	void NonGenericFileFound();
117	bool GenericFilesOnly() const;
118
119	bool ShowAllApplications() const;
120
121private:
122	static int32 Relation(const Model* node, const Model* app);
123		// returns the reason why an application is shown in
124		// Open With window
125
126	CachedEntryIteratorList* fIteratorList;
127	BObjectList<BString> fSignatures;
128
129	entry_ref fPreferredRef;
130	int32 fPreferredAppCount;
131	entry_ref fPreferredRefForFile;
132	int32 fPreferredAppForFileCount;
133	bool fGenericFilesOnly;
134	bool fCanAddAllApps;
135	bool fFoundOneNonSuperHandler;
136};
137
138
139class OpenWithContainerWindow : public BContainerWindow {
140public:
141	OpenWithContainerWindow(BMessage* entriesToOpen,
142		LockingList<BWindow>* windowList);
143		// <entriesToOpen> eventually get opened by the selected app
144	virtual ~OpenWithContainerWindow();
145
146	virtual void Init(const BMessage* message);
147	virtual void InitLayout();
148
149	const BMessage* EntryList() const;
150		// return the list of the entries we are supposed to open
151
152	void SetCanSetAppAsDefault(bool);
153	void SetCanOpen(bool);
154
155	OpenWithPoseView* PoseView() const;
156
157protected:
158	virtual BPoseView* NewPoseView(Model* model, uint32 viewMode);
159
160	virtual bool ShouldAddMenus() const;
161	virtual void ShowContextMenu(BPoint, const entry_ref*);
162	virtual void AddShortcuts();
163	virtual void NewAttributesMenu(BMenu*);
164
165	virtual void RestoreState();
166	virtual void RestoreState(const BMessage&);
167	virtual void RestoreWindowState(AttributeStreamNode*);
168	virtual void RestoreWindowState(const BMessage&);
169	virtual bool NeedsDefaultStateSetup();
170	virtual void SaveState(bool hide = true);
171	virtual void SaveState(BMessage&) const;
172	virtual void SetupDefaultState();
173
174	virtual bool IsShowing(const node_ref*) const;
175	virtual bool IsShowing(const entry_ref*) const;
176
177	virtual void MessageReceived(BMessage*);
178
179	void OpenWithSelection();
180		// open entries with the selected app
181	void MakeDefaultAndOpen();
182		// open entries with the selected app and make it
183		// the default handler
184
185private:
186	static filter_result KeyDownFilter(BMessage*, BHandler**,
187		BMessageFilter*);
188
189	BMessage* fEntriesToOpen;
190	BButton* fLaunchButton;
191	BButton* fLaunchAndMakeDefaultButton;
192	BButton* fCancelButton;
193
194	BGroupView* fButtonContainer;
195
196	typedef BContainerWindow _inherited;
197};
198
199
200class OpenWithPoseView : public BPoseView {
201public:
202	OpenWithPoseView();
203	virtual ~OpenWithPoseView();
204
205	virtual void OpenSelection(BPose*, int32*);
206		// open entries with the selected app
207
208	int32 OpenWithRelation(const Model*) const;
209		// returns the reason why an application is shown in
210		// Open With window
211	void OpenWithRelationDescription(const Model*, BString*) const;
212		// returns a string describing why application handles files
213		// to open
214
215	OpenWithContainerWindow* ContainerWindow() const;
216
217	virtual bool AddPosesThreadValid(const entry_ref*) const;
218
219protected:
220	// don't do any volume watching and memtamime watching in open with
221	// panels for now
222	virtual void InitialStartWatching() {}
223	virtual void FinalStopWatching() {}
224
225	virtual void AttachedToWindow();
226	virtual EntryListBase* InitDirentIterator(const entry_ref* ref);
227	virtual void ReturnDirentIterator(EntryListBase* iterator);
228
229	virtual void SetupDefaultColumnsIfNeeded();
230		// show launch window specific columns
231
232	// empty overrides for functions that depend on having an fModel
233	virtual void SaveState(AttributeStreamNode*);
234	virtual void RestoreState(AttributeStreamNode*);
235	virtual void SaveState(BMessage&) const;
236	virtual void RestoreState(const BMessage&);
237	virtual void SavePoseLocations(BRect* = NULL);
238	virtual void MoveSelectionToTrash(bool selectNext = true);
239	virtual void MoveSelectionTo(BPoint, BPoint, BContainerWindow*);
240	virtual void MoveSelectionInto(Model* destFolder,
241		BContainerWindow* srcWindow, bool forceCopy,
242		bool create_link = false);
243	virtual bool HandleMessageDropped(BMessage*);
244	virtual bool CanHandleDragSelection(const Model*, const BMessage*,
245		bool);
246
247	virtual bool Represents(const node_ref*) const;
248	virtual bool Represents(const entry_ref*) const;
249
250	virtual void CreatePoses(Model** models, PoseInfo* poseInfoArray,
251		int32 count, BPose** resultingPoses, bool insertionSort = true,
252		int32* lastPoseIndexPtr = NULL, BRect* boundsPtr = NULL,
253		bool forceDraw = false);
254		// override to add selecting the default handling app
255		// for selection
256
257	virtual void Pulse();
258
259	virtual void KeyDown(const char* bytes, int32 count);
260
261private:
262	entry_ref fPreferredRef;
263	bool fHaveCommonPreferredApp;
264
265	SearchForSignatureEntryList* fIterator;
266	BRefFilter* fRefFilter;
267
268	typedef BPoseView _inherited;
269};
270
271
272class OpenWithRefFilter: public BRefFilter {
273public:
274	OpenWithRefFilter(SearchForSignatureEntryList*, const BMessage*,
275		entry_ref*);
276	bool Filter(const entry_ref* ref, BNode* node, stat_beos* st,
277		const char* filetype);
278
279private:
280	SearchForSignatureEntryList* fIterator;
281	const BMessage *fEntryList;
282	entry_ref* fPreferredRef;
283};
284
285
286class RelationCachingModelProxy {
287public:
288	RelationCachingModelProxy(Model* model);
289	~RelationCachingModelProxy();
290
291	int32 Relation(SearchForSignatureEntryList* iterator,
292		BMessage* entries) const;
293
294	Model* fModel;
295	mutable int32 fRelation;
296};
297
298
299class OpenWithMenu: public BSlowMenu {
300public:
301	OpenWithMenu(const char* label, const BMessage* entriesToOpen,
302		BWindow* parentWindow, BHandler* target);
303	OpenWithMenu(const char* label, const BMessage* entriesToOpen,
304		BWindow* parentWindow, const BMessenger &target);
305
306private:
307	friend int SortByRelation(const RelationCachingModelProxy*,
308		const RelationCachingModelProxy*, void*);
309	friend int SortByName(const RelationCachingModelProxy*,
310		const RelationCachingModelProxy*, void*);
311	friend int SortByRelationAndName(const RelationCachingModelProxy*,
312		const RelationCachingModelProxy*, void*);
313
314	virtual bool StartBuildingItemList();
315	virtual bool AddNextItem();
316	virtual void DoneBuildingItemList();
317	virtual void ClearMenuBuildingState();
318
319	BMessage fEntriesToOpen;
320	BHandler* target;
321	BMessenger fMessenger;
322
323	// menu building state
324	SearchForSignatureEntryList* fIterator;
325	entry_ref fPreferredRef;
326	BObjectList<RelationCachingModelProxy>* fSupportingAppList;
327	bool fHaveCommonPreferredApp;
328	BWindow* fParentWindow;
329
330	typedef BSlowMenu _inherited;
331};
332
333
334// used for optionally showing the list of all apps. Do nothing
335// until asked to iterate and only if supposed to do so
336class ConditionalAllAppsIterator : public EntryListBase {
337public:
338	ConditionalAllAppsIterator(SearchForSignatureEntryList* parent);
339	~ConditionalAllAppsIterator();
340
341	virtual status_t GetNextEntry(BEntry* entry, bool traverse = false);
342	virtual status_t GetNextRef(entry_ref* ref);
343	virtual int32 GetNextDirents(struct dirent* buffer, size_t length,
344		int32 count = INT_MAX);
345
346	virtual status_t Rewind();
347	virtual int32 CountEntries();
348
349protected:
350	bool Iterate() const;
351	void Instantiate();
352
353private:
354	SearchForSignatureEntryList* fParent;
355	BTrackerPrivate::TWalker* fWalker;
356};
357
358} // namespace BPrivate
359
360using namespace BPrivate;
361
362
363#endif	// _OPEN_WITH_WINDOW_H
364