2 * Public domain source code.
5 * Joseph "looncraz" Groover <looncraz@satx.rr.com>
15 #include <FindDirectory.h>
17 #include <Resources.h>
18 #include <SystemCatalog.h>
20 #include <DecoratorPrivate.h>
23 #define B_TRANSLATION_CONTEXT "Default decorator about box"
29 DecorInfo::DecorInfo()
33 fInitStatus(B_NO_INIT
)
38 DecorInfo::DecorInfo(const BString
& path
)
43 fInitStatus(B_NO_INIT
)
45 BEntry
entry(path
.String(), true);
52 DecorInfo::DecorInfo(const entry_ref
& ref
)
57 fInitStatus(B_NO_INIT
)
66 DecorInfo::~DecorInfo()
72 DecorInfo::SetTo(const entry_ref
& ref
)
86 DecorInfo::SetTo(BString path
)
88 BEntry
entry(path
.String(), true);
96 DecorInfo::InitCheck() const
109 fShortDescription
= "";
114 fModificationTime
= 0;
115 fInitStatus
= B_NO_INIT
;
120 DecorInfo::IsDefault() const
122 return fInitStatus
== B_OK
&& fPath
== "Default";
127 DecorInfo::Path() const
134 DecorInfo::Ref() const
136 if (InitCheck() != B_OK
|| IsDefault())
143 DecorInfo::Name() const
150 DecorInfo::ShortcutName() const
159 DecorInfo::Authors() const
166 DecorInfo::ShortDescription() const
168 return fShortDescription
;
173 DecorInfo::LongDescription() const
175 return fLongDescription
;
180 DecorInfo::LicenseURL() const
187 DecorInfo::LicenseName() const
194 DecorInfo::SupportURL() const
201 DecorInfo::Version() const
208 DecorInfo::ModificationTime() const
210 return fModificationTime
;
215 DecorInfo::CheckForChanges(bool& deleted
)
217 if (InitCheck() != B_OK
)
222 if (entry
.InitCheck() != B_OK
)
225 if (!entry
.Exists()) {
231 if (entry
.GetModificationTime(&modtime
) != B_OK
) {
232 fprintf(stderr
, "DecorInfo::CheckForChanges()\tERROR: "
233 "BEntry:GetModificationTime() failed\n");
237 if (fModificationTime
!= modtime
) {
247 DecorInfo::_Init(bool isUpdate
)
249 if (!isUpdate
&& InitCheck() != B_NO_INIT
) {
250 // TODO: remove after validation
251 fprintf(stderr
, "DecorInfo::_Init()\tImproper init state\n");
257 if (fPath
== "Default") {
259 // should never happen
260 fprintf(stderr
, "DecorInfo::_Init(true)\tBUG BUG updating default"
265 fAuthors
= "DarkWyrm, Stephan Aßmus, Clemens Zeidler, Ingo Weinhold";
266 fLongDescription
= fShortDescription
;
267 fLicenseURL
= "http://";
268 fLicenseName
= "MIT";
269 fSupportURL
= "http://www.haiku-os.org/";
273 fName
= gSystemCatalog
.GetString(B_TRANSLATE_MARK("Default"),
274 B_TRANSLATION_CONTEXT
);
275 fShortDescription
= gSystemCatalog
.GetString(B_TRANSLATE_MARK(
276 "Default Haiku window decorator."),
277 B_TRANSLATION_CONTEXT
);
279 // The following is to get the modification time of the app_server
280 // and, thusly, the Default decorator...
281 // If you can make it more simple, please do!
283 find_directory(B_SYSTEM_SERVERS_DIRECTORY
, &path
);
284 path
.Append("app_server");
285 entry
.SetTo(path
.Path(), true);
286 if (!entry
.Exists()) {
287 fprintf(stderr
, "Server MIA the world has become its slave! "
292 entry
.GetModificationTime(&fModificationTime
);
296 // Is a file system object...
298 entry
.SetTo(&fRef
, true); // follow link
299 if (entry
.InitCheck() != B_OK
) {
300 fInitStatus
= entry
.InitCheck();
304 if (!entry
.Exists()) {
306 fprintf(stderr
, "DecorInfo::_Init()\tERROR: decorator deleted"
307 " after CheckForChanges() found it!\n");
308 fprintf(stderr
, "DecorInfo::_Init()\tERROR: DecorInfo will "
315 // update fRef to match file system object
317 entry
.GetModificationTime(&fModificationTime
);
319 BResources
resources(&fRef
);
320 if (resources
.InitCheck() != B_OK
) {
321 fprintf(stderr
, "DecorInfo::_Init()\t BResource InitCheck() failure\n");
326 const void* infoData
= resources
.LoadResource(B_MESSAGE_TYPE
,
327 "be:decor:info", &infoSize
);
328 BMessage infoMessage
;
330 if (infoData
== NULL
|| infoSize
== 0
331 || infoMessage
.Unflatten((const char*)infoData
) != B_OK
) {
332 fprintf(stderr
, "DecorInfo::_init()\tNo extended information found for"
333 " \"%s\"\n", fRef
.name
);
335 infoMessage
.FindString("name", &fName
);
336 infoMessage
.FindString("authors", &fAuthors
);
337 infoMessage
.FindString("short_descr", &fShortDescription
);
338 infoMessage
.FindString("long_descr", &fLongDescription
);
339 infoMessage
.FindString("lic_url", &fLicenseURL
);
340 infoMessage
.FindString("lic_name", &fLicenseName
);
341 infoMessage
.FindString("support_url", &fSupportURL
);
342 infoMessage
.FindFloat ("version", &fVersion
);
350 // #pragma mark - DecorInfoUtility
353 DecorInfoUtility::DecorInfoUtility(bool scanNow
)
357 // get default decorator from app_server
358 DecorInfo
* info
= new(std::nothrow
) DecorInfo("Default");
359 if (info
== NULL
|| info
->InitCheck() != B_OK
) {
361 fprintf(stderr
, "DecorInfoUtility::constructor\tdefault decorator's "
362 "DecorInfo failed InitCheck()\n");
373 DecorInfoUtility::~DecorInfoUtility()
376 for (int i
= fList
.CountItems() - 1; i
>= 0; --i
)
377 delete fList
.ItemAt(i
);
382 DecorInfoUtility::ScanDecorators()
387 result
= find_directory(B_SYSTEM_ADDONS_DIRECTORY
, &systemPath
);
389 result
= systemPath
.Append("decorators");
391 if (result
== B_OK
) {
392 BDirectory
systemDirectory(systemPath
.Path());
393 result
= systemDirectory
.InitCheck();
394 if (result
== B_OK
) {
395 result
= _ScanDecorators(systemDirectory
);
396 if (result
!= B_OK
) {
397 fprintf(stderr
, "DecorInfoUtility::ScanDecorators()\tERROR: %s\n",
404 BPath systemNonPackagedPath
;
405 result
= find_directory(B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY
,
406 &systemNonPackagedPath
);
408 result
= systemNonPackagedPath
.Append("decorators");
410 if (result
== B_OK
) {
411 BDirectory
systemNonPackagedDirectory(systemNonPackagedPath
.Path());
412 result
= systemNonPackagedDirectory
.InitCheck();
413 if (result
== B_OK
) {
414 result
= _ScanDecorators(systemNonPackagedDirectory
);
415 if (result
!= B_OK
) {
416 fprintf(stderr
, "DecorInfoUtility::ScanDecorators()\tERROR: %s\n",
424 result
= find_directory(B_USER_ADDONS_DIRECTORY
, &userPath
);
426 result
= userPath
.Append("decorators");
428 if (result
== B_OK
) {
429 BDirectory
userDirectory(userPath
.Path());
430 result
= userDirectory
.InitCheck();
431 if (result
== B_OK
) {
432 result
= _ScanDecorators(userDirectory
);
433 if (result
!= B_OK
) {
434 fprintf(stderr
, "DecorInfoUtility::ScanDecorators()\tERROR: %s\n",
441 BPath userNonPackagedPath
;
442 result
= find_directory(B_USER_NONPACKAGED_ADDONS_DIRECTORY
,
443 &userNonPackagedPath
);
445 result
= userNonPackagedPath
.Append("decorators");
447 if (result
== B_OK
) {
448 BDirectory
userNonPackagedDirectory(userNonPackagedPath
.Path());
449 result
= userNonPackagedDirectory
.InitCheck();
450 if (result
== B_OK
) {
451 result
= _ScanDecorators(userNonPackagedDirectory
);
452 if (result
!= B_OK
) {
453 fprintf(stderr
, "DecorInfoUtility::ScanDecorators()\tERROR: %s\n",
467 DecorInfoUtility::CountDecorators()
473 return fList
.CountItems();
478 DecorInfoUtility::DecoratorAt(int32 index
)
481 return fList
.ItemAt(index
);
486 DecorInfoUtility::FindDecorator(const BString
& string
)
488 if (string
.Length() == 0)
489 return CurrentDecorator();
491 if (string
.ICompare("default") == 0)
492 return DefaultDecorator();
499 DecorInfo
* decor
= _FindDecor(string
);
503 // search by name or short cut name
504 for (int i
= 1; i
< fList
.CountItems(); ++i
) {
505 decor
= fList
.ItemAt(i
);
506 if (string
.ICompare(decor
->ShortcutName()) == 0
507 || string
.ICompare(decor
->Name()) == 0) {
517 DecorInfoUtility::CurrentDecorator()
525 return FindDecorator(name
);
530 DecorInfoUtility::DefaultDecorator()
533 return fList
.ItemAt(0);
538 DecorInfoUtility::IsCurrentDecorator(DecorInfo
* decor
)
543 return decor
->Path() == CurrentDecorator()->Path();
548 DecorInfoUtility::SetDecorator(DecorInfo
* decor
)
554 if (decor
->IsDefault())
555 return set_decorator("Default");
557 return set_decorator(decor
->Path());
562 DecorInfoUtility::SetDecorator(int32 index
)
568 DecorInfo
* decor
= DecoratorAt(index
);
572 return SetDecorator(decor
);
577 DecorInfoUtility::Preview(DecorInfo
* decor
, BWindow
* window
)
582 return preview_decorator(decor
->Path(), window
);
586 // #pargma mark - private
590 DecorInfoUtility::_FindDecor(const BString
& pathString
)
592 // find decor by path and path alone!
593 if (!fLock
.IsLocked()) {
594 fprintf(stderr
, "DecorInfoUtility::_find_decor()\tfailure to lock! - "
599 if (pathString
== "Default")
600 return fList
.ItemAt(0);
602 for (int i
= 1; i
< fList
.CountItems(); ++i
) {
603 DecorInfo
* decor
= fList
.ItemAt(i
);
604 // Find the DecoratorInfo either by its true current location or by
605 // what we still think the location is (before we had a chance to
606 // update). NOTE: This will only catch the case when the user moved the
607 // folder in which the add-on file lives. It will not work when the user
608 // moves the add-on file itself or renames it.
609 BPath
path(decor
->Ref());
610 if (path
.Path() == pathString
|| decor
->Path() == pathString
)
619 DecorInfoUtility::_ScanDecorators(BDirectory decoratorDirectory
)
623 // First, run through our list and DecorInfos CheckForChanges()
625 for (int i
= fList
.CountItems() - 1; i
> 0; --i
) {
626 DecorInfo
* decorInfo
= fList
.ItemAt(i
);
628 bool deleted
= false;
629 decorInfo
->CheckForChanges(deleted
);
632 fList
.RemoveItem(decorInfo
);
639 // Now, look at file system, skip the entries for which we already have
640 // a DecorInfo in the list.
641 while (decoratorDirectory
.GetNextRef(&ref
) == B_OK
) {
642 BPath
path(&decoratorDirectory
);
643 status_t result
= path
.Append(ref
.name
);
644 if (result
!= B_OK
) {
645 fprintf(stderr
, "DecorInfoUtility::_ScanDecorators()\tFailed to"
646 "append decorator file to path, skipping: %s.\n", strerror(result
));
649 if (_FindDecor(path
.Path()) != NULL
)
652 DecorInfo
* decorInfo
= new(std::nothrow
) DecorInfo(ref
);
653 if (decorInfo
== NULL
|| decorInfo
->InitCheck() != B_OK
) {
654 fprintf(stderr
, "DecorInfoUtility::_ScanDecorators()\tInitCheck() "
655 "failure on decorator, skipping.\n");
660 fList
.AddItem(decorInfo
);
667 } // namespace BPrivate