* Added first working "display_as" type "duration".
* Changed Media:Length to int64, and use the new duration view in Tracker. * Renamed the pretty name for video's Media:Length to "Runtime" (that's how it's called in IMDB, and I was never really fond of "Playing Time"). * FileTypes AttributeWindow needed to check the display-as types, as well as if the contents are acceptable when opening, too. * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38856 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -2410,12 +2410,10 @@ MainWin::_UpdatePlaylistItemFile()
|
|||||||
attr_info info;
|
attr_info info;
|
||||||
status_t status = node.GetAttrInfo(kDurationAttrName, &info);
|
status_t status = node.GetAttrInfo(kDurationAttrName, &info);
|
||||||
if (status != B_OK || info.size == 0) {
|
if (status != B_OK || info.size == 0) {
|
||||||
time_t duration = fController->TimeDuration() / 1000000L;
|
bigtime_t duration = fController->TimeDuration();
|
||||||
|
// TODO: Tracker does not seem to care about endian for scalar types
|
||||||
char text[256];
|
node.WriteAttr(kDurationAttrName, B_INT64_TYPE, 0, &duration,
|
||||||
duration_to_string(duration, text, sizeof(text));
|
sizeof(int64));
|
||||||
node.WriteAttr(kDurationAttrName, B_STRING_TYPE, 0, text,
|
|
||||||
strlen(text) + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write audio bitrate
|
// Write audio bitrate
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ resource(6, "META:ATTR_INFO") message(233) {
|
|||||||
"attr:type" = 'CSTR',
|
"attr:type" = 'CSTR',
|
||||||
"attr:type" = 'CSTR',
|
"attr:type" = 'CSTR',
|
||||||
"attr:type" = 'LONG',
|
"attr:type" = 'LONG',
|
||||||
"attr:type" = 'CSTR',
|
"attr:type" = 'LLNG',
|
||||||
"attr:type" = 'CSTR',
|
"attr:type" = 'CSTR',
|
||||||
"attr:viewable" = true,
|
"attr:viewable" = true,
|
||||||
"attr:viewable" = true,
|
"attr:viewable" = true,
|
||||||
@@ -84,6 +84,16 @@ resource(6, "META:ATTR_INFO") message(233) {
|
|||||||
"attr:alignment" = 0,
|
"attr:alignment" = 0,
|
||||||
"attr:alignment" = 1,
|
"attr:alignment" = 1,
|
||||||
"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"
|
"type" = "audio"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -26,14 +26,14 @@ resource(6, "META:ATTR_INFO") message(233) {
|
|||||||
"attr:public_name" = "Comment",
|
"attr:public_name" = "Comment",
|
||||||
"attr:public_name" = "Genre",
|
"attr:public_name" = "Genre",
|
||||||
"attr:public_name" = "Rating",
|
"attr:public_name" = "Rating",
|
||||||
"attr:public_name" = "Playing time",
|
"attr:public_name" = "Runtime",
|
||||||
"attr:public_name" = "Video bitrate",
|
"attr:public_name" = "Video bitrate",
|
||||||
"attr:type" = 'CSTR',
|
"attr:type" = 'CSTR',
|
||||||
"attr:type" = 'LONG',
|
"attr:type" = 'LONG',
|
||||||
"attr:type" = 'CSTR',
|
"attr:type" = 'CSTR',
|
||||||
"attr:type" = 'CSTR',
|
"attr:type" = 'CSTR',
|
||||||
"attr:type" = 'LONG',
|
"attr:type" = 'LONG',
|
||||||
"attr:type" = 'CSTR',
|
"attr:type" = 'LLNG',
|
||||||
"attr:type" = 'CSTR',
|
"attr:type" = 'CSTR',
|
||||||
"attr:viewable" = true,
|
"attr:viewable" = true,
|
||||||
"attr:viewable" = true,
|
"attr:viewable" = true,
|
||||||
@@ -63,6 +63,13 @@ resource(6, "META:ATTR_INFO") message(233) {
|
|||||||
"attr:alignment" = 0,
|
"attr:alignment" = 0,
|
||||||
"attr:alignment" = 1,
|
"attr:alignment" = 1,
|
||||||
"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"
|
"type" = "video"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -250,6 +250,11 @@ WidgetAttributeText::NewWidgetText(const Model* model,
|
|||||||
if (strcmp(attrName, kAttrOriginalPath) == 0)
|
if (strcmp(attrName, kAttrOriginalPath) == 0)
|
||||||
return new OriginalPathAttributeText(model, column);
|
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);
|
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
|
// fDirty could already be true, in that case we mustn't set it to
|
||||||
// false, even if the attribute text hasn't changed
|
// 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)
|
if (changed)
|
||||||
fDirty = true;
|
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 -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -206,32 +206,46 @@ union GenericValueStruct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//! Used for displaying mime extra attributes. Supports different formats.
|
||||||
class GenericAttributeText : public StringAttributeText {
|
class GenericAttributeText : public StringAttributeText {
|
||||||
// used for displaying mime extra attributes
|
public:
|
||||||
// supports different formats
|
GenericAttributeText(const Model* model,
|
||||||
public:
|
const BColumn* column);
|
||||||
GenericAttributeText(const Model *model, const BColumn *column);
|
|
||||||
virtual bool CheckAttributeChanged();
|
|
||||||
|
|
||||||
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 void SetUpEditing(BTextView* view);
|
||||||
virtual bool CommitEditedText(BTextView *);
|
virtual bool CommitEditedText(BTextView* view);
|
||||||
|
|
||||||
virtual const char *ValueAsText(const BPoseView *view);
|
virtual const char* ValueAsText(const BPoseView* view);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
virtual bool CommitEditedTextFlavor(BTextView *);
|
virtual bool CommitEditedTextFlavor(BTextView* view);
|
||||||
|
|
||||||
virtual void FitValue(BString *result, const BPoseView *);
|
virtual void FitValue(BString* result,
|
||||||
virtual void ReadValue(BString *result);
|
const BPoseView* view);
|
||||||
|
virtual void ReadValue(BString* result);
|
||||||
|
|
||||||
// TODO:
|
protected:
|
||||||
// split this up into a scalar flavor and string flavor
|
// TODO: split this up into a scalar flavor and string flavor
|
||||||
// to save memory
|
// to save memory
|
||||||
GenericValueStruct fValue;
|
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -27,6 +27,8 @@ const struct type_map kTypeMap[] = {
|
|||||||
const struct display_as_map kDisplayAsMap[] = {
|
const struct display_as_map kDisplayAsMap[] = {
|
||||||
{"Default", NULL, {}},
|
{"Default", NULL, {}},
|
||||||
{"Rating", "rating", {B_INT32_TYPE, B_INT8_TYPE, B_INT16_TYPE}},
|
{"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, {}}
|
{NULL, NULL, {}}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -126,7 +128,8 @@ create_attribute_item(BMessage& attributes, int32 index)
|
|||||||
AttributeItem::AttributeItem(const char* name, const char* publicName,
|
AttributeItem::AttributeItem(const char* name, const char* publicName,
|
||||||
type_code type, const char* displayAs, int32 alignment,
|
type_code type, const char* displayAs, int32 alignment,
|
||||||
int32 width, bool visible, bool editable)
|
int32 width, bool visible, bool editable)
|
||||||
: BStringItem(publicName),
|
:
|
||||||
|
BStringItem(publicName),
|
||||||
fName(name),
|
fName(name),
|
||||||
fType(type),
|
fType(type),
|
||||||
fDisplayAs(displayAs),
|
fDisplayAs(displayAs),
|
||||||
@@ -139,7 +142,8 @@ AttributeItem::AttributeItem(const char* name, const char* publicName,
|
|||||||
|
|
||||||
|
|
||||||
AttributeItem::AttributeItem()
|
AttributeItem::AttributeItem()
|
||||||
: BStringItem(""),
|
:
|
||||||
|
BStringItem(""),
|
||||||
fType(B_STRING_TYPE),
|
fType(B_STRING_TYPE),
|
||||||
fAlignment(B_ALIGN_LEFT),
|
fAlignment(B_ALIGN_LEFT),
|
||||||
fWidth(60),
|
fWidth(60),
|
||||||
@@ -150,7 +154,8 @@ AttributeItem::AttributeItem()
|
|||||||
|
|
||||||
|
|
||||||
AttributeItem::AttributeItem(const AttributeItem& other)
|
AttributeItem::AttributeItem(const AttributeItem& other)
|
||||||
: BStringItem(other.PublicName())
|
:
|
||||||
|
BStringItem(other.PublicName())
|
||||||
{
|
{
|
||||||
*this = other;
|
*this = other;
|
||||||
}
|
}
|
||||||
@@ -179,7 +184,8 @@ AttributeItem::DrawItem(BView* owner, BRect frame, bool drawEverything)
|
|||||||
else
|
else
|
||||||
owner->SetHighColor(black);
|
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;
|
BString type;
|
||||||
name_for_type(type, fType, fDisplayAs.String());
|
name_for_type(type, fType, fDisplayAs.String());
|
||||||
|
|||||||
@@ -280,6 +280,9 @@ AttributeWindow::AttributeWindow(FileTypesWindow* target, BMimeType& mimeType,
|
|||||||
|
|
||||||
target->PlaceSubWindow(this);
|
target->PlaceSubWindow(this);
|
||||||
AddToSubset(target);
|
AddToSubset(target);
|
||||||
|
|
||||||
|
_CheckDisplayAs();
|
||||||
|
_CheckAcceptable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user