<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (<EMAIL>)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "basetextdocument.h"
#include "basetexteditor.h"
#include "storagesettings.h"

#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QTextStream>
#include <QtCore/QTextCodec>
#include <QtGui/QMainWindow>
#include <QtGui/QSyntaxHighlighter>
#include <QtGui/QApplication>

#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h>
#include <utils/qtcassert.h>
#include <utils/reloadpromptutils.h>

using namespace TextEditor;

DocumentMarker::DocumentMarker(QTextDocument *doc)
  : ITextMarkable(doc), document(doc)
{
}

BaseTextDocument::BaseTextDocument()
  : m_document(new QTextDocument(this)),
    m_highlighter(0)
{
    m_documentMarker = new DocumentMarker(m_document);
    m_lineTerminatorMode = NativeLineTerminator;
    m_fileIsReadOnly = false;
    m_isBinaryData = false;
    m_codec = QTextCodec::codecForLocale();
    m_hasDecodingError = false;
}

BaseTextDocument::~BaseTextDocument()
{
    QTextBlock block = m_document->begin();
    while (block.isValid()) {
        if (TextBlockUserData *data = static_cast<TextBlockUserData *>(block.userData()))
            data->documentClosing();
        block = block.next();
    }
    delete m_document;
    m_document = 0;
}

QString BaseTextDocument::mimeType() const
{
    return m_mimeType;
}

void BaseTextDocument::setMimeType(const QString &mt)
{
    m_mimeType = mt;
}

bool BaseTextDocument::save(const QString &fileName)
{
    QTextCursor cursor(m_document);

    cursor.beginEditBlock();
    if (m_storageSettings.m_cleanWhitespace)
        cleanWhitespace(cursor, m_storageSettings.m_cleanIndentation, m_storageSettings.m_inEntireDocument);
    if (m_storageSettings.m_addFinalNewLine)
        ensureFinalNewLine(cursor);
    cursor.endEditBlock();

    QString fName = m_fileName;
    if (!fileName.isEmpty())
        fName = fileName;

    QFile file(fName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
        return false;

    QString plainText = m_document->toPlainText();

    if (m_lineTerminatorMode == CRLFLineTerminator)
        plainText.replace(QLatin1Char('\n'), QLatin1String("\r\n"));

    file.write(m_codec->fromUnicode(plainText));
    if (!file.flush())
        return false;
    file.close();

    const QFileInfo fi(fName);
    m_fileName = fi.absoluteFilePath();

    m_document->setModified(false);
    emit titleChanged(fi.fileName());
    emit changed();

    m_isBinaryData = false;
    m_hasDecodingError = false;
    m_decodingErrorSample.clear();

    return true;
}

bool BaseTextDocument::isReadOnly() const
{
    if (m_isBinaryData || m_hasDecodingError)
        return true;
    if (m_fileName.isEmpty()) //have no corresponding file, so editing is ok
        return false;
    return m_fileIsReadOnly;
}

bool BaseTextDocument::isModified() const
{
    return m_document->isModified();
}

void BaseTextDocument::checkPermissions()
{
    if (!m_fileName.isEmpty()) {
        const QFileInfo fi(m_fileName);
        m_fileIsReadOnly = !fi.isWritable();
    } else {
        m_fileIsReadOnly = false;
    }
}

bool BaseTextDocument::open(const QString &fileName)
{
    QString title = tr("untitled");
    if (!fileName.isEmpty()) {
        const QFileInfo fi(fileName);
        m_fileIsReadOnly = !fi.isWritable();
        m_fileName = fi.absoluteFilePath();

        QFile file(fileName);
        if (!file.open(QIODevice::ReadOnly))
            return false;

        title = fi.fileName();

        QByteArray buf = file.readAll();
        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)<commit_msg>Clean the BaseTextDocument filename.<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (<EMAIL>)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "basetextdocument.h"
#include "basetexteditor.h"
#include "storagesettings.h"

#include <QtCore/QFile>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QTextStream>
#include <QtCore/QTextCodec>
#include <QtGui/QMainWindow>
#include <QtGui/QSyntaxHighlighter>
#include <QtGui/QApplication>

#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h>
#include <utils/qtcassert.h>
#include <utils/reloadpromptutils.h>

using namespace TextEditor;

DocumentMarker::DocumentMarker(QTextDocument *doc)
  : ITextMarkable(doc), document(doc)
{
}

BaseTextDocument::BaseTextDocument()
  : m_document(new QTextDocument(this)),
    m_highlighter(0)
{
    m_documentMarker = new DocumentMarker(m_document);
    m_lineTerminatorMode = NativeLineTerminator;
    m_fileIsReadOnly = false;
    m_isBinaryData = false;
    m_codec = QTextCodec::codecForLocale();
    m_hasDecodingError = false;
}

BaseTextDocument::~BaseTextDocument()
{
    QTextBlock block = m_document->begin();
    while (block.isValid()) {
        if (TextBlockUserData *data = static_cast<TextBlockUserData *>(block.userData()))
            data->documentClosing();
        block = block.next();
    }
    delete m_document;
    m_document = 0;
}

QString BaseTextDocument::mimeType() const
{
    return m_mimeType;
}

void BaseTextDocument::setMimeType(const QString &mt)
{
    m_mimeType = mt;
}

bool BaseTextDocument::save(const QString &fileName)
{
    QTextCursor cursor(m_document);

    cursor.beginEditBlock();
    if (m_storageSettings.m_cleanWhitespace)
        cleanWhitespace(cursor, m_storageSettings.m_cleanIndentation, m_storageSettings.m_inEntireDocument);
    if (m_storageSettings.m_addFinalNewLine)
        ensureFinalNewLine(cursor);
    cursor.endEditBlock();

    QString fName = m_fileName;
    if (!fileName.isEmpty())
        fName = fileName;

    QFile file(fName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
        return false;

    QString plainText = m_document->toPlainText();

    if (m_lineTerminatorMode == CRLFLineTerminator)
        plainText.replace(QLatin1Char('\n'), QLatin1String("\r\n"));

    file.write(m_codec->fromUnicode(plainText));
    if (!file.flush())
        return false;
    file.close();

    const QFileInfo fi(fName);
    m_fileName = QDir::cleanPath(fi.absoluteFilePath());

    m_document->setModified(false);
    emit titleChanged(fi.fileName());
    emit changed();

    m_isBinaryData = false;
    m_hasDecodingError = false;
    m_decodingErrorSample.clear();

    return true;
}

bool BaseTextDocument::isReadOnly() const
{
    if (m_isBinaryData || m_hasDecodingError)
        return true;
    if (m_fileName.isEmpty()) //have no corresponding file, so editing is ok
        return false;
    return m_fileIsReadOnly;
}

bool BaseTextDocument::isModified() const
{
    return m_document->isModified();
}

void BaseTextDocument::checkPermissions()
{
    if (!m_fileName.isEmpty()) {
        const QFileInfo fi(m_fileName);
        m_fileIsReadOnly = !fi.isWritable();
    } else {
        m_fileIsReadOnly = false;
    }
}

bool BaseTextDocument::open(const QString &fileName)
{
    QString title = tr("untitled");
    if (!fileName.isEmpty()) {
        const QFileInfo fi(fileName);
        m_fileIsReadOnly = !fi.isWritable();
        m_fileName = QDir::cleanPath(fi.absoluteFilePath());

        QFile file(fileName);
        if (!file.open(QIODevice::ReadOnly))
            return false;

        title = fi.fileName();

        QByteArray buf = file.readAll();
        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)
{'fraction_non_alphanumeric': 0.1486409966024915, 'fraction_numerical': 0.007172517931294828, 'mean_word_length': 3.924256505576208, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3510114', 'n_tokens_mistral': 3278, 'n_tokens_neox': 3212, 'n_words': 782}