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
MediaFileInfoView()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
~MediaFileInfoView()34 MediaFileInfoView::~MediaFileInfoView()
35 {
36 }
37
38
39 void
Draw(BRect)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
MinSize()83 MediaFileInfoView::MinSize()
84 {
85 _ValidateMinMax();
86 return fMinSize;
87 }
88
89
90 BSize
MaxSize()91 MediaFileInfoView::MaxSize()
92 {
93 return BSize(B_SIZE_UNLIMITED, fMinSize.height);
94 }
95
96
97 BSize
PreferredSize()98 MediaFileInfoView::PreferredSize()
99 {
100 _ValidateMinMax();
101 return fMinSize;
102 }
103
104
105 BAlignment
LayoutAlignment()106 MediaFileInfoView::LayoutAlignment()
107 {
108 return BAlignment(B_ALIGN_LEFT, B_ALIGN_TOP);
109 }
110
111
112 void
InvalidateLayout(bool)113 MediaFileInfoView::InvalidateLayout(bool /*children*/)
114 {
115 fMinMaxValid = false;
116 BView::InvalidateLayout();
117 }
118
119
120 void
SetFont(const BFont * font,uint32 mask)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
AttachedToWindow()142 MediaFileInfoView::AttachedToWindow()
143 {
144 rgb_color c = Parent()->LowColor();
145 SetViewColor(c);
146 SetLowColor(c);
147 }
148
149
150 void
Update(BMediaFile * file,entry_ref * ref)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 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
179 float
_LineHeight()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
_MaxLineWidth(BString * strings,int32 count,const BFont & font)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
_ValidateMinMax()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
_SetFontFace(uint16 face)239 MediaFileInfoView::_SetFontFace(uint16 face)
240 {
241 BFont font;
242 font.SetFace(face);
243 SetFont(&font, B_FONT_FACE);
244 }
245
246