📄 kcharsetsdata.cpp
字号:
const char * KCharsetConverterData::outputCharset()const{ return output->name;}/////////////////////////////////////////////////KCharsetsData::KCharsetsData(){ displayableCharsDict=0; tempResult=new KCharsetConversionResult; QString fileName=KApplication::kde_configdir() + "/charsets"; kchdebug("Reading config from %s...\n",(const char *)fileName); config=new KSimpleConfig(fileName, TRUE); config->setGroup("general"); QString i18dir = config->readEntry("i18ndir"); if (i18dir) scanDirectory(i18dir); kchdebug("Creating alias dictionary...\n"); KEntryIterator *it=config->entryIterator("aliases"); if ( it ) { while( it->current() ){ const char*alias=it->currentKey(); kchdebug(" %s -> ",alias); const char*name=it->current()->aValue; kchdebug(" %s:",name); KCharsetEntry *ce=varCharsetEntry(name); if (ce){ aliases.insert(alias,ce); kchdebug("ok\n"); } else kchdebug("not found\n"); ++(*it); } } delete it; kchdebug("done!\n");}void KCharsetsData::scanDirectory(const char *path){ kchdebug("Scanning directory: %s\n",path); QDir d(path); if ( ! d.exists() ) return; d.setFilter(QDir::Files); d.setSorting(QDir::Name); const QFileInfoList *list=d.entryInfoList(); QFileInfoListIterator it(*list); QFileInfo *fi; while( (fi=it.current()) ){ QString name=fi->fileName(); QString alias=name.copy(); int comma=alias.find(','); if (comma) alias.remove(comma,alias.length()-comma); else alias=""; if (!charsetEntry(alias) && !charsetEntry(name)){ KCharsetEntry *entry=new KCharsetEntry; char *ptr=new char [fi->fileName().length()+1]; strcpy(ptr,name); entry->name=ptr; entry->qtCharset=QFont::AnyCharSet; entry->toUnicode=0; entry->registered=FALSE; entry->toUnicodeDict=0; i18nCharsets.insert(name.lower(),entry); if (alias!="") aliases.insert(alias,entry); } ++it; }}void KCharsetsData::createDictFromi18n(KCharsetEntry *e){ kchdebug("Creating unicode dict for %s\n",e->name); config->setGroup("general"); QString dir=config->readEntry("i18ndir"); kchdebug("Dir: %s\n",(const char *)dir); QString filename=dir+'/'+e->name; kchdebug("Trying to open file %s\n",(const char *)filename); QFile f(filename); if (!f.open(IO_ReadOnly)) return; QTextStream t(&f); QString l; do{ l=t.readLine(); }while(!t.eof() && l!="CHARMAP"); if (t.eof()){ f.close(); return; } QIntDict<unsigned> *dict=new QIntDict<unsigned>; dict->setAutoDelete(TRUE); char codeBuf[20]; char unicodeBuf[10]; unsigned unicode; unsigned code; while(!t.eof()){ l=t.readLine(); if (l=="END CHARMAP") break; sscanf(l,"%*s %16s %8s %*s",codeBuf,unicodeBuf); sscanf(unicodeBuf,"<U%x>",&unicode); code=0; if ( sscanf(codeBuf,"/x%X",&code) < 1 ) code=codeBuf[0]; kchdebug("(%s %s) %x->%x\n",codeBuf,unicodeBuf,code,unicode); dict->insert(code,new unsigned(unicode)); } e->toUnicodeDict=dict; defaultCh=charsetEntry("us-ascii");} KCharsetsData::~KCharsetsData(){ if (tempResult) delete tempResult; QDictIterator<KCharsetEntry> it(i18nCharsets); KCharsetEntry *e; while( (e=it.current()) ){ ++it; if (e->toUnicodeDict) delete e->toUnicodeDict; if (e->name) delete e->name; delete e; } if (displayableCharsDict) delete displayableCharsDict; delete config;}KCharsetEntry * KCharsetsData::varCharsetEntry(const char *name){ for(int i=0;charsets[i].name;i++){ if ( stricmp(name,charsets[i].name) == 0 ){ kchdebug("Found!\n"); return charsets+i; } } KCharsetEntry *e=i18nCharsets[QString(name).lower()]; if (!e){ kchdebug("Searchin in aliases...\n"); e=aliases[QString(name).lower()]; } return e;}const KCharsetEntry * KCharsetsData::charsetEntry(int index){ int i; for(i=0;charsets[i].name;i++) if ( i==index ) return charsets+i; QDictIterator<KCharsetEntry> it(i18nCharsets); KCharsetEntry *e = 0L; while( (e=it.current()) ){ if (i==index) return e; ++i; ++it; } return 0;}const KCharsetEntry * KCharsetsData::charsetEntry(QFont::CharSet qtCharset){ int i; for(i=0;charsets[i].name;i++) if ( charsets[i].qtCharset==qtCharset ) return charsets+i; return 0;}bool KCharsetsData::setDefaultCharset(const KCharsetEntry *charset){ if (charset){ defaultCh=charset; return TRUE; } return FALSE;}QString KCharsetsData::charsetFace(const KCharsetEntry *charset ,const QString &face){ config->setGroup("faces"); const char *faceStr=config->readEntry(charset->name); if (!faceStr) return face; QString newFace(faceStr); newFace.replace(QRegExp("\\*"),face); return newFace;}bool KCharsetsData::charsetOfFace(const KCharsetEntry * charset,const QString &face){ kchdebug("Testing if face %s is of charset %s...",(const char *)face, charset->name); config->setGroup("faces"); const char *faceStr=config->readEntry(charset->name); kchdebug("%s...",faceStr); QRegExp rexp(faceStr,FALSE,TRUE); if (face.contains(rexp)){ kchdebug("Yes, it is\n"); return TRUE; } kchdebug("No, it isn't\n"); return FALSE;}const KCharsetEntry* KCharsetsData::charsetOfFace(const QString &face){ kchdebug("Searching for charset for face %s...\n",(const char *)face); KEntryIterator * it=config->entryIterator("faces"); if (!it) return 0; while( it->current() ){ const char * faceStr=it->current()->aValue; const char * key=it->currentKey(); if (!faceStr || faceStr[0]==0){ delete it; return charsetEntry(key); } kchdebug("testing if it is %s (%s)...",(const char *)it->currentKey(),faceStr); QRegExp rexp(faceStr,FALSE,TRUE); kchdebug("regexp: %s face: %s\n",rexp.pattern(),(const char *)face); if (face.contains(rexp)){ kchdebug("Yes, it is\n"); delete it; return charsetEntry(key); } kchdebug("No, it isn't\n"); ++(*it); } delete it; return 0;} const unsigned *KCharsetsData::getToUnicodeTable(const KCharsetEntry *charset){ if (!charset) return 0; return charset->toUnicode;} QIntDict<unsigned> *KCharsetsData::getToUnicodeDict(const KCharsetEntry *charset){ if (!charset) return 0; if (charset->toUnicodeDict == 0) createDictFromi18n(varCharsetEntry(charset->name)); return charset->toUnicodeDict;}const char *KCharsetsData::faceForCharset(const KCharsetEntry *charset){ config->setGroup("faces"); return config->readEntry(charset->name);}const KCharsetEntry *KCharsetsData::conversionHint(const KCharsetEntry *charset){ QStrList list; kchdebug("Serching for conversion hint for %s\n",charset->name); config->setGroup("conversionHints"); int n=config->readListEntry(charset->name,list); kchdebug("%i entries found\n",n); for(const char *hint=list.first();hint;hint=list.next()){ kchdebug("Found: %s\n",hint); KCharsetEntry *ce=varCharsetEntry(hint); if (isDisplayable(ce)) return ce; } return defaultCh; }bool KCharsetsData::getFontList(QStrList*lst,QString xcharsetname){char **fontNames;int numFonts;QString mask("-*-*-*-*-*-*-*-*-*-*-*-*-");QString qfontname;Display *kde_display; if (!lst) return FALSE; kde_display = XOpenDisplay( 0L ); mask+=xcharsetname; fontNames = XListFonts(kde_display, mask, 32767, &numFonts); for(int i = 0; i < numFonts; i++){ QString face; qfontname = fontNames[i]; int dash = qfontname.find ('-', 1, TRUE); // find next dash if (dash == -1) continue; // the font name is between the second and third dash so: // let's find the third dash: int dash_two = qfontname.find ('-', dash + 1 , TRUE); if (dash == -1) continue; // fish the name of the font info string face = qfontname.mid(dash +1, dash_two - dash -1); if(qfontname.find("-p-") != -1) face += "-p"; if(qfontname.find("-0-0-0-0-") != -1) face += "-s"; if(qfontname.find("-b-") != -1) face += "-b"; if(qfontname.find("-i-") != -1) face += "-i"; if(!lst->contains(face)) lst->append(face); } XFreeFontNames(fontNames);}bool KCharsetsData::isDisplayableHack(KCharsetEntry *charset){QFont::CharSet qcharset=charset->qtCharset; QString face=faceForCharset(charset); if ( !face.isEmpty() ){ if ( face.isEmpty()) return FALSE; QFont f(face); f.setCharSet(qcharset); f.setFamily(face); QFontInfo fi(f); kchdebug("fi.charset()=%i fi.family()=%s\n",fi.charSet(),fi.family()); if (fi.family()!=face ) return FALSE; /* This face will work for this charset, remember it */ if (!charset->good_family) charset->good_family=new QString; if (charset->good_family->isEmpty()) *(charset->good_family)=face; return TRUE; } return FALSE; }//#define kchdebug printfbool KCharsetsData::isDisplayable(KCharsetEntry *charset){ QFont::CharSet qcharset=charset->qtCharset; kchdebug("qtcharset=%i\n",qcharset); /* Qt doesn't support this charset. We must use the hack */ if (qcharset==QFont::AnyCharSet && strcmp(charset->name,"us-ascii")!=0) return isDisplayableHack(charset); kchdebug("searching for charset %s\n", charset->name); if (charset->good_family){ kchdebug("found good family\n"); if (charset->good_family->isEmpty()) /* no good_family is known */ return isDisplayableHack(charset); return TRUE; } QStrList lst; kchdebug("getting good families, charset=%s\n",toX(charset->name).data()); getFontList(&lst,toX(charset->name)); if(lst.isEmpty()) { charset->good_family=new QString; return isDisplayableHack(charset); } else { charset->good_family = new QString; for (const char* fm = lst.first(); fm; fm = lst.next()) { *(charset->good_family) += fm; *(charset->good_family) += "/"; } return true; }}#undef kchdebugvoid KCharsetsData::convert(unsigned code,KCharsetConversionResult &convResult){unsigned chr; kchdebug("KCD:convert(code) %4X -> ",code); chr=0; kchdebug("Clearing result (was: %s)...\n",(const char *)convResult.cText); convResult.cText=""; kchdebug("Clearing charset...\n"); convResult.cCharset=charsetEntry("us-ascii"); if (code>127 && code != 0xA0){ // 0xa0 is present in ever iso8859 charset kchdebug("Hi code, dictonary needed, getting...\n"); const QIntDict<KDispCharEntry> *dict=getDisplayableDict(); kchdebug("Dictonary: %p\n",dict); KDispCharEntry *ptr=(*dict)[code]; kchdebug("Entry: %p\n",ptr); if (ptr){ chr=ptr->code; kchdebug("Setting charset to %s...\n",ptr->charset->name); convResult.cCharset=ptr->charset; kchdebug("Setting text to code %2X...\n",chr); convResult.cText+=(unsigned char)chr; } } else{ kchdebug("Setting text to code %2X...\n",code); convResult.cText+=(unsigned char)code; } kchdebug("%s\n",(const char *)convResult);}unsigned KCharsetsData::decodeAmp(const char *seq,int &len){ unsigned int i; kchdebug("Sequence: '%0.20s'\n",seq); if (*seq=='&') { seq++; len=1; } else len=0; if (*seq=='#'){ char *endptr; unsigned num; if (*(seq+1) == 'x') num =strtoul(seq+2,&endptr,16); else num =strtoul(seq+1,&endptr,10); kchdebug("Number: '%u'\n",num); if (*endptr==';') len+=endptr-seq+1; else len+=endptr-seq; return num; } else for(i=0;i<CHAR_TAGS_COUNT;i++){ KCharTags tag=tags[i]; int l=strlen(tag.tag); if ( strncmp(seq,tag.tag,l)==0 ){ if (seq[l]==';' && tag.tag[l-1]!=';') len+=l+1; else len+=l; return tag.code; } } len=0; return 0;}void KCharsetsData::convertTag(const char *tag ,KCharsetConversionResult &convResult ,int &l){ convert(decodeAmp(tag,l),convResult);}const QIntDict<KDispCharEntry> * KCharsetsData::getDisplayableDict(){ if (displayableCharsDict) return displayableCharsDict; kchdebug("Generating dictonary for displayable characters\n"); displayableCharsDict=new QIntDict<KDispCharEntry>; displayableCharsDict->setAutoDelete(TRUE); for(int i=0;charsets[i].name!=0;i++) if (charsets[i].toUnicode && isDisplayable(charsets+i)){ kchdebug("Adding characters form %s\n",charsets[i].name); for(int j=0;j<256;j++){ unsigned unicode=charsets[i].toUnicode[j]; if ( !(*displayableCharsDict)[unicode] ){ KDispCharEntry *e=new KDispCharEntry; e->charset=charsets+i; e->code=j; displayableCharsDict->insert(unicode,e); } } } #ifdef KCH_DEBUG displayableCharsDict->statistics(); #endif return displayableCharsDict;}QString KCharsetsData::fromX(QString name){ if ( strncmp(name,"iso",3)==0 ){ name="iso-"+name.mid(3,100); return name; } if ( strncmp(name,"koi8", 4) == 0 ) return name; KEntryIterator *it=config->entryIterator("XNames"); if ( it ) { while( it->current() ){ const char * key = it->currentKey(); if (it->current()->aValue==name ){ delete it; return key; } ++(*it); } } delete it; return ""; }QString KCharsetsData::toX(QString name){ if ( strncmp(name,"iso-",4)==0 ){ name="iso"+name.mid(4,100); return name; } if ( strncmp(name,"koi8", 4) == 0 ) return name; config->setGroup("XNames"); return config->readEntry(name,"");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -