xref: /haiku/src/kits/tracker/Utilities.h (revision 7bbfd0ff4956fd50e18cfb6f6f994f3f9446d77d)
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 _UTILITIES_H
35 #define _UTILITIES_H
36 
37 
38 #include <ctype.h>
39 #include <stdarg.h>
40 #include <stdlib.h>
41 
42 #include <Bitmap.h>
43 #include <ByteOrder.h>
44 #include <DataIO.h>
45 #include <Directory.h>
46 #include <Entry.h>
47 #include <GraphicsDefs.h>
48 #include <Looper.h>
49 #include <MenuItem.h>
50 #include <MessageFilter.h>
51 #include <Mime.h>
52 #include <NaturalCompare.h>
53 #include <ObjectList.h>
54 #include <Point.h>
55 #include <Path.h>
56 #include <String.h>
57 #include <StringView.h>
58 
59 
60 class BMessage;
61 class BTextView;
62 class BView;
63 class BVolume;
64 
65 namespace BPrivate {
66 
67 class Benaphore;
68 class BPose;
69 class BPoseView;
70 class Model;
71 
72 // global variables
73 static const rgb_color kBlack = {0, 0, 0, 255};
74 static const rgb_color kWhite = {255, 255, 255 ,255};
75 
76 const int64 kHalfKBSize = 512;
77 const int64 kKBSize = 1024;
78 const int64 kMBSize = 1048576;
79 const int64 kGBSize = 1073741824;
80 const int64 kTBSize = kGBSize * kKBSize;
81 
82 const int32 kMiniIconSeparator = 3;
83 
84 const color_space kDefaultIconDepth = B_RGBA32;
85 
86 
87 extern bool gLocalizedNamePreferred;
88 
89 
90 // misc typedefs, constants and structs
91 
92 class PeriodicUpdatePoses {
93 	// Periodically updated poses (ones with a volume space bar) register
94 	// themselfs in this global list. This way they can be iterated over instead
95 	// of sending around update messages.
96 public:
97 	PeriodicUpdatePoses();
98 	~PeriodicUpdatePoses();
99 
100 	typedef bool (*PeriodicUpdateCallback)(BPose* pose, void* cookie);
101 
102 	void AddPose(BPose* pose, BPoseView* poseView,
103 		PeriodicUpdateCallback callback, void* cookie);
104 	bool RemovePose(BPose* pose, void** cookie);
105 
106 	void DoPeriodicUpdate(bool forceRedraw);
107 
108 private:
109 	struct periodic_pose {
110 		BPose*					pose;
111 		BPoseView*				pose_view;
112 		PeriodicUpdateCallback	callback;
113 		void*					cookie;
114 	};
115 
116 	Benaphore* fLock;
117 	BObjectList<periodic_pose> fPoseList;
118 };
119 
120 extern PeriodicUpdatePoses gPeriodicUpdatePoses;
121 
122 
123 class PoseInfo {
124 	// PoseInfo is the structure that gets saved as attributes for every node
125 	// on disk, defining the node's position and visibility
126 public:
127 	static void EndianSwap(void* castToThis);
128 	void PrintToStream();
129 
130 	bool fInvisible;
131 	ino_t fInitedDirectory;
132 		// For a location to be valid, fInitedDirectory has to contain
133 		// the inode of the items parent directory. This makes it
134 		// impossible to for instance zip up files and extract them in
135 		// the same location. This should probably be reworked.
136 		// Tracker could strip the file location attributes when dropping
137 		// files into a closed folder.
138 	BPoint fLocation;
139 };
140 
141 
142 class ExtendedPoseInfo {
143 	// extends PoseInfo adding workspace support; used for desktop
144 	// poses only
145 public:
146 	size_t Size() const;
147 	static size_t Size(int32);
148 	size_t SizeWithHeadroom() const;
149 	static size_t SizeWithHeadroom(size_t);
150 	bool HasLocationForFrame(BRect) const;
151 	BPoint LocationForFrame(BRect) const;
152 	bool SetLocationForFrame(BPoint, BRect);
153 
154 	static void EndianSwap(void* castToThis);
155 	void PrintToStream();
156 
157 	uint32 fWorkspaces;
158 	bool fInvisible;
159 	bool fShowFromBootOnly;
160 	bool fReservedBool1;
161 	bool fReservedBool2;
162 	int32 fReservedInt1;
163 	int32 fReservedInt2;
164 	int32 fReservedInt3;
165 	int32 fReservedInt4;
166 	int32 fReservedInt5;
167 
168 	int32 fNumFrames;
169 	struct FrameLocation {
170 		BPoint fLocation;
171 		BRect fFrame;
172 		uint32 fWorkspaces;
173 	};
174 
175 	FrameLocation fLocations[0];
176 };
177 
178 // misc functions
179 void DisallowMetaKeys(BTextView*);
180 void DisallowFilenameKeys(BTextView*);
181 
182 
183 bool ValidateStream(BMallocIO*, uint32, int32 version);
184 
185 
186 bool SecondaryMouseButtonDown(int32 modifiers, int32 buttons);
187 uint32 HashString(const char* string, uint32 seed);
188 uint32 AttrHashString(const char* string, uint32 type);
189 
190 
191 class OffscreenBitmap {
192 	// a utility class for setting up offscreen bitmaps
193 	public:
194 		OffscreenBitmap(BRect bounds);
195 		OffscreenBitmap();
196 		~OffscreenBitmap();
197 
198 		BView* BeginUsing(BRect bounds);
199 		void DoneUsing();
200 		BBitmap* Bitmap() const;
201 			// blit this to your view when you are done rendering
202 		BView* View() const;
203 			// use this to render your image
204 
205 	private:
206 		void NewBitmap(BRect frame);
207 		BBitmap* fBitmap;
208 };
209 
210 
211 // bitmap functions
212 extern void FadeRGBA32Horizontal(uint32* bits, int32 width, int32 height,
213 	int32 from, int32 to);
214 extern void FadeRGBA32Vertical(uint32* bits, int32 width, int32 height,
215 	int32 from, int32 to);
216 
217 
218 class FlickerFreeStringView : public BStringView {
219 	// adds support for offscreen bitmap drawing for string views that update
220 	// often this would be better implemented as an option of BStringView
221 public:
222 	FlickerFreeStringView(BRect bounds, const char* name,
223 		const char* text, uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP,
224 		uint32 flags = B_WILL_DRAW);
225 	FlickerFreeStringView(BRect bounds, const char* name,
226 		const char* text, BBitmap* existingOffscreen,
227 		uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP,
228 		uint32 flags = B_WILL_DRAW);
229 	virtual ~FlickerFreeStringView();
230 	virtual void Draw(BRect);
231 	virtual void AttachedToWindow();
232 	virtual void SetViewColor(rgb_color);
233 	virtual void SetLowColor(rgb_color);
234 
235 private:
236 	OffscreenBitmap* fBitmap;
237 	rgb_color fViewColor;
238 	rgb_color fLowColor;
239 	BBitmap* fOriginalBitmap;
240 
241 	typedef BStringView _inherited;
242 };
243 
244 
245 class DraggableIcon : public BView {
246 	// used to determine a save location for a file
247 public:
248 	DraggableIcon(BRect rect, const char* name, const char* mimeType,
249 		icon_size which, const BMessage* message, BMessenger target,
250 		uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP,
251 		uint32 flags = B_WILL_DRAW);
252 	virtual ~DraggableIcon();
253 
254 	static BRect PreferredRect(BPoint offset, icon_size which);
255 	void SetTarget(BMessenger);
256 
257 protected:
258 	virtual void AttachedToWindow();
259 	virtual void MouseDown(BPoint);
260 	virtual void Draw(BRect);
261 
262 	virtual bool DragStarted(BMessage* dragMessage);
263 
264 protected:
265 	BBitmap* fBitmap;
266 	BMessage fMessage;
267 	BMessenger fTarget;
268 };
269 
270 
271 class PositionPassingMenuItem : public BMenuItem {
272 public:
273 	PositionPassingMenuItem(const char* title, BMessage*,
274 		char shortcut = 0, uint32 modifiers = 0);
275 	PositionPassingMenuItem(BMenu*, BMessage*);
276 	PositionPassingMenuItem(BMessage* data);
277 
278 	static BArchivable* Instantiate(BMessage* data);
279 
280 protected:
281 	virtual status_t Invoke(BMessage* = 0);
282 		// appends the invoke location for NewFolder, etc. to use
283 
284 private:
285 	typedef BMenuItem _inherited;
286 };
287 
288 
289 class Benaphore {
290 	// aka benaphore
291 public:
292 	Benaphore(const char* name = "Light Lock")
293 	:	fSemaphore(create_sem(0, name)),
294 		fCount(1)
295 	{
296 	}
297 
298 	~Benaphore()
299 	{
300 		delete_sem(fSemaphore);
301 	}
302 
303 	bool Lock()
304 	{
305 		if (atomic_add(&fCount, -1) <= 0)
306 			return acquire_sem(fSemaphore) == B_OK;
307 
308 		return true;
309 	}
310 
311 	void Unlock()
312 	{
313 		if (atomic_add(&fCount, 1) < 0)
314 			release_sem(fSemaphore);
315 	}
316 
317 	bool IsLocked() const
318 	{
319 		return fCount <= 0;
320 	}
321 
322 private:
323 	sem_id fSemaphore;
324 	int32 fCount;
325 };
326 
327 
328 class SeparatorLine : public BView {
329 public:
330 	SeparatorLine(BPoint, float, bool vertical, const char* name = "");
331 	virtual void Draw(BRect bounds);
332 };
333 
334 
335 class TitledSeparatorItem : public BMenuItem {
336 public:
337 	TitledSeparatorItem(const char*);
338 	virtual ~TitledSeparatorItem();
339 
340 	virtual void SetEnabled(bool state);
341 
342 protected:
343 	virtual void GetContentSize(float* width, float* height);
344 	virtual void Draw();
345 
346 private:
347 	typedef BMenuItem _inherited;
348 };
349 
350 
351 class LooperAutoLocker {
352 public:
353 	LooperAutoLocker(BHandler* handler)
354 	:	fHandler(handler),
355 		fHasLock(handler->LockLooper())
356 	{
357 	}
358 
359 	~LooperAutoLocker()
360 	{
361 		if (fHasLock)
362 			fHandler->UnlockLooper();
363 	}
364 
365 	bool operator!() const
366 	{
367 		return !fHasLock;
368 	}
369 
370 	bool IsLocked() const
371 	{
372 		return fHasLock;
373 	}
374 
375 private:
376 	BHandler* fHandler;
377 	bool fHasLock;
378 };
379 
380 
381 class ShortcutFilter : public BMessageFilter {
382 public:
383 	ShortcutFilter(uint32 shortcutKey, uint32 shortcutModifier,
384 		uint32 shortcutWhat, BHandler* target);
385 
386 protected:
387 	filter_result Filter(BMessage*, BHandler**);
388 
389 private:
390 	uint32 fShortcutKey;
391 	uint32 fShortcutModifier;
392 	uint32 fShortcutWhat;
393 	BHandler* fTarget;
394 };
395 
396 
397 // iterates over all the refs in a message
398 entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*),
399 	void* passThru = 0);
400 const entry_ref* EachEntryRef(const BMessage*,
401 	const entry_ref* (*)(const entry_ref*, void*), void* passThru = 0);
402 
403 entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*),
404 	void* passThru, int32 maxCount);
405 const entry_ref* EachEntryRef(const BMessage*,
406 	const entry_ref* (*)(const entry_ref*, void*), void* passThru,
407 	int32 maxCount);
408 
409 
410 bool ContainsEntryRef(const BMessage*, const entry_ref*);
411 int32 CountRefs(const BMessage*);
412 
413 BMenuItem* EachMenuItem(BMenu* menu, bool recursive,
414 	BMenuItem* (*func)(BMenuItem*));
415 const BMenuItem* EachMenuItem(const BMenu* menu, bool recursive,
416 	BMenuItem* (*func)(const BMenuItem*));
417 
418 int64 StringToScalar(const char* text);
419 	// string to num, understands kB, MB, etc.
420 
421 int32 ListIconSize();
422 
423 // misc calls
424 void EmbedUniqueVolumeInfo(BMessage* message, const BVolume* volume);
425 status_t MatchArchivedVolume(BVolume* volume, const BMessage* message,
426 	int32 index = 0);
427 void TruncateLeaf(BString* string);
428 
429 void StringFromStream(BString*, BMallocIO*, bool endianSwap = false);
430 void StringToStream(const BString*, BMallocIO*);
431 int32 ArchiveSize(const BString*);
432 
433 extern void EnableNamedMenuItem(BMenu* menu, const char* itemName, bool on);
434 extern void MarkNamedMenuItem(BMenu* menu, const char* itemName, bool on);
435 extern void EnableNamedMenuItem(BMenu* menu, uint32 commandName, bool on);
436 extern void MarkNamedMenuItem(BMenu* menu, uint32 commandName, bool on);
437 extern void DeleteSubmenu(BMenuItem* submenuItem);
438 
439 extern bool BootedInSafeMode();
440 
441 
442 inline rgb_color
443 Color(int32 r, int32 g, int32 b, int32 alpha = 255)
444 {
445 	rgb_color result;
446 	result.red = (uchar)r;
447 	result.green = (uchar)g;
448 	result.blue = (uchar)b;
449 	result.alpha = (uchar)alpha;
450 
451 	return result;
452 }
453 
454 void PrintToStream(rgb_color color);
455 
456 template <class InitCheckable>
457 void
458 ThrowOnInitCheckError(InitCheckable* item)
459 {
460 	if (item == NULL)
461 		throw (status_t)B_ERROR;
462 
463 	status_t result = item->InitCheck();
464 	if (result != B_OK)
465 		throw (status_t)result;
466 }
467 
468 #if DEBUG
469 #	define ThrowOnError(x) _ThrowOnError(x, __FILE__, __LINE__)
470 #	define ThrowIfNotSize(x) _ThrowIfNotSize(x, __FILE__, __LINE__)
471 #	define ThrowOnAssert(x) _ThrowOnAssert(x, __FILE__, __LINE__)
472 #else
473 #	define ThrowOnError(x) _ThrowOnError(x, NULL, 0)
474 #	define ThrowIfNotSize(x) _ThrowIfNotSize(x, NULL, 0)
475 #	define ThrowOnAssert(x) _ThrowOnAssert(x, NULL, 0)
476 #endif
477 
478 void _ThrowOnError(status_t, const char*, int32);
479 void _ThrowIfNotSize(ssize_t, const char*, int32);
480 void _ThrowOnAssert(bool, const char*, int32);
481 
482 // stub calls that work around BAppFile info inefficiency
483 status_t GetAppSignatureFromAttr(BFile*, char*);
484 status_t GetAppIconFromAttr(BFile* file, BBitmap* icon, icon_size which);
485 status_t GetFileIconFromAttr(Model* model, BBitmap* icon, icon_size which);
486 status_t GetThumbnailIcon(Model* model, BBitmap* icon, icon_size which);
487 
488 bool ShouldGenerateThumbnail(const char* type);
489 
490 // debugging
491 void HexDump(const void* buffer, int32 length);
492 
493 #if xDEBUG
494 
495 inline void
496 PrintRefToStream(const entry_ref* ref, const char* trailer = "\n")
497 {
498 	if (ref == NULL) {
499 		PRINT(("NULL entry_ref%s", trailer));
500 		return;
501 	}
502 
503 	BPath path;
504 	BEntry entry(ref);
505 	entry.GetPath(&path);
506 	PRINT(("%s%s", path.Path(), trailer));
507 }
508 
509 
510 inline void
511 PrintEntryToStream(const BEntry* entry, const char* trailer = "\n")
512 {
513 	if (entry == NULL) {
514 		PRINT(("NULL entry%s", trailer));
515 		return;
516 	}
517 
518 	BPath path;
519 	entry->GetPath(&path);
520 	PRINT(("%s%s", path.Path(), trailer));
521 }
522 
523 
524 inline void
525 PrintDirToStream(const BDirectory* dir, const char* trailer = "\n")
526 {
527 	if (dir == NULL) {
528 		PRINT(("NULL entry_ref%s", trailer));
529 		return;
530 	}
531 
532 	BPath path;
533 	BEntry entry;
534 	dir->GetEntry(&entry);
535 	entry.GetPath(&path);
536 	PRINT(("%s%s", path.Path(), trailer));
537 }
538 
539 #else
540 
541 inline void PrintRefToStream(const entry_ref*, const char* = 0) {}
542 inline void PrintEntryToStream(const BEntry*, const char* = 0) {}
543 inline void PrintDirToStream(const BDirectory*, const char* = 0) {}
544 
545 #endif
546 
547 #ifdef xDEBUG
548 
549 	extern FILE* logFile;
550 
551 	inline void PrintToLogFile(const char* format, ...)
552 	{
553 		va_list ap;
554 		va_start(ap, fmt);
555 		vfprintf(logFile, fmt, ap);
556 		va_end(ap);
557 	}
558 
559 #define WRITELOG(_ARGS_)													\
560 	if (logFile == 0) 														\
561 		logFile = fopen("/var/log/tracker.log", "a+");						\
562 																			\
563 	if (logFile != 0) {														\
564 		thread_info info;													\
565 		get_thread_info(find_thread(NULL), &info);							\
566 		PrintToLogFile("[t %Ld] \"%s\" (%s:%i) ", system_time(),			\
567 			info.name, __FILE__, __LINE__);									\
568 		PrintToLogFile _ARGS_;												\
569 		PrintToLogFile("\n");												\
570 		fflush(logFile);													\
571 	}
572 
573 #else
574 
575 #define WRITELOG(_ARGS_)
576 
577 #endif
578 
579 // fancy casting macros
580 
581 template <typename NewType, typename OldType>
582 inline NewType assert_cast(OldType castedPointer) {
583 	ASSERT(dynamic_cast<NewType>(castedPointer) != NULL);
584 	return static_cast<NewType>(castedPointer);
585 }
586 
587 // B_SWAP_INT32 have broken signedness, simple cover calls to fix that
588 // should fix up in ByteOrder.h
589 
590 inline int32 SwapInt32(int32 value)
591 	{ return (int32)B_SWAP_INT32((uint32)value); }
592 inline uint32 SwapUInt32(uint32 value) { return B_SWAP_INT32(value); }
593 inline int64 SwapInt64(int64 value)
594 	{ return (int64)B_SWAP_INT64((uint64)value); }
595 inline uint64 SwapUInt64(uint64 value) { return B_SWAP_INT64(value); }
596 
597 
598 extern const float kExactMatchScore;
599 float ComputeTypeAheadScore(const char* text, const char* match,
600 	bool wordMode = false);
601 
602 } // namespace BPrivate
603 
604 
605 #endif	// _UTILITIES_H
606