Merge branch 'master' into f7

This commit is contained in:
Léa Saviot
2019-06-14 16:03:59 +02:00
9 changed files with 94 additions and 62 deletions

View File

@@ -361,9 +361,10 @@ bool PythonToolbox::selectLeaf(int selectedRow) {
m_selectableTableView.deselectTable();
ToolboxMessageTree * node = (ToolboxMessageTree *)m_messageTreeModel->children(selectedRow);
const char * editedText = I18n::translate(node->insertedText());
// strippedEditedText array needs to be in the same scope as editedText
char strippedEditedText[k_maxMessageSize];
if (node->stripInsertedText()) {
int strippedEditedTextMaxLength = strlen(editedText)+1;
char strippedEditedText[k_maxMessageSize];
assert(strippedEditedTextMaxLength <= k_maxMessageSize);
Shared::ToolboxHelpers::TextToInsertForCommandMessage(node->insertedText(), strippedEditedText, strippedEditedTextMaxLength, true);
editedText = strippedEditedText;

View File

@@ -1,5 +1,6 @@
#include "graph_controller.h"
#include "../shared/poincare_helpers.h"
#include "../shared/text_helpers.h"
#include "../apps_container.h"
#include <cmath>
@@ -110,16 +111,15 @@ void GraphController::reloadBannerView() {
numberOfChar += strlcpy(buffer, legend, bufferSize);
if (*m_selectedDotIndex == m_store->numberOfPairsOfSeries(*m_selectedSeriesIndex)) {
legend = I18n::translate(I18n::Message::MeanDot);
numberOfChar += strlcpy(buffer+numberOfChar, legend, bufferSize - numberOfChar);
numberOfChar += strlcpy(buffer + numberOfChar, legend, bufferSize - numberOfChar);
} else if (*m_selectedDotIndex < 0) {
legend = I18n::translate(I18n::Message::Reg);
numberOfChar += strlcpy(buffer+numberOfChar, legend, bufferSize - numberOfChar);
numberOfChar += strlcpy(buffer + numberOfChar, legend, bufferSize - numberOfChar);
} else {
numberOfChar += PrintFloat::convertFloatToText<float>(std::round((float)*m_selectedDotIndex+1.0f), buffer+numberOfChar, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::ShortNumberOfSignificantDigits), Constant::ShortNumberOfSignificantDigits, Preferences::PrintFloatMode::Decimal);
numberOfChar += PrintFloat::convertFloatToText<float>(std::round((float)*m_selectedDotIndex+1.0f), buffer + numberOfChar, bufferSize - numberOfChar, Constant::ShortNumberOfSignificantDigits, Preferences::PrintFloatMode::Decimal);
}
legend = ") ";
strlcpy(buffer+numberOfChar, legend, bufferSize - numberOfChar);
buffer[k_maxLegendLength] = 0;
strlcpy(buffer + numberOfChar, legend, bufferSize - numberOfChar);
m_bannerView.dotNameView()->setText(buffer);
// Set "x=..." or "xmean=..."
@@ -133,12 +133,9 @@ void GraphController::reloadBannerView() {
}
m_bannerView.abscissaSymbol()->setText(legend);
numberOfChar = PoincareHelpers::ConvertFloatToText<double>(x, buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits);
assert(UTF8Decoder::CharSizeOfCodePoint(' ') == 1);
for (int i = numberOfChar; i < k_maxLegendLength; i++) {
buffer[numberOfChar++] = ' ';
}
buffer[k_maxLegendLength] = 0;
numberOfChar = PoincareHelpers::ConvertFloatToText<double>(x, buffer, bufferSize, Constant::MediumNumberOfSignificantDigits);
// Padding
Shared::TextHelpers::PadWithSpaces(buffer, bufferSize, &numberOfChar, k_maxLegendLength);
m_bannerView.abscissaValue()->setText(buffer);
// Set "y=..." or "ymean=..."
@@ -151,11 +148,9 @@ void GraphController::reloadBannerView() {
y = m_store->meanOfColumn(*m_selectedSeriesIndex, 1);
}
numberOfChar += strlcpy(buffer, legend, bufferSize);
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(y, buffer+numberOfChar, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits);
for (int i = numberOfChar; i < k_maxLegendLength; i++) {
buffer[numberOfChar++] = ' ';
}
buffer[k_maxLegendLength] = 0;
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(y, buffer + numberOfChar, bufferSize - numberOfChar, Constant::MediumNumberOfSignificantDigits);
// Padding
Shared::TextHelpers::PadWithSpaces(buffer, bufferSize, &numberOfChar, k_maxLegendLength);
m_bannerView.ordinateView()->setText(buffer);
// Set formula
@@ -176,10 +171,8 @@ void GraphController::reloadBannerView() {
// Force the "Data not suitable" message to be on the next line
int numberOfCharToCompleteLine = maxInt(Ion::Display::Width / BannerView::Font()->glyphSize().width() - strlen(I18n::translate(formula)), 0);
numberOfChar = 0;
for (int i = 0; i < numberOfCharToCompleteLine-1; i++) {
buffer[numberOfChar++] = ' ';
}
buffer[numberOfChar] = 0;
// Padding
Shared::TextHelpers::PadWithSpaces(buffer, bufferSize, &numberOfChar, numberOfCharToCompleteLine - 1);
m_bannerView.subTextAtIndex(0)->setText(buffer);
const char * dataNotSuitableMessage = I18n::translate(I18n::Message::DataNotSuitableForRegression);
@@ -195,8 +188,7 @@ void GraphController::reloadBannerView() {
char leg[] = {' ', coefficientName, '=', 0};
legend = leg;
numberOfChar += strlcpy(buffer, legend, bufferSize);
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(coefficients[i], buffer+numberOfChar, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
buffer[k_maxLegendLength] = 0;
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(coefficients[i], buffer + numberOfChar, bufferSize - numberOfChar, Constant::LargeNumberOfSignificantDigits);
m_bannerView.subTextAtIndex(i)->setText(buffer);
coefficientName++;
}
@@ -207,8 +199,7 @@ void GraphController::reloadBannerView() {
legend = " r=";
double r = m_store->correlationCoefficient(*m_selectedSeriesIndex);
numberOfChar += strlcpy(buffer, legend, bufferSize);
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(r, buffer+numberOfChar, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
buffer[k_maxLegendLength+10] = 0;
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(r, buffer + numberOfChar, bufferSize - numberOfChar, Constant::LargeNumberOfSignificantDigits);
m_bannerView.subTextAtIndex(2)->setText(buffer);
// Set "r2=..."
@@ -216,8 +207,7 @@ void GraphController::reloadBannerView() {
legend = " r2=";
double r2 = m_store->squaredCorrelationCoefficient(*m_selectedSeriesIndex);
numberOfChar += strlcpy(buffer, legend, bufferSize);
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(r2, buffer+numberOfChar, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
buffer[k_maxLegendLength] = 0;
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(r2, buffer + numberOfChar, bufferSize - numberOfChar, Constant::LargeNumberOfSignificantDigits);
m_bannerView.subTextAtIndex(3)->setText(buffer);
// Clean the last subview

View File

@@ -65,6 +65,7 @@ app_src += $(addprefix apps/shared/,\
text_field_delegate.cpp \
text_field_delegate_app.cpp \
text_field_with_extension.cpp \
text_helpers.cpp \
toolbox_helpers.cpp \
values_controller.cpp \
values_function_parameter_controller.cpp \

View File

@@ -0,0 +1,25 @@
#include "text_helpers.h"
#include <ion/unicode/utf8_decoder.h>
#include <ion/unicode/utf8_helper.h>
#include <assert.h>
namespace Shared {
namespace TextHelpers {
void PadWithSpaces(char * buffer, int bufferSize, int * currentNumberOfChar, int maxGlyphLengthWithPadding) {
assert(*currentNumberOfChar <= bufferSize);
size_t currentGlyphLength = UTF8Helper::StringGlyphLength(buffer, *currentNumberOfChar);
bool addedPadding = false;
assert(UTF8Decoder::CharSizeOfCodePoint(' ') == 1);
while (currentGlyphLength < maxGlyphLengthWithPadding && *currentNumberOfChar < bufferSize) {
*currentNumberOfChar = *currentNumberOfChar + UTF8Decoder::CodePointToChars(' ', buffer + *currentNumberOfChar, bufferSize - *currentNumberOfChar);
addedPadding = true;
currentGlyphLength++;
}
if (addedPadding) {
buffer[*currentNumberOfChar-1] = 0;
}
}
}
}

View File

@@ -0,0 +1,12 @@
#ifndef SHARED_TEXT_HELPERS_H
#define SHARED_TEXT_HELPERS_H
namespace Shared {
namespace TextHelpers {
void PadWithSpaces(char * buffer, int bufferSize, int * currentNumberOfChar, int maxGlyphLengthWithPadding);
}
}
#endif

View File

@@ -1,6 +1,7 @@
#include "histogram_controller.h"
#include "../apps_container.h"
#include "../shared/poincare_helpers.h"
#include "../shared/text_helpers.h"
#include "app.h"
#include <cmath>
#include <assert.h>
@@ -90,20 +91,6 @@ Responder * HistogramController::tabController() const {
return (parentResponder()->parentResponder()->parentResponder()->parentResponder());
}
void pad(char * buffer, int bufferSize, int * currentNumberOfChar, int maxGlyphLengthWithPadding) {
assert(*currentNumberOfChar <= bufferSize);
size_t currentGlyphLength = UTF8Helper::StringGlyphLength(buffer, *currentNumberOfChar);
bool addedPadding = false;
while (currentGlyphLength < maxGlyphLengthWithPadding && *currentNumberOfChar < bufferSize) {
*currentNumberOfChar = *currentNumberOfChar + UTF8Decoder::CodePointToChars(' ', buffer + *currentNumberOfChar, bufferSize - *currentNumberOfChar);
addedPadding = true;
currentGlyphLength++;
}
if (addedPadding) {
buffer[*currentNumberOfChar-1] = 0;
}
}
void HistogramController::reloadBannerView() {
if (selectedSeriesIndex() < 0) {
return;
@@ -134,7 +121,7 @@ void HistogramController::reloadBannerView() {
numberOfChar+= UTF8Decoder::CodePointToChars('[', buffer + numberOfChar, bufferSize - numberOfChar);
// Padding
pad(buffer, bufferSize, &numberOfChar, k_maxIntervalLegendLength);
Shared::TextHelpers::PadWithSpaces(buffer, bufferSize, &numberOfChar, k_maxIntervalLegendLength);
m_view.bannerView()->intervalView()->setText(buffer);
// Add Size Data
@@ -149,7 +136,7 @@ void HistogramController::reloadBannerView() {
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(size, buffer+numberOfChar, bufferSize-numberOfChar, Constant::LargeNumberOfSignificantDigits);
}
// Padding
pad(buffer, bufferSize, &numberOfChar, k_maxLegendLength);
Shared::TextHelpers::PadWithSpaces(buffer, bufferSize, &numberOfChar, k_maxLegendLength);
m_view.bannerView()->sizeView()->setText(buffer);
// Add Frequency Data
@@ -163,7 +150,7 @@ void HistogramController::reloadBannerView() {
numberOfChar += PoincareHelpers::ConvertFloatToText<double>(frequency, buffer+numberOfChar, bufferSize - numberOfChar, Constant::LargeNumberOfSignificantDigits);
}
// Padding
pad(buffer, bufferSize, &numberOfChar, k_maxLegendLength);
Shared::TextHelpers::PadWithSpaces(buffer, bufferSize, &numberOfChar, k_maxLegendLength);
m_view.bannerView()->frequencyView()->setText(buffer);
m_view.bannerView()->reload();

View File

@@ -287,25 +287,37 @@ void LayoutField::insertLayoutAtCursor(Layout layoutR, Poincare::Expression corr
cursor->showEmptyLayoutIfNeeded();
bool layoutWillBeMerged = layoutR.type() == LayoutNode::Type::HorizontalLayout;
Layout lastMergedLayoutChild = layoutWillBeMerged ? layoutR.childAtIndex(layoutR.numberOfChildren()-1) : Layout();
// Find the layout where the cursor will point
assert(!correspondingExpression.isUninitialized());
Layout cursorLayout = forceCursorRightOfLayout ? layoutR : layoutR.layoutToPointWhenInserting(&correspondingExpression);
assert(!cursorLayout.isUninitialized());
Layout lastMergedLayoutChild = (layoutWillBeMerged && layoutR.numberOfChildren() > 0) ? layoutR.childAtIndex(layoutR.numberOfChildren()-1) : Layout();
// Add the layout. This puts the cursor at the right of the added layout
cursor->addLayoutAndMoveCursor(layoutR);
/* Move the cursor if needed.
* If the layout to point to has been merged, it means that only its children
* have been inserted in the layout, so we must not move the cursor to the
* parent. In this case, addLayoutAndMoveCursor made the cursor point to the
* last merged child, which is what is wanted.
* For other cases, move the cursor to the computed layout. */
if (!(layoutWillBeMerged && cursorLayout == layoutR)) {
cursor->setLayout(cursorLayout);
cursor->setPosition(LayoutCursor::Position::Right);
*
* If forceCursorRightOfLayout is true, there is no need to move the cursor
* because it already points to the right of the added layout.
*
* If the layout to point to has been merged, only its children have been
* inserted in the layout, so we must not move the cursor to the parent.
* addLayoutAndMoveCursor made the cursor point to the last merged child,
* which is what is wanted.
*
* For other cases, move the cursor to the layout indicated by
* layoutToPointWhenInserting. This pointed layout cannot be computed before
* adding layoutR, because addLayoutAndMoveCursor might have changed layoutR's
* children.
* For instance, if we add an absolute value with an empty child left of a 0,
* the empty child is deleted and the 0 is collapsed into the absolute value.
* Sketch of the situation, ' being the cursor:
* Initial layout: '0
* "abs(x)" pressed in the toolbox => |•| is added, • being an empty layout
* Final layout: |0'|
* */
if (!forceCursorRightOfLayout && !layoutWillBeMerged) {
assert(!correspondingExpression.isUninitialized());
m_contentView.cursor()->setLayout(layoutR.layoutToPointWhenInserting(&correspondingExpression));
m_contentView.cursor()->setPosition(LayoutCursor::Position::Right);
}
// Handle matrices

View File

@@ -340,13 +340,16 @@ size_t StringGlyphLength(const char * s, int maxSize) {
return 0;
}
UTF8Decoder decoder(s);
CodePoint codePoint = decoder.nextCodePoint();
CodePoint codePoint = 0;
size_t glyphIndex = 0;
while (codePoint != UCodePointNull && (maxSize < 0 || ((decoder.stringPosition() - s) <= maxSize))) {
while (maxSize < 0 || ((decoder.stringPosition() - s) < maxSize)) {
codePoint = decoder.nextCodePoint();
if (codePoint == UCodePointNull) {
break;
}
if (!codePoint.isCombining()) {
glyphIndex++;
}
codePoint = decoder.nextCodePoint();
}
return glyphIndex;
}

View File

@@ -10,5 +10,6 @@ QUIZ_CASE(ion_utf8_helper_glyph_length) {
assert_string_glyph_length_is("1ᴇ3", -1, 3);
assert_string_glyph_length_is("∑∫𝐢", -1, 3);
assert_string_glyph_length_is("123", 2, 2);
assert_string_glyph_length_is("1ᴇ3", 2, 1);
uint8_t testString[] = {'a', 'b', 'c', 0b11111111, 0b11111111, 0}; // Malformed utf-8 string
assert_string_glyph_length_is((const char *)testString, 3, 3);
}