xref: /haiku/src/apps/mediaconverter/MediaFileInfoView.cpp (revision 99d027cd0238c1d86da86d7c3f4200509ccc61a6)
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 
20 const float kSpacing = 5.0f;
21 
22 
23 MediaFileInfoView::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 
34 MediaFileInfoView::~MediaFileInfoView()
35 {
36 }
37 
38 
39 void
40 MediaFileInfoView::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 
82 BSize
83 MediaFileInfoView::MinSize()
84 {
85 	_ValidateMinMax();
86 	return fMinSize;
87 }
88 
89 
90 BSize
91 MediaFileInfoView::MaxSize()
92 {
93 	return BSize(B_SIZE_UNLIMITED, fMinSize.height);
94 }
95 
96 
97 BSize
98 MediaFileInfoView::PreferredSize()
99 {
100 	_ValidateMinMax();
101 	return fMinSize;
102 }
103 
104 
105 BAlignment
106 MediaFileInfoView::LayoutAlignment()
107 {
108 	return BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP);
109 }
110 
111 
112 void
113 MediaFileInfoView::InvalidateLayout(bool /*children*/)
114 {
115 	fMinMaxValid = false;
116 	BView::InvalidateLayout();
117 }
118 
119 
120 void
121 MediaFileInfoView::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 
141 void
142 MediaFileInfoView::AttachedToWindow()
143 {
144 	rgb_color c = Parent()->LowColor();
145 	SetViewColor(c);
146 	SetLowColor(c);
147 }
148 
149 
150 void
151 MediaFileInfoView::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 ret = fInfo.LoadInfo(file);
161 		if (ret != B_OK) {
162 			BString error(B_TRANSLATE("An error has occurred reading the "
163 				"file info.\n\nError : "));
164 			error << strerror(ret);
165 			BAlert* alert = new BAlert(
166 				B_TRANSLATE("File Error"), error.String(),
167 				B_TRANSLATE("OK"));
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 
179 float
180 MediaFileInfoView::_LineHeight()
181 {
182 	font_height fontHeight;
183 	GetFontHeight(&fontHeight);
184 	return ceilf(fontHeight.ascent + fontHeight.descent + fontHeight.leading);
185 }
186 
187 
188 float
189 MediaFileInfoView::_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 
200 void
201 MediaFileInfoView::_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 
238 void
239 MediaFileInfoView::_SetFontFace(uint16 face)
240 {
241 	BFont font;
242 	font.SetFace(face);
243 	SetFont(&font, B_FONT_FACE);
244 }
245 
246