kcharsets.cpp
来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 665 行 · 第 1/2 页
CPP
665 行
if( qstrcmp( pos->index, entry ) == 0 ) return pos->data; return 0;}class KCharsetsPrivate{public: KCharsetsPrivate(KCharsets* _kc) : codecForNameDict(43, false) // case insensitive { db = 0; kc = _kc; } ~KCharsetsPrivate() { delete db; } QFontDatabase *db; QAsciiDict<QTextCodec> codecForNameDict; KCharsets* kc;};// --------------------------------------------------------------------------KCharsets::KCharsets(){ d = new KCharsetsPrivate(this);}KCharsets::~KCharsets(){ delete d;}QChar KCharsets::fromEntity(const QString &str){ QChar res = QChar::null; int pos = 0; if(str[pos] == '&') pos++; // Check for '�' or '�' sequence if (str[pos] == '#' && str.length()-pos > 1) { bool ok; pos++; if (str[pos] == 'x' || str[pos] == 'X') { pos++; // '�', hexadeciaml character reference QString tmp(str.unicode()+pos, str.length()-pos); res = tmp.toInt(&ok, 16); } else { // '�', decimal character reference QString tmp(str.unicode()+pos, str.length()-pos); res = tmp.toInt(&ok, 10); } return res; } const entity *e = kde_findEntity(str.ascii(), str.length()); if(!e) { //kdDebug( 0 ) << "unknown entity " << str <<", len = " << str.length() << endl; return QChar::null; } //kdDebug() << "got entity " << str << " = " << e->code << endl; return QChar(e->code);}QChar KCharsets::fromEntity(const QString &str, int &len){ // entities are never longer than 8 chars... we start from // that length and work backwards... len = 8; while(len > 0) { QString tmp = str.left(len); QChar res = fromEntity(tmp); if( res != QChar::null ) return res; len--; } return QChar::null;}QString KCharsets::toEntity(const QChar &ch){ QString ent; ent.sprintf("�x%x;", ch.unicode()); return ent;}QString KCharsets::resolveEntities( const QString &input ){ QString text = input; const QChar *p = text.unicode(); const QChar *end = p + text.length(); const QChar *ampersand = 0; bool scanForSemicolon = false; for ( ; p < end; ++p ) { const QChar ch = *p; if ( ch == '&' ) { ampersand = p; scanForSemicolon = true; continue; } if ( ch != ';' || scanForSemicolon == false ) continue; assert( ampersand ); scanForSemicolon = false; const QChar *entityBegin = ampersand + 1; const uint entityLength = p - entityBegin; if ( entityLength == 0 ) continue; const QChar entityValue = KCharsets::fromEntity( QConstString( entityBegin, entityLength ).string() ); if ( entityValue.isNull() ) continue; const uint ampersandPos = ampersand - text.unicode(); text[ (int)ampersandPos ] = entityValue; text.remove( ampersandPos + 1, entityLength + 1 ); p = text.unicode() + ampersandPos; end = text.unicode() + text.length(); ampersand = 0; } return text;}QStringList KCharsets::availableEncodingNames(){ QStringList available; for ( const char* const* pos = charsets_for_encoding; *pos; ++pos ) { //kdDebug(0) << *charsets << " available" << endl; available.append( QString::fromLatin1( *pos )); } return available;}QString KCharsets::languageForEncoding( const QString &encoding ){ int lang = kcharsets_array_search< LanguageForEncoding, int > ( language_for_encoding, encoding.latin1()); return i18n( language_names[lang] );}QString KCharsets::encodingForName( const QString &descriptiveName ){ const int left = descriptiveName.findRev( '(' ); if (left<0) // No parenthesis, so assume it is a normal encoding name return descriptiveName.stripWhiteSpace(); QString name(descriptiveName.mid(left+1)); const int right = name.findRev( ')' ); if (right<0) return name; return name.left(right).stripWhiteSpace();}QStringList KCharsets::descriptiveEncodingNames(){ // As we are sorting, we can directly read the array language_for_encoding QStringList encodings; for ( const LanguageForEncoding* pos = language_for_encoding; pos->index; ++pos ) { const QString name = QString::fromLatin1( pos->index ); const QString description = i18n( language_names[ pos->data ] ); encodings.append( i18n("Descriptive Encoding Name", "%1 ( %2 )"). arg ( description ). arg( name ) ); } encodings.sort(); return encodings;}QTextCodec *KCharsets::codecForName(const QString &n) const{ bool b; return codecForName( n, b );}QTextCodec *KCharsets::codecForName(const QString &n, bool &ok) const{ ok = true; QTextCodec* codec = 0; // dict lookup is case insensitive anyway if((codec = d->codecForNameDict[n.isEmpty() ? "->locale<-" : n.latin1()])) return codec; // cache hit, return if (n.isEmpty()) { codec = KGlobal::locale()->codecForEncoding(); d->codecForNameDict.replace("->locale<-", codec); return codec; } QCString name = n.lower().latin1(); QCString key = name; if (name.right(8) == "_charset") name.truncate(name.length()-8); if (name.isEmpty()) { ok = false; return QTextCodec::codecForName("iso8859-1"); } codec = QTextCodec::codecForName(name); if(codec) { d->codecForNameDict.replace(key, codec); return codec; } // these codecs are built into Qt, but the name given for the codec is different, // so QTextCodec did not recognize it. QCString cname = kcharsets_array_search< Builtin, const char* >( builtin, name.data()); if(!cname.isEmpty()) codec = QTextCodec::codecForName(cname); if(codec) { d->codecForNameDict.replace(key, codec); return codec; } QString dir; { KConfigGroupSaver cfgsav( KGlobal::config(), "i18n" ); dir = KGlobal::config()->readPathEntry("i18ndir", QString::fromLatin1("/usr/share/i18n/charmaps")); } // these are codecs not included in Qt. They can be build up if the corresponding charmap // is available in the charmap directory. cname = kcharsets_array_search< Aliases, const char* >( aliases, name.data()); if(cname.isEmpty()) cname = name; cname = cname.upper(); const QString basicName = QString::fromLatin1(cname); kdDebug() << k_funcinfo << endl << " Trying to find " << cname << " in " << dir << endl; QString charMapFileName; bool gzipped = false; QDir qdir(dir); if (!qdir.exists()) { // The directory for the charmaps does not even exist... (That is common!) } else if (qdir.exists(basicName, false)) { charMapFileName = basicName; } else if (qdir.exists(basicName+".gz", false)) { charMapFileName = basicName + ".gz"; gzipped = true; } else { // Check if we are asking a code page // If yes, then check "CP99999" and "IBM99999" // First we need to find the number of the codepage QRegExp regexp("^(X-)?(CP|IBM)(-| )?(0-9)+"); if ( regexp.search(basicName) != -1) { const QString num = regexp.cap(4); if (num.isEmpty()) { // No number, not a code page (or something went wrong) } else if (qdir.exists("IBM"+num)) { charMapFileName = "IBM"+num; } else if (qdir.exists("IBM"+num+".gz")) { charMapFileName = "IBM"+num+".gz"; gzipped = true; } else if (qdir.exists("CP"+num)) { charMapFileName = "CP"+num; } else if (qdir.exists("CP"+num+".gz")) { charMapFileName = "CP"+num+".gz"; gzipped = true; } } } if (gzipped && !charMapFileName.isEmpty()) { KQIODeviceGZip gzip(dir + "/" + charMapFileName); if (gzip.open(IO_ReadOnly)) { kdDebug() << "Loading gzipped charset..." << endl; codec = QTextCodec::loadCharmap(&gzip); gzip.close(); } else kdWarning() << "Could not open gzipped charset!" << endl; } else if (!charMapFileName.isEmpty()) { codec = QTextCodec::loadCharmapFile(dir + "/" + charMapFileName); } if(codec) { d->codecForNameDict.replace(key, codec); return codec; } // this also failed, the last resort is now to take some compatibility charmap cname = kcharsets_array_search< ConversionHints, const char* >( conversion_hints, (const char*)name.data() ); if(!cname.isEmpty()) codec = QTextCodec::codecForName(cname); if(codec) { d->codecForNameDict.replace(key, codec); return codec; } // could not assign a codec, let's return Latin1 ok = false; return QTextCodec::codecForName("iso8859-1");}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?