vfs: check userland buffers before reading them.
[haiku.git] / src / apps / showimage / ShowImageStatusView.cpp
blob436e323f9c5e652a01d7af0f15d67c9cc56d7a9e
1 /*
2 * Copyright 2003-2010, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Fernando Francisco de Oliveira
7 * Michael Wilber
8 * Axel Dörfler, axeld@pinc-software.de
9 */
12 #include "ShowImageStatusView.h"
14 #include <ControlLook.h>
15 #include <Entry.h>
16 #include <MenuItem.h>
17 #include <Path.h>
18 #include <PopUpMenu.h>
19 #include <ScrollView.h>
21 #include <tracker_private.h>
22 #include "DirMenu.h"
24 #include "ShowImageView.h"
25 #include "ShowImageWindow.h"
27 const float kHorzSpacing = 5.f;
30 ShowImageStatusView::ShowImageStatusView(BScrollView* scrollView)
32 BView(BRect(), "statusview", B_FOLLOW_BOTTOM | B_FOLLOW_LEFT, B_WILL_DRAW),
33 fScrollView(scrollView),
34 fPreferredSize(0.0, 0.0)
36 memset(fCellWidth, 0, sizeof(fCellWidth));
40 void
41 ShowImageStatusView::AttachedToWindow()
43 SetFont(be_plain_font);
44 SetFontSize(10.0);
46 BScrollBar* scrollBar = fScrollView->ScrollBar(B_HORIZONTAL);
47 MoveTo(0.0, scrollBar->Frame().top);
49 AdoptParentColors();
51 ResizeToPreferred();
55 void
56 ShowImageStatusView::GetPreferredSize(float* _width, float* _height)
58 _ValidatePreferredSize();
60 if (_width)
61 *_width = fPreferredSize.width;
63 if (_height)
64 *_height = fPreferredSize.height;
68 void
69 ShowImageStatusView::ResizeToPreferred()
71 float width, height;
72 GetPreferredSize(&width, &height);
74 if (Bounds().Width() > width)
75 width = Bounds().Width();
77 BView::ResizeTo(width, height);
81 void
82 ShowImageStatusView::Draw(BRect updateRect)
84 if (fPreferredSize.width <= 0)
85 return;
87 if (be_control_look != NULL) {
88 BRect bounds(Bounds());
89 be_control_look->DrawMenuBarBackground(this,
90 bounds, updateRect, ViewColor());
93 BRect bounds(Bounds());
94 rgb_color highColor = ui_color(B_PANEL_TEXT_COLOR);
96 SetHighColor(tint_color(ViewColor(), B_DARKEN_2_TINT));
97 StrokeLine(bounds.LeftTop(), bounds.RightTop());
99 float x = bounds.left;
100 for (size_t i = 0; i < kStatusCellCount - 1; i++) {
101 x += fCellWidth[i];
102 StrokeLine(BPoint(x, bounds.top + 3), BPoint(x, bounds.bottom - 3));
105 SetLowColor(ViewColor());
106 SetHighColor(highColor);
108 font_height fontHeight;
109 GetFontHeight(&fontHeight);
111 x = bounds.left;
112 float y = (bounds.bottom + bounds.top
113 + ceilf(fontHeight.ascent) - ceilf(fontHeight.descent)) / 2;
115 for (size_t i = 0; i < kStatusCellCount; i++) {
116 if (fCellText[i].Length() == 0)
117 continue;
118 DrawString(fCellText[i], BPoint(x + kHorzSpacing, y));
119 x += fCellWidth[i];
124 void
125 ShowImageStatusView::MouseDown(BPoint where)
127 BPrivate::BDirMenu* menu = new BDirMenu(NULL, BMessenger(kTrackerSignature),
128 B_REFS_RECEIVED);
129 BEntry entry;
130 if (entry.SetTo(&fRef) == B_OK)
131 menu->Populate(&entry, Window(), false, false, true, false, true);
132 else
133 menu->Populate(NULL, Window(), false, false, true, false, true);
135 BPoint point = Bounds().LeftBottom();
136 point.y += 3;
137 ConvertToScreen(&point);
138 BRect clickToOpenRect(Bounds());
139 ConvertToScreen(&clickToOpenRect);
140 menu->Go(point, true, true, clickToOpenRect);
141 delete menu;
145 void
146 ShowImageStatusView::Update(const entry_ref& ref, const BString& text,
147 const BString& pages, const BString& imageType, float zoom)
149 fRef = ref;
151 _SetFrameText(text);
152 _SetZoomText(zoom);
153 _SetPagesText(pages);
154 _SetImageTypeText(imageType);
156 _ValidatePreferredSize();
157 Invalidate();
161 void
162 ShowImageStatusView::SetZoom(float zoom)
164 _SetZoomText(zoom);
165 _ValidatePreferredSize();
166 Invalidate();
170 void
171 ShowImageStatusView::_SetFrameText(const BString& text)
173 fCellText[kFrameSizeCell] = text;
177 void
178 ShowImageStatusView::_SetZoomText(float zoom)
180 fCellText[kZoomCell].SetToFormat("%.0f%%", zoom * 100);
184 void
185 ShowImageStatusView::_SetPagesText(const BString& pages)
187 fCellText[kPagesCell] = pages;
191 void
192 ShowImageStatusView::_SetImageTypeText(const BString& imageType)
194 fCellText[kImageTypeCell] = imageType;
198 void
199 ShowImageStatusView::_ValidatePreferredSize()
201 float orgWidth = fPreferredSize.width;
202 // width
203 fPreferredSize.width = 0.f;
204 for (size_t i = 0; i < kStatusCellCount; i++) {
205 if (fCellText[i].Length() == 0) {
206 fCellWidth[i] = 0;
207 continue;
209 float width = ceilf(StringWidth(fCellText[i]));
210 if (width > 0)
211 width += kHorzSpacing * 2;
212 fCellWidth[i] = width;
213 fPreferredSize.width += fCellWidth[i];
216 // height
217 font_height fontHeight;
218 GetFontHeight(&fontHeight);
220 fPreferredSize.height = ceilf(fontHeight.ascent + fontHeight.descent
221 + fontHeight.leading);
223 if (fPreferredSize.height < B_H_SCROLL_BAR_HEIGHT)
224 fPreferredSize.height = B_H_SCROLL_BAR_HEIGHT;
226 float delta = fPreferredSize.width - orgWidth;
227 ResizeBy(delta, 0);
228 BScrollBar* scrollBar = fScrollView->ScrollBar(B_HORIZONTAL);
229 scrollBar->ResizeBy(-delta, 0);
230 scrollBar->MoveBy(delta, 0);