51 void save(QDesignerSettingsInterface *s,
const QString &prefix)
const;
52 void restore(
const QDesignerSettingsInterface *s,
const QString &prefix);
55 int add(
const QString &fontFile, QString *errorMessage);
57 bool remove(
int id, QString *errorMessage);
58 bool remove(
const QString &fontFile, QString *errorMessage);
59 bool removeAt(
int index, QString *errorMessage);
62 using FileNameFontIdPair =
std::pair<QString,
int>;
67 FileNameFontIdPairs m_fonts;
95 const QString key = prefix + u'/' + fontFileKeyC;
96 const QStringList fontFiles = s->value(key, QStringList()).toStringList();
99 qDebug() <<
"AppFontManager::restoring" << fontFiles.size() <<
"fonts from " << prefix;
100 if (!fontFiles.isEmpty()) {
101 QString errorMessage;
102 for (
const auto &ff : fontFiles) {
103 if (add(ff, &errorMessage) == -1)
104 qWarning(
"%s", qPrintable(errorMessage));
111 const QFileInfo inf(fontFile);
113 *errorMessage = QCoreApplication::translate(
"AppFontManager",
"'%1' is not a file.").arg(fontFile);
116 if (!inf.isReadable()) {
117 *errorMessage = QCoreApplication::translate(
"AppFontManager",
"The font file '%1' does not have read permissions.").arg(fontFile);
120 const QString fullPath = inf.absoluteFilePath();
122 for (
const auto &fnp : std::as_const(m_fonts)) {
123 if (fnp.first == fullPath) {
124 *errorMessage = QCoreApplication::translate(
"AppFontManager",
"The font file '%1' is already loaded.").arg(fontFile);
129 const int id = QFontDatabase::addApplicationFont(fullPath);
131 *errorMessage = QCoreApplication::translate(
"AppFontManager",
"The font file '%1' could not be loaded.").arg(fontFile);
136 qDebug() <<
"AppFontManager::add" << fontFile << id;
137 m_fonts.push_back(FileNameFontIdPair(fullPath, id));
143 for (qsizetype i = 0, count = m_fonts.size(); i < count; ++i)
144 if (m_fonts.at(i).second == id)
145 return removeAt(i, errorMessage);
147 *errorMessage = QCoreApplication::translate(
"AppFontManager",
"'%1' is not a valid font id.").arg(id);
153 for (qsizetype i = 0, count = m_fonts.size(); i < count; ++i)
154 if (m_fonts.at(i).first == fontFile)
155 return removeAt(i, errorMessage);
157 *errorMessage = QCoreApplication::translate(
"AppFontManager",
"There is no loaded font matching the id '%1'.").arg(fontFile);
163 Q_ASSERT(index >= 0 && index < m_fonts.size());
165 const QString fontFile = m_fonts[index].first;
166 const int id = m_fonts[index].second;
169 qDebug() <<
"AppFontManager::removeAt" << index <<
'(' << fontFile << id <<
')';
171 if (!QFontDatabase::removeApplicationFont(id)) {
172 *errorMessage = QCoreApplication::translate(
"AppFontManager",
"The font '%1' (%2) could not be unloaded.").arg(fontFile).arg(id);
175 m_fonts.removeAt(index);
212 const QFileInfo inf(fontFile);
214 QStandardItem *fileItem =
new QStandardItem(inf.completeBaseName());
215 const QString fullPath = inf.absoluteFilePath();
217 fileItem->setToolTip(fullPath);
218 fileItem->setData(id,
IdRole);
219 fileItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
222 const QStringList families = QFontDatabase::applicationFontFamilies(id);
223 for (
const auto &fam : families) {
224 QStandardItem *familyItem =
new QStandardItem(fam);
225 familyItem->setToolTip(fullPath);
226 familyItem->setFont(QFont(fam));
227 familyItem->setFlags(Qt::ItemIsEnabled);
228 fileItem->appendRow(familyItem);
242 m_view(
new QTreeView),
243 m_addButton(
new QToolButton),
244 m_removeButton(
new QToolButton),
245 m_removeAllButton(
new QToolButton),
246 m_model(
new AppFontModel(
this))
249 m_view->setModel(m_model);
250 m_view->setSelectionMode(QAbstractItemView::ExtendedSelection);
252 connect(m_view->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &AppFontWidget::selectionChanged);
254 m_addButton->setToolTip(tr(
"Add font files"));
255 m_addButton->setIcon(qdesigner_internal::createIconSet(
"plus.png"_L1));
256 connect(m_addButton, &QAbstractButton::clicked,
this, &AppFontWidget::addFiles);
258 m_removeButton->setEnabled(
false);
259 m_removeButton->setToolTip(tr(
"Remove current font file"));
260 m_removeButton->setIcon(qdesigner_internal::createIconSet(
"minus.png"_L1));
261 connect(m_removeButton, &QAbstractButton::clicked,
this, &AppFontWidget::slotRemoveFiles);
263 m_removeAllButton->setToolTip(tr(
"Remove all font files"));
264 m_removeAllButton->setIcon(qdesigner_internal::createIconSet(QIcon::ThemeIcon::EditDelete,
265 "editdelete.png"_L1));
266 connect(m_removeAllButton, &QAbstractButton::clicked,
this, &AppFontWidget::slotRemoveAll);
268 QHBoxLayout *hLayout =
new QHBoxLayout;
269 hLayout->addWidget(m_addButton);
270 hLayout->addWidget(m_removeButton);
271 hLayout->addWidget(m_removeAllButton);
272 hLayout->addItem(
new QSpacerItem(0, 0,QSizePolicy::MinimumExpanding));
274 QVBoxLayout *vLayout =
new QVBoxLayout;
275 vLayout->addWidget(m_view);
276 vLayout->addLayout(hLayout);
304 if (selectedIndexes.isEmpty())
310 rows.reserve(selectedIndexes.size());
312 QString errorMessage;
313 for (
const auto &mi : selectedIndexes) {
314 const int id = model->idAt(mi);
316 if (fmgr.remove(id, &errorMessage)) {
317 rows.append(mi.row());
319 QMessageBox::critical(dialogParent, AppFontWidget::tr(
"Error Removing Fonts"), errorMessage);
324 std::stable_sort(rows.begin(), rows.end());
325 for (qsizetype i = rows.size() - 1; i >= 0; --i)
326 model->removeRow(rows.at(i));
372 setAttribute(Qt::WA_DeleteOnClose,
true);
373 setWindowTitle(tr(
"Additional Fonts"));
375 QVBoxLayout *vl =
new QVBoxLayout;
376 vl->addWidget(m_appFontWidget);
378 QDialogButtonBox *bb =
new QDialogButtonBox(QDialogButtonBox::Close);
379 QDialog::connect(bb, &QDialogButtonBox::rejected,
this, &AppFontDialog::reject);