BColumnListView: use automatic formatting for i18n
Use BDateTimeFormat, BDateFormat, and BNumberFormat for various date, time, decimal, and percent formatting. Change-Id: I994563d207db8bd28342ca6543b69a356ced38af Reviewed-on: https://review.haiku-os.org/c/haiku/+/7505 Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org> Reviewed-by: Adrien Destugues <pulkomandy@pulkomandy.tk>
This commit is contained in:
parent
f42b1cb118
commit
058be77bec
@ -16,9 +16,12 @@
|
||||
|
||||
#include "ColumnListView.h"
|
||||
|
||||
#include <String.h>
|
||||
#include <Font.h>
|
||||
#include <Bitmap.h>
|
||||
#include <DateFormat.h>
|
||||
#include <DateTimeFormat.h>
|
||||
#include <Font.h>
|
||||
#include <NumberFormat.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
//=====================================================================
|
||||
@ -40,6 +43,9 @@ public:
|
||||
|
||||
virtual float GetPreferredWidth(BField* field, BView* parent) const;
|
||||
|
||||
protected:
|
||||
BNumberFormat fNumberFormat;
|
||||
|
||||
private:
|
||||
float fFontHeight;
|
||||
BString fTitle;
|
||||
@ -122,6 +128,8 @@ public:
|
||||
virtual int CompareFields(BField* field1, BField* field2);
|
||||
|
||||
private:
|
||||
BDateTimeFormat fDateTimeFormat;
|
||||
BDateFormat fDateFormat;
|
||||
BString fTitle;
|
||||
};
|
||||
|
||||
|
@ -6,34 +6,29 @@
|
||||
/ data types for use in BColumnListView.
|
||||
/
|
||||
/ Copyright 2000+, Be Incorporated, All Rights Reserved
|
||||
/ Copyright 2024, Haiku, Inc. All Rights Reserved
|
||||
/
|
||||
*******************************************************************************/
|
||||
|
||||
|
||||
#include "ColumnTypes.h"
|
||||
|
||||
#include <StringFormat.h>
|
||||
#include <SystemCatalog.h>
|
||||
#include <View.h>
|
||||
|
||||
#include <parsedate.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
using BPrivate::gSystemCatalog;
|
||||
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "ColumnTypes"
|
||||
|
||||
#define kTEXT_MARGIN 8
|
||||
|
||||
|
||||
const int64 kKB_SIZE = 1024;
|
||||
const int64 kMB_SIZE = 1048576;
|
||||
const int64 kGB_SIZE = 1073741824;
|
||||
const int64 kTB_SIZE = kGB_SIZE * kKB_SIZE;
|
||||
|
||||
const char* kSIZE_FORMATS[] = {
|
||||
"%.2f %s",
|
||||
"%.1f %s",
|
||||
"%.f %s",
|
||||
"%.f%s",
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
BTitledColumn::BTitledColumn(const char* title, float width, float minWidth,
|
||||
float maxWidth, alignment align)
|
||||
:
|
||||
@ -320,17 +315,6 @@ BDateColumn::BDateColumn(const char* title, float width, float minWidth,
|
||||
}
|
||||
|
||||
|
||||
const char *kTIME_FORMATS[] = {
|
||||
"%A, %B %d %Y, %I:%M:%S %p", // Monday, July 09 1997, 05:08:15 PM
|
||||
"%a, %b %d %Y, %I:%M:%S %p", // Mon, Jul 09 1997, 05:08:15 PM
|
||||
"%a, %b %d %Y, %I:%M %p", // Mon, Jul 09 1997, 05:08 PM
|
||||
"%b %d %Y, %I:%M %p", // Jul 09 1997, 05:08 PM
|
||||
"%m/%d/%y, %I:%M %p", // 07/09/97, 05:08 PM
|
||||
"%m/%d/%y", // 07/09/97
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
BDateColumn::DrawField(BField* _field, BRect rect, BView* parent)
|
||||
{
|
||||
@ -346,15 +330,28 @@ BDateColumn::DrawField(BField* _field, BRect rect, BView* parent)
|
||||
parent->GetFont(&font);
|
||||
localtime_r(¤tTime, &time_data);
|
||||
|
||||
for (int32 index = 0; ; index++) {
|
||||
if (!kTIME_FORMATS[index])
|
||||
break;
|
||||
// dateStyles[] and timeStyles[] must be the same length
|
||||
const BDateFormatStyle dateStyles[] = {
|
||||
B_FULL_DATE_FORMAT, B_FULL_DATE_FORMAT, B_LONG_DATE_FORMAT, B_LONG_DATE_FORMAT,
|
||||
B_MEDIUM_DATE_FORMAT, B_SHORT_DATE_FORMAT,
|
||||
};
|
||||
|
||||
strftime(dateString, 256, kTIME_FORMATS[index], &time_data);
|
||||
if (font.StringWidth(dateString) <= width)
|
||||
const BTimeFormatStyle timeStyles[] = {
|
||||
B_MEDIUM_TIME_FORMAT, B_SHORT_TIME_FORMAT, B_MEDIUM_TIME_FORMAT, B_SHORT_TIME_FORMAT,
|
||||
B_SHORT_TIME_FORMAT, B_SHORT_TIME_FORMAT,
|
||||
};
|
||||
|
||||
size_t index;
|
||||
for (index = 0; index < B_COUNT_OF(dateStyles); index++) {
|
||||
ssize_t output = fDateTimeFormat.Format(dateString, sizeof(dateString), currentTime,
|
||||
dateStyles[index], timeStyles[index]);
|
||||
if (output >= 0 && font.StringWidth(dateString) <= width)
|
||||
break;
|
||||
}
|
||||
|
||||
if (index == B_COUNT_OF(dateStyles))
|
||||
fDateFormat.Format(dateString, sizeof(dateString), currentTime, B_SHORT_DATE_FORMAT);
|
||||
|
||||
if (font.StringWidth(dateString) > width) {
|
||||
BString out_string(dateString);
|
||||
|
||||
@ -414,58 +411,55 @@ BSizeColumn::BSizeColumn(const char* title, float width, float minWidth,
|
||||
void
|
||||
BSizeColumn::DrawField(BField* _field, BRect rect, BView* parent)
|
||||
{
|
||||
char str[256];
|
||||
float width = rect.Width() - (2 * kTEXT_MARGIN);
|
||||
BFont font;
|
||||
BString printedSize;
|
||||
BString string;
|
||||
off_t size = ((BSizeField*)_field)->Size();
|
||||
|
||||
float width = rect.Width() - (2 * kTEXT_MARGIN);
|
||||
|
||||
double value = ((BSizeField*)_field)->Size() / 1024.0;
|
||||
parent->GetFont(&font);
|
||||
if (size < kKB_SIZE) {
|
||||
sprintf(str, "%" B_PRId64 " bytes", size);
|
||||
if (font.StringWidth(str) > width)
|
||||
sprintf(str, "%" B_PRId64 " B", size);
|
||||
// we cannot use string_for_size due to the precision/cell width logic
|
||||
if (value < 1024.0) {
|
||||
BStringFormat format(B_TRANSLATE_MARK_ALL("{0, plural, one{# byte} other{# bytes}}",
|
||||
B_TRANSLATION_CONTEXT, "unit size"));
|
||||
format.Format(printedSize, value);
|
||||
string = gSystemCatalog.GetString(printedSize, B_TRANSLATION_CONTEXT, "unit size");
|
||||
if (font.StringWidth(string) > width) {
|
||||
BString tmp = B_TRANSLATE_MARK_ALL("%s B", B_TRANSLATION_CONTEXT, "unit size");
|
||||
fNumberFormat.Format(printedSize, value);
|
||||
string.SetToFormat(gSystemCatalog.GetString(tmp, B_TRANSLATION_CONTEXT, "unit size"),
|
||||
printedSize.String());
|
||||
}
|
||||
} else {
|
||||
const char* suffix;
|
||||
float float_value;
|
||||
if (size >= kTB_SIZE) {
|
||||
suffix = "TB";
|
||||
float_value = (float)size / kTB_SIZE;
|
||||
} else if (size >= kGB_SIZE) {
|
||||
suffix = "GB";
|
||||
float_value = (float)size / kGB_SIZE;
|
||||
} else if (size >= kMB_SIZE) {
|
||||
suffix = "MB";
|
||||
float_value = (float)size / kMB_SIZE;
|
||||
} else {
|
||||
suffix = "KB";
|
||||
float_value = (float)size / kKB_SIZE;
|
||||
const char* kFormats[] = {
|
||||
B_TRANSLATE_MARK_ALL("%s KiB", B_TRANSLATION_CONTEXT, "unit size"),
|
||||
B_TRANSLATE_MARK_ALL("%s MiB", B_TRANSLATION_CONTEXT, "unit size"),
|
||||
B_TRANSLATE_MARK_ALL("%s GiB", B_TRANSLATION_CONTEXT, "unit size"),
|
||||
B_TRANSLATE_MARK_ALL("%s TiB", B_TRANSLATION_CONTEXT, "unit size")
|
||||
};
|
||||
|
||||
size_t index = 0;
|
||||
while (index < B_COUNT_OF(kFormats) && value >= 1024.0) {
|
||||
value /= 1024.0;
|
||||
index++;
|
||||
}
|
||||
|
||||
for (int32 index = 0; ; index++) {
|
||||
if (!kSIZE_FORMATS[index])
|
||||
int precision = 2;
|
||||
while (precision >= 0) {
|
||||
double formattedSize = value;
|
||||
fNumberFormat.SetPrecision(precision);
|
||||
fNumberFormat.Format(printedSize, formattedSize);
|
||||
string.SetToFormat(
|
||||
gSystemCatalog.GetString(kFormats[index], B_TRANSLATION_CONTEXT, "unit size"),
|
||||
printedSize.String());
|
||||
if (font.StringWidth(string) <= width)
|
||||
break;
|
||||
|
||||
sprintf(str, kSIZE_FORMATS[index], float_value, suffix);
|
||||
// strip off an insignificant zero so we don't get readings
|
||||
// such as 1.00
|
||||
char *period = 0;
|
||||
char *tmp (NULL);
|
||||
for (tmp = str; *tmp; tmp++) {
|
||||
if (*tmp == '.')
|
||||
period = tmp;
|
||||
}
|
||||
if (period && period[1] && period[2] == '0') {
|
||||
// move the rest of the string over the insignificant zero
|
||||
for (tmp = &period[2]; *tmp; tmp++)
|
||||
*tmp = tmp[1];
|
||||
}
|
||||
if (font.StringWidth(str) <= width)
|
||||
break;
|
||||
precision--;
|
||||
}
|
||||
}
|
||||
|
||||
string = str;
|
||||
parent->TruncateString(&string, B_TRUNCATE_MIDDLE, width + 2);
|
||||
DrawString(string.String(), parent, rect);
|
||||
}
|
||||
@ -521,13 +515,10 @@ BIntegerColumn::BIntegerColumn(const char* title, float width, float minWidth,
|
||||
void
|
||||
BIntegerColumn::DrawField(BField *field, BRect rect, BView* parent)
|
||||
{
|
||||
char formatted[256];
|
||||
float width = rect.Width() - (2 * kTEXT_MARGIN);
|
||||
BString string;
|
||||
|
||||
sprintf(formatted, "%d", (int)((BIntegerField*)field)->Value());
|
||||
|
||||
string = formatted;
|
||||
fNumberFormat.Format(string, (int32)((BIntegerField*)field)->Value());
|
||||
float width = rect.Width() - (2 * kTEXT_MARGIN);
|
||||
parent->TruncateString(&string, B_TRUNCATE_MIDDLE, width + 2);
|
||||
DrawString(string.String(), parent, rect);
|
||||
}
|
||||
@ -554,32 +545,35 @@ GraphColumn::GraphColumn(const char* name, float width, float minWidth,
|
||||
void
|
||||
GraphColumn::DrawField(BField* field, BRect rect, BView* parent)
|
||||
{
|
||||
int number = ((BIntegerField*)field)->Value();
|
||||
double fieldValue = ((BIntegerField*)field)->Value();
|
||||
double percentValue = fieldValue / 100.0;
|
||||
|
||||
if (number > 100)
|
||||
number = 100;
|
||||
else if (number < 0)
|
||||
number = 0;
|
||||
if (percentValue > 1.0)
|
||||
percentValue = 1.0;
|
||||
else if (percentValue < 0.0)
|
||||
percentValue = 0.0;
|
||||
|
||||
BRect graphRect(rect);
|
||||
graphRect.InsetBy(5, 3);
|
||||
parent->StrokeRect(graphRect);
|
||||
if (number > 0) {
|
||||
parent->StrokeRoundRect(graphRect, 2.5, 2.5);
|
||||
|
||||
if (percentValue > 0.0) {
|
||||
graphRect.InsetBy(1, 1);
|
||||
float value = graphRect.Width() * (float)number / 100;
|
||||
double value = graphRect.Width() * percentValue;
|
||||
graphRect.right = graphRect.left + value;
|
||||
parent->SetHighColor(0, 0, 190);
|
||||
parent->SetHighUIColor(B_NAVIGATION_BASE_COLOR);
|
||||
parent->FillRect(graphRect);
|
||||
}
|
||||
|
||||
parent->SetDrawingMode(B_OP_INVERT);
|
||||
parent->SetHighColor(128, 128, 128);
|
||||
char numberString[256];
|
||||
sprintf(numberString, "%d%%", number);
|
||||
|
||||
float width = be_plain_font->StringWidth(numberString);
|
||||
BString percentString;
|
||||
fNumberFormat.FormatPercent(percentString, percentValue);
|
||||
float width = be_plain_font->StringWidth(percentString);
|
||||
|
||||
parent->MovePenTo(rect.left + rect.Width() / 2 - width / 2, rect.bottom - FontHeight());
|
||||
parent->DrawString(numberString);
|
||||
parent->DrawString(percentString.String());
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user