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