xref: /haiku/src/kits/tracker/Utilities.h (revision 3be79a33b059ba22f25c7db93743b758717d8b68)
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 uint32 HashString(const char* string, uint32 seed);
190 uint32 AttrHashString(const char* string, uint32 type);
191 
192 
193 class OffscreenBitmap {
194 	// a utility class for setting up offscreen bitmaps
195 	public:
196 		OffscreenBitmap(BRect bounds);
197 		OffscreenBitmap();
198 		~OffscreenBitmap();
199 
200 		BView* BeginUsing(BRect bounds);
201 		void DoneUsing();
202 		BBitmap* Bitmap() const;
203 			// blit this to your view when you are done rendering
204 		BView* View() const;
205 			// use this to render your image
206 
207 	private:
208 		void NewBitmap(BRect frame);
209 		BBitmap* fBitmap;
210 };
211 
212 
213 // bitmap functions
214 extern void FadeRGBA32Horizontal(uint32* bits, int32 width, int32 height,
215 	int32 from, int32 to);
216 extern void FadeRGBA32Vertical(uint32* bits, int32 width, int32 height,
217 	int32 from, int32 to);
218 
219 
220 class FlickerFreeStringView : public BStringView {
221 	// adds support for offscreen bitmap drawing for string views that update
222 	// often this would be better implemented as an option of BStringView
223 public:
224 	FlickerFreeStringView(BRect bounds, const char* name,
225 		const char* text, uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP,
226 		uint32 flags = B_WILL_DRAW);
227 	FlickerFreeStringView(BRect bounds, const char* name,
228 		const char* text, BBitmap* existingOffscreen,
229 		uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP,
230 		uint32 flags = B_WILL_DRAW);
231 	virtual ~FlickerFreeStringView();
232 	virtual void Draw(BRect);
233 	virtual void AttachedToWindow();
234 	virtual void SetViewColor(rgb_color);
235 	virtual void SetLowColor(rgb_color);
236 
237 private:
238 	OffscreenBitmap* fBitmap;
239 	rgb_color fViewColor;
240 	rgb_color fLowColor;
241 	BBitmap* fOriginalBitmap;
242 
243 	typedef BStringView _inherited;
244 };
245 
246 
247 class DraggableIcon : public BView {
248 	// used to determine a save location for a file
249 public:
250 	DraggableIcon(BRect rect, const char* name, const char* mimeType,
251 		icon_size which, const BMessage* message, BMessenger target,
252 		uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP,
253 		uint32 flags = B_WILL_DRAW);
254 	virtual ~DraggableIcon();
255 
256 	static BRect PreferredRect(BPoint offset, icon_size which);
257 	void SetTarget(BMessenger);
258 
259 protected:
260 	virtual void AttachedToWindow();
261 	virtual void MouseDown(BPoint);
262 	virtual void Draw(BRect);
263 
264 	virtual bool DragStarted(BMessage* dragMessage);
265 
266 protected:
267 	BBitmap* fBitmap;
268 	BMessage fMessage;
269 	BMessenger fTarget;
270 };
271 
272 
273 class PositionPassingMenuItem : public BMenuItem {
274 public:
275 	PositionPassingMenuItem(const char* title, BMessage*,
276 		char shortcut = 0, uint32 modifiers = 0);
277 	PositionPassingMenuItem(BMenu*, BMessage*);
278 	PositionPassingMenuItem(BMessage* data);
279 
280 	static BArchivable* Instantiate(BMessage* data);
281 
282 protected:
283 	virtual status_t Invoke(BMessage* = 0);
284 		// appends the invoke location for NewFolder, etc. to use
285 
286 private:
287 	typedef BMenuItem _inherited;
288 };
289 
290 
291 class Benaphore {
292 	// aka benaphore
293 public:
294 	Benaphore(const char* name = "Light Lock")
295 	:	fSemaphore(create_sem(0, name)),
296 		fCount(1)
297 	{
298 	}
299 
300 	~Benaphore()
301 	{
302 		delete_sem(fSemaphore);
303 	}
304 
305 	bool Lock()
306 	{
307 		if (atomic_add(&fCount, -1) <= 0)
308 			return acquire_sem(fSemaphore) == B_OK;
309 
310 		return true;
311 	}
312 
313 	void Unlock()
314 	{
315 		if (atomic_add(&fCount, 1) < 0)
316 			release_sem(fSemaphore);
317 	}
318 
319 	bool IsLocked() const
320 	{
321 		return fCount <= 0;
322 	}
323 
324 private:
325 	sem_id fSemaphore;
326 	int32 fCount;
327 };
328 
329 
330 class SeparatorLine : public BView {
331 public:
332 	SeparatorLine(BPoint, float, bool vertical, const char* name = "");
333 	virtual void Draw(BRect bounds);
334 };
335 
336 
337 class TitledSeparatorItem : public BMenuItem {
338 public:
339 	TitledSeparatorItem(const char*);
340 	virtual ~TitledSeparatorItem();
341 
342 	virtual void SetEnabled(bool state);
343 
344 protected:
345 	virtual void GetContentSize(float* width, float* height);
346 	virtual void Draw();
347 
348 private:
349 	typedef BMenuItem _inherited;
350 };
351 
352 
353 class ShortcutFilter : public BMessageFilter {
354 public:
355 	ShortcutFilter(uint32 shortcutKey, uint32 shortcutModifier,
356 		uint32 shortcutWhat, BHandler* target);
357 
358 protected:
359 	filter_result Filter(BMessage*, BHandler**);
360 
361 private:
362 	uint32 fShortcutKey;
363 	uint32 fShortcutModifier;
364 	uint32 fShortcutWhat;
365 	BHandler* fTarget;
366 };
367 
368 
369 // iterates over all the refs in a message
370 entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*),
371 	void* passThru = 0);
372 const entry_ref* EachEntryRef(const BMessage*,
373 	const entry_ref* (*)(const entry_ref*, void*), void* passThru = 0);
374 
375 entry_ref* EachEntryRef(BMessage*, entry_ref* (*)(entry_ref*, void*),
376 	void* passThru, int32 maxCount);
377 const entry_ref* EachEntryRef(const BMessage*,
378 	const entry_ref* (*)(const entry_ref*, void*), void* passThru,
379 	int32 maxCount);
380 
381 
382 bool ContainsEntryRef(const BMessage*, const entry_ref*);
383 int32 CountRefs(const BMessage*);
384 
385 BMenuItem* EachMenuItem(BMenu* menu, bool recursive,
386 	BMenuItem* (*func)(BMenuItem*));
387 const BMenuItem* EachMenuItem(const BMenu* menu, bool recursive,
388 	BMenuItem* (*func)(const BMenuItem*));
389 
390 int64 StringToScalar(const char* text);
391 	// string to num, understands kB, MB, etc.
392 
393 int32 ListIconSize();
394 
395 // misc calls
396 void EmbedUniqueVolumeInfo(BMessage* message, const BVolume* volume);
397 status_t MatchArchivedVolume(BVolume* volume, const BMessage* message,
398 	int32 index = 0);
399 void TruncateLeaf(BString* string);
400 
401 void StringFromStream(BString*, BMallocIO*, bool endianSwap = false);
402 void StringToStream(const BString*, BMallocIO*);
403 int32 ArchiveSize(const BString*);
404 
405 extern int CompareLabels(const BMenuItem*, const BMenuItem*);
406 extern void EnableNamedMenuItem(BMenu* menu, const char* itemName, bool on);
407 extern void MarkNamedMenuItem(BMenu* menu, const char* itemName, bool on);
408 extern void EnableNamedMenuItem(BMenu* menu, uint32 commandName, bool on);
409 extern void MarkNamedMenuItem(BMenu* menu, uint32 commandName, bool on);
410 extern void DeleteSubmenu(BMenuItem* submenuItem);
411 
412 extern bool BootedInSafeMode();
413 
414 
415 void PrintToStream(rgb_color color);
416 
417 template <class InitCheckable>
418 void
419 ThrowOnInitCheckError(InitCheckable* item)
420 {
421 	if (item == NULL)
422 		throw (status_t)B_ERROR;
423 
424 	status_t result = item->InitCheck();
425 	if (result != B_OK)
426 		throw (status_t)result;
427 }
428 
429 #if DEBUG
430 #	define ThrowOnError(x) _ThrowOnError(x, __FILE__, __LINE__)
431 #	define ThrowIfNotSize(x) _ThrowIfNotSize(x, __FILE__, __LINE__)
432 #	define ThrowOnAssert(x) _ThrowOnAssert(x, __FILE__, __LINE__)
433 #else
434 #	define ThrowOnError(x) _ThrowOnError(x, NULL, 0)
435 #	define ThrowIfNotSize(x) _ThrowIfNotSize(x, NULL, 0)
436 #	define ThrowOnAssert(x) _ThrowOnAssert(x, NULL, 0)
437 #endif
438 
439 void _ThrowOnError(status_t, const char*, int32);
440 void _ThrowIfNotSize(ssize_t, const char*, int32);
441 void _ThrowOnAssert(bool, const char*, int32);
442 
443 // stub calls that work around BAppFile info inefficiency
444 status_t GetAppSignatureFromAttr(BFile*, char*);
445 status_t GetAppIconFromAttr(BFile* file, BBitmap* icon, icon_size which);
446 status_t GetFileIconFromAttr(BNode* node, BBitmap* icon, icon_size which);
447 
448 // debugging
449 void HexDump(const void* buffer, int32 length);
450 
451 #if xDEBUG
452 
453 inline void
454 PrintRefToStream(const entry_ref* ref, const char* trailer = "\n")
455 {
456 	if (ref == NULL) {
457 		PRINT(("NULL entry_ref%s", trailer));
458 		return;
459 	}
460 
461 	BPath path;
462 	BEntry entry(ref);
463 	entry.GetPath(&path);
464 	PRINT(("%s%s", path.Path(), trailer));
465 }
466 
467 
468 inline void
469 PrintEntryToStream(const BEntry* entry, const char* trailer = "\n")
470 {
471 	if (entry == NULL) {
472 		PRINT(("NULL entry%s", trailer));
473 		return;
474 	}
475 
476 	BPath path;
477 	entry->GetPath(&path);
478 	PRINT(("%s%s", path.Path(), trailer));
479 }
480 
481 
482 inline void
483 PrintDirToStream(const BDirectory* dir, const char* trailer = "\n")
484 {
485 	if (dir == NULL) {
486 		PRINT(("NULL entry_ref%s", trailer));
487 		return;
488 	}
489 
490 	BPath path;
491 	BEntry entry;
492 	dir->GetEntry(&entry);
493 	entry.GetPath(&path);
494 	PRINT(("%s%s", path.Path(), trailer));
495 }
496 
497 #else
498 
499 inline void PrintRefToStream(const entry_ref*, const char* = 0) {}
500 inline void PrintEntryToStream(const BEntry*, const char* = 0) {}
501 inline void PrintDirToStream(const BDirectory*, const char* = 0) {}
502 
503 #endif
504 
505 #ifdef xDEBUG
506 
507 	extern FILE* logFile;
508 
509 	inline void PrintToLogFile(const char* format, ...)
510 	{
511 		va_list ap;
512 		va_start(ap, fmt);
513 		vfprintf(logFile, fmt, ap);
514 		va_end(ap);
515 	}
516 
517 #define WRITELOG(_ARGS_)													\
518 	if (logFile == 0) 														\
519 		logFile = fopen("/var/log/tracker.log", "a+");						\
520 																			\
521 	if (logFile != 0) {														\
522 		thread_info info;													\
523 		get_thread_info(find_thread(NULL), &info);							\
524 		PrintToLogFile("[t %lld] \"%s\" (%s:%i) ", system_time(),			\
525 			info.name, __FILE__, __LINE__);									\
526 		PrintToLogFile _ARGS_;												\
527 		PrintToLogFile("\n");												\
528 		fflush(logFile);													\
529 	}
530 
531 #else
532 
533 #define WRITELOG(_ARGS_)
534 
535 #endif
536 
537 // fancy casting macros
538 
539 template <typename NewType, typename OldType>
540 inline NewType assert_cast(OldType castedPointer) {
541 	ASSERT(dynamic_cast<NewType>(castedPointer) != NULL);
542 	return static_cast<NewType>(castedPointer);
543 }
544 
545 // B_SWAP_INT32 have broken signedness, simple cover calls to fix that
546 // should fix up in ByteOrder.h
547 
548 inline int32 SwapInt32(int32 value)
549 	{ return (int32)B_SWAP_INT32((uint32)value); }
550 inline uint32 SwapUInt32(uint32 value) { return B_SWAP_INT32(value); }
551 inline int64 SwapInt64(int64 value)
552 	{ return (int64)B_SWAP_INT64((uint64)value); }
553 inline uint64 SwapUInt64(uint64 value) { return B_SWAP_INT64(value); }
554 
555 
556 extern const float kExactMatchScore;
557 float ComputeTypeAheadScore(const char* text, const char* match,
558 	bool wordMode = false);
559 
560 
561 inline float
562 ActualFontHeight(const BView* view)
563 {
564 	font_height height;
565 	view->GetFontHeight(&height);
566 	return height.ascent + height.descent + 1;
567 }
568 
569 } // namespace BPrivate
570 
571 
572 #endif	// _UTILITIES_H
573