btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / apps / stylededit / StatusView.cpp
blobdbe1bcf12cb526827200ad4dc319e4d8ea89cf33
1 /*
2 * Copyright 2002-2012, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Vlad Slepukhin
7 * Siarzhuk Zharski
8 */
11 #include "StatusView.h"
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
17 #include <Catalog.h>
18 #include <CharacterSet.h>
19 #include <CharacterSetRoster.h>
20 #include <ControlLook.h>
21 #include <MenuItem.h>
22 #include <Message.h>
23 #include <PopUpMenu.h>
24 #include <ScrollView.h>
25 #include <StringView.h>
26 #include <Window.h>
28 #include <tracker_private.h>
29 #include "DirMenu.h"
31 #include "Constants.h"
34 const float kHorzSpacing = 5.f;
35 #define UTF8_EXPAND_ARROW "\xe2\x96\xbe"
37 using namespace BPrivate;
40 #undef B_TRANSLATION_CONTEXT
41 #define B_TRANSLATION_CONTEXT "StatusView"
44 StatusView::StatusView(BScrollView* scrollView)
46 BView(BRect(), "statusview",
47 B_FOLLOW_BOTTOM | B_FOLLOW_LEFT, B_WILL_DRAW),
48 fScrollView(scrollView),
49 fPreferredSize(0., 0.),
50 fReadOnly(false),
51 fCanUnlock(false)
53 memset(fCellWidth, 0, sizeof(fCellWidth));
57 StatusView::~StatusView()
62 void
63 StatusView::AttachedToWindow()
65 SetFont(be_plain_font);
66 SetFontSize(10.);
68 BMessage message(UPDATE_STATUS);
69 message.AddInt32("line", 1);
70 message.AddInt32("column", 1);
71 message.AddString("encoding", "");
72 SetStatus(&message);
74 BScrollBar* scrollBar = fScrollView->ScrollBar(B_HORIZONTAL);
75 MoveTo(0., scrollBar->Frame().top);
77 rgb_color color = B_TRANSPARENT_COLOR;
78 BView* parent = Parent();
79 if (parent != NULL)
80 color = parent->ViewColor();
82 if (color == B_TRANSPARENT_COLOR)
83 color = ui_color(B_PANEL_BACKGROUND_COLOR);
85 SetViewColor(color);
87 ResizeToPreferred();
91 void
92 StatusView::GetPreferredSize(float* _width, float* _height)
94 _ValidatePreferredSize();
96 if (_width)
97 *_width = fPreferredSize.width;
99 if (_height)
100 *_height = fPreferredSize.height;
104 void
105 StatusView::ResizeToPreferred()
107 float width, height;
108 GetPreferredSize(&width, &height);
110 if (Bounds().Width() > width)
111 width = Bounds().Width();
113 BView::ResizeTo(width, height);
117 void
118 StatusView::Draw(BRect updateRect)
120 if (fPreferredSize.width <= 0)
121 return;
123 if (be_control_look != NULL) {
124 BRect bounds(Bounds());
125 be_control_look->DrawMenuBarBackground(this,
126 bounds, updateRect, ViewColor());
129 BRect bounds(Bounds());
130 rgb_color highColor = HighColor();
131 SetHighColor(tint_color(ViewColor(), B_DARKEN_2_TINT));
132 StrokeLine(bounds.LeftTop(), bounds.RightTop());
134 float x = bounds.left;
135 for (size_t i = 0; i < kStatusCellCount - 1; i++) {
136 x += fCellWidth[i];
137 StrokeLine(BPoint(x, bounds.top + 3), BPoint(x, bounds.bottom - 3));
140 SetLowColor(ViewColor());
141 SetHighColor(highColor);
143 font_height fontHeight;
144 GetFontHeight(&fontHeight);
146 x = bounds.left;
147 float y = (bounds.bottom + bounds.top
148 + ceilf(fontHeight.ascent) - ceilf(fontHeight.descent)) / 2;
150 for (size_t i = 0; i < kStatusCellCount; i++) {
151 if (fCellText[i].Length() == 0)
152 continue;
153 DrawString(fCellText[i], BPoint(x + kHorzSpacing, y));
154 x += fCellWidth[i];
159 void
160 StatusView::MouseDown(BPoint where)
162 if (where.x < fCellWidth[kPositionCell]) {
163 _ShowDirMenu();
164 return;
167 if (!fReadOnly || !fCanUnlock)
168 return;
170 float left = fCellWidth[kPositionCell] + fCellWidth[kEncodingCell];
171 if (where.x < left)
172 return;
174 int32 clicks = 0;
175 BMessage* message = Window()->CurrentMessage();
176 if (message != NULL
177 && message->FindInt32("clicks", &clicks) == B_OK && clicks > 1)
178 return;
180 BPopUpMenu *menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
181 menu->AddItem(new BMenuItem(B_TRANSLATE("Unlock file"),
182 new BMessage(UNLOCK_FILE)));
183 where.x = left;
184 where.y = Bounds().bottom;
186 ConvertToScreen(&where);
187 menu->SetTargetForItems(this);
188 menu->Go(where, true, true, true);
192 void
193 StatusView::SetStatus(BMessage* message)
195 int32 line = 0, column = 0;
196 if (B_OK == message->FindInt32("line", &line)
197 && B_OK == message->FindInt32("column", &column))
199 char info[256];
200 snprintf(info, sizeof(info),
201 B_TRANSLATE("line %d, column %d"), line, column);
202 fCellText[kPositionCell].SetTo(info);
205 if (B_OK == message->FindString("encoding", &fEncoding)) {
206 // sometime corresponding Int-32 "encoding" attrib is read as string :(
207 if (fEncoding.Length() == 0
208 || fEncoding.Compare("\xff\xff") == 0
209 || fEncoding.Compare("UTF-8") == 0)
211 // do not display default UTF-8 encoding
212 fCellText[kEncodingCell].Truncate(0);
213 fEncoding.Truncate(0);
214 } else {
215 const BCharacterSet* charset
216 = BCharacterSetRoster::FindCharacterSetByName(fEncoding);
217 fCellText[kEncodingCell]
218 = charset != NULL ? charset->GetPrintName() : "";
222 bool modified = false;
223 fReadOnly = false;
224 fCanUnlock = false;
225 if (B_OK == message->FindBool("modified", &modified) && modified) {
226 fCellText[kFileStateCell] = B_TRANSLATE("Modified");
227 } else if (B_OK == message->FindBool("readOnly", &fReadOnly) && fReadOnly) {
228 fCellText[kFileStateCell] = B_TRANSLATE("Read-only");
229 if (B_OK == message->FindBool("canUnlock", &fCanUnlock) && fCanUnlock)
230 fCellText[kFileStateCell] << " " UTF8_EXPAND_ARROW;
231 } else
232 fCellText[kFileStateCell].Truncate(0);
234 _ValidatePreferredSize();
235 Invalidate();
239 void
240 StatusView::SetRef(const entry_ref& ref)
242 fRef = ref;
246 void
247 StatusView::_ValidatePreferredSize()
249 float orgWidth = fPreferredSize.width;
250 // width
251 fPreferredSize.width = 0.f;
252 for (size_t i = 0; i < kStatusCellCount; i++) {
253 if (fCellText[i].Length() == 0) {
254 fCellWidth[i] = 0;
255 continue;
257 float width = ceilf(StringWidth(fCellText[i]));
258 if (width > 0)
259 width += kHorzSpacing * 2;
260 if (width > fCellWidth[i] || i != kPositionCell)
261 fCellWidth[i] = width;
262 fPreferredSize.width += fCellWidth[i];
265 // height
266 font_height fontHeight;
267 GetFontHeight(&fontHeight);
269 fPreferredSize.height = ceilf(fontHeight.ascent + fontHeight.descent
270 + fontHeight.leading);
272 if (fPreferredSize.height < B_H_SCROLL_BAR_HEIGHT)
273 fPreferredSize.height = B_H_SCROLL_BAR_HEIGHT;
275 float delta = fPreferredSize.width - orgWidth;
276 ResizeBy(delta, 0);
277 BScrollBar* scrollBar = fScrollView->ScrollBar(B_HORIZONTAL);
278 scrollBar->ResizeBy(-delta, 0);
279 scrollBar->MoveBy(delta, 0);
283 void
284 StatusView::_ShowDirMenu()
286 BEntry entry;
287 status_t status = entry.SetTo(&fRef);
289 if (status != B_OK || !entry.Exists())
290 return;
292 BPrivate::BDirMenu* menu = new BDirMenu(NULL,
293 BMessenger(kTrackerSignature), B_REFS_RECEIVED);
295 menu->Populate(&entry, Window(), false, false, true, false, true);
297 BPoint point = Bounds().LeftBottom();
298 point.y += 3;
299 ConvertToScreen(&point);
300 BRect clickToOpenRect(Bounds());
301 ConvertToScreen(&clickToOpenRect);
302 menu->Go(point, true, true, clickToOpenRect);
303 delete menu;