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