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_TRANSLATE_CONTEXT 17 #define B_TRANSLATE_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->Go(NULL); 169 } 170 } else { 171 fRef = entry_ref(); 172 } 173 InvalidateLayout(); 174 Invalidate(); 175 } 176 177 178 float 179 MediaFileInfoView::_LineHeight() 180 { 181 font_height fontHeight; 182 GetFontHeight(&fontHeight); 183 return ceilf(fontHeight.ascent + fontHeight.descent + fontHeight.leading); 184 } 185 186 187 float 188 MediaFileInfoView::_MaxLineWidth(BString* strings, int32 count, 189 const BFont& font) 190 { 191 float width = 0; 192 for (int32 i = 0; i < count; i++) 193 width = max_c(font.StringWidth(strings[i]), width); 194 195 return ceilf(width); 196 } 197 198 199 void 200 MediaFileInfoView::_ValidateMinMax() 201 { 202 if (fMinMaxValid) 203 return; 204 205 BFont font; 206 GetFont(&font); 207 208 BFont bold(font); 209 bold.SetFace(B_BOLD_FACE); 210 fMinSize.Set(0, 0); 211 212 if (fMediaFile == NULL) { 213 fMinSize.width = fNoFileLabelWidth + kSpacing * 2; 214 fMinSize.height = fLineHeight + kSpacing; 215 return; 216 } 217 218 fMinSize.height += fLineHeight + kSpacing + 1; 219 fMinSize.width = ceilf(bold.StringWidth(fRef.name)); 220 221 BString strings[5] = {fInfo.audio.format, fInfo.audio.details, 222 fInfo.video.format, fInfo.video.details, fInfo.duration}; 223 float maxInfoWidth = _MaxLineWidth(strings, 5, font); 224 225 fMinSize.width = max_c(fMinSize.width, fMaxLabelWidth 226 + maxInfoWidth + kSpacing); 227 fMinSize.width += kSpacing; 228 229 fMinSize.height += fLineHeight * 5 + 2 * kSpacing; 230 // 5 lines of info, w/ spacing above and below (not between lines) 231 232 ResetLayoutInvalidation(); 233 fMinMaxValid = true; 234 } 235 236 237 void 238 MediaFileInfoView::_SetFontFace(uint16 face) 239 { 240 BFont font; 241 font.SetFace(face); 242 SetFont(&font, B_FONT_FACE); 243 } 244 245