<commit_before>#include "qhexdocument.h"
#include "commands/insertcommand.h"
#include "commands/removecommand.h"
#include "commands/replacecommand.h"
#include <functional>
#include <QGuiApplication>
#include <QClipboard>
#include <QFileInfo>
#include <QBuffer>
#include <QFile>

static void removeMetadata(MetadataMultiHash& metadata, std::function<bool(QHexMetadata*)> cb)
{
    MetadataHashIterator it(metadata);

    while(it.hasNext())
    {
        it.next();
        sinteger_t i = 0;
        MetadataList values = metadata.values(it.key());

        while(i < values.length())
        {
            if(cb(values[i]))
                values.removeAt(i);
            else
                i++;
        }
    }
}

QHexDocument::QHexDocument(QIODevice *device, QObject *parent): QObject(parent)
{
    this->_baseaddress = 0;
    this->_gapbuffer = new GapBuffer(device);
    this->_cursor = new QHexCursor(this);

    connect(&this->_undostack, &QUndoStack::canUndoChanged, this, &QHexDocument::canUndoChanged);
    connect(&this->_undostack, &QUndoStack::canRedoChanged, this, &QHexDocument::canRedoChanged);
}

QHexDocument::~QHexDocument()
{
    delete this->_gapbuffer;
    this->_gapbuffer = NULL;
}

QHexCursor *QHexDocument::cursor() const
{
    return this->_cursor;
}

const MetadataMultiHash &QHexDocument::metadata() const
{
    return this->_metadata;
}

integer_t QHexDocument::length() const
{
    return this->_gapbuffer->length();
}

integer_t QHexDocument::baseAddress() const
{
    return this->_baseaddress;
}

bool QHexDocument::canUndo() const
{
    return this->_undostack.canUndo();
}

bool QHexDocument::canRedo() const
{
    return this->_undostack.canRedo();
}

QByteArray QHexDocument::read(integer_t offset, integer_t len)
{
    return this->_gapbuffer->read(offset, len);
}

QByteArray QHexDocument::selectedBytes() const
{
    if(!this->_cursor->hasSelection())
        return QByteArray();

    return this->_gapbuffer->read(this->_cursor->selectionStart(), this->_cursor->selectionEnd());
}

QString QHexDocument::commentString(integer_t offset) const
{
    if(!this->_comments.contains(offset))
        return QString();

    return this->_comments[offset]->comment();
}

char QHexDocument::at(integer_t offset) const
{
    return this->_gapbuffer->at(offset);
}

void QHexDocument::setBaseAddress(integer_t baseaddress)
{
    if(this->_baseaddress == baseaddress)
        return;

    this->_baseaddress = baseaddress;
    emit baseAddressChanged();
}

QHexDocument *QHexDocument::fromDevice(QIODevice *iodevice)
{
    if(!iodevice->isOpen())
        iodevice->open(QFile::ReadWrite);

    return new QHexDocument(iodevice);
}

QHexDocument *QHexDocument::fromFile(QString filename)
{
    QFileInfo fi(filename);
    QFile* f = new QFile(filename);

    if(fi.isWritable())
        f->open(QFile::ReadWrite);
    else
        f->open(QFile::ReadOnly);

    QHexDocument* document = QHexDocument::fromDevice(f);
    f->setParent(document);
    return document;
}

QHexDocument *QHexDocument::fromMemory(const QByteArray &ba)
{
    QBuffer* b = new QBuffer();
    b->setData(ba);
    b->open(QFile::ReadOnly);

    QHexDocument* document = QHexDocument::fromDevice(b);
    b->setParent(document);
    return document;
}

void QHexDocument::undo()
{
    this->_undostack.undo();
    emit documentChanged();
}

void QHexDocument::redo()
{
    this->_undostack.redo();
    emit documentChanged();
}

void QHexDocument::cut()
{
    if(!this->_cursor->hasSelection())
        return;

    QClipboard* c = qApp->clipboard();
    c->setText(QString(this->selectedBytes()));
    this->_cursor->removeSelection();
}

void QHexDocument::copy()
{
    if(!this->_cursor->hasSelection())
        return;

    QClipboard* c = qApp->clipboard();
    c->setText(QString(this->selectedBytes()));
}

void QHexDocument::paste()
{
    QClipboard* c = qApp->clipboard();
    QByteArray data = c->text().toUtf8();

    if(data.isEmpty())
        return;

    this->_cursor->removeSelection();
    this->insert(this->_cursor->offset(), data);
    this->_cursor->moveOffset(data.length());
}

void QHexDocument::insert(integer_t offset, uchar b)
{
    this->insert(offset, QByteArray(1, b));
}

void QHexDocument::replace(integer_t offset, uchar b)
{
    this->replace(offset, QByteArray(1, b));
}<commit_msg>QHexDocument: Check for INS/OVR mode before pasting data<commit_after>#include "qhexdocument.h"
#include "commands/insertcommand.h"
#include "commands/removecommand.h"
#include "commands/replacecommand.h"
#include <functional>
#include <QGuiApplication>
#include <QClipboard>
#include <QFileInfo>
#include <QBuffer>
#include <QFile>

static void removeMetadata(MetadataMultiHash& metadata, std::function<bool(QHexMetadata*)> cb)
{
    MetadataHashIterator it(metadata);

    while(it.hasNext())
    {
        it.next();
        sinteger_t i = 0;
        MetadataList values = metadata.values(it.key());

        while(i < values.length())
        {
            if(cb(values[i]))
                values.removeAt(i);
            else
                i++;
        }
    }
}

QHexDocument::QHexDocument(QIODevice *device, QObject *parent): QObject(parent)
{
    this->_baseaddress = 0;
    this->_gapbuffer = new GapBuffer(device);
    this->_cursor = new QHexCursor(this);

    connect(&this->_undostack, &QUndoStack::canUndoChanged, this, &QHexDocument::canUndoChanged);
    connect(&this->_undostack, &QUndoStack::canRedoChanged, this, &QHexDocument::canRedoChanged);
}

QHexDocument::~QHexDocument()
{
    delete this->_gapbuffer;
    this->_gapbuffer = NULL;
}

QHexCursor *QHexDocument::cursor() const
{
    return this->_cursor;
}

const MetadataMultiHash &QHexDocument::metadata() const
{
    return this->_metadata;
}

integer_t QHexDocument::length() const
{
    return this->_gapbuffer->length();
}

integer_t QHexDocument::baseAddress() const
{
    return this->_baseaddress;
}

bool QHexDocument::canUndo() const
{
    return this->_undostack.canUndo();
}

bool QHexDocument::canRedo() const
{
    return this->_undostack.canRedo();
}

QByteArray QHexDocument::read(integer_t offset, integer_t len)
{
    return this->_gapbuffer->read(offset, len);
}

QByteArray QHexDocument::selectedBytes() const
{
    if(!this->_cursor->hasSelection())
        return QByteArray();

    return this->_gapbuffer->read(this->_cursor->selectionStart(), this->_cursor->selectionEnd());
}

QString QHexDocument::commentString(integer_t offset) const
{
    if(!this->_comments.contains(offset))
        return QString();

    return this->_comments[offset]->comment();
}

char QHexDocument::at(integer_t offset) const
{
    return this->_gapbuffer->at(offset);
}

void QHexDocument::setBaseAddress(integer_t baseaddress)
{
    if(this->_baseaddress == baseaddress)
        return;

    this->_baseaddress = baseaddress;
    emit baseAddressChanged();
}

QHexDocument *QHexDocument::fromDevice(QIODevice *iodevice)
{
    if(!iodevice->isOpen())
        iodevice->open(QFile::ReadWrite);

    return new QHexDocument(iodevice);
}

QHexDocument *QHexDocument::fromFile(QString filename)
{
    QFileInfo fi(filename);
    QFile* f = new QFile(filename);

    if(fi.isWritable())
        f->open(QFile::ReadWrite);
    else
        f->open(QFile::ReadOnly);

    QHexDocument* document = QHexDocument::fromDevice(f);
    f->setParent(document);
    return document;
}

QHexDocument *QHexDocument::fromMemory(const QByteArray &ba)
{
    QBuffer* b = new QBuffer();
    b->setData(ba);
    b->open(QFile::ReadOnly);

    QHexDocument* document = QHexDocument::fromDevice(b);
    b->setParent(document);
    return document;
}

void QHexDocument::undo()
{
    this->_undostack.undo();
    emit documentChanged();
}

void QHexDocument::redo()
{
    this->_undostack.redo();
    emit documentChanged();
}

void QHexDocument::cut()
{
    if(!this->_cursor->hasSelection())
        return;

    QClipboard* c = qApp->clipboard();
    c->setText(QString(this->selectedBytes()));
    this->_cursor->removeSelection();
}

void QHexDocument::copy()
{
    if(!this->_cursor->hasSelection())
        return;

    QClipboard* c = qApp->clipboard();
    c->setText(QString(this->selectedBytes()));
}

void QHexDocument::paste()
{
    QClipboard* c = qApp->clipboard();
    QByteArray data = c->text().toUtf8();

    if(data.isEmpty())
        return;

    this->_cursor->removeSelection();

    if(this->_cursor->isInsertMode())
        this->insert(this->_cursor->offset(), data);
    else
        this->replace(this->_cursor->offset(), data);

    this->_cursor->moveOffset(data.length());
}

void QHexDocument::insert(integer_t offset, uchar b)
{
    this->insert(offset, QByteArray(1, b));
}

void QHexDocument::replace(integer_t offset, uchar b)
{
    this->replace(offset, QByteArray(1, b));
}
{'fraction_non_alphanumeric': 0.15088757396449703, 'fraction_numerical': 0.001137915339098771, 'mean_word_length': 4.056962025316456, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 150, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2818188', 'n_tokens_mistral': 2881, 'n_tokens_neox': 2820, 'n_words': 493}