File indexing completed on 2024-05-05 10:03:35
0001 /* 0002 SPDX-FileCopyrightText: 2011-2012 Ni Hui <shuizhuyuanluo@126.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 #include "pocreator.h" 0008 0009 #include <gettext-po.h> 0010 #include <QColor> 0011 #include <QImage> 0012 #include <QLatin1String> 0013 #include <QPainter> 0014 #include <QWidget> 0015 0016 #include <KLocalizedString> 0017 #include <KPluginFactory> 0018 0019 #include "pocreatorsettings.h" 0020 #include "ui_pocreatorform.h" 0021 0022 K_PLUGIN_CLASS_WITH_JSON(PoCreator, "pothumbnail.json") 0023 0024 static bool readerror = false; 0025 0026 static void xerror( int severity, 0027 po_message_t /*message*/, 0028 const char */*filename*/, size_t /*lineno*/, size_t /*column*/, 0029 int /*multiline_p*/, const char */*message_text*/ ) 0030 { 0031 if ( severity == PO_SEVERITY_ERROR || severity == PO_SEVERITY_FATAL_ERROR ) 0032 readerror = true; 0033 } 0034 0035 static void xerror2( int severity, 0036 po_message_t /*message1*/, 0037 const char */*filename1*/, size_t /*lineno1*/, size_t /*column1*/, 0038 int /*multiline_p1*/, const char */*message_text1*/, 0039 po_message_t /*message2*/, 0040 const char */*filename2*/, size_t /*lineno2*/, size_t /*column2*/, 0041 int /*multiline_p2*/, const char */*message_text2*/ ) 0042 { 0043 if ( severity == PO_SEVERITY_ERROR || severity == PO_SEVERITY_FATAL_ERROR ) 0044 readerror = true; 0045 } 0046 0047 static bool get_po_info( const char* filepath, int& translate, int& untranslate, int& fuzzy, int& obsolete ) 0048 { 0049 po_file_t pofile; 0050 const struct po_xerror_handler handler = { xerror, xerror2 }; 0051 0052 pofile = po_file_read( filepath, &handler ); 0053 if ( pofile == NULL || readerror ) 0054 return false; 0055 0056 po_message_iterator_t it; 0057 it = po_message_iterator( pofile, NULL ); 0058 po_message_t msg; 0059 const char* msgstr; 0060 while ( ( msg = po_next_message( it ) ) != NULL ) { 0061 if ( po_message_is_obsolete( msg ) ) 0062 ++obsolete; 0063 else if ( po_message_is_fuzzy( msg ) ) 0064 ++fuzzy; 0065 else { 0066 msgstr = po_message_msgstr( msg ); 0067 if ( msgstr[0] == '\0' ) 0068 ++untranslate; 0069 else 0070 ++translate; 0071 } 0072 } 0073 po_message_iterator_free( it ); 0074 0075 /// do not count domain header as translated message 0076 const char* header = po_file_domain_header( pofile, NULL ); 0077 if ( header != NULL ) 0078 --translate; 0079 0080 po_file_free( pofile ); 0081 0082 return true; 0083 } 0084 0085 PoCreator::PoCreator(QObject *parent, const QVariantList &args) 0086 : KIO::ThumbnailCreator(parent, args) 0087 { 0088 } 0089 0090 PoCreator::~PoCreator() 0091 { 0092 } 0093 0094 KIO::ThumbnailResult PoCreator::create( const KIO::ThumbnailRequest &request ) 0095 { 0096 int translate = 0; 0097 int untranslate = 0; 0098 int fuzzy = 0; 0099 int obsolete = 0; 0100 0101 if ( !get_po_info( request.url().toLocalFile().toLocal8Bit().constData(), translate, untranslate, fuzzy, obsolete ) ) 0102 return KIO::ThumbnailResult::fail(); 0103 0104 int total = translate + untranslate + fuzzy + obsolete; 0105 0106 if (total == 0) { 0107 // Treat a .po file with no strings as an invalid file 0108 return KIO::ThumbnailResult::fail(); 0109 } 0110 0111 int d = ( request.targetSize().width() < request.targetSize().height() ) ? request.targetSize().width() - 2 : request.targetSize().height() - 2; 0112 0113 QImage pix( d + 2, d + 2, QImage::Format_ARGB32_Premultiplied ); 0114 pix.fill( Qt::transparent ); /// transparent background 0115 0116 int circle = 16 * 360; 0117 int untranslateAngle = untranslate * circle / total; 0118 int fuzzyAngle = fuzzy * circle / total; 0119 int obsoleteAngle = obsolete * circle / total; 0120 int translateAngle = circle - untranslateAngle - fuzzyAngle - obsoleteAngle; 0121 0122 QPainter p( &pix ); 0123 p.setRenderHint( QPainter::Antialiasing ); 0124 0125 if ( fuzzyAngle > 0 ) { 0126 p.setBrush( PoCreatorSettings::self()->fuzzyColor() ); 0127 if ( fuzzy == total ) 0128 p.drawEllipse( 1, 1, d, d ); 0129 else 0130 p.drawPie( 1, 1, d, d, 0, -fuzzyAngle ); 0131 } 0132 if ( untranslateAngle > 0 ) { 0133 p.setBrush( PoCreatorSettings::self()->untranslatedColor() ); 0134 if ( untranslate == total ) 0135 p.drawEllipse( 1, 1, d, d ); 0136 else 0137 p.drawPie( 1, 1, d, d, -fuzzyAngle, -untranslateAngle ); 0138 } 0139 if ( obsoleteAngle > 0 ) { 0140 p.setBrush( PoCreatorSettings::self()->obsoletedColor() ); 0141 if ( obsolete == total ) 0142 p.drawEllipse( 1, 1, d, d ); 0143 else 0144 p.drawPie( 1, 1, d, d, -fuzzyAngle-untranslateAngle, -obsoleteAngle ); 0145 } 0146 if ( translateAngle > 0 ) { 0147 p.setBrush( PoCreatorSettings::self()->translatedColor() ); 0148 if ( translate == total ) 0149 p.drawEllipse( 1, 1, d, d ); 0150 else 0151 p.drawPie( 1, 1, d, d, -fuzzyAngle-untranslateAngle-obsoleteAngle, -translateAngle ); 0152 } 0153 0154 return KIO::ThumbnailResult::pass(pix); 0155 } 0156 0157 #include "pocreator.moc"