From 8cc114bf2c77566020c6cf78ca6aa1e1e70550ba Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 27 Jan 2021 23:51:03 +0100 Subject: [PATCH] [libcalamares] Move smart-string-truncation to library Expand the API a little to support first-lines, last-lines, and something of both. Use strong types to make the names clear for each. --- src/libcalamares/utils/String.cpp | 49 ++++++++++++++++++++++++++++++ src/libcalamares/utils/String.h | 30 ++++++++++++++++++ src/libcalamaresui/ViewManager.cpp | 38 ++--------------------- 3 files changed, 81 insertions(+), 36 deletions(-) diff --git a/src/libcalamares/utils/String.cpp b/src/libcalamares/utils/String.cpp index 34a7038e3..e2409d3c0 100644 --- a/src/libcalamares/utils/String.cpp +++ b/src/libcalamares/utils/String.cpp @@ -121,4 +121,53 @@ obscure( const QString& string ) return result; } + +QString +truncateMultiLine( const QString& string, CalamaresUtils::LinesStartEnd lines, CalamaresUtils::CharCount chars ) +{ + const int maxLines = lines.atStart + lines.atEnd; + if ( ( string.length() <= chars.total ) && ( string.count( '\n' ) <= maxLines ) ) + { + return string; + } + + QString shorter = string.simplified(); + QString front, back; + if ( shorter.count( '\n' ) >= maxLines ) + { + int from = -1; + for ( int i = 0; i < lines.atStart; ++i ) + { + from = shorter.indexOf( '\n', from + 1 ); + if ( from < 0 ) + { + // That's strange, we counted at least maxLines newlines before + break; + } + } + if ( from > 0 ) + { + front = shorter.left( from ); + } + + int lastNewLine = -1; + int lastCount = 0; + for ( auto i = shorter.rbegin(); i != shorter.rend() && lastCount < lines.atEnd; ++i ) + { + if ( *i == '\n' ) + { + ++lastCount; + lastNewLine = shorter.length() - int( i - shorter.rbegin() ); + } + } + if ( ( lastNewLine >= 0 ) && ( lastCount >= lines.atEnd ) ) + { + back = shorter.right( lastNewLine ); + } + } + + return front + back; +} + + } // namespace CalamaresUtils diff --git a/src/libcalamares/utils/String.h b/src/libcalamares/utils/String.h index 48bb17aac..405c6caad 100644 --- a/src/libcalamares/utils/String.h +++ b/src/libcalamares/utils/String.h @@ -61,6 +61,36 @@ DLLEXPORT QString removeDiacritics( const QString& string ); * @return the obfuscated string. */ DLLEXPORT QString obscure( const QString& string ); + +struct LinesStartEnd +{ + int atStart; + int atEnd; +}; + +struct CharCount +{ + int total; +}; + +/** @brief Truncate a string to some reasonable length for display + * + * Keep the first few, or last few (or both) lines of a possibly lengthy + * message @p string and reduce it to a displayable size (e.g. for + * pop-up windows that display the message). If the message is longer + * than @p chars, then characters are removed from the front (if + * @p lines.atStart is zero) or end (if @p lines.atEnd is zero) or in the middle + * (if both are nonzero). + * + * @param string the input string. + * @param lines number of lines to preserve. + * @param chars maximum number of characters in the returned string. + * @return a string built from parts of the input string. + */ +DLLEXPORT QString truncateMultiLine( const QString& string, + LinesStartEnd lines = LinesStartEnd { 3, 5 }, + CharCount chars = CharCount { 812 } ); + } // namespace CalamaresUtils #endif diff --git a/src/libcalamaresui/ViewManager.cpp b/src/libcalamaresui/ViewManager.cpp index a34c55741..aaa55059e 100644 --- a/src/libcalamaresui/ViewManager.cpp +++ b/src/libcalamaresui/ViewManager.cpp @@ -19,6 +19,7 @@ #include "utils/Logger.h" #include "utils/Paste.h" #include "utils/Retranslator.h" +#include "utils/String.h" #include "viewpages/BlankViewStep.h" #include "viewpages/ExecutionViewStep.h" #include "viewpages/ViewStep.h" @@ -136,41 +137,6 @@ ViewManager::insertViewStep( int before, ViewStep* step ) emit endInsertRows(); } -/** Makes a long details message suitable for display - * - * @returns a (possibly shortened) version of @p text that - * will fit sensibly in a messagebox. - */ -static QString -simplifyText( const QString& text ) -{ - constexpr const int maxLines = 8; - constexpr const int maxChars = 640; - QString shorter = text.simplified(); - if ( shorter.count( '\n' ) >= maxLines ) - { - int from = -1; - for ( int i = 0; i < maxLines; ++i ) - { - from = shorter.indexOf( '\n', from + 1 ); - if ( from < 0 ) - { - // That's odd, we counted at least maxLines newlines before - break; - } - } - if ( from > 0 ) - { - shorter.truncate( from ); - } - } - if ( shorter.length() > maxChars ) - { - shorter.truncate( maxChars ); - } - return shorter; -} - void ViewManager::onInstallationFailed( const QString& message, const QString& details ) { @@ -186,7 +152,7 @@ ViewManager::onInstallationFailed( const QString& message, const QString& detail QString text = "

" + message + "

"; if ( !details.isEmpty() ) { - text += "

" + simplifyText( details ) + "

"; + text += "

" + CalamaresUtils::truncateMultiLine( details, CalamaresUtils::LinesStartEnd{8, 0}) + "

"; } if ( shouldOfferWebPaste ) {