1// Copyright 1999, Be Incorporated. All Rights Reserved.
2// Copyright 2000-2004, Jun Suzuki. All Rights Reserved.
3// Copyright 2007, Stephan A��mus. All Rights Reserved.
4// This file may be used under the terms of the Be Sample Code License.
5#include "MediaFileInfoView.h"
6
7#include <Alert.h>
8#include <Catalog.h>
9#include <ControlLook.h>
10#include <Locale.h>
11#include <MediaFile.h>
12#include <MediaTrack.h>
13#include <String.h>
14
15
16#undef B_TRANSLATION_CONTEXT
17#define B_TRANSLATION_CONTEXT "MediaConverter-FileInfo"
18
19
20const float kSpacing = 5.0f;
21
22
23MediaFileInfoView::MediaFileInfoView()
24	:
25	BView("MediaFileInfoView", B_WILL_DRAW | B_SUPPORTS_LAYOUT),
26	fMinMaxValid(false),
27	fRef(),
28	fMediaFile(NULL)
29{
30	SetFont(be_plain_font);
31}
32
33
34MediaFileInfoView::~MediaFileInfoView()
35{
36}
37
38
39void
40MediaFileInfoView::Draw(BRect /*update*/)
41{
42	_ValidateMinMax();
43
44	_SetFontFace(B_BOLD_FACE);
45
46	font_height fh;
47	GetFontHeight(&fh);
48	BPoint labelStart(kSpacing, fh.ascent + fh.leading + 1);
49
50	if (fMediaFile == NULL) {
51		DrawString(B_TRANSLATE("No file selected"), labelStart);
52		return;
53	}
54
55	// draw filename
56	DrawString(fRef.name, labelStart);
57	labelStart.y += fLineHeight + kSpacing;
58	BPoint infoStart(labelStart.x + fMaxLabelWidth + kSpacing, labelStart.y);
59
60	// draw labels
61	DrawString(B_TRANSLATE("Audio:"), labelStart);
62	labelStart.y += fLineHeight * 2;
63
64	DrawString(B_TRANSLATE("Video:"), labelStart);
65	labelStart.y += fLineHeight * 2;
66
67	DrawString(B_TRANSLATE("Duration:"), labelStart);
68	labelStart.y += fLineHeight * 2;
69
70	// draw audio/video/duration info
71	_SetFontFace(B_REGULAR_FACE);
72
73	BString* infoStrings[5] = {&fInfo.audio.format, &fInfo.audio.details,
74		&fInfo.video.format, &fInfo.video.details, &fInfo.duration};
75	for (int32 i = 0; i < 5; i++) {
76		DrawString(*infoStrings[i], infoStart);
77		infoStart.y += fLineHeight;
78	}
79}
80
81
82BSize
83MediaFileInfoView::MinSize()
84{
85	_ValidateMinMax();
86	return fMinSize;
87}
88
89
90BSize
91MediaFileInfoView::MaxSize()
92{
93	return BSize(B_SIZE_UNLIMITED, fMinSize.height);
94}
95
96
97BSize
98MediaFileInfoView::PreferredSize()
99{
100	_ValidateMinMax();
101	return fMinSize;
102}
103
104
105BAlignment
106MediaFileInfoView::LayoutAlignment()
107{
108	return BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP);
109}
110
111
112void
113MediaFileInfoView::InvalidateLayout(bool /*children*/)
114{
115	fMinMaxValid = false;
116	BView::InvalidateLayout();
117}
118
119
120void
121MediaFileInfoView::SetFont(const BFont* font, uint32 mask)
122{
123	BView::SetFont(font, mask);
124	if (mask == B_FONT_FACE)
125		return;
126
127	fLineHeight = _LineHeight();
128	BFont bold(font);
129	bold.SetFace(B_BOLD_FACE);
130	fMaxLabelWidth = 0;
131
132	BString labels[] = {B_TRANSLATE("Video:"), B_TRANSLATE("Duration:"), B_TRANSLATE("Audio:")};
133	int32 labelCount = sizeof(labels) / sizeof(BString);
134	fMaxLabelWidth = _MaxLineWidth(labels, labelCount, bold);
135
136	fNoFileLabelWidth = ceilf(bold.StringWidth(B_TRANSLATE("No file selected")));
137	InvalidateLayout();
138}
139
140
141void
142MediaFileInfoView::AttachedToWindow()
143{
144	rgb_color c = Parent()->LowColor();
145	SetViewColor(c);
146	SetLowColor(c);
147}
148
149
150void
151MediaFileInfoView::Update(BMediaFile* file, entry_ref* ref)
152{
153	if (fMediaFile == file)
154		return;
155
156	fMediaFile = file;
157
158	if (file != NULL && ref != NULL) {
159		fRef = *ref;
160		status_t result = fInfo.LoadInfo(file);
161		if (result != B_OK) {
162			BString error(B_TRANSLATE("An error has occurred reading the "
163				"file info.\n\nError : "));
164			error << strerror(result);
165			BAlert* alert = new BAlert(
166				B_TRANSLATE("File Error"), error.String(),
167				B_TRANSLATE("OK"), NULL, NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT);
168			alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
169			alert->Go(NULL);
170		}
171	} else
172		fRef = entry_ref();
173
174	InvalidateLayout();
175	Invalidate();
176}
177
178
179float
180MediaFileInfoView::_LineHeight()
181{
182	font_height fontHeight;
183	GetFontHeight(&fontHeight);
184	return ceilf(fontHeight.ascent + fontHeight.descent + fontHeight.leading);
185}
186
187
188float
189MediaFileInfoView::_MaxLineWidth(BString* strings, int32 count,
190	const BFont& font)
191{
192	float width = 0;
193	for (int32 i = 0; i < count; i++)
194		width = max_c(font.StringWidth(strings[i]), width);
195
196	return ceilf(width);
197}
198
199
200void
201MediaFileInfoView::_ValidateMinMax()
202{
203	if (fMinMaxValid)
204		return;
205
206	BFont font;
207	GetFont(&font);
208
209	BFont bold(font);
210	bold.SetFace(B_BOLD_FACE);
211	fMinSize.Set(0, 0);
212
213	if (fMediaFile == NULL) {
214		fMinSize.width =  fNoFileLabelWidth + kSpacing * 2;
215		fMinSize.height = fLineHeight + kSpacing;
216		return;
217	}
218
219	fMinSize.height += fLineHeight + kSpacing + 1;
220	fMinSize.width = ceilf(bold.StringWidth(fRef.name));
221
222	BString strings[5] = {fInfo.audio.format, fInfo.audio.details,
223		fInfo.video.format, fInfo.video.details, fInfo.duration};
224	float maxInfoWidth = _MaxLineWidth(strings, 5, font);
225
226	fMinSize.width = max_c(fMinSize.width, fMaxLabelWidth
227		+ maxInfoWidth + kSpacing);
228	fMinSize.width += kSpacing;
229
230	fMinSize.height += fLineHeight * 5 + 2 * kSpacing;
231		// 5 lines of info, w/ spacing above and below (not between lines)
232
233	ResetLayoutInvalidation();
234	fMinMaxValid = true;
235}
236
237
238void
239MediaFileInfoView::_SetFontFace(uint16 face)
240{
241	BFont font;
242	font.SetFace(face);
243	SetFont(&font, B_FONT_FACE);
244}
245
246