ConversionStatus GettextImportPlugin::load(QIODevice* device) { _testBorked=false; _errorLine=0; // find codec for file // bool hadCodec; QTextCodec* codec=codecForDevice(device/*, &hadCodec*/ ); QTextStream stream(device); stream.seek(0); stream.setCodec(codec); //QIODevice *dev = stream.device(); //int fileSize = dev->size(); // if somethings goes wrong with the parsing, we don't have deleted the old contents CatalogItem tempHeader; kDebug() << "start parsing..."; QTime aaa; aaa.start(); // first read header const ConversionStatus status = readEntry(stream); bool recoveredErrorInHeader = false; if (KDE_ISUNLIKELY( status == RECOVERED_PARSE_ERROR )) { kDebug() << "Recovered error in header entry"; recoveredErrorInHeader = true; } else if (KDE_ISUNLIKELY( status != OK )) { kWarning() << "Parse error in header entry"; return status; } bool reconstructedHeader=!_msgid.isEmpty() && !_msgid.first().isEmpty(); //kWarning() << "HEADER MSGID: " << _msgid; //kWarning() << "HEADER MSGSTR: " << _msgstr; if (KDE_ISUNLIKELY( reconstructedHeader )) { // The header must have an empty msgid kWarning() << "Header entry has non-empty msgid. Creating a temporary header! " << _msgid; tempHeader.setMsgid( QString() ); QString tmp( "Content-Type: text/plain; charset=UTF-8\\n" // Unknown charset "Content-Transfer-Encoding: 8bit\\n" "Mime-Version: 1.0" ); tempHeader.setMsgstr( tmp); // We keep the comment of the first entry, as it might really be a header comment (at least partially) const QString comment( "# Header entry was created by Lokalize.\n#\n" + _comment ); tempHeader.setComment( comment ); recoveredErrorInHeader = true; } else { tempHeader.setMsgid( _msgid ); tempHeader.setMsgstr( _msgstr ); tempHeader.setComment( _comment ); } // if(tempHeader.isFuzzy()) // { // tempHeader.removeFuzzy(); // } // check if header seems to indicate docbook content generated by xml2pot const bool docbookContent = tempHeader.msgstr().contains( "application/x-xml2pot" ); // now parse the rest of the file uint counter=0; QList<int> errorIndex; bool recoveredError=false; bool docbookFile=false; ExtraDataSaver _extraDataSaver; ConversionStatus success=OK; while( !stream.atEnd() ) { if (reconstructedHeader) reconstructedHeader=false; else success=readEntry(stream); if(KDE_ISLIKELY(success==OK)) { if( _obsolete ) _extraDataSaver(_comment); else { CatalogItem tempCatItem; tempCatItem.setPlural(_gettextPluralForm); tempCatItem.setMsgid( _msgid, _msgidMultiline ); tempCatItem.setMsgstr( _msgstr, _msgstrMultiline ); tempCatItem.setMsgctxt( _msgctxt ); tempCatItem.setComment( _comment ); // add new entry to the list of entries appendCatalogItem(tempCatItem); // check if first comment seems to indicate a docbook source file if(counter==0) docbookFile = tempCatItem.comment().contains(".docbook" ); } } else if(KDE_ISUNLIKELY( success==RECOVERED_PARSE_ERROR )) { kDebug() << "Recovered parse error in entry: " << counter; recoveredError=true; errorIndex.append(counter); CatalogItem tempCatItem; tempCatItem.setPlural(_gettextPluralForm); tempCatItem.setMsgid( _msgid ); tempCatItem.setMsgstr( _msgstr ); tempCatItem.setMsgctxt( _msgctxt ); tempCatItem.setComment( _comment ); // add new entry to the list of entries appendCatalogItem(tempCatItem); } else if (success == PARSE_ERROR) { kDebug() << "Parse error in entry: " << counter; return PARSE_ERROR; } else { kDebug() << "Unknown success status, assumig parse error " << success; return PARSE_ERROR; } counter++; } // TODO: can we check that there is no useful entry? if (KDE_ISUNLIKELY( !counter && !recoveredErrorInHeader )) { // Empty file? (Otherwise, there would be a try of getting an entry and the count would be 1 !) kDebug() << " Empty file?"; return PARSE_ERROR; } kDebug() << " ready"; // We have successfully loaded the file (perhaps with recovered errors) // qWarning() << " done in " << aaa.elapsed() <<_extraDataSaver->extraData.size() << endl; setGeneratedFromDocbook(docbookContent || docbookFile); setHeader(tempHeader); setCatalogExtraData(_extraDataSaver.extraData); setErrorIndex(errorIndex); //setFileCodec(codec); //setMimeTypes( "text/x-gettext-translation" ); #if 0 if (KDE_ISUNLIKELY( recoveredErrorInHeader )) { kDebug() << " Returning: header error"; return RECOVERED_HEADER_ERROR; } else if (KDE_ISUNLIKELY( recoveredError )) { kDebug() << " Returning: recovered parse error"; return RECOVERED_PARSE_ERROR; } else #endif { kDebug() << " Returning: OK! :-)"; return OK; } }
ConversionStatus GettextImportPlugin::load(const QString& filename, const QString&) { kdDebug( KBABEL ) << k_funcinfo << endl; if ( filename.isEmpty() ) { kdDebug(KBABEL) << "fatal error: empty filename to open" << endl; return NO_FILE; } QFileInfo info(filename); if(!info.exists() || info.isDir()) return NO_FILE; if(!info.isReadable()) return NO_PERMISSIONS; QFile file(filename); if ( !file.open( IO_ReadOnly ) ) return NO_PERMISSIONS; uint oldPercent = 0; emit signalResetProgressBar(i18n("loading file"),100); QByteArray ba = file.readAll(); file.close(); // find codec for file bool hadCodec; QTextCodec* codec=codecForArray( ba, &hadCodec ); bool recoveredErrorInHeader = false; QTextStream stream(ba,IO_ReadOnly); if(codec) stream.setCodec(codec); else { kdWarning() << "No encoding declared or found, using UTF-8" << endl; stream.setEncoding( QTextStream::UnicodeUTF8 ); #ifdef __GNUC__ # warning Default UTF-8 encoding needs to be improved #endif // Templates define CHARSET, so if e make it a recoverable error, the template is not loadable anymore, as for templates recoverable errors are disqualifying. //recoveredErrorInHeader = true; } QIODevice *dev = stream.device(); int fileSize = dev->size(); // if somethings goes wrong with the parsing, we don't have deleted the old contents CatalogItem tempHeader; QStringList tempObsolete; kdDebug(KBABEL) << "start parsing..." << endl; // first read header const ConversionStatus status = readHeader(stream); if ( status == RECOVERED_PARSE_ERROR ) { kdDebug( KBABEL ) << "Recovered error in header entry" << endl; recoveredErrorInHeader = true; } else if ( status != OK ) { emit signalClearProgressBar(); kdDebug( KBABEL ) << "Parse error in header entry" << endl; return status; } kdDebug() << "HEADER MSGID: " << _msgid << endl; kdDebug() << "HEADER MSGSTR: " << _msgstr << endl; if ( !_msgid.isEmpty() && !_msgid.first().isEmpty() ) { // The header must have an empty msgid kdWarning(KBABEL) << "Header entry has non-empty msgid. Creating a temporary header! " << _msgid << endl; tempHeader.setMsgid( QStringList() ); QStringList tmp; tmp.append( "Content-Type: text/plain; charset=UTF-8\\n" // Unknown charset "Content-Transfer-Encoding: 8bit\\n" "Mime-Version: 1.0" ); tempHeader.setMsgstr( tmp ); // We keep the comment of the first entry, as it might really be a header comment (at least partially) const QString comment( "# Header entry was created by KBabel!\n#\n" + _comment ); tempHeader.setComment( comment ); recoveredErrorInHeader = true; } else { tempHeader.setMsgid( _msgid ); tempHeader.setMsgstr( _msgstr ); tempHeader.setComment( _comment ); } if(tempHeader.isFuzzy()) { tempHeader.removeFuzzy(); } // check if header seems to indicate docbook content generated by xml2pot const bool docbookContent = (tempHeader.msgstr().find("application/x-xml2pot") != tempHeader.msgstr().end()); // now parse the rest of the file uint counter=0; QValueList<uint> errorIndex; bool recoveredError=false; bool docbookFile=false; while( !stream.eof() ) { kapp->processEvents(10); if( isStopped() ) { return STOPPED; } const ConversionStatus success=readEntry(stream); if(success==OK) { if( _obsolete ) { tempObsolete.append(_comment); } else { CatalogItem tempCatItem; tempCatItem.setMsgctxt( _msgctxt ); tempCatItem.setMsgid( _msgid ); tempCatItem.setMsgstr( _msgstr ); tempCatItem.setComment( _comment ); tempCatItem.setGettextPluralForm( _gettextPluralForm ); // add new entry to the list of entries appendCatalogItem(tempCatItem); // check if first comment seems to indicate a docbook source file if(counter==0) docbookFile = ( tempCatItem.comment().find(".docbook") != -1 ); } } else if(success==RECOVERED_PARSE_ERROR) { kdDebug( KBABEL ) << "Recovered parse error in entry: " << counter << endl; recoveredError=true; errorIndex.append(counter); CatalogItem tempCatItem; tempCatItem.setMsgctxt( _msgctxt ); tempCatItem.setMsgid( _msgid ); tempCatItem.setMsgstr( _msgstr ); tempCatItem.setComment( _comment ); tempCatItem.setGettextPluralForm( _gettextPluralForm ); // add new entry to the list of entries appendCatalogItem(tempCatItem); } else if ( success == PARSE_ERROR ) { kdDebug( KBABEL ) << "Parse error in entry: " << counter << endl; return PARSE_ERROR; } else { kdWarning( KBABEL ) << "Unknown success status, assumig parse error " << success << endl; return PARSE_ERROR; } counter++; const uint newPercent = (100*dev->at())/fileSize; if(newPercent > oldPercent) { oldPercent = newPercent; emit signalProgress(oldPercent); } } // to be sure it is set to 100, if someone don't connect to // signalClearProgressBar() emit signalProgress(100); emit signalClearProgressBar(); // ### TODO: can we check that there is no useful entry? if ( !counter ) { // Empty file? (Otherwise, there would be a try of getting an entry and the count would be 1 !) kdDebug( KBABEL ) << k_funcinfo << " Empty file?" << endl; return PARSE_ERROR; } kdDebug(KBABEL) << k_funcinfo << " ready" << endl; // We have succesfully loaded the file (perhaps with recovered errors) setGeneratedFromDocbook(docbookContent || docbookFile); setHeader(tempHeader); setCatalogExtraData(tempObsolete); setErrorIndex(errorIndex); if(hadCodec) setFileCodec(codec); else setFileCodec(0); setMimeTypes( "application/x-gettext" ); if ( recoveredErrorInHeader ) { kdDebug( KBABEL ) << k_funcinfo << " Returning: header error" << endl; return RECOVERED_HEADER_ERROR; } else if ( recoveredError ) { kdDebug( KBABEL ) << k_funcinfo << " Returning: recovered parse error" << endl; return RECOVERED_PARSE_ERROR; } else { kdDebug( KBABEL ) << k_funcinfo << " Returning: OK! :-)" << endl; return OK; } }