diff options
Diffstat (limited to 'kxkb/pixmap.cpp')
-rw-r--r-- | kxkb/pixmap.cpp | 357 |
1 files changed, 357 insertions, 0 deletions
diff --git a/kxkb/pixmap.cpp b/kxkb/pixmap.cpp new file mode 100644 index 000000000..37176b097 --- /dev/null +++ b/kxkb/pixmap.cpp @@ -0,0 +1,357 @@ +#include <qimage.h> +//#include <qbitmap.h> +#include <qfont.h> +#include <qpainter.h> +#include <qregexp.h> +#include <qdict.h> + +#include <kstandarddirs.h> +#include <klocale.h> +#include <kdebug.h> + +#include "pixmap.h" +#include "x11helper.h" +#include "kxkbconfig.h" + + +static const int FLAG_MAX_WIDTH = 21; +static const int FLAG_MAX_HEIGHT = 14; + +const QString LayoutIcon::flagTemplate("l10n/%1/flag.png"); +const QString& LayoutIcon::ERROR_CODE("error"); +LayoutIcon* LayoutIcon::instance; + + +LayoutIcon& LayoutIcon::getInstance() { + if( instance == NULL ) { + instance = new LayoutIcon(); + } + return *instance; +} + +LayoutIcon::LayoutIcon(): + m_pixmapCache(80), + m_labelFont("sans") +{ + m_labelFont.setPixelSize(10); + m_labelFont.setWeight(QFont::Bold); +} + +const QPixmap& +LayoutIcon::findPixmap(const QString& code_, bool showFlag, const QString& displayName_) +{ + QPixmap* pm = NULL; + + if( code_ == ERROR_CODE ) { + pm = m_pixmapCache[ERROR_CODE]; + if( pm == NULL ) { + pm = createErrorPixmap(); + m_pixmapCache.insert(ERROR_CODE, pm); + } + return *pm; + } + + QString displayName(displayName_); + + if( displayName.isEmpty() ) { + displayName = KxkbConfig::getDefaultDisplayName(code_); + } + if( displayName.length() > 3 ) + displayName = displayName.left(3); + + const QString pixmapKey( showFlag ? code_ + "." + displayName : displayName ); + + pm = m_pixmapCache[pixmapKey]; + if( pm ) + return *pm; + + QString flag; + if( showFlag ) { + QString countryCode = getCountryFromLayoutName( code_ ); + flag = locate("locale", flagTemplate.arg(countryCode)); + } + + if( flag.isEmpty() ) { + pm = new QPixmap(FLAG_MAX_WIDTH, FLAG_MAX_HEIGHT); + pm->fill(Qt::gray); + } + else { + pm = new QPixmap(flag); + dimPixmap( *pm ); + +#if 0 + if( pm->height() < FLAG_MAX_HEIGHT ) { + QPixmap* pix = new QPixmap(FLAG_MAX_WIDTH, FLAG_MAX_HEIGHT); + pix->fill( Qt::lightGray ); +// pix->fill( QColor(qRgba(127,127,127,255)) ); +// QBitmap mask; +// mask.fill(1); +// pix->setMask(mask); + + int dy = (pix->height() - pm->height()) / 2; + copyBlt( pix, 0, dy, pm, 0, 0, -1, -1 ); +// QPixmap* px = new QPixmap(21, 14); +// px->convertFromImage(img);*/ + delete pm; + pm = pix; + } +#endif + } + + QPainter p(pm); + p.setFont(m_labelFont); + + p.setPen(Qt::black); + p.drawText(1, 1, pm->width(), pm->height()-2, Qt::AlignCenter, displayName); + p.setPen(Qt::white); + p.drawText(0, 0, pm->width(), pm->height()-2, Qt::AlignCenter, displayName); + + m_pixmapCache.insert(pixmapKey, pm); + + return *pm; +} + +/** +@brief Try to get country code from layout name in xkb before xorg 6.9.0 +*/ +QString LayoutIcon::getCountryFromLayoutName(const QString& layoutName) +{ + QString flag; + + if( X11Helper::areLayoutsClean() ) { // >= Xorg 6.9.0 + if( layoutName == "mkd" ) + flag = "mk"; + else + if( layoutName == "srp" ) { + QString csFlagFile = locate("locale", flagTemplate.arg("cs")); + flag = csFlagFile.isEmpty() ? "yu" : "cs"; + } + else + if( layoutName.endsWith("/jp") ) + flag = "jp"; + else + if( layoutName == "trq" || layoutName == "trf" || layoutName == "tralt" ) + flag = "tr"; + else + if( layoutName.length() > 2 ) + flag = ""; + else + flag = layoutName; + } + else { + if( layoutName == "ar" ) // Arabic - not argentina + ; + else + if( layoutName == "sr" || layoutName == "cs") // Serbian language - Yugoslavia + flag = "yu"; + else + if( layoutName == "bs" ) // Bosnian language - Bosnia + flag = "ba"; + else + if( layoutName == "la" ) // Latin America + ; + else + if( layoutName == "lo" ) // Lao + flag = "la"; + else + if( layoutName == "pl2" ) // Poland + flag = "pl"; + else + if( layoutName == "iu" ) // Inuktitut - Canada + flag = "ca"; + else + if( layoutName == "syr" ) // Syriac + flag = "sy"; + else + if( layoutName == "dz" ) // Dzongka/Tibetian - Buthan + flag = "bt"; + else + if( layoutName == "ogham" ) // Ogham - Ireland + flag = "ie"; + else + if( layoutName == "ge_la" || layoutName == "ge_ru" ) + flag = "ge"; + else + if( layoutName == "el" ) + flag = "gr"; + else + if( layoutName.endsWith("/jp") ) + flag = "jp"; + else + if( layoutName == "ml" || layoutName == "dev" || layoutName == "gur" + || layoutName == "guj" || layoutName == "kan" || layoutName == "ori" + || layoutName == "tel" || layoutName == "tml" || layoutName == "ben" ) // some Indian languages + flag = "in"; + else { + int sepPos = layoutName.find(QRegExp("[-_]")); + QString leftCode = layoutName.mid(0, sepPos); + QString rightCode; + if( sepPos != -1 ) + rightCode = layoutName.mid(sepPos+1); +// kdDebug() << "layout name breakup: " << leftCode << ":" << rightCode << endl; + + if( rightCode.length() == 2 + && QRegExp("[A-Z][A-Z]").exactMatch(rightCode) ) { + flag = rightCode.lower(); + } + else { + flag = leftCode.length() == 2 ? leftCode : ""; + } + } + } + + return flag; +} + + +void LayoutIcon::dimPixmap(QPixmap& pm) +{ + QImage image = pm.convertToImage(); + for (int y=0; y<image.height(); y++) + for(int x=0; x<image.width(); x++) + { + QRgb rgb = image.pixel(x,y); + QRgb dimRgb(qRgb(qRed(rgb)*3/4, qGreen(rgb)*3/4, qBlue(rgb)*3/4)); + image.setPixel(x, y, dimRgb); + } + pm.convertFromImage(image); +} + +static const char* ERROR_LABEL = "err"; + +//private +QPixmap* LayoutIcon::createErrorPixmap() +{ + QPixmap* pm = new QPixmap(21, 14); + pm->fill(Qt::white); + + QPainter p(pm); + + p.setFont(m_labelFont); + p.setPen(Qt::red); + p.drawText(1, 1, pm->width(), pm->height()-2, Qt::AlignCenter, ERROR_LABEL); + p.setPen(Qt::blue); + p.drawText(0, 0, pm->width(), pm->height()-2, Qt::AlignCenter, ERROR_LABEL); + m_pixmapCache.insert(ERROR_CODE, pm); + + return pm; +} + + +// Note: this seems stupid, but allows for translations +#if 0 + I18N_NOOP("Belgian"); + I18N_NOOP("Bulgarian"); + I18N_NOOP("Brazilian"); + I18N_NOOP("Canadian"); + I18N_NOOP("Czech"); + I18N_NOOP("Czech (qwerty)"); + I18N_NOOP("Danish"); + I18N_NOOP("Estonian"); + I18N_NOOP("Finnish"); + I18N_NOOP("French"); + I18N_NOOP("German"); + I18N_NOOP("Hungarian"); + I18N_NOOP("Hungarian (qwerty)"); + I18N_NOOP("Italian"); + I18N_NOOP("Japanese"); + I18N_NOOP("Lithuanian"); + I18N_NOOP("Norwegian"); + I18N_NOOP("PC-98xx Series"); + I18N_NOOP("Polish"); + I18N_NOOP("Portuguese"); + I18N_NOOP("Romanian"); + I18N_NOOP("Russian"); + I18N_NOOP("Slovak"); + I18N_NOOP("Slovak (qwerty)"); + I18N_NOOP("Spanish"); + I18N_NOOP("Swedish"); + I18N_NOOP("Swiss German"); + I18N_NOOP("Swiss French"); + I18N_NOOP("Thai"); + I18N_NOOP("United Kingdom"); + I18N_NOOP("U.S. English"); + I18N_NOOP("U.S. English w/ deadkeys"); + I18N_NOOP("U.S. English w/ISO9995-3"); + + //lukas: these seem to be new in XF 4.0.2 + I18N_NOOP("Armenian"); + I18N_NOOP("Azerbaijani"); + I18N_NOOP("Icelandic"); + I18N_NOOP("Israeli"); + I18N_NOOP("Lithuanian azerty standard"); + I18N_NOOP("Lithuanian querty \"numeric\""); //for bw compatibility + I18N_NOOP("Lithuanian querty \"programmer's\""); + I18N_NOOP("Macedonian"); + I18N_NOOP("Serbian"); + I18N_NOOP("Slovenian"); + I18N_NOOP("Vietnamese"); + + //these seem to be new in XFree86 4.1.0 + I18N_NOOP("Arabic"); + I18N_NOOP("Belarusian"); + I18N_NOOP("Bengali"); + I18N_NOOP("Croatian"); + I18N_NOOP("Greek"); + I18N_NOOP("Latvian"); + I18N_NOOP("Lithuanian qwerty \"numeric\""); + I18N_NOOP("Lithuanian qwerty \"programmer's\""); + I18N_NOOP("Turkish"); + I18N_NOOP("Ukrainian"); + + //these seem to be new in XFree86 4.2.0 + I18N_NOOP("Albanian"); + I18N_NOOP("Burmese"); + I18N_NOOP("Dutch"); + I18N_NOOP("Georgian (latin)"); + I18N_NOOP("Georgian (russian)"); + I18N_NOOP("Gujarati"); + I18N_NOOP("Gurmukhi"); + I18N_NOOP("Hindi"); + I18N_NOOP("Inuktitut"); + I18N_NOOP("Iranian"); +// I18N_NOOP("Iranian"); // should be not Iranian but Farsi + I18N_NOOP("Latin America"); + I18N_NOOP("Maltese"); + I18N_NOOP("Maltese (US layout)"); + I18N_NOOP("Northern Saami (Finland)"); + I18N_NOOP("Northern Saami (Norway)"); + I18N_NOOP("Northern Saami (Sweden)"); + I18N_NOOP("Polish (qwertz)"); + I18N_NOOP("Russian (cyrillic phonetic)"); + I18N_NOOP("Tajik"); + I18N_NOOP("Turkish (F)"); + I18N_NOOP("U.S. English w/ ISO9995-3"); + I18N_NOOP("Yugoslavian"); + + //these seem to be new in XFree86 4.3.0 + I18N_NOOP("Bosnian"); + I18N_NOOP("Croatian (US)"); + I18N_NOOP("Dvorak"); + I18N_NOOP("French (alternative)"); + I18N_NOOP("French Canadian"); + I18N_NOOP("Kannada"); + I18N_NOOP("Lao"); + I18N_NOOP("Malayalam"); + I18N_NOOP("Mongolian"); + I18N_NOOP("Ogham"); + I18N_NOOP("Oriya"); + I18N_NOOP("Syriac"); + I18N_NOOP("Telugu"); + I18N_NOOP("Thai (Kedmanee)"); + I18N_NOOP("Thai (Pattachote)"); + I18N_NOOP("Thai (TIS-820.2538)"); + + //these seem to be new in XFree86 4.4.0 + I18N_NOOP("Uzbek"); + I18N_NOOP("Faroese"); + + //these seem to be new in XOrg 6.8.2 + I18N_NOOP("Dzongkha / Tibetan"); + I18N_NOOP("Hungarian (US)"); + I18N_NOOP("Irish"); + I18N_NOOP("Israeli (phonetic)"); + I18N_NOOP("Serbian (Cyrillic)"); + I18N_NOOP("Serbian (Latin)"); + I18N_NOOP("Swiss"); +#endif |