📄 xchmfile.cpp
字号:
if ( !m_detectedLCID || (enc = KCHMTextEncoding::lookupByLCID (m_detectedLCID)) == 0 ) qFatal ("Could not detect text encoding by LCID"); if ( changeFileEncoding (enc->qtcodec) ) { m_currentEncoding = enc;// mainWindow->showInStatusBar (QString("Detected help file charset: ") + enc->charset); return true; } return false;}bool CHMFile::changeFileEncoding( const char * qtencoding ){ // Set up encoding m_textCodec = QTextCodec::codecForName (qtencoding); if ( !m_textCodec ) { qWarning ("Could not set up Text Codec for encoding '%s'", qtencoding); return false; } m_entityDecodeMap.clear(); return true;}bool CHMFile::setCurrentEncoding( const KCHMTextEncoding::text_encoding_t * enc ){ m_currentEncoding = enc; return changeFileEncoding (enc->qtcodec);}bool CHMFile::GetFileContentAsString(QString& str, chmUnitInfo *ui){ QByteArray buf (ui->length + 1,'\0'); if ( RetrieveObject (ui, (unsigned char*) buf.data(), 0, ui->length) ) { buf [(int)ui->length] = '\0'; str = encodeWithCurrentCodec((const char*) buf); return true; } else { str = QString::null; return false; }}bool CHMFile::GetFileContentAsString( QString & str, QString filename, QString location ){ str = QString::null; if ( m_filename == filename ) return GetFileContentAsString (str, location); // Load a file if it is not already loaded CHMFile * file = getCHMfilePointer (filename); if ( !file ) return false; return file->GetFileContentAsString (str, location);}bool CHMFile::GetFileContentAsString (QString& str, QString location){ chmUnitInfo ui; if( !ResolveObject(location, &ui) ) return false; return GetFileContentAsString(str, &ui);}CHMFile * CHMFile::getCHMfilePointer( const QString & filename ){ if ( m_filename == filename ) return this; // Load a file if it is not already loaded if ( m_chmLoadedFiles.find (filename) == m_chmLoadedFiles.end() ) { CHMFile * newfile = new CHMFile; if ( !newfile->LoadCHM (filename) ) { delete newfile; return 0; } m_chmLoadedFiles[filename] = newfile; } return m_chmLoadedFiles[filename];}static int chm_enumerator_callback (struct chmFile*, struct chmUnitInfo *ui, void *context){ ((QVector<QString> *) context)->push_back (ui->path); return CHM_ENUMERATOR_CONTINUE;}bool CHMFile::enumerateArchive( QVector< QString > & files ){ files.clear(); return chm_enumerate (m_chmFile, CHM_ENUMERATE_ALL, chm_enumerator_callback, &files);}QByteArray CHMFile::convertSearchWord( const QString & src ){ static const char * searchwordtable[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "s", 0, "oe", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "s", 0, "oe", 0, 0, "y", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "a", "a", "a", "a", "a", "a", "ae", "c", "e", "e", "e", "e", "i", "i", "i", "i", "d", "n", "o", "o", "o", "o", "o", 0, "o", "u", "u", "u", "u", "y", "\xDE", "ss", "a", "a", "a", "a", "a", "a", "ae", "c", "e", "e", "e", "e", "i", "i", "i", "i", "o", "n", "o", "o", "o", "o", "o", 0, "o", "u", "u", "u", "u", "y", "\xFE", "y" }; if ( !m_textCodec ) return src.toLower().toLocal8Bit(); QByteArray dest = m_textCodec->fromUnicode (src); for ( int i = 0; i < dest.size(); i++ ) { if ( dest[i] & 0x80 ) { int index = dest[i] & 0x7F; if ( searchwordtable[index] ) dest.replace (i, 1, searchwordtable[index]); else dest.remove (i, 1); } } return dest.toLower();}QString CHMFile::getTopicByUrl( const QString & search_url ){ if ( !m_lookupTablesValid ) return QString::null; unsigned char buf[COMMON_BUF_LEN]; int pos = search_url.indexOf ('#'); QString fixedurl = pos == -1 ? search_url : search_url.left (pos); for ( unsigned int i = 0; i < m_chmTOPICS.length; i += TOPICS_ENTRY_LEN ) { if ( RetrieveObject ( &m_chmTOPICS, buf, i, TOPICS_ENTRY_LEN) == 0 ) return QString::null; u_int32_t off_title = *(u_int32_t *)(buf + 4); FIXENDIAN32(off_title); u_int32_t off_url = *(u_int32_t *)(buf + 8); FIXENDIAN32(url); QString topic, url; if ( RetrieveObject ( &m_chmURLTBL, buf, off_url, URLTBL_ENTRY_LEN) == 0 ) return QString::null; off_url = *(u_int32_t *)(buf + 8); FIXENDIAN32(off_url); if ( RetrieveObject ( &m_chmURLSTR, buf, off_url + 8, sizeof(buf) - 1) == 0 ) return false; buf[sizeof(buf) - 1] = '\0';// url = KCHMViewWindow::makeURLabsoluteIfNeeded ((const char*)buf); url = ((const char*)buf); if ( url != fixedurl ) continue; if ( RetrieveObject ( &m_chmSTRINGS, buf, off_title, sizeof(buf) - 1) != 0 ) { buf[sizeof(buf) - 1] = '\0'; topic = encodeWithCurrentCodec ((const char*)buf); } else topic = "Untitled"; return topic; } return QString::null;}void CHMFile::GetSearchResults( const KCHMSearchProgressResults_t & tempres, KCHMSearchResults_t & results, unsigned int limit_results ){ unsigned char combuf [COMMON_BUF_LEN]; QMap<u_int32_t, u_int32_t> urlsmap; // used to prevent duplicated urls for ( int i = 0; i < tempres.size(); i++ ) { if ( urlsmap.find (tempres[i].urloff) != urlsmap.end() ) continue; urlsmap[tempres[i].urloff] = 1; KCHMSearchResult res; if ( RetrieveObject (&m_chmSTRINGS, combuf, tempres[i].titleoff, COMMON_BUF_LEN - 1) != 0 ) { combuf[COMMON_BUF_LEN - 1] = 0; res.title = encodeWithCurrentCodec ((const char*)combuf); } else res.title = "Untitled"; if ( RetrieveObject (&m_chmURLSTR, combuf, tempres[i].urloff + 8, COMMON_BUF_LEN - 1) == 0 ) continue; combuf[COMMON_BUF_LEN - 1] = 0;// res.url = KCHMViewWindow::makeURLabsoluteIfNeeded ((const char*) combuf); res.url = ((const char*)combuf); results.push_back (res); if ( --limit_results == 0 ) break; }}/*bool CHMFile::ParseChmIndexFile ( const QString& file, bool asIndex, KCHMParsedIndexEntry_t & cont ){ QString src; const int MAX_NEST_DEPTH = 256; if ( file.isEmpty() || !GetFileContentAsString ( src, file ) ) return false; unsigned int defaultimagenum = asIndex ? KCHMImageType::IMAGE_INDEX : KCHMImageType::IMAGE_AUTO; unsigned int imagenum = defaultimagenum; int pos = 0, indent = 0; bool in_object = false, root_created = false; QString name; QStringList urls; KCHMParsedIndexEntry * rootentry[MAX_NEST_DEPTH]; memset (rootentry, 0, sizeof(*rootentry)); // Split the HHC file by HTML tags int stringlen = src.length(); while ( pos < stringlen && (pos = src.find ('<', pos)) != -1 ) { int i, word_end = 0; for ( i = ++pos; i < stringlen; i++ ) { // If a " or ' is found, skip to the next one. if ( (src[i] == '"' || src[i] == '\'') ) { // find where quote ends, either by another quote, or by '>' symbol (some people don't know HTML) int nextpos = src.find ( src[i], i+1 ); if ( nextpos == -1 && ( nextpos = src.find ('>', i+1) ) == -1 ) { qWarning ("CHMFile::ParseHhcAndFillTree: corrupted TOC: %s", src.mid(i).toAscii().constData()); return false; } i = nextpos; } else if ( src[i] == '>' ) break; else if ( !src[i].isLetterOrNumber() && src[i] != '/' && !word_end ) word_end = i; } QString tagword, tag = src.mid (pos, i - pos); if ( word_end ) tagword = src.mid (pos, word_end - pos).toLower(); else tagword = tag.toLower();//qDebug ("tag: '%s', tagword: '%s'\n", tag.toAscii().constData(), tagword.toAscii().constData()); // <OBJECT type="text/sitemap"> - a topic entry if ( tagword == "object" && tag.find ("text/sitemap", 0, false) != -1 ) in_object = true; else if ( tagword == "/object" && in_object ) { // a topic entry closed. Add a tree item if ( name ) { KCHMParsedIndexEntry * item; if ( !root_created ) indent = 0; QString url = urls.join ("|"); // Add item into the tree if ( !indent ) { item = new KCHMParsedIndexEntry (name, 0, url, imagenum); } else { if ( !rootentry[indent-1] ) qFatal("CHMFile::ParseAndFillTopicsTree: child entry %d with no root entry!", indent-1); item = new KCHMParsedIndexEntry (name, rootentry[indent-1], url, imagenum); } if ( indent == 0 || !rootentry[indent] ) { rootentry[indent] = item; root_created = true; } } else { if ( !urls.isEmpty() ) qDebug ("CHMFile::ParseAndFillTopicsTree: <object> tag with url \"%s\" is parsed, but name is empty.", urls[0].toAscii().constData()); else qDebug ("CHMFile::ParseAndFillTopicsTree: <object> tag is parsed, but both name and url are empty."); } name = QString::null; urls.clear(); in_object = false; imagenum = defaultimagenum; } else if ( tagword == "param" && in_object ) { // <param name="Name" value="First Page"> int offset; // strlen("param ") QString name_pattern = "name=", value_pattern = "value="; QString pname, pvalue; if ( (offset = tag.find (name_pattern, 0, false)) == -1 ) qFatal ("CHMFile::ParseAndFillTopicsTree: bad <param> tag '%s': no name=\n", tag.toAscii().constData()); // offset+5 skips 'name=' offset = findStringInQuotes (tag, offset + name_pattern.length(), pname, true, false); pname = pname.toLower(); if ( (offset = tag.find (value_pattern, offset, false)) == -1 ) qFatal ("CHMFile::ParseAndFillTopicsTree: bad <param> tag '%s': no value=\n", tag.toAscii().constData()); // offset+6 skips 'value=' findStringInQuotes (tag, offset + value_pattern.length(), pvalue, false, true);//qDebug ("<param>: name '%s', value '%s'", pname.toAscii().constData(), pvalue.toAscii().constData()); if ( pname == "name" ) name = pvalue; else if ( pname == "local" ) urls.push_back (KCHMViewWindow::makeURLabsoluteIfNeeded (pvalue)); else if ( pname == "see also" && asIndex && name != pvalue ) urls.push_back (":" + pvalue); else if ( pname == "imagenumber" ) { bool bok; int imgnum = pvalue.toInt (&bok); if ( bok && imgnum >= 0 && (unsigned) imgnum < MAX_BUILTIN_ICONS ) imagenum = imgnum; } } else if ( tagword == "ul" ) // increase indent level { // Fix for buggy help files if ( ++indent >= MAX_NEST_DEPTH ) qFatal("CHMFile::ParseAndFillTopicsTree: max nest depth (%d) is reached, error in help file", MAX_NEST_DEPTH); rootentry[indent] = 0; } else if ( tagword == "/ul" ) // decrease indent level { if ( --indent < 0 ) indent = 0; rootentry[indent] = 0; } pos = i; } return true;}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -