예제 #1
0
bool LiteEditorFile::open(const QString &fileName, const QString &mimeType, bool bCheckCodec)
{
    QFile file(fileName);
    if (!file.open(QFile::ReadOnly)) {
        return false;
    }
    const QFileInfo fi(fileName);
    m_bReadOnly = !fi.isWritable();

    m_mimeType = mimeType;
    m_fileName = fileName;

    QByteArray buf = file.readAll();
    m_hasDecodingError = false;

    if (bCheckCodec) {
        if (mimeType == "text/html" || mimeType == "text/xml") {
            m_codec = QTextCodec::codecForHtml(buf,QTextCodec::codecForName("utf-8"));
        } else {
            LiteApi::IMimeType *im = m_liteApp->mimeTypeManager()->findMimeType(mimeType);
            if (im) {
                QString codecName = im->codec();
                if (!codecName.isEmpty()) {
                    m_codec = QTextCodec::codecForName(codecName.toLatin1());
                }
            }
            int bytesRead = buf.size();
            QTextCodec *codec = m_codec;
            // code taken from qtextstream
            if (bytesRead >= 4 && ((uchar(buf[0]) == 0xff && uchar(buf[1]) == 0xfe && uchar(buf[2]) == 0 && uchar(buf[3]) == 0)
                                   || (uchar(buf[0]) == 0 && uchar(buf[1]) == 0 && uchar(buf[2]) == 0xfe && uchar(buf[3]) == 0xff))) {
                codec = QTextCodec::codecForName("UTF-32");
            } else if (bytesRead >= 2 && ((uchar(buf[0]) == 0xff && uchar(buf[1]) == 0xfe)
                                          || (uchar(buf[0]) == 0xfe && uchar(buf[1]) == 0xff))) {
                codec = QTextCodec::codecForName("UTF-16");
            } else if (bytesRead >= 3 && uchar(buf[0]) == 0xef && uchar(buf[1]) == 0xbb && uchar(buf[2])== 0xbf) {
                codec = QTextCodec::codecForName("UTF-8");
            } else if (!codec) {
                codec = QTextCodec::codecForLocale();
            }
            // end code taken from qtextstream
            m_codec = codec;
        }
    }


    QTextCodec::ConverterState state;
    QString text = m_codec->toUnicode(buf,buf.size(),&state);
    if (state.invalidChars > 0 || state.remainingChars > 0) {
        m_hasDecodingError = true;
    }
    //qDebug() << state.invalidChars << state.remainingChars;

/*
    QByteArray verifyBuf = m_codec->fromUnicode(text); // slow
    // the minSize trick lets us ignore unicode headers
    int minSize = qMin(verifyBuf.size(), buf.size());
    m_hasDecodingError = (minSize < buf.size()- 4
                          || memcmp(verifyBuf.constData() + verifyBuf.size() - minSize,
                                    buf.constData() + buf.size() - minSize, minSize));
*/
    /*
    if (text.length()*2+4 < buf.length()) {
        m_hasDecodingError = true;
    }
    */

    int lf = text.indexOf('\n');
    if (lf < 0) {
        m_lineTerminatorMode = NativeLineTerminator;
    } else if (lf == 0) {
        m_lineTerminatorMode = LFLineTerminator;
    } else {
        lf = text.indexOf(QRegExp("[^\r]\n"),lf-1);
        if (lf >= 0) {
            m_lineTerminatorMode = LFLineTerminator;
        } else {
            m_lineTerminatorMode = CRLFLineTerminator;
        }
    }
    bool noprintCheck = m_liteApp->settings()->value(EDITOR_NOPRINTCHECK,true).toBool();
    if (noprintCheck) {
        for (int i = 0; i < text.length(); i++) {
            if (!text[i].isPrint() && !text[i].isSpace() && text[i] != '\r' && text[i] != '\n') {
                text[i] = '.';
                m_hasDecodingError = true;
            }
        }
    }

    m_document->setPlainText(text);
    return true;
}