xref: /haiku/src/kits/tracker/Utilities.h (revision fc7456e9b1ec38c941134ed6d01c438cf289381e)
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 = make_color(0, 0, 0, 255);
74 static const rgb_color kWhite = make_color(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 bool ValidateStream(BMallocIO*, uint32, int32 version);
183 
184 float ReadOnlyTint(rgb_color base);
185 rgb_color InvertColor(rgb_color color);
186 rgb_color InvertedBackColor(rgb_color background);
187 
188 bool SecondaryMouseButtonDown(int32 modifiers, int32 buttons);
189 
190 uint32 SeededHashString(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 	PositionPassingMenuItem(BMenu*, BMessage*);
279 	PositionPassingMenuItem(BMessage* data);
280 
281 	static BArchivable* Instantiate(BMessage* data);
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 ShortcutFilter : public BMessageFilter {
355 public:
356 	ShortcutFilter(uint32 shortcutKey, uint32 shortcutModifier,
357 		uint32 shortcutWhat, BHandler* target);
358 
359 protected:
360 	filter_result Filter(BMessage*, BHandler**);
361 
362 private:
363 	uint32 fShortcutKey;
364 	uint32 fShortcutModifier;
365 	uint32 fShortcutWhat;
366 	BHandler* fTarget;
367 };
368 
369 
370 // iterates over all the refs in a message
371 entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*),
372 	void* passThru = 0);
373 const entry_ref* EachEntryRef(const BMessage*,
374 	const entry_ref* (*)(const entry_ref*, void*), void* passThru = 0);
375 
376 entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*),
377 	void* passThru, int32 maxCount);
378 const entry_ref* EachEntryRef(const BMessage*,
379 	const entry_ref* (*)(const entry_ref*, void*), void* passThru,
380 	int32 maxCount);
381 
382 
383 bool ContainsEntryRef(const BMessage*, const entry_ref*);
384 int32 CountRefs(const BMessage*);
385 
386 BMenuItem* EachMenuItem(BMenu* menu, bool recursive,
387 	BMenuItem* (*func)(BMenuItem*));
388 const BMenuItem* EachMenuItem(const BMenu* menu, bool recursive,
389 	BMenuItem* (*func)(const BMenuItem*));
390 
391 int64 StringToScalar(const char* text);
392 	// string to num, understands kB, MB, etc.
393 
394 int32 ListIconSize();
395 
396 // misc calls
397 void EmbedUniqueVolumeInfo(BMessage* message, const BVolume* volume);
398 status_t MatchArchivedVolume(BVolume* volume, const BMessage* message,
399 	int32 index = 0);
400 void TruncateLeaf(BString* string);
401 
402 void StringFromStream(BString*, BMallocIO*, bool endianSwap = false);
403 void StringToStream(const BString*, BMallocIO*);
404 int32 ArchiveSize(const BString*);
405 
406 extern int CompareLabels(const BMenuItem*, const BMenuItem*);
407 extern void EnableNamedMenuItem(BMenu* menu, const char* itemName, bool on);
408 extern void MarkNamedMenuItem(BMenu* menu, const char* itemName, bool on);
409 extern void EnableNamedMenuItem(BMenu* menu, uint32 commandName, bool on);
410 extern void MarkNamedMenuItem(BMenu* menu, uint32 commandName, bool on);
411 extern void DeleteSubmenu(BMenuItem* submenuItem);
412 
413 extern bool BootedInSafeMode();
414 
415 
416 void PrintToStream(rgb_color color);
417 
418 template <class InitCheckable>
419 void
420 ThrowOnInitCheckError(InitCheckable* item)
421 {
422 	if (item == NULL)
423 		throw (status_t)B_ERROR;
424 
425 	status_t result = item->InitCheck();
426 	if (result != B_OK)
427 		throw (status_t)result;
428 }
429 
430 #if DEBUG
431 #	define ThrowOnError(x) _ThrowOnError(x, __FILE__, __LINE__)
432 #	define ThrowIfNotSize(x) _ThrowIfNotSize(x, __FILE__, __LINE__)
433 #	define ThrowOnAssert(x) _ThrowOnAssert(x, __FILE__, __LINE__)
434 #else
435 #	define ThrowOnError(x) _ThrowOnError(x, NULL, 0)
436 #	define ThrowIfNotSize(x) _ThrowIfNotSize(x, NULL, 0)
437 #	define ThrowOnAssert(x) _ThrowOnAssert(x, NULL, 0)
438 #endif
439 
440 void _ThrowOnError(status_t, const char*, int32);
441 void _ThrowIfNotSize(ssize_t, const char*, int32);
442 void _ThrowOnAssert(bool, const char*, int32);
443 
444 // stub calls that work around BAppFile info inefficiency
445 status_t GetAppSignatureFromAttr(BFile*, char*);
446 status_t GetAppIconFromAttr(BFile* file, BBitmap* icon, icon_size which);
447 status_t GetFileIconFromAttr(BNode* node, BBitmap* icon, icon_size which);
448 
449 // debugging
450 void HexDump(const void* buffer, int32 length);
451 
452 #if xDEBUG
453 
454 inline void
455 PrintRefToStream(const entry_ref* ref, const char* trailer = "\n")
456 {
457 	if (ref == NULL) {
458 		PRINT(("NULL entry_ref%s", trailer));
459 		return;
460 	}
461 
462 	BPath path;
463 	BEntry entry(ref);
464 	entry.GetPath(&path);
465 	PRINT(("%s%s", path.Path(), trailer));
466 }
467 
468 
469 inline void
470 PrintEntryToStream(const BEntry* entry, const char* trailer = "\n")
471 {
472 	if (entry == NULL) {
473 		PRINT(("NULL entry%s", trailer));
474 		return;
475 	}
476 
477 	BPath path;
478 	entry->GetPath(&path);
479 	PRINT(("%s%s", path.Path(), trailer));
480 }
481 
482 
483 inline void
484 PrintDirToStream(const BDirectory* dir, const char* trailer = "\n")
485 {
486 	if (dir == NULL) {
487 		PRINT(("NULL entry_ref%s", trailer));
488 		return;
489 	}
490 
491 	BPath path;
492 	BEntry entry;
493 	dir->GetEntry(&entry);
494 	entry.GetPath(&path);
495 	PRINT(("%s%s", path.Path(), trailer));
496 }
497 
498 #else
499 
500 inline void PrintRefToStream(const entry_ref*, const char* = 0) {}
501 inline void PrintEntryToStream(const BEntry*, const char* = 0) {}
502 inline void PrintDirToStream(const BDirectory*, const char* = 0) {}
503 
504 #endif
505 
506 #ifdef xDEBUG
507 
508 	extern FILE* logFile;
509 
510 	inline void PrintToLogFile(const char* format, ...)
511 	{
512 		va_list ap;
513 		va_start(ap, fmt);
514 		vfprintf(logFile, fmt, ap);
515 		va_end(ap);
516 	}
517 
518 #define WRITELOG(_ARGS_)													\
519 	if (logFile == 0) 														\
520 		logFile = fopen("/var/log/tracker.log", "a+");						\
521 																			\
522 	if (logFile != 0) {														\
523 		thread_info info;													\
524 		get_thread_info(find_thread(NULL), &info);							\
525 		PrintToLogFile("[t %lld] \"%s\" (%s:%i) ", system_time(),			\
526 			info.name, __FILE__, __LINE__);									\
527 		PrintToLogFile _ARGS_;												\
528 		PrintToLogFile("\n");												\
529 		fflush(logFile);													\
530 	}
531 
532 #else
533 
534 #define WRITELOG(_ARGS_)
535 
536 #endif
537 
538 // fancy casting macros
539 
540 template <typename NewType, typename OldType>
541 inline NewType assert_cast(OldType castedPointer) {
542 	ASSERT(dynamic_cast<NewType>(castedPointer) != NULL);
543 	return static_cast<NewType>(castedPointer);
544 }
545 
546 // B_SWAP_INT32 have broken signedness, simple cover calls to fix that
547 // should fix up in ByteOrder.h
548 
549 inline int32 SwapInt32(int32 value)
550 	{ return (int32)B_SWAP_INT32((uint32)value); }
551 inline uint32 SwapUInt32(uint32 value) { return B_SWAP_INT32(value); }
552 inline int64 SwapInt64(int64 value)
553 	{ return (int64)B_SWAP_INT64((uint64)value); }
554 inline uint64 SwapUInt64(uint64 value) { return B_SWAP_INT64(value); }
555 
556 
557 extern const float kExactMatchScore;
558 float ComputeTypeAheadScore(const char* text, const char* match,
559 	bool wordMode = false);
560 
561 
562 inline float
563 ActualFontHeight(const BView* view)
564 {
565 	font_height height;
566 	view->GetFontHeight(&height);
567 	return height.ascent + height.descent + 1;
568 }
569 
570 } // namespace BPrivate
571 
572 
573 #endif	// _UTILITIES_H
574