diff --git a/src/apps/mediaplayer/MainWin.cpp b/src/apps/mediaplayer/MainWin.cpp index e662d75da5..dd3a47aef6 100644 --- a/src/apps/mediaplayer/MainWin.cpp +++ b/src/apps/mediaplayer/MainWin.cpp @@ -2410,12 +2410,10 @@ MainWin::_UpdatePlaylistItemFile() attr_info info; status_t status = node.GetAttrInfo(kDurationAttrName, &info); if (status != B_OK || info.size == 0) { - time_t duration = fController->TimeDuration() / 1000000L; - - char text[256]; - duration_to_string(duration, text, sizeof(text)); - node.WriteAttr(kDurationAttrName, B_STRING_TYPE, 0, text, - strlen(text) + 1); + bigtime_t duration = fController->TimeDuration(); + // TODO: Tracker does not seem to care about endian for scalar types + node.WriteAttr(kDurationAttrName, B_INT64_TYPE, 0, &duration, + sizeof(int64)); } // Write audio bitrate diff --git a/src/data/beos_mime/audio.super b/src/data/beos_mime/audio.super index c6fecf297c..9ff4068401 100644 --- a/src/data/beos_mime/audio.super +++ b/src/data/beos_mime/audio.super @@ -42,7 +42,7 @@ resource(6, "META:ATTR_INFO") message(233) { "attr:type" = 'CSTR', "attr:type" = 'CSTR', "attr:type" = 'LONG', - "attr:type" = 'CSTR', + "attr:type" = 'LLNG', "attr:type" = 'CSTR', "attr:viewable" = true, "attr:viewable" = true, @@ -84,6 +84,16 @@ resource(6, "META:ATTR_INFO") message(233) { "attr:alignment" = 0, "attr:alignment" = 1, "attr:alignment" = 1, + "attr:display_as" = "", + "attr:display_as" = "", + "attr:display_as" = "", + "attr:display_as" = "", + "attr:display_as" = "", + "attr:display_as" = "", + "attr:display_as" = "", + "attr:display_as" = "", + "attr:display_as" = "duration", + "attr:display_as" = "", "type" = "audio" }; diff --git a/src/data/beos_mime/video.super b/src/data/beos_mime/video.super index 3581c29ce1..7de7bea2da 100644 --- a/src/data/beos_mime/video.super +++ b/src/data/beos_mime/video.super @@ -26,14 +26,14 @@ resource(6, "META:ATTR_INFO") message(233) { "attr:public_name" = "Comment", "attr:public_name" = "Genre", "attr:public_name" = "Rating", - "attr:public_name" = "Playing time", + "attr:public_name" = "Runtime", "attr:public_name" = "Video bitrate", "attr:type" = 'CSTR', "attr:type" = 'LONG', "attr:type" = 'CSTR', "attr:type" = 'CSTR', "attr:type" = 'LONG', - "attr:type" = 'CSTR', + "attr:type" = 'LLNG', "attr:type" = 'CSTR', "attr:viewable" = true, "attr:viewable" = true, @@ -63,6 +63,13 @@ resource(6, "META:ATTR_INFO") message(233) { "attr:alignment" = 0, "attr:alignment" = 1, "attr:alignment" = 1, + "attr:display_as" = "", + "attr:display_as" = "", + "attr:display_as" = "", + "attr:display_as" = "", + "attr:display_as" = "", + "attr:display_as" = "duration", + "attr:display_as" = "", "type" = "video" }; diff --git a/src/kits/tracker/WidgetAttributeText.cpp b/src/kits/tracker/WidgetAttributeText.cpp index b1708d5be1..8e9319607d 100644 --- a/src/kits/tracker/WidgetAttributeText.cpp +++ b/src/kits/tracker/WidgetAttributeText.cpp @@ -250,6 +250,11 @@ WidgetAttributeText::NewWidgetText(const Model* model, if (strcmp(attrName, kAttrOriginalPath) == 0) return new OriginalPathAttributeText(model, column); + if (column->DisplayAs() != NULL) { + if (!strncmp(column->DisplayAs(), "duration", 8)) + return new DurationAttributeText(model, column); + } + return new GenericAttributeText(model, column); } @@ -1057,7 +1062,8 @@ GenericAttributeText::CheckAttributeChanged() // fDirty could already be true, in that case we mustn't set it to // false, even if the attribute text hasn't changed - bool changed = (fValue.int64t != tmpValue.int64t) || (tmpString != fFullValueText); + bool changed = fValue.int64t != tmpValue.int64t + || tmpString != fFullValueText; if (changed) fDirty = true; @@ -1643,6 +1649,88 @@ GenericAttributeText::CommitEditedTextFlavor(BTextView* textView) } +// #pragma mark - display as: duration + + +DurationAttributeText::DurationAttributeText(const Model* model, + const BColumn* column) + : + GenericAttributeText(model, column) +{ +} + + +// TODO: support editing! + + +void +DurationAttributeText::FitValue(BString* result, const BPoseView* view) +{ + if (fValueDirty) + ReadValue(&fFullValueText); + + fOldWidth = fColumn->Width(); + fDirty = false; + + if (!fValueIsDefined) { + *result = "-"; + fTruncatedWidth = TruncString(result, fFullValueText.String(), + fFullValueText.Length(), view, fOldWidth); + return; + } + + int64 time = 0; + + switch (fColumn->AttrType()) { + case B_TIME_TYPE: + time = fValue.time_tt * 1000000LL; + break; + + case B_INT8_TYPE: + time = fValue.int8t * 1000000LL; + break; + + case B_INT16_TYPE: + time = fValue.int16t * 1000000LL; + break; + + case B_INT32_TYPE: + time = fValue.int32t * 1000000LL; + break; + + case B_INT64_TYPE: + time = fValue.int64t; + break; + } + + // TODO: ignores micro seconds for now + int32 seconds = time / 1000000LL; + + bool negative = seconds < 0; + if (negative) + seconds = -seconds; + + int32 hours = seconds / 3600; + seconds -= hours * 3600; + int32 minutes = seconds / 60; + seconds = seconds % 60; + + char buffer[256]; + if (hours > 0) { + snprintf(buffer, sizeof(buffer), "%s%ld:%02ld:%02ld", + negative ? "-" : "", hours, minutes, seconds); + } else { + snprintf(buffer, sizeof(buffer), "%s%ld:%02ld", + negative ? "-" : "", minutes, seconds); + } + + fFullValueText = buffer; + + fTruncatedWidth = TruncString(result, fFullValueText.String(), + fFullValueText.Length(), view, fOldWidth); +} + + // #pragma mark - diff --git a/src/kits/tracker/WidgetAttributeText.h b/src/kits/tracker/WidgetAttributeText.h index 64b28adeee..be347e55e5 100644 --- a/src/kits/tracker/WidgetAttributeText.h +++ b/src/kits/tracker/WidgetAttributeText.h @@ -206,32 +206,46 @@ union GenericValueStruct { }; +//! Used for displaying mime extra attributes. Supports different formats. class GenericAttributeText : public StringAttributeText { - // used for displaying mime extra attributes - // supports different formats - public: - GenericAttributeText(const Model *model, const BColumn *column); - virtual bool CheckAttributeChanged(); +public: + GenericAttributeText(const Model* model, + const BColumn* column); - virtual float PreferredWidth(const BPoseView *view) const; + virtual bool CheckAttributeChanged(); + virtual float PreferredWidth(const BPoseView* view) const; - virtual int Compare(WidgetAttributeText &, BPoseView *view); + virtual int Compare(WidgetAttributeText& other, + BPoseView* view); - virtual void SetUpEditing(BTextView *); - virtual bool CommitEditedText(BTextView *); + virtual void SetUpEditing(BTextView* view); + virtual bool CommitEditedText(BTextView* view); - virtual const char *ValueAsText(const BPoseView *view); + virtual const char* ValueAsText(const BPoseView* view); - private: - virtual bool CommitEditedTextFlavor(BTextView *); +protected: + virtual bool CommitEditedTextFlavor(BTextView* view); - virtual void FitValue(BString *result, const BPoseView *); - virtual void ReadValue(BString *result); + virtual void FitValue(BString* result, + const BPoseView* view); + virtual void ReadValue(BString* result); - // TODO: - // split this up into a scalar flavor and string flavor - // to save memory - GenericValueStruct fValue; +protected: + // TODO: split this up into a scalar flavor and string flavor + // to save memory + GenericValueStruct fValue; +}; + + +//! Used for the display-as type "duration" +class DurationAttributeText : public GenericAttributeText { +public: + DurationAttributeText(const Model* model, + const BColumn* column); + +private: + virtual void FitValue(BString* result, + const BPoseView* view); }; diff --git a/src/preferences/filetypes/AttributeListView.cpp b/src/preferences/filetypes/AttributeListView.cpp index b961d20076..8a754b84bf 100644 --- a/src/preferences/filetypes/AttributeListView.cpp +++ b/src/preferences/filetypes/AttributeListView.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2006-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2006-2010, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ @@ -27,6 +27,8 @@ const struct type_map kTypeMap[] = { const struct display_as_map kDisplayAsMap[] = { {"Default", NULL, {}}, {"Rating", "rating", {B_INT32_TYPE, B_INT8_TYPE, B_INT16_TYPE}}, + {"Duration", "duration", + {B_TIME_TYPE, B_INT8_TYPE, B_INT16_TYPE, B_INT32_TYPE, B_INT64_TYPE}}, {NULL, NULL, {}} }; @@ -126,7 +128,8 @@ create_attribute_item(BMessage& attributes, int32 index) AttributeItem::AttributeItem(const char* name, const char* publicName, type_code type, const char* displayAs, int32 alignment, int32 width, bool visible, bool editable) - : BStringItem(publicName), + : + BStringItem(publicName), fName(name), fType(type), fDisplayAs(displayAs), @@ -139,7 +142,8 @@ AttributeItem::AttributeItem(const char* name, const char* publicName, AttributeItem::AttributeItem() - : BStringItem(""), + : + BStringItem(""), fType(B_STRING_TYPE), fAlignment(B_ALIGN_LEFT), fWidth(60), @@ -150,7 +154,8 @@ AttributeItem::AttributeItem() AttributeItem::AttributeItem(const AttributeItem& other) - : BStringItem(other.PublicName()) + : + BStringItem(other.PublicName()) { *this = other; } @@ -179,7 +184,8 @@ AttributeItem::DrawItem(BView* owner, BRect frame, bool drawEverything) else owner->SetHighColor(black); - owner->MovePenTo(frame.left + frame.Width() / 2.0f + 5.0f, owner->PenLocation().y); + owner->MovePenTo(frame.left + frame.Width() / 2.0f + 5.0f, + owner->PenLocation().y); BString type; name_for_type(type, fType, fDisplayAs.String()); diff --git a/src/preferences/filetypes/AttributeWindow.cpp b/src/preferences/filetypes/AttributeWindow.cpp index 7a64478eb3..744cf89a9c 100644 --- a/src/preferences/filetypes/AttributeWindow.cpp +++ b/src/preferences/filetypes/AttributeWindow.cpp @@ -280,6 +280,9 @@ AttributeWindow::AttributeWindow(FileTypesWindow* target, BMimeType& mimeType, target->PlaceSubWindow(this); AddToSubset(target); + + _CheckDisplayAs(); + _CheckAcceptable(); }