#include "qbrainfuck.h" #include "ui_qbrainfuck.h" QBrainfuck::QBrainfuck(QWidget *parent) : QMainWindow(parent), ui(new Ui::QBrainfuck) { ui->setupUi(this); decoder = new DecoderThread(); QObject::connect(decoder, &DecoderThread::programDecoded, this, &QBrainfuck::setText); QObject::connect(decoder, &DecoderThread::errorMessage, this, &QBrainfuck::errorMessage); } QBrainfuck::~QBrainfuck() { delete ui; } /********** Text part **********/ void QBrainfuck::on_encodeButton_clicked() { QByteArray text = ui->textTextEdit->document()->toPlainText().toLatin1(); ui->programTextEdit->setPlainText(""); // First pass : find decades/steps QList decades; // Store the decades for initial loop decades.append(0); QList memory; // Store the program's memory memory.append(0); QList steps; // Store the steps to construct the program QByteArray::const_iterator textIterator; for (textIterator = text.constBegin(); textIterator != text.constEnd(); ++textIterator) { int max_diff = ui->maxSignsSpinBox->value()+1; QList::iterator index; // Find nearest memory's case and store it QList::iterator memoryIterator; for (memoryIterator = memory.begin(); memoryIterator != memory.end(); ++memoryIterator) { if (qAbs(*memoryIterator-*textIterator) < max_diff) { max_diff = qAbs(*memoryIterator-*textIterator); index = memoryIterator; } } // Add step and insert current value in the memory, else add a decade if we don't find a case nearer than max_diff if (max_diff <= ui->maxSignsSpinBox->value()) { steps.append(*index); *index = *textIterator; } else { steps.append(qRound(*textIterator/(float)ui->decadesSpinBox->value())*ui->decadesSpinBox->value()); decades.append(qRound(*textIterator/(float)ui->decadesSpinBox->value())*ui->decadesSpinBox->value()); memory.append(*textIterator); } } qSort(decades); // Second pass : write program QString program = ""; for (int i = 0; i < ui->decadesSpinBox->value(); ++i) { program += "+"; } program += "\["; QList::iterator decadesIterator; for (decadesIterator = decades.begin()+1; decadesIterator != decades.end(); ++decadesIterator) { program += ">"; for (int i = 0; i < *decadesIterator; i+=ui->decadesSpinBox->value()) { program += "+"; } } for (int i = 0; i < decades.size()-1; ++i) { program += "<"; } program += "-]"; int prev_ptr = 0; QList::const_iterator stepsIterator; textIterator = text.constBegin(); for (stepsIterator = steps.constBegin(); stepsIterator != steps.constEnd(); ++stepsIterator) { int next_ptr = decades.indexOf(*stepsIterator); if (next_ptr > prev_ptr) { for (int i = 0; i < next_ptr-prev_ptr; ++i) { program += ">"; } } else { for (int i = 0; i < prev_ptr-next_ptr; ++i) { program += "<"; } } if (*textIterator > *stepsIterator) { for (int i = 0; i < *textIterator-*stepsIterator; ++i) { program += "+"; } } else { for (int i = 0; i < *stepsIterator-*textIterator; ++i) { program += "-"; } } program += "."; prev_ptr = next_ptr; decades[next_ptr] = *textIterator; ++textIterator; } ui->programTextEdit->setPlainText(program); ui->tabWidget->setCurrentIndex(1); } void QBrainfuck::on_textLoadButton_clicked() { QFileDialog dialog(this); dialog.setFileMode(QFileDialog::AnyFile); dialog.setNameFilter("Txt Files (*.txt)"); dialog.setDefaultSuffix("txt"); dialog.setAcceptMode(QFileDialog::AcceptOpen); if (dialog.exec()) { QFile loadFile(dialog.selectedFiles().first()); if (!loadFile.open(QIODevice::ReadOnly)) { return; } ui->textTextEdit->document()->setPlainText(loadFile.readAll()); loadFile.close(); } } void QBrainfuck::on_textSaveButton_clicked() { QFileDialog dialog(this); dialog.setFileMode(QFileDialog::AnyFile); dialog.setNameFilter("Txt Files (*.txt)"); dialog.setDefaultSuffix("txt"); dialog.setAcceptMode(QFileDialog::AcceptSave); if (dialog.exec()) { QFile saveFile(dialog.selectedFiles().first()); if (!saveFile.open(QIODevice::WriteOnly)) { return; } saveFile.write(ui->textTextEdit->document()->toPlainText().toUtf8()); saveFile.close(); } } void QBrainfuck::on_textTextEdit_textChanged() { ui->textLabel->setText("Text length: " + QString().setNum(ui->textTextEdit->document()->toPlainText().length())); } /********** Program part **********/ void QBrainfuck::on_decodeButton_clicked() { ui->textTextEdit->setPlainText(""); QByteArray program = ui->programTextEdit->document()->toPlainText().toLatin1(); QByteArray input = ui->inputLineEdit->text().toLatin1(); decoder->decode(program, input); ui->tabWidget->setCurrentIndex(0); } void QBrainfuck::on_programLoadButton_clicked() { QFileDialog dialog(this); dialog.setFileMode(QFileDialog::AnyFile); dialog.setNameFilter("Bf Files (*.bf)"); dialog.setDefaultSuffix("bf"); dialog.setAcceptMode(QFileDialog::AcceptOpen); if (dialog.exec()) { QFile loadFile(dialog.selectedFiles().first()); if (!loadFile.open(QIODevice::ReadOnly)) { return; } ui->programTextEdit->document()->setPlainText(loadFile.readAll()); loadFile.close(); } } void QBrainfuck::on_programSaveButton_clicked() { QFileDialog dialog(this); dialog.setFileMode(QFileDialog::AnyFile); dialog.setNameFilter("Bf Files (*.bf)"); dialog.setDefaultSuffix("bf"); dialog.setAcceptMode(QFileDialog::AcceptSave); if (dialog.exec()) { QFile saveFile(dialog.selectedFiles().first()); if (!saveFile.open(QIODevice::WriteOnly)) { return; } saveFile.write(ui->programTextEdit->document()->toPlainText().toUtf8()); saveFile.close(); } } void QBrainfuck::on_programTextEdit_textChanged() { ui->programLabel->setText("Program length: " + QString().setNum(ui->programTextEdit->document()->toPlainText().count(QRegExp(">|<|\\+|-|\\.|,|\\[|\\]")))); } /********** Motif part **********/ void QBrainfuck::on_motifButton_clicked() { QString motif = ui->motifTextEdit->document()->toPlainText(); QByteArray program = ui->programTextEdit->document()->toPlainText().toLatin1(); if (motif.contains(QRegExp(">|<|\\+|-|\\.|,|\\[|\\]"))) { QMessageBox::critical(this, "QBrainfuck error", "Error: Motif contains Brainfuck characters"); return; } QByteArray::const_iterator programIterator; for (programIterator = program.constBegin(); programIterator != program.constEnd(); ++programIterator) { switch (*programIterator) { case '>': case '<': case '+': case '-': case '.': case ',': case '[': case ']': int index = motif.indexOf(QRegExp(ui->regexLineEdit->text())); if (index==-1) { motif += *programIterator; } else { motif.replace(index, 1, *programIterator); } break; } } ui->resultTextEdit->setPlainText(motif); ui->tabWidget->setCurrentIndex(3); } void QBrainfuck::on_motifLoadButton_clicked() { QFileDialog dialog(this); dialog.setFileMode(QFileDialog::AnyFile); dialog.setNameFilter("Txt Files (*.txt)"); dialog.setDefaultSuffix("txt"); dialog.setAcceptMode(QFileDialog::AcceptOpen); if (dialog.exec()) { QFile loadFile(dialog.selectedFiles().first()); if (!loadFile.open(QIODevice::ReadOnly)) { return; } ui->motifTextEdit->document()->setPlainText(loadFile.readAll()); loadFile.close(); } } void QBrainfuck::on_motifSaveButton_clicked() { QFileDialog dialog(this); dialog.setFileMode(QFileDialog::AnyFile); dialog.setNameFilter("Txt Files (*.txt)"); dialog.setDefaultSuffix("txt"); dialog.setAcceptMode(QFileDialog::AcceptSave); if (dialog.exec()) { QFile saveFile(dialog.selectedFiles().first()); if (!saveFile.open(QIODevice::WriteOnly)) { return; } saveFile.write(ui->motifTextEdit->document()->toPlainText().toUtf8()); saveFile.close(); } } void QBrainfuck::on_motifTextEdit_textChanged() { ui->motifLabel->setText("Motif length: " + QString().setNum(ui->motifTextEdit->document()->toPlainText().count(QRegExp(ui->regexLineEdit->text())))); } void QBrainfuck::on_regexLineEdit_textChanged(const QString &arg1) { on_motifTextEdit_textChanged(); } /********** Result part **********/ void QBrainfuck::on_qrcodeButton_clicked() { char* text = new char[ui->resultTextEdit->document()->toPlainText().toLatin1().size() + 1]; strcpy(text, ui->resultTextEdit->document()->toPlainText().toLatin1().data()); QRcode *qrCode=QRcode_encodeString(text, 0, QR_ECLEVEL_L, QR_MODE_8, 1); if(qrCode) { int width = qrCode->width; QImage image((width + 4)*8, (width + 4)*8, QImage::Format_RGB32);; QPainter painter(&image); QLinearGradient linearGrad(QPointF(2*8, 2*8), QPointF((width + 2)*8, (width + 2)*8)); linearGrad.setColorAt(0, Qt::black); linearGrad.setColorAt(1, Qt::black); painter.fillRect(0, 0, (width + 4)*8, (width + 4)*8, Qt::white); painter.fillRect(2*8, 2*8, width*8, width*8, linearGrad); for (int i = 0; i < width*width; ++i) { if (!(qrCode->data[i] &0x01)) { int col = i % width; int row = (i - col) / width; painter.fillRect((col + 2)*8, (row + 2)*8, 8, 8, Qt::white); } } ui->qrcodeLabel->setPixmap(QPixmap::fromImage(image)); ui->tabWidget->setCurrentIndex(4); } } void QBrainfuck::on_resultLoadButton_clicked() { QFileDialog dialog(this); dialog.setFileMode(QFileDialog::AnyFile); dialog.setNameFilter("Txt Files (*.txt)"); dialog.setDefaultSuffix("txt"); dialog.setAcceptMode(QFileDialog::AcceptOpen); if (dialog.exec()) { QFile loadFile(dialog.selectedFiles().first()); if (!loadFile.open(QIODevice::ReadOnly)) { return; } ui->resultTextEdit->document()->setPlainText(loadFile.readAll()); loadFile.close(); } } void QBrainfuck::on_resultSaveButton_clicked() { QFileDialog dialog(this); dialog.setFileMode(QFileDialog::AnyFile); dialog.setNameFilter("Txt Files (*.txt)"); dialog.setDefaultSuffix("txt"); dialog.setAcceptMode(QFileDialog::AcceptSave); if (dialog.exec()) { QFile saveFile(dialog.selectedFiles().first()); if (!saveFile.open(QIODevice::WriteOnly)) { return; } saveFile.write(ui->resultTextEdit->document()->toPlainText().toUtf8()); saveFile.close(); } } void QBrainfuck::on_resultTextEdit_textChanged() { ui->resultLabel->setText("Result length: " + QString().setNum(ui->resultTextEdit->document()->toPlainText().length())); } /********** QRCode part **********/ void QBrainfuck::on_qrcodeSaveButton_clicked() { QFileDialog dialog(this); dialog.setFileMode(QFileDialog::AnyFile); dialog.setNameFilter("PNG Files (*.png)"); dialog.setDefaultSuffix("png"); dialog.setAcceptMode(QFileDialog::AcceptSave); if (dialog.exec()) { ui->qrcodeLabel->pixmap()->toImage().save(dialog.selectedFiles().first(), "PNG"); } } /*******************************/ void QBrainfuck::setText(QString text) { ui->textTextEdit->setPlainText(text); } void QBrainfuck::errorMessage(QString message) { QMessageBox::critical(this, "QBrainfuck error", "Error: " + message); } void QBrainfuck::on_saveAllButton_clicked() { QFileDialog dialog(this); dialog.setFileMode(QFileDialog::Directory); dialog.setAcceptMode(QFileDialog::AcceptSave); if (dialog.exec()) { QString saveDir(dialog.selectedFiles().first()); QFile textFile(saveDir + "/text.txt"); if (!textFile.open(QIODevice::WriteOnly)) { return; } textFile.write(ui->textTextEdit->document()->toPlainText().toUtf8()); textFile.close(); QFile programFile(saveDir + "/program.bf"); if (!programFile.open(QIODevice::WriteOnly)) { return; } programFile.write(ui->programTextEdit->document()->toPlainText().toUtf8()); programFile.close(); QFile motifFile(saveDir + "/motif.txt"); if (!motifFile.open(QIODevice::WriteOnly)) { return; } motifFile.write(ui->motifTextEdit->document()->toPlainText().toUtf8()); motifFile.close(); QFile resultFile(saveDir + "/result.txt"); if (!resultFile.open(QIODevice::WriteOnly)) { return; } resultFile.write(ui->resultTextEdit->document()->toPlainText().toUtf8()); resultFile.close(); ui->qrcodeLabel->pixmap()->toImage().save(saveDir + "/qrcode.png", "PNG"); } } void QBrainfuck::on_loadAllButton_clicked() { QFileDialog dialog(this); dialog.setFileMode(QFileDialog::Directory); dialog.setAcceptMode(QFileDialog::AcceptOpen); if (dialog.exec()) { QString saveDir(dialog.selectedFiles().first()); QFile textFile(saveDir + "/text.txt"); if (!textFile.open(QIODevice::ReadOnly)) { return; } ui->textTextEdit->document()->setPlainText(textFile.readAll()); textFile.close(); QFile programFile(saveDir + "/program.bf"); if (!programFile.open(QIODevice::ReadOnly)) { return; } ui->programTextEdit->document()->setPlainText(programFile.readAll()); programFile.close(); QFile motifFile(saveDir + "/motif.txt"); if (!motifFile.open(QIODevice::ReadOnly)) { return; } ui->motifTextEdit->document()->setPlainText(motifFile.readAll()); motifFile.close(); QFile resultFile(saveDir + "/result.txt"); if (!resultFile.open(QIODevice::ReadOnly)) { return; } ui->resultTextEdit->document()->setPlainText(resultFile.readAll()); resultFile.close(); QImage image; image.load(saveDir + "/qrcode.png", "PNG"); ui->qrcodeLabel->setPixmap(QPixmap::fromImage(image)); } }