#include "DesktopPoseView.h"
#include <NodeMonitor.h>
#include <Path.h>
#include <Screen.h>
#include <Volume.h>
#include <VolumeRoster.h>
#include "Background.h"
#include "Commands.h"
#include "FSUtils.h"
#include "PoseList.h"
#include "Tracker.h"
#include "TrackerDefaults.h"
#include "TrackerSettings.h"
#include "TrackerString.h"
DesktopPoseView::DesktopPoseView(Model* model, uint32 viewMode)
:
BPoseView(model, viewMode)
{
SetFlags(Flags() | B_DRAW_ON_CHILDREN);
}
void
DesktopPoseView::AttachedToWindow()
{
AddFilter(new TPoseViewFilter(this));
_inherited::AttachedToWindow();
}
void
DesktopPoseView::MessageReceived(BMessage* message)
{
switch (message->what) {
case B_WORKSPACE_ACTIVATED:
{
bool active;
int32 workspace;
if (message->FindBool("active", &active) != B_OK || !active
|| message->FindInt32("workspace", &workspace) != B_OK
|| workspace != current_workspace()) {
break;
}
AdoptSystemColors();
Invalidate();
_inherited::MessageReceived(message);
break;
}
case B_RESTORE_BACKGROUND_IMAGE:
{
AdoptSystemColors();
Invalidate();
BMessage forward(B_WORKSPACE_ACTIVATED);
forward.AddBool("active", true);
forward.AddInt32("workspace", current_workspace());
_inherited::MessageReceived(&forward);
break;
}
default:
_inherited::MessageReceived(message);
break;
}
}
EntryListBase*
DesktopPoseView::InitDesktopDirentIterator(BPoseView* nodeMonitoringTarget,
const entry_ref* ref)
{
Model sourceModel(ref, false, true);
if (sourceModel.InitCheck() != B_OK)
return NULL;
CachedEntryIteratorList* result = new CachedEntryIteratorList();
ASSERT(!sourceModel.IsQuery());
ASSERT(!sourceModel.IsVirtualDirectory());
ASSERT(sourceModel.Node() != NULL);
BDirectory* sourceDirectory = dynamic_cast<BDirectory*>(sourceModel.Node());
ThrowOnAssert(sourceDirectory != NULL);
EntryListBase* perDesktopIterator
= new CachedDirectoryEntryList(*sourceDirectory);
result->AddItem(perDesktopIterator);
if (nodeMonitoringTarget != NULL) {
TTracker::WatchNode(sourceModel.NodeRef(), B_WATCH_DIRECTORY | B_WATCH_CHILDREN
| B_WATCH_NAME | B_WATCH_STAT | B_WATCH_INTERIM_STAT | B_WATCH_ATTR,
nodeMonitoringTarget);
}
if (result->Rewind() != B_OK) {
delete result;
if (nodeMonitoringTarget != NULL)
nodeMonitoringTarget->HideBarberPole();
return NULL;
}
return result;
}
void
DesktopPoseView::AdoptSystemColors()
{
BScreen screen(Window());
rgb_color background = screen.DesktopColor();
SetLowColor(background);
SetViewColor(background);
AdaptToBackgroundColorChange();
}
bool
DesktopPoseView::HasSystemColors() const
{
return false;
}
EntryListBase*
DesktopPoseView::InitDirentIterator(const entry_ref* ref)
{
return InitDesktopDirentIterator(this, ref);
}
bool
DesktopPoseView::AddPosesThreadValid(const entry_ref*) const
{
return true;
}
void
DesktopPoseView::AddPosesCompleted()
{
_inherited::AddPosesCompleted();
CreateTrashPose();
}
void
DesktopPoseView::CreateTrashPose()
{
BPath path;
if (find_directory(B_TRASH_DIRECTORY, &path) != B_OK)
return;
BDirectory trashDir(path.Path());
BEntry entry;
if (trashDir.GetEntry(&entry) != B_OK)
return;
node_ref nref;
if (entry.GetNodeRef(&nref) == B_OK)
WatchNewNode(&nref, B_WATCH_ATTR, BMessenger(this));
Model* trashModel = new Model(&entry);
PoseInfo poseInfo;
ReadPoseInfo(trashModel, &poseInfo);
CreatePose(trashModel, &poseInfo, false, NULL, NULL, true);
}
bool
DesktopPoseView::Represents(const node_ref* ref) const
{
return _inherited::Represents(ref);
}
bool
DesktopPoseView::Represents(const entry_ref* ref) const
{
BEntry entry(ref);
node_ref nref;
entry.GetNodeRef(&nref);
return Represents(&nref);
}
void
DesktopPoseView::StartSettingsWatch()
{
TTracker* tracker = dynamic_cast<TTracker*>(be_app);
if (tracker != NULL && tracker->LockLooper()) {
tracker->StartWatching(this, kShowDisksIconChanged);
tracker->StartWatching(this, kVolumesOnDesktopChanged);
tracker->StartWatching(this, kDesktopIntegrationChanged);
tracker->UnlockLooper();
}
}
void
DesktopPoseView::StopSettingsWatch()
{
TTracker* tracker = dynamic_cast<TTracker*>(be_app);
if (tracker != NULL && tracker->LockLooper()) {
tracker->StopWatching(this, kShowDisksIconChanged);
tracker->StopWatching(this, kVolumesOnDesktopChanged);
tracker->StopWatching(this, kDesktopIntegrationChanged);
tracker->UnlockLooper();
}
}
void
DesktopPoseView::AdaptToVolumeChange(BMessage* message)
{
if (Window() == NULL)
return;
TTracker* tracker = dynamic_cast<TTracker*>(be_app);
ThrowOnAssert(tracker != NULL);
bool showDisksIcon = kDefaultShowDisksIcon;
message->FindBool("ShowDisksIcon", &showDisksIcon);
BEntry entry("/");
Model model(&entry);
if (model.InitCheck() == B_OK) {
BMessage entryMessage;
entryMessage.what = B_NODE_MONITOR;
if (showDisksIcon)
entryMessage.AddInt32("opcode", B_ENTRY_CREATED);
else {
entryMessage.AddInt32("opcode", B_ENTRY_REMOVED);
entry_ref ref;
if (entry.GetRef(&ref) == B_OK) {
BContainerWindow* disksWindow = tracker->FindContainerWindow(&ref);
if (disksWindow != NULL) {
disksWindow->Lock();
disksWindow->Close();
}
}
}
entryMessage.AddInt32("device", model.NodeRef()->device);
entryMessage.AddInt64("node", model.NodeRef()->node);
entryMessage.AddInt64("directory", model.EntryRef()->directory);
entryMessage.AddString("name", model.EntryRef()->name);
Window()->PostMessage(&entryMessage, this);
}
ToggleDisksVolumes();
}
void
DesktopPoseView::AdaptToDesktopIntegrationChange(BMessage* message)
{
ToggleDisksVolumes();
}
void
DesktopPoseView::AdaptToBackgroundColorChange()
{
int32 desktopBrightness = ui_color(B_DESKTOP_COLOR).Brightness();
SetHighColor(LowColor().Brightness() <= desktopBrightness ? kWhite : kBlack);
}