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