mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-08-03 18:44:13 +02:00
Merge pull request #592 from DieterMayerOSS/pr/font-report
Report salvaged and unreadable font descriptions after opening a project
This commit is contained in:
@@ -45,6 +45,7 @@
|
|||||||
#include "ui/backupdialog.h"
|
#include "ui/backupdialog.h"
|
||||||
#include "ui/dialogwaiting.h"
|
#include "ui/dialogwaiting.h"
|
||||||
#include "undocommand/addelementtextcommand.h"
|
#include "undocommand/addelementtextcommand.h"
|
||||||
|
#include "utils/qetutils.h"
|
||||||
#include "undocommand/rotateselectioncommand.h"
|
#include "undocommand/rotateselectioncommand.h"
|
||||||
#include "undocommand/rotatetextscommand.h"
|
#include "undocommand/rotatetextscommand.h"
|
||||||
#include "diagram.h"
|
#include "diagram.h"
|
||||||
@@ -1184,6 +1185,13 @@ bool QETDiagramEditor::openAndAddProject(
|
|||||||
//Create the project
|
//Create the project
|
||||||
DialogWaiting::instance(this);
|
DialogWaiting::instance(this);
|
||||||
|
|
||||||
|
//Per-project window for the font counters reported below; the folios
|
||||||
|
//(and with them the stored font descriptions) are built between here
|
||||||
|
//and the end of addProject(). RAII, because DialogWaiting pumps the
|
||||||
|
//event loop during the load: a nested openAndAddProject() gets its
|
||||||
|
//own window and this one resumes unharmed.
|
||||||
|
QETUtils::FontRestorationScope font_scope;
|
||||||
|
|
||||||
QETProject *project = new QETProject(filepath);
|
QETProject *project = new QETProject(filepath);
|
||||||
if (project -> state() != QETProject::Ok)
|
if (project -> state() != QETProject::Ok)
|
||||||
{
|
{
|
||||||
@@ -1210,6 +1218,42 @@ bool QETDiagramEditor::openAndAddProject(
|
|||||||
addProject(project);
|
addProject(project);
|
||||||
DialogWaiting::dropInstance();
|
DialogWaiting::dropInstance();
|
||||||
|
|
||||||
|
//Report font descriptions which could not be read as-is (written by
|
||||||
|
//an incompatible Qt version or corrupted), so the user learns about
|
||||||
|
//it from somewhere else than the console. See issue #553.
|
||||||
|
const int salvaged_fonts = font_scope.salvaged();
|
||||||
|
const int unreadable_fonts = font_scope.unreadable();
|
||||||
|
if (salvaged_fonts || unreadable_fonts)
|
||||||
|
{
|
||||||
|
qInfo().nospace() << "Project font descriptions: "
|
||||||
|
<< salvaged_fonts << " salvaged from a foreign format, "
|
||||||
|
<< unreadable_fonts << " unreadable (default font applies)";
|
||||||
|
}
|
||||||
|
if (interactive && (salvaged_fonts || unreadable_fonts))
|
||||||
|
{
|
||||||
|
QStringList details;
|
||||||
|
if (salvaged_fonts) {
|
||||||
|
details << tr("%n description(s) de police écrite(s) dans un "
|
||||||
|
"format étranger ou corrompu ont été restaurée(s). "
|
||||||
|
"Elles seront réécrites dans un format stable au "
|
||||||
|
"prochain enregistrement du projet.",
|
||||||
|
"message box content",
|
||||||
|
salvaged_fonts);
|
||||||
|
}
|
||||||
|
if (unreadable_fonts) {
|
||||||
|
details << tr("%n description(s) de police n'ont pas pu être "
|
||||||
|
"lue(s) ; la police par défaut sera utilisée pour "
|
||||||
|
"ces textes.",
|
||||||
|
"message box content",
|
||||||
|
unreadable_fonts);
|
||||||
|
}
|
||||||
|
QET::QetMessageBox::information(
|
||||||
|
this,
|
||||||
|
tr("Polices du projet", "message box title"),
|
||||||
|
details.join("\n\n")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
BackupDialog backup_dialog(this);
|
BackupDialog backup_dialog(this);
|
||||||
if (backup_dialog.exec() == QDialog::Accepted)
|
if (backup_dialog.exec() == QDialog::Accepted)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -153,6 +153,12 @@ void QETUtils::pixelSizedFont(QFont &font)
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
/* Counters for fontFromString(), reset per project load so the editor
|
||||||
|
* can report how many stored font descriptions needed salvaging or were
|
||||||
|
* unreadable. Font parsing only happens on the main thread. */
|
||||||
|
int salvaged_font_count = 0;
|
||||||
|
int unreadable_font_count = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Legacy (Qt 5) weight <- OpenType weight, closest match,
|
* Legacy (Qt 5) weight <- OpenType weight, closest match,
|
||||||
* same table Qt uses when parsing a 10/11 field string.
|
* same table Qt uses when parsing a 10/11 field string.
|
||||||
@@ -235,6 +241,10 @@ QString QETUtils::fontToString(const QFont &font)
|
|||||||
*/
|
*/
|
||||||
bool QETUtils::fontFromString(QFont &font, const QString &description)
|
bool QETUtils::fontFromString(QFont &font, const QString &description)
|
||||||
{
|
{
|
||||||
|
if (description.trimmed().isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QFont parsed(font);
|
QFont parsed(font);
|
||||||
if (parsed.fromString(description)) {
|
if (parsed.fromString(description)) {
|
||||||
font = parsed;
|
font = parsed;
|
||||||
@@ -271,8 +281,10 @@ bool QETUtils::fontFromString(QFont &font, const QString &description)
|
|||||||
|
|
||||||
if (parsed.fromString(legacy)) {
|
if (parsed.fromString(legacy)) {
|
||||||
font = parsed;
|
font = parsed;
|
||||||
|
++salvaged_font_count;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
++unreadable_font_count;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,7 +296,50 @@ bool QETUtils::fontFromString(QFont &font, const QString &description)
|
|||||||
if (count > 11
|
if (count > 11
|
||||||
&& parsed.fromString(QStringList(l.mid(0, 11)).join(comma))) {
|
&& parsed.fromString(QStringList(l.mid(0, 11)).join(comma))) {
|
||||||
font = parsed;
|
font = parsed;
|
||||||
|
++salvaged_font_count;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
++unreadable_font_count;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief QETUtils::FontRestorationScope::FontRestorationScope
|
||||||
|
* Open a fresh counting window: the enclosing window's counts are kept
|
||||||
|
* aside and restored by the destructor, so a project load nested inside
|
||||||
|
* another one (through the event loop) reports its own numbers only.
|
||||||
|
*/
|
||||||
|
QETUtils::FontRestorationScope::FontRestorationScope() :
|
||||||
|
m_outer_salvaged(salvaged_font_count),
|
||||||
|
m_outer_unreadable(unreadable_font_count)
|
||||||
|
{
|
||||||
|
salvaged_font_count = 0;
|
||||||
|
unreadable_font_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QETUtils::FontRestorationScope::~FontRestorationScope()
|
||||||
|
{
|
||||||
|
salvaged_font_count = m_outer_salvaged;
|
||||||
|
unreadable_font_count = m_outer_unreadable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief QETUtils::FontRestorationScope::salvaged
|
||||||
|
* @return How many font descriptions fontFromString() restored from a
|
||||||
|
* foreign or corrupt format since this window was opened. Such descriptions
|
||||||
|
* are rewritten in the stable format on the next save.
|
||||||
|
*/
|
||||||
|
int QETUtils::FontRestorationScope::salvaged() const
|
||||||
|
{
|
||||||
|
return salvaged_font_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief QETUtils::FontRestorationScope::unreadable
|
||||||
|
* @return How many font descriptions fontFromString() could not restore at
|
||||||
|
* all since this window was opened (the caller's default font applies).
|
||||||
|
*/
|
||||||
|
int QETUtils::FontRestorationScope::unreadable() const
|
||||||
|
{
|
||||||
|
return unreadable_font_count;
|
||||||
|
}
|
||||||
|
|||||||
@@ -35,6 +35,29 @@ namespace QETUtils
|
|||||||
QString fontToString (const QFont &font);
|
QString fontToString (const QFont &font);
|
||||||
bool fontFromString (QFont &font, const QString &description);
|
bool fontFromString (QFont &font, const QString &description);
|
||||||
|
|
||||||
|
/**
|
||||||
|
RAII counting window for the font descriptions fontFromString()
|
||||||
|
salvages or fails to read: construction opens a fresh window, the
|
||||||
|
destructor restores the enclosing one. Windows nest strictly LIFO,
|
||||||
|
which covers project loads re-entered through the event loop
|
||||||
|
(DialogWaiting pumps it while the folios are built).
|
||||||
|
*/
|
||||||
|
class FontRestorationScope
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FontRestorationScope();
|
||||||
|
~FontRestorationScope();
|
||||||
|
FontRestorationScope(const FontRestorationScope &) = delete;
|
||||||
|
FontRestorationScope &operator=(const FontRestorationScope &) = delete;
|
||||||
|
|
||||||
|
int salvaged() const;
|
||||||
|
int unreadable() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_outer_salvaged;
|
||||||
|
int m_outer_unreadable;
|
||||||
|
};
|
||||||
|
|
||||||
bool sortBeginIntString(const QString &str_a, const QString &str_b);
|
bool sortBeginIntString(const QString &str_a, const QString &str_b);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|||||||
Reference in New Issue
Block a user