xref: /haiku/src/kits/tracker/Utilities.h (revision a2d9c45398ebcab924c89b2d4961bbebc2aeb3d6)
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 
275 	PositionPassingMenuItem(BMenu*, BMessage*);
276 
277 protected:
278 	virtual status_t Invoke(BMessage* = 0);
279 		// appends the invoke location for NewFolder, etc. to use
280 
281 private:
282 	typedef BMenuItem _inherited;
283 };
284 
285 
286 class Benaphore {
287 	// aka benaphore
288 public:
289 	Benaphore(const char* name = "Light Lock")
290 	:	fSemaphore(create_sem(0, name)),
291 		fCount(1)
292 	{
293 	}
294 
295 	~Benaphore()
296 	{
297 		delete_sem(fSemaphore);
298 	}
299 
300 	bool Lock()
301 	{
302 		if (atomic_add(&fCount, -1) <= 0)
303 			return acquire_sem(fSemaphore) == B_OK;
304 
305 		return true;
306 	}
307 
308 	void Unlock()
309 	{
310 		if (atomic_add(&fCount, 1) < 0)
311 			release_sem(fSemaphore);
312 	}
313 
314 	bool IsLocked() const
315 	{
316 		return fCount <= 0;
317 	}
318 
319 private:
320 	sem_id fSemaphore;
321 	int32 fCount;
322 };
323 
324 
325 class SeparatorLine : public BView {
326 public:
327 	SeparatorLine(BPoint, float, bool vertical, const char* name = "");
328 	virtual void Draw(BRect bounds);
329 };
330 
331 
332 class TitledSeparatorItem : public BMenuItem {
333 public:
334 	TitledSeparatorItem(const char*);
335 	virtual ~TitledSeparatorItem();
336 
337 	virtual void SetEnabled(bool state);
338 
339 protected:
340 	virtual void GetContentSize(float* width, float* height);
341 	virtual void Draw();
342 
343 private:
344 	typedef BMenuItem _inherited;
345 };
346 
347 
348 class LooperAutoLocker {
349 public:
350 	LooperAutoLocker(BHandler* handler)
351 	:	fHandler(handler),
352 		fHasLock(handler->LockLooper())
353 	{
354 	}
355 
356 	~LooperAutoLocker()
357 	{
358 		if (fHasLock)
359 			fHandler->UnlockLooper();
360 	}
361 
362 	bool operator!() const
363 	{
364 		return !fHasLock;
365 	}
366 
367 	bool IsLocked() const
368 	{
369 		return fHasLock;
370 	}
371 
372 private:
373 	BHandler* fHandler;
374 	bool fHasLock;
375 };
376 
377 
378 class ShortcutFilter : public BMessageFilter {
379 public:
380 	ShortcutFilter(uint32 shortcutKey, uint32 shortcutModifier,
381 		uint32 shortcutWhat, BHandler* target);
382 
383 protected:
384 	filter_result Filter(BMessage*, BHandler**);
385 
386 private:
387 	uint32 fShortcutKey;
388 	uint32 fShortcutModifier;
389 	uint32 fShortcutWhat;
390 	BHandler* fTarget;
391 };
392 
393 
394 // iterates over all the refs in a message
395 entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*),
396 	void* passThru = 0);
397 const entry_ref* EachEntryRef(const BMessage*,
398 	const entry_ref* (*)(const entry_ref*, void*), void* passThru = 0);
399 
400 entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*),
401 	void* passThru, int32 maxCount);
402 const entry_ref* EachEntryRef(const BMessage*,
403 	const entry_ref* (*)(const entry_ref*, void*), void* passThru,
404 	int32 maxCount);
405 
406 
407 bool ContainsEntryRef(const BMessage*, const entry_ref*);
408 int32 CountRefs(const BMessage*);
409 
410 BMenuItem* EachMenuItem(BMenu* menu, bool recursive,
411 	BMenuItem* (*func)(BMenuItem*));
412 const BMenuItem* EachMenuItem(const BMenu* menu, bool recursive,
413 	BMenuItem* (*func)(const BMenuItem*));
414 
415 int64 StringToScalar(const char* text);
416 	// string to num, understands kB, MB, etc.
417 
418 // misc calls
419 void EmbedUniqueVolumeInfo(BMessage* message, const BVolume* volume);
420 status_t MatchArchivedVolume(BVolume* volume, const BMessage* message,
421 	int32 index = 0);
422 void TruncateLeaf(BString* string);
423 
424 void StringFromStream(BString*, BMallocIO*, bool endianSwap = false);
425 void StringToStream(const BString*, BMallocIO*);
426 int32 ArchiveSize(const BString*);
427 
428 extern void EnableNamedMenuItem(BMenu* menu, const char* itemName, bool on);
429 extern void MarkNamedMenuItem(BMenu* menu, const char* itemName, bool on);
430 extern void EnableNamedMenuItem(BMenu* menu, uint32 commandName, bool on);
431 extern void MarkNamedMenuItem(BMenu* menu, uint32 commandName, bool on);
432 extern void DeleteSubmenu(BMenuItem* submenuItem);
433 
434 extern bool BootedInSafeMode();
435 
436 
437 inline rgb_color
438 Color(int32 r, int32 g, int32 b, int32 alpha = 255)
439 {
440 	rgb_color result;
441 	result.red = (uchar)r;
442 	result.green = (uchar)g;
443 	result.blue = (uchar)b;
444 	result.alpha = (uchar)alpha;
445 
446 	return result;
447 }
448 
449 void PrintToStream(rgb_color color);
450 
451 template <class InitCheckable>
452 void
453 ThrowOnInitCheckError(InitCheckable* item)
454 {
455 	if (item == NULL)
456 		throw (status_t)B_ERROR;
457 
458 	status_t result = item->InitCheck();
459 	if (result != B_OK)
460 		throw (status_t)result;
461 }
462 
463 #if DEBUG
464 #	define ThrowOnError(x) _ThrowOnError(x, __FILE__, __LINE__)
465 #	define ThrowIfNotSize(x) _ThrowIfNotSize(x, __FILE__, __LINE__)
466 #	define ThrowOnAssert(x) _ThrowOnAssert(x, __FILE__, __LINE__)
467 #else
468 #	define ThrowOnError(x) _ThrowOnError(x, NULL, 0)
469 #	define ThrowIfNotSize(x) _ThrowIfNotSize(x, NULL, 0)
470 #	define ThrowOnAssert(x) _ThrowOnAssert(x, NULL, 0)
471 #endif
472 
473 void _ThrowOnError(status_t, const char*, int32);
474 void _ThrowIfNotSize(ssize_t, const char*, int32);
475 void _ThrowOnAssert(bool, const char*, int32);
476 
477 // stub calls that work around BAppFile info inefficiency
478 status_t GetAppSignatureFromAttr(BFile*, char*);
479 status_t GetAppIconFromAttr(BFile* file, BBitmap* icon, icon_size which);
480 status_t GetFileIconFromAttr(BNode* node, BBitmap* icon, icon_size which);
481 
482 // debugging
483 void HexDump(const void* buffer, int32 length);
484 
485 #if xDEBUG
486 
487 inline void
488 PrintRefToStream(const entry_ref* ref, const char* trailer = "\n")
489 {
490 	if (ref == NULL) {
491 		PRINT(("NULL entry_ref%s", trailer));
492 		return;
493 	}
494 
495 	BPath path;
496 	BEntry entry(ref);
497 	entry.GetPath(&path);
498 	PRINT(("%s%s", path.Path(), trailer));
499 }
500 
501 
502 inline void
503 PrintEntryToStream(const BEntry* entry, const char* trailer = "\n")
504 {
505 	if (entry == NULL) {
506 		PRINT(("NULL entry%s", trailer));
507 		return;
508 	}
509 
510 	BPath path;
511 	entry->GetPath(&path);
512 	PRINT(("%s%s", path.Path(), trailer));
513 }
514 
515 
516 inline void
517 PrintDirToStream(const BDirectory* dir, const char* trailer = "\n")
518 {
519 	if (dir == NULL) {
520 		PRINT(("NULL entry_ref%s", trailer));
521 		return;
522 	}
523 
524 	BPath path;
525 	BEntry entry;
526 	dir->GetEntry(&entry);
527 	entry.GetPath(&path);
528 	PRINT(("%s%s", path.Path(), trailer));
529 }
530 
531 #else
532 
533 inline void PrintRefToStream(const entry_ref*, const char* = 0) {}
534 inline void PrintEntryToStream(const BEntry*, const char* = 0) {}
535 inline void PrintDirToStream(const BDirectory*, const char* = 0) {}
536 
537 #endif
538 
539 #ifdef xDEBUG
540 
541 	extern FILE* logFile;
542 
543 	inline void PrintToLogFile(const char* format, ...)
544 	{
545 		va_list ap;
546 		va_start(ap, fmt);
547 		vfprintf(logFile, fmt, ap);
548 		va_end(ap);
549 	}
550 
551 #define WRITELOG(_ARGS_)													\
552 	if (logFile == 0) 														\
553 		logFile = fopen("/var/log/tracker.log", "a+");						\
554 																			\
555 	if (logFile != 0) {														\
556 		thread_info info;													\
557 		get_thread_info(find_thread(NULL), &info);							\
558 		PrintToLogFile("[t %Ld] \"%s\" (%s:%i) ", system_time(),			\
559 			info.name, __FILE__, __LINE__);									\
560 		PrintToLogFile _ARGS_;												\
561 		PrintToLogFile("\n");												\
562 		fflush(logFile);													\
563 	}
564 
565 #else
566 
567 #define WRITELOG(_ARGS_)
568 
569 #endif
570 
571 // fancy casting macros
572 
573 template <typename NewType, typename OldType>
574 inline NewType assert_cast(OldType castedPointer) {
575 	ASSERT(dynamic_cast<NewType>(castedPointer) != NULL);
576 	return static_cast<NewType>(castedPointer);
577 }
578 
579 // B_SWAP_INT32 have broken signedness, simple cover calls to fix that
580 // should fix up in ByteOrder.h
581 
582 inline int32 SwapInt32(int32 value)
583 	{ return (int32)B_SWAP_INT32((uint32)value); }
584 inline uint32 SwapUInt32(uint32 value) { return B_SWAP_INT32(value); }
585 inline int64 SwapInt64(int64 value)
586 	{ return (int64)B_SWAP_INT64((uint64)value); }
587 inline uint64 SwapUInt64(uint64 value) { return B_SWAP_INT64(value); }
588 
589 
590 extern const float kExactMatchScore;
591 float ComputeTypeAheadScore(const char* text, const char* match,
592 	bool wordMode = false);
593 
594 } // namespace BPrivate
595 
596 
597 #endif	// _UTILITIES_H
598