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