File indexing completed on 2025-02-02 04:11:27
0001 /* 0002 * SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best> 0003 * 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 */ 0006 0007 #include "external_font_widget.hpp" 0008 #include "ui_external_font_widget.h" 0009 0010 #include <QEvent> 0011 #include <QStandardItemModel> 0012 #include <QFileDialog> 0013 0014 #include "widgets/font/font_loader.hpp" 0015 #include "font_delegate.hpp" 0016 0017 class glaxnimate::gui::font::ExternalFontWidget::Private 0018 { 0019 public: 0020 Ui::ExternalFontWidget ui; 0021 FontLoader loader; 0022 std::map<QString, std::vector<model::CustomFont>> fonts; 0023 QStandardItemModel font_model; 0024 QUrl url; 0025 ExternalFontWidget* parent; 0026 QFont current_font; 0027 FontDelegate delegate; 0028 0029 static bool style_lte(const model::CustomFont& a, const model::CustomFont& b) 0030 { 0031 return a.raw_font().weight() < b.raw_font().weight() || ( 0032 a.raw_font().weight() == b.raw_font().weight() && 0033 a.raw_font().style() < b.raw_font().style() 0034 ); 0035 } 0036 0037 void set_active_font(const QString& family) 0038 { 0039 ui.view_style->clear(); 0040 0041 for ( const auto& style : fonts.at(family) ) 0042 { 0043 auto item = new QListWidgetItem(style.raw_font().styleName()); 0044 ui.view_style->addItem(item); 0045 } 0046 0047 current_font.setFamily(family); 0048 ui.view_style->setCurrentRow(0); 0049 } 0050 0051 void loader_finished() 0052 { 0053 for ( const auto& font : loader.fonts() ) 0054 fonts[font.family()].push_back(font); 0055 0056 loader.clear(); 0057 ui.progress_bar->setVisible(false); 0058 0059 if ( !fonts.empty() ) 0060 { 0061 ui.widget_data->setEnabled(true); 0062 0063 for ( auto& p : fonts ) 0064 { 0065 font_model.appendRow(new QStandardItem(p.first)); 0066 std::sort(p.second.begin(), p.second.end(), &style_lte); 0067 } 0068 0069 ui.view_fonts->setCurrentIndex(font_model.index(0, 0)); 0070 } 0071 } 0072 0073 void style_selected(const QString& style) 0074 { 0075 current_font.setStyleName(style); 0076 Q_EMIT parent->font_changed(current_font); 0077 } 0078 }; 0079 0080 glaxnimate::gui::font::ExternalFontWidget::ExternalFontWidget(QWidget* parent) 0081 : QWidget(parent), d(std::make_unique<Private>()) 0082 { 0083 d->parent = this; 0084 d->ui.setupUi(this); 0085 d->ui.view_fonts->setModel(&d->font_model); 0086 d->ui.view_fonts->setItemDelegateForColumn(0, &d->delegate); 0087 connect(&d->loader, &FontLoader::finished, this, [this]{d->loader_finished();}); 0088 connect(&d->loader, &FontLoader::fonts_queued, d->ui.progress_bar, &QProgressBar::setMaximum); 0089 connect(&d->loader, &FontLoader::fonts_loaded, d->ui.progress_bar, &QProgressBar::setValue); 0090 /// \todo handle FontLoader::error 0091 connect(d->ui.view_style->selectionModel(), &QItemSelectionModel::currentChanged, this, [this](const QModelIndex& index){ 0092 d->style_selected(index.data().toString()); 0093 }); 0094 connect(d->ui.size_widget, &FontSizeWidget::font_size_changed, this, [this](double size){ 0095 d->current_font.setPointSizeF(size); 0096 Q_EMIT font_changed(d->current_font); 0097 }); 0098 connect(d->ui.view_fonts->selectionModel(), &QItemSelectionModel::currentChanged, this, [this](const QModelIndex& index){ 0099 d->set_active_font(index.data().toString()); 0100 }); 0101 } 0102 0103 glaxnimate::gui::font::ExternalFontWidget::~ExternalFontWidget() = default; 0104 0105 void glaxnimate::gui::font::ExternalFontWidget::changeEvent ( QEvent* e ) 0106 { 0107 QWidget::changeEvent(e); 0108 0109 if ( e->type() == QEvent::LanguageChange) 0110 { 0111 d->ui.retranslateUi(this); 0112 } 0113 } 0114 0115 void glaxnimate::gui::font::ExternalFontWidget::load_url() 0116 { 0117 if ( d->url.scheme() == "" ) 0118 { 0119 d->url = QUrl::fromLocalFile(d->ui.edit_url->text()); 0120 d->ui.edit_url->setText(d->url.toString()); 0121 } 0122 0123 d->loader.cancel(); 0124 0125 d->loader.queue("", d->url); 0126 d->ui.progress_bar->setVisible(true); 0127 d->font_model.clear(); 0128 d->ui.widget_data->setEnabled(false); 0129 d->ui.view_style->clear(); 0130 0131 d->loader.load_queue(); 0132 } 0133 0134 void glaxnimate::gui::font::ExternalFontWidget::url_from_file() 0135 { 0136 QString path = QFileDialog::getOpenFileName(this, i18n("Open File"), {}, 0137 i18n("All supported files (*.ttf, *.otf, *.css); CSS files (*.css); Font files (*.ttf, *.otf); All files (*)") 0138 ); 0139 0140 if ( !path.isEmpty() ) 0141 { 0142 d->url = QUrl::fromLocalFile(path); 0143 d->ui.edit_url->setText(d->url.toString()); 0144 load_url(); 0145 } 0146 } 0147 0148 void glaxnimate::gui::font::ExternalFontWidget::url_changed(const QString& url) 0149 { 0150 d->url = QUrl(url); 0151 d->ui.button_load->setEnabled(d->url.isValid()); 0152 } 0153 0154 glaxnimate::model::CustomFont glaxnimate::gui::font::ExternalFontWidget::custom_font() const 0155 { 0156 if ( !d->ui.widget_data->isEnabled() ) 0157 return {}; 0158 0159 auto font_iter = d->fonts.find(d->ui.view_fonts->currentIndex().data().toString()); 0160 if ( font_iter == d->fonts.end() ) 0161 return {}; 0162 0163 int style_index = d->ui.view_style->currentRow(); 0164 if ( style_index < 0 || style_index >= int(font_iter->second.size()) ) 0165 return {}; 0166 0167 return font_iter->second[style_index]; 0168 } 0169 0170 void glaxnimate::gui::font::ExternalFontWidget::set_font_size(double size) 0171 { 0172 d->ui.size_widget->set_font_size(size); 0173 } 0174 0175 const QFont & glaxnimate::gui::font::ExternalFontWidget::selected_font() const 0176 { 0177 return d->current_font; 0178 } 0179 0180 0181 void glaxnimate::gui::font::ExternalFontWidget::showEvent(QShowEvent* event) 0182 { 0183 QWidget::showEvent(event); 0184 d->ui.progress_bar->setVisible(d->loader.loading()); 0185 }