static std::string splitString(const std::string & text, const int maxwidth, LcdFont *font, bool dumb, bool utf8) { int width, pos; std::string tmp = removeLeadingSpaces(text); if (font->getRenderWidth(tmp.c_str(), utf8) > maxwidth) { do { if (dumb) { do { tmp = tmp.substr(0, tmp.length()-1); width = font->getRenderWidth(tmp.c_str(), utf8); } while (utf8 && font->getRenderWidth(tmp.substr(0, tmp.length()-1).c_str(), true) == width); // cut an UTF-8 character completely } else { pos = tmp.find_last_of("[ .-]+"); if (pos != -1) { tmp = tmp.substr(0, pos); width = font->getRenderWidth(tmp.c_str(), utf8); } else // does not fit -> fall back to dumb split { do { tmp = tmp.substr(0, tmp.length()-1); width = font->getRenderWidth(tmp.c_str(), utf8); } while (utf8 && font->getRenderWidth(tmp.substr(0, tmp.length()-1).c_str(), true) == width); // cut an UTF-8 character completely } } } while (width > maxwidth); } return tmp; }
/*! * \brief ModelicaEditor::setPlainText * Reimplementation of QPlainTextEdit::setPlainText method. * Makes sure we dont update if the passed text is same. * \param text the string to set. */ void ModelicaEditor::setPlainText(const QString &text) { QMap<int, int> leadingSpacesMap; QString contents = text; // store and remove leading spaces if (mpModelWidget->getLibraryTreeItem()->isInPackageOneFile()) { leadingSpacesMap = StringHandler::getLeadingSpaces(contents); contents = removeLeadingSpaces(contents); } // Only set the text when it is really new if (contents != mpPlainTextEdit->toPlainText()) { mForceSetPlainText = true; if (mpModelWidget->getLibraryTreeItem()->isInPackageOneFile()) { mpPlainTextEdit->setPlainText(contents); storeLeadingSpaces(leadingSpacesMap); } else { mpPlainTextEdit->setPlainText(contents); } mForceSetPlainText = false; mLastValidText = contents; } }
static std::string splitString(const std::string & text, const int maxwidth, LcdFont *font, bool dumb, bool utf8) { int pos; std::string tmp = removeLeadingSpaces(text); if (font->getRenderWidth(tmp.c_str(), utf8) > maxwidth) { do { if (dumb) tmp = tmp.substr(0, tmp.length()-1); else { pos = tmp.find_last_of("[ .-]+"); // TODO characters might be UTF-encoded! if (pos != -1) tmp = tmp.substr(0, pos); else // does not fit -> fall back to dumb split tmp = tmp.substr(0, tmp.length()-1); } } while (font->getRenderWidth(tmp.c_str(), utf8) > maxwidth); } return tmp; }
/* display "big" and "small" text. TODO: right now, "big" is hardcoded as utf-8, small is not (for EPG) */ void CLCD::showTextScreen(const std::string & big, const std::string & small, const int showmode, const bool perform_wakeup) { /* the "showmode" variable is a bit map: EPG_NAME show "big" string EPG_SHORT show only one line of "big" string EPG_TITLE show "small" string EPG_SEPLINE show separator line if big and small are present / shown */ /* draw_fill_rect is braindead: it actually fills _inside_ the described rectangle, so that you have to give it one pixel additionally in every direction ;-( this is where the "-1 to 120" intead of "0 to 119" comes from */ display.draw_fill_rect(-1, 10, LCD_COLS, 51, CLCDDisplay::PIXEL_OFF); bool big_utf8 = false; bool small_utf8 = false; std::string cname[2]; std::string event[4]; int namelines = 0, eventlines = 0, maxnamelines = 2; if (showmode & EPG_SHORT) maxnamelines = 1; if ((showmode & EPG_NAME) && !big.empty()) { bool dumb = false; big_utf8 = isUTF8(big); while (true) { namelines = 0; std::string title = big; do { // first try "intelligent" splitting cname[namelines] = splitString(title, LCD_COLS, fonts.channelname, dumb, big_utf8); title = removeLeadingSpaces(title.substr(cname[namelines].length())); namelines++; } while (!title.empty() && namelines < maxnamelines); if (title.empty()) break; dumb = !dumb; // retry with dumb splitting; if (!dumb) // second retry -> get out; break; } } // one nameline => 2 eventlines, 2 namelines => 1 eventline int maxeventlines = 4 - (namelines * 3 + 1) / 2; if ((showmode & EPG_TITLE) && !small.empty()) { bool dumb = false; small_utf8 = isUTF8(small); while (true) { eventlines = 0; std::string title = small; do { // first try "intelligent" splitting event[eventlines] = splitString(title, LCD_COLS, fonts.menu, dumb, small_utf8); title = removeLeadingSpaces(title.substr(event[eventlines].length())); /* DrDish TV appends a 0x0a to the EPG title. We could strip it in sectionsd... ...instead, strip all control characters at the end of the text for now */ if (!event[eventlines].empty() && event[eventlines].at(event[eventlines].length() - 1) < ' ') event[eventlines].erase(event[eventlines].length() - 1); eventlines++; } while (!title.empty() && eventlines < maxeventlines); if (title.empty()) break; dumb = !dumb; // retry with dumb splitting; if (!dumb) // second retry -> get out; break; } } /* this values were determined empirically */ int y = 8 + (41 - namelines*14 - eventlines*10)/2; int x = 1; for (int i = 0; i < namelines; i++) { y += 14; if (g_settings.lcd_setting[SNeutrinoSettings::LCD_EPGALIGN] == EPGALIGN_CENTER) { int w = fonts.channelname->getRenderWidth(cname[i].c_str(), big_utf8); x = (LCD_COLS - w) / 2; } fonts.channelname->RenderString(x, y, LCD_COLS + 10, cname[i].c_str(), CLCDDisplay::PIXEL_ON, 0, big_utf8); } y++; if (eventlines > 0 && namelines > 0 && (showmode & EPG_SEPLINE)) { y++; display.draw_line(0, y, LCD_COLS - 1, y, CLCDDisplay::PIXEL_ON); } if (eventlines > 0) { for (int i = 0; i < eventlines; i++) { y += 10; if (g_settings.lcd_setting[SNeutrinoSettings::LCD_EPGALIGN] == EPGALIGN_CENTER) { int w = fonts.menu->getRenderWidth(event[i].c_str(), small_utf8); x = (LCD_COLS - w) / 2; } fonts.menu->RenderString(x, y, LCD_COLS + 10, event[i].c_str(), CLCDDisplay::PIXEL_ON, 0, small_utf8); } } if (perform_wakeup) wake_up(); displayUpdate(); }
String& String::trim () { removeTrailingSpaces (); removeLeadingSpaces (); return *this; }
/* display "big" and "small" text. TODO: right now, "big" is hardcoded as utf-8, small is not (for EPG) */ void CLCD::showTextScreen(const std::string & big, const std::string & small, const int showmode, const bool perform_wakeup, const bool centered) { /* the "showmode" variable is a bit map: 0x01 show "big" string 0x02 show "small" string 0x04 show separator line if big and small are present / shown 0x08 show only one line of "big" string */ /* draw_fill_rect is braindead: it actually fills _inside_ the described rectangle, so that you have to give it one pixel additionally in every direction ;-( this is where the "-1 to 120" intead of "0 to 119" comes from */ display.draw_fill_rect(-1, 10, 120, 51, CLCDDisplay::PIXEL_OFF); std::string cname[2]; std::string event[4]; int namelines = 0, eventlines = 0, maxnamelines = 2; if (showmode & 8) maxnamelines = 1; if ((showmode & 1) && !big.empty()) { bool dumb = false; while (true) { namelines = 0; std::string title = big; do { // first try "intelligent" splitting cname[namelines] = splitString(title, 120, fonts.channelname, dumb, true); title = removeLeadingSpaces(title.substr(cname[namelines].length())); namelines++; } while (title.length() > 0 && namelines < maxnamelines); if (title.length() == 0) break; dumb = !dumb; // retry with dumb splitting; if (!dumb) // second retry -> get out; break; } } // one nameline => 2 eventlines, 2 namelines => 1 eventline int maxeventlines = 4 - (namelines * 3 + 1) / 2; if ((showmode & 2) && !small.empty()) { bool dumb = false; while (true) { eventlines = 0; std::string title = small; do { // first try "intelligent" splitting event[eventlines] = splitString(title, 120, fonts.menu, dumb, false); title = removeLeadingSpaces(title.substr(event[eventlines].length())); eventlines++; } while (title.length() >0 && eventlines < maxeventlines); if (title.length() == 0) break; dumb = !dumb; // retry with dumb splitting; if (!dumb) // second retry -> get out; break; } } /* this values were determined empirically */ int y = 8 + (41 - namelines*14 - eventlines*10)/2; int x = 1; for (int i = 0; i < namelines; i++) { y += 14; if (centered) { int w = fonts.channelname->getRenderWidth(cname[i].c_str(), true); x = 60 - (w / 2); } fonts.channelname->RenderString(x, y, 130, cname[i].c_str(), CLCDDisplay::PIXEL_ON, 0, true); // UTF-8 } y++; if (eventlines > 0 && namelines > 0 && showmode & 4) { y++; display.draw_line(0, y, 119, y, CLCDDisplay::PIXEL_ON); } if (eventlines > 0) { for (int i = 0; i < eventlines; i++) { y += 10; if (centered) { int w = fonts.menu->getRenderWidth(event[i].c_str(), false); x = 60 - (w / 2); } fonts.menu->RenderString(x, y, 130, event[i].c_str(), CLCDDisplay::PIXEL_ON, 0,false); // UTF-8 } } if (perform_wakeup) wake_up(); displayUpdate(); }