IconView can now also be set to a MIME type instead of a file or a buffer.

Untested actually, but FileTypesWindow's TypeIconView will be merged to this
one soon.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19298 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2006-11-15 18:39:30 +00:00
parent 93ced9a11c
commit b724cb6408
2 changed files with 219 additions and 90 deletions
+197 -75
View File
@@ -211,8 +211,37 @@ Icon::SetTo(entry_ref& ref, const char* type)
} }
void
Icon::SetTo(BMimeType& type, icon_source* _source)
{
Unset();
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
uint8* data;
size_t size;
if (icon_for_type(type, &data, &size, _source) == B_OK) {
// we have the vector icon, no need to get the rest
AdoptData(data, size);
return;
}
#endif
BBitmap* icon = AllocateBitmap(B_LARGE_ICON, B_CMAP8);
if (icon && icon_for_type(type, *icon, B_LARGE_ICON, _source) == B_OK)
AdoptLarge(icon);
else
delete icon;
icon = AllocateBitmap(B_MINI_ICON, B_CMAP8);
if (icon && icon_for_type(type, *icon, B_MINI_ICON) == B_OK)
AdoptMini(icon);
else
delete icon;
}
status_t status_t
Icon::CopyTo(BAppFileInfo& info, const char* type, bool force) Icon::CopyTo(BAppFileInfo& info, const char* type, bool force) const
{ {
status_t status = B_OK; status_t status = B_OK;
@@ -229,7 +258,7 @@ Icon::CopyTo(BAppFileInfo& info, const char* type, bool force)
status_t status_t
Icon::CopyTo(entry_ref& ref, const char* type, bool force) Icon::CopyTo(entry_ref& ref, const char* type, bool force) const
{ {
BFile file; BFile file;
status_t status = file.SetTo(&ref, B_READ_ONLY); status_t status = file.SetTo(&ref, B_READ_ONLY);
@@ -246,7 +275,24 @@ Icon::CopyTo(entry_ref& ref, const char* type, bool force)
status_t status_t
Icon::CopyTo(BMessage& message) Icon::CopyTo(BMimeType& type, bool force) const
{
status_t status = B_OK;
if (fLarge != NULL || force)
status = type.SetIcon(fLarge, B_LARGE_ICON);
if (fMini != NULL || force)
status = type.SetIcon(fMini, B_MINI_ICON);
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
if (fData != NULL || force)
status = type.SetIcon(fData, fSize);
#endif
return status;
}
status_t
Icon::CopyTo(BMessage& message) const
{ {
status_t status = B_OK; status_t status = B_OK;
@@ -480,9 +526,9 @@ IconView::IconView(BRect rect, const char* name, uint32 resizeMode, uint32 flags
fIconSize(B_LARGE_ICON), fIconSize(B_LARGE_ICON),
fIcon(NULL), fIcon(NULL),
fHeapIcon(NULL), fHeapIcon(NULL),
fIconData(NULL),
fHasRef(false), fHasRef(false),
fIsLive(false), fHasType(false),
fIconData(NULL),
fTracking(false), fTracking(false),
fDragging(false), fDragging(false),
fDropTarget(false), fDropTarget(false),
@@ -508,7 +554,7 @@ IconView::AttachedToWindow()
fTarget = this; fTarget = this;
// SetTo() was already called before we were a valid messenger // SetTo() was already called before we were a valid messenger
if (fIsLive) if (fHasRef || fHasType)
_StartWatching(); _StartWatching();
} }
@@ -560,6 +606,9 @@ IconView::MessageReceived(BMessage* message)
case B_NODE_MONITOR: case B_NODE_MONITOR:
{ {
if (!fHasRef)
break;
int32 opcode; int32 opcode;
if (message->FindInt32("opcode", &opcode) != B_OK if (message->FindInt32("opcode", &opcode) != B_OK
|| opcode != B_ATTR_CHANGED) || opcode != B_ATTR_CHANGED)
@@ -574,6 +623,33 @@ IconView::MessageReceived(BMessage* message)
break; break;
} }
case B_META_MIME_CHANGED:
{
if (!fHasType)
break;
const char* type;
int32 which;
if (message->FindString("be:type", &type) != B_OK
|| !strcmp(type, fType.Type())
|| message->FindInt32("be:which", &which) != B_OK)
break;
switch (which) {
case B_MIME_TYPE_DELETED:
Unset();
break;
case B_ICON_CHANGED:
Update();
break;
default:
break;
}
break;
}
default: default:
BView::MessageReceived(message); BView::MessageReceived(message);
break; break;
@@ -739,7 +815,7 @@ IconView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage)
::Icon* icon = fIconData; ::Icon* icon = fIconData;
if (fHasRef) { if (fHasRef) {
icon = new ::Icon; icon = new ::Icon;
icon->SetTo(fRef, fFileType.Length() > 0 ? fFileType.String() : NULL); icon->SetTo(fRef, fType.Type());
} }
icon->CopyTo(message); icon->CopyTo(message);
@@ -810,18 +886,31 @@ IconView::MakeFocus(bool focus)
void void
IconView::SetTo(entry_ref& ref, const char* fileType) IconView::SetTo(entry_ref& ref, const char* fileType)
{ {
if (fHasRef && fIsLive) Unset();
_StopWatching();
fHasRef = true; fHasRef = true;
fRef = ref; fRef = ref;
if (fileType != NULL) if (fileType != NULL)
fFileType = fileType; fType.SetTo(fileType);
else else
fFileType = ""; fType.Unset();
_StartWatching();
Update();
}
void
IconView::SetTo(BMimeType& type)
{
Unset();
if (type.Type() == NULL)
return;
fHasType = true;
fType.SetTo(type.Type());
fIsLive = true;
_StartWatching(); _StartWatching();
Update(); Update();
} }
@@ -833,12 +922,73 @@ IconView::SetTo(::Icon* icon)
if (fIconData == icon) if (fIconData == icon)
return; return;
Unset();
fIconData = icon; fIconData = icon;
fHasRef = false;
Update(); Update();
} }
void
IconView::Unset()
{
if (fHasRef || fHasType)
_StopWatching();
fHasRef = false;
fHasType = false;
fType.Unset();
fIconData = NULL;
}
void
IconView::Update()
{
delete fIcon;
fIcon = NULL;
Invalidate();
// this will actually trigger a redraw *after* we updated the icon below
BBitmap* icon = NULL;
if (fHasRef) {
BFile file(&fRef, B_READ_ONLY);
if (file.InitCheck() != B_OK)
return;
BAppFileInfo info;
if (info.SetTo(&file) != B_OK)
return;
icon = Icon::AllocateBitmap(fIconSize);
if (icon != NULL && info.GetIconForType(fType.Type(), icon,
(icon_size)fIconSize) != B_OK) {
delete icon;
return;
}
} else if (fHasType) {
icon = Icon::AllocateBitmap(fIconSize);
if (icon != NULL && icon_for_type(fType, *icon, (icon_size)fIconSize,
&fSource) != B_OK) {
delete icon;
return;
}
} else if (fIconData) {
icon = Icon::AllocateBitmap(fIconSize);
if (fIconData->GetIcon(icon) != B_OK) {
delete icon;
icon = NULL;
}
}
fIcon = icon;
}
void void
IconView::SetIconSize(int32 size) IconView::SetIconSize(int32 size)
{ {
@@ -895,51 +1045,6 @@ IconView::SetEnabled(bool enabled)
} }
void
IconView::Update()
{
delete fIcon;
fIcon = NULL;
Invalidate();
// this will actually trigger a redraw *after* we updated the icon below
BBitmap* icon = NULL;
if (fHasRef) {
if (fIconData != NULL)
fIconData->Unset();
BFile file(&fRef, B_READ_ONLY);
if (file.InitCheck() != B_OK)
return;
const char* fileType = fFileType.Length() > 0 ? fFileType.String() : NULL;
BAppFileInfo info;
if (info.SetTo(&file) != B_OK)
return;
icon = Icon::AllocateBitmap(fIconSize);
if (icon != NULL && info.GetIconForType(fileType, icon, (icon_size)fIconSize) != B_OK) {
delete icon;
return;
}
if (fIconData != NULL)
fIconData->SetTo(info, fileType);
} else if (fIconData) {
icon = Icon::AllocateBitmap(fIconSize);
if (fIconData->GetIcon(icon) != B_OK) {
delete icon;
icon = NULL;
}
}
fIcon = icon;
}
void void
IconView::Invoke() IconView::Invoke()
{ {
@@ -958,13 +1063,15 @@ void
IconView::_AddOrEditIcon() IconView::_AddOrEditIcon()
{ {
BMessage message; BMessage message;
if (fIsLive) { if (fHasRef) {
// in live mode, Icon-O-Matic can change the icon directly, and // in ref mode, Icon-O-Matic can change the icon directly, and
// we'll pick it up via node monitoring // we'll pick it up via node monitoring
message.what = B_REFS_RECEIVED; message.what = B_REFS_RECEIVED;
message.AddRef("refs", &fRef); message.AddRef("refs", &fRef);
if (fFileType.Length() > 0) if (fType.Type() != NULL)
message.AddString("file type", fFileType.String()); message.AddString("file type", fType.Type());
// } else if (fHasType) {
// // TODO!
} else { } else {
// in static mode, Icon-O-Matic need to return the buffer it // in static mode, Icon-O-Matic need to return the buffer it
// changed once its done // changed once its done
@@ -980,23 +1087,32 @@ IconView::_AddOrEditIcon()
void void
IconView::_SetIcon(BBitmap* large, BBitmap* mini, const uint8* data, size_t size, bool force) IconView::_SetIcon(BBitmap* large, BBitmap* mini, const uint8* data, size_t size, bool force)
{ {
if (fIsLive) { if (fHasRef) {
BFile file(&fRef, B_READ_WRITE); BFile file(&fRef, B_READ_WRITE);
BAppFileInfo info(&file); BAppFileInfo info(&file);
if (info.InitCheck() == B_OK) { if (info.InitCheck() == B_OK) {
const char* type = fFileType.Length() > 0 ? fFileType.String() : NULL;
if (large != NULL || force) if (large != NULL || force)
info.SetIconForType(type, large, B_LARGE_ICON); info.SetIconForType(fType.Type(), large, B_LARGE_ICON);
if (mini != NULL || force) if (mini != NULL || force)
info.SetIconForType(type, mini, B_MINI_ICON); info.SetIconForType(fType.Type(), mini, B_MINI_ICON);
#ifdef HAIKU_TARGET_PLATFORM_HAIKU #ifdef HAIKU_TARGET_PLATFORM_HAIKU
if (data != NULL || force) if (data != NULL || force)
info.SetIconForType(type, data, size); info.SetIconForType(fType.Type(), data, size);
#endif #endif
} }
// the icon shown will be updated using node monitoring // the icon shown will be updated using node monitoring
} else if (fHasType) {
if (large != NULL || force)
fType.SetIcon(large, B_LARGE_ICON);
if (mini != NULL || force)
fType.SetIcon(mini, B_MINI_ICON);
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
if (data != NULL || force)
fType.SetIcon(data, size);
#endif
// the icon shown will be updated automatically - we're watching
// any changes to the MIME database
} else if (fIconData != NULL) { } else if (fIconData != NULL) {
if (large != NULL || force) if (large != NULL || force)
fIconData->SetLarge(large); fIconData->SetLarge(large);
@@ -1109,17 +1225,23 @@ IconView::_StartWatching()
return; return;
} }
BNode node(&fRef); if (fHasRef) {
node_ref nodeRef; BNode node(&fRef);
if (node.InitCheck() == B_OK node_ref nodeRef;
&& node.GetNodeRef(&nodeRef) == B_OK) if (node.InitCheck() == B_OK
watch_node(&nodeRef, B_WATCH_ATTR, this); && node.GetNodeRef(&nodeRef) == B_OK)
watch_node(&nodeRef, B_WATCH_ATTR, this);
} else if (fHasType)
BMimeType::StartWatching(this);
} }
void void
IconView::_StopWatching() IconView::_StopWatching()
{ {
stop_watching(this); if (fHasRef)
stop_watching(this);
else if (fHasType)
BMimeType::StopWatching(this);
} }
+22 -15
View File
@@ -13,6 +13,14 @@
#include <View.h> #include <View.h>
enum icon_source {
kNoIcon = 0,
kOwnIcon,
kApplicationIcon,
kSupertypeIcon
};
class Icon { class Icon {
public: public:
Icon(); Icon();
@@ -21,9 +29,11 @@ class Icon {
void SetTo(BAppFileInfo& info, const char* type = NULL); void SetTo(BAppFileInfo& info, const char* type = NULL);
void SetTo(entry_ref& ref, const char* type = NULL); void SetTo(entry_ref& ref, const char* type = NULL);
status_t CopyTo(BAppFileInfo& info, const char* type = NULL, bool force = false); void SetTo(BMimeType& type, icon_source* _source = NULL);
status_t CopyTo(entry_ref& ref, const char* type = NULL, bool force = false); status_t CopyTo(BAppFileInfo& info, const char* type = NULL, bool force = false) const;
status_t CopyTo(BMessage& message); status_t CopyTo(entry_ref& ref, const char* type = NULL, bool force = false) const;
status_t CopyTo(BMimeType& type, bool force = false) const;
status_t CopyTo(BMessage& message) const;
void SetData(const uint8* data, size_t size); void SetData(const uint8* data, size_t size);
void SetLarge(const BBitmap* large); void SetLarge(const BBitmap* large);
@@ -72,12 +82,15 @@ class IconView : public BView {
virtual void MakeFocus(bool focus = true); virtual void MakeFocus(bool focus = true);
void SetTo(entry_ref& file, const char* fileType = NULL); void SetTo(entry_ref& file, const char* fileType = NULL);
void SetTo(BMimeType& type);
void SetTo(::Icon* icon); void SetTo(::Icon* icon);
void Unset();
void Update();
void SetIconSize(int32 size); void SetIconSize(int32 size);
void ShowIconHeap(bool show); void ShowIconHeap(bool show);
void SetEnabled(bool enabled); void SetEnabled(bool enabled);
void SetTarget(const BMessenger& target); void SetTarget(const BMessenger& target);
void Update();
void Invoke(); void Invoke();
::Icon* Icon(); ::Icon* Icon();
@@ -99,12 +112,13 @@ class IconView : public BView {
BBitmap* fIcon; BBitmap* fIcon;
BBitmap* fHeapIcon; BBitmap* fHeapIcon;
bool fHasRef;
bool fHasType;
entry_ref fRef;
BMimeType fType;
icon_source fSource;
::Icon* fIconData; ::Icon* fIconData;
bool fHasRef;
bool fIsLive;
entry_ref fRef;
BString fFileType;
BPoint fDragPoint; BPoint fDragPoint;
bool fTracking; bool fTracking;
bool fDragging; bool fDragging;
@@ -117,13 +131,6 @@ static const uint32 kMsgRemoveIcon = 'icrm';
static const uint32 kMsgAddIcon = 'icad'; static const uint32 kMsgAddIcon = 'icad';
static const uint32 kMsgEditIcon = 'iced'; static const uint32 kMsgEditIcon = 'iced';
enum icon_source {
kNoIcon = 0,
kOwnIcon,
kApplicationIcon,
kSupertypeIcon
};
extern status_t icon_for_type(BMimeType& type, uint8** _data, size_t* _size, extern status_t icon_for_type(BMimeType& type, uint8** _data, size_t* _size,
icon_source* _source = NULL); icon_source* _source = NULL);
extern status_t icon_for_type(BMimeType& type, BBitmap& bitmap, extern status_t icon_for_type(BMimeType& type, BBitmap& bitmap,