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