Commit d1539695 authored by heretiK's avatar heretiK
Browse files

Proof of concept

parent 79542953
cmake_minimum_required( VERSION 3.6 )
project( prototypator )
set( CMAKE_CXX_STANDARD 17 )
set( CXX_STANDARD_REQUIRED ON )
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
add_compile_options(-Wall -Wextra -pedantic -Werror -Weffc++)
endif()
find_package( Boost REQUIRED )
include_directories( ${Boost_INCLUDE_DIRS} )
add_executable( ${PROJECT_NAME} main.cpp )
target_link_libraries( ${PROJECT_NAME} ${Boost_LIBRARIES} stdc++fs )
int main() {
return 0;
}
......@@ -23,4 +23,4 @@ qt5_create_translation( QM_FILES ${${PROJECT_NAME}_SOURCES} ${${PROJECT_NAME}_TS
# executable
include_directories( ${Boost_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/src )
add_executable( ${PROJECT_NAME} ${${PROJECT_NAME}_SOURCES} ${QM_FILES} )
target_link_libraries( ${PROJECT_NAME} ${Boost_LIBRARIES} Qt5::Widgets )
target_link_libraries( ${PROJECT_NAME} ${Boost_LIBRARIES} Qt5::Widgets stdc++fs )
<RCC>
<qresource prefix="/">
<file>../../resources/icon-256.png</file>
<file>../../resources/main.cpp</file>
<file>../../resources/CMakeLists.txt</file>
</qresource>
</RCC>
......@@ -2,15 +2,124 @@
#include "mainwindow.hpp"
#include "ui_mainwindow.h"
#include <QSettings>
#include <filesystem>
#include <fstream>
namespace fs = std::filesystem;
MainWindow::MainWindow( QWidget *parent )
: QMainWindow( parent )
, ui_ptr_{ new Ui::MainWindow }
, directory_{ fs::temp_directory_path() / "prototypator" }
, process_{ parent }
{
ui_ptr_->setupUi( this );
connect( &process_, &QProcess::readyReadStandardOutput, this, &MainWindow::update_std_out );
connect( &process_, &QProcess::readyReadStandardError, this, &MainWindow::update_std_err );
connect( &process_, SIGNAL(finished(int)), this, SLOT(finished(int)));
restore_settings();
}
// TODO c'est de la merde.
// C'est juste pour le prototype.
// Il faut passer par QProcess et pas par std::system pour récupérer correctement
// les messages d'erreurs et les passer dans la zone de texte.
// TODO aussi dégager CMake et utiliser directement gcc ???
void MainWindow::prepare()
{
// check cmake executable
auto errc = std::system( "cmake --version" );
if( errc ) {
throw std::runtime_error( "The program 'cmake' can't be found in the system." );
}
// create directory
const auto build_directory = directory_ / "build";
fs::create_directories( build_directory );
// copy files
QFile::copy( ":/resources/CMakeLists.txt", (directory_ / "CMakeLists.txt").c_str() );
QFile::copy( ":/resources/main.cpp", (directory_ / "main.cpp").c_str() );
// run cmake
auto os = std::ostringstream{};
os << "cd " << build_directory << " && cmake ..";
errc = std::system( os.str().c_str() );
if( errc ) {
// TODO gestion des erreurs correctes
throw std::runtime_error( "The program 'cmake' failes" );
}
// Great success !!
is_prepared_ = true;
}
// pareil pour ici, il faut virer les access a std::system
// et faire la remontee d'erreur via QProcess
void MainWindow::run()
{
// show compilation tab
ui_ptr_->tabWidget->setCurrentIndex( 0 );
const auto build_directory = directory_ / "build";
try {
// ensure preparation has been done
if( not is_prepared_ ) {
prepare();
}
// copy code
auto fos = std::ofstream{};
fos.exceptions( std::ifstream::failbit );
fos.open( (directory_ / "main.cpp").c_str(), std::ios_base::trunc );
fos << ui_ptr_->textEdit_code->toPlainText().toStdString();
fos.close();
// compile
auto os = std::ostringstream{};
os << "cd " << build_directory << " && make";
auto errc = std::system( os.str().c_str() );
if( errc ) {
// TODO gestion des erreurs correctes
throw std::runtime_error( "The program failed to compile." );
}
} catch( const std::exception &e ) {
ui_ptr_->plainTextEdit_compilation->setPlainText( QString{ e.what() } );
return;
}
// show io tab
ui_ptr_->tabWidget->setCurrentIndex( 1 );
// write output
ui_ptr_->plainTextEdit_io->clear();
process_.start( QString::fromStdString( (build_directory / "prototypator").string() ) );
bool started = process_.waitForStarted();
if( not started ) {
throw std::runtime_error( "Unable to start program." );
}
}
void MainWindow::update_std_out()
{
const auto &text = process_.readAllStandardOutput();
ui_ptr_->plainTextEdit_io->textCursor().insertText( text );
}
void MainWindow::update_std_err()
{
const auto &text = process_.readAllStandardError();
ui_ptr_->plainTextEdit_io->textCursor().insertText( text );
}
void MainWindow::finished( int exit_code )
{
auto os = std::ostringstream{};
os << tr( "Process finished. Exit code: " ).toStdString() << exit_code;
ui_ptr_->plainTextEdit_io->appendPlainText( QString::fromStdString( os.str() ) );
}
MainWindow::~MainWindow() = default;
void MainWindow::closeEvent( QCloseEvent *event )
......@@ -19,6 +128,7 @@ void MainWindow::closeEvent( QCloseEvent *event )
settings.beginGroup( "main_window" );
settings.setValue( "geometry", saveGeometry() );
settings.setValue( "windowState", saveState() );
settings.setValue( "code", ui_ptr_->textEdit_code->toPlainText() );
settings.endGroup();
QMainWindow::closeEvent( event );
}
......@@ -29,5 +139,6 @@ void MainWindow::restore_settings()
settings.beginGroup( "main_window" );
restoreGeometry( settings.value( "geometry" ).toByteArray() );
restoreState( settings.value( "windowState" ).toByteArray() );
ui_ptr_->textEdit_code->setText( settings.value( "code" ).toString() );
settings.endGroup();
}
#ifndef MAINWINDOW_HPP
#define MAINWINDOW_HPP
#include <filesystem>
#include <memory>
#include <QMainWindow>
#include <QProcess>
namespace Ui {
class MainWindow;
......@@ -17,6 +19,13 @@ public:
explicit MainWindow( QWidget *parent = nullptr );
~MainWindow() override;
public slots:
void prepare();
void run();
void update_std_out();
void update_std_err();
void finished( int exit_code );
protected:
void closeEvent( QCloseEvent *event ) override;
......@@ -25,6 +34,9 @@ private:
private:
std::unique_ptr<Ui::MainWindow> ui_ptr_;
bool is_prepared_ = false;
std::filesystem::path directory_;
QProcess process_;
};
#endif // MAINWINDOW_HPP
......@@ -29,7 +29,20 @@
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QTextEdit" name="textEdit_code"/>
<widget class="QTextEdit" name="textEdit_code">
<property name="font">
<font>
<family>Inconsolata</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="tabStopWidth">
<number>20</number>
</property>
<property name="acceptRichText">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
......@@ -65,47 +78,112 @@
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="plainTextEdit_result">
<property name="palette">
<palette>
<active>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>208</red>
<green>208</green>
<blue>208</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>208</red>
<green>208</green>
<blue>208</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>68</red>
<green>68</green>
<blue>68</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="readOnly">
<bool>true</bool>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab_compilation">
<attribute name="title">
<string>Compilation</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QPlainTextEdit" name="plainTextEdit_compilation">
<property name="palette">
<palette>
<active>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>208</red>
<green>208</green>
<blue>208</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>208</red>
<green>208</green>
<blue>208</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>68</red>
<green>68</green>
<blue>68</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_io">
<attribute name="title">
<string>Input/output</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPlainTextEdit" name="plainTextEdit_io">
<property name="palette">
<palette>
<active>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>208</red>
<green>208</green>
<blue>208</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>208</red>
<green>208</green>
<blue>208</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>68</red>
<green>68</green>
<blue>68</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
......@@ -114,5 +192,25 @@
<resources>
<include location="main.qrc"/>
</resources>
<connections/>
<connections>
<connection>
<sender>pushButton_run</sender>
<signal>clicked()</signal>
<receiver>MainWindow</receiver>
<slot>run()</slot>
<hints>
<hint type="sourcelabel">
<x>592</x>
<y>220</y>
</hint>
<hint type="destinationlabel">
<x>565</x>
<y>107</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>run()</slot>
</slots>
</ui>
......@@ -14,14 +14,29 @@
<translation></translation>
</message>
<message>
<location filename="../src/prototypator/mainwindow.ui" line="52"/>
<location filename="../src/prototypator/mainwindow.ui" line="65"/>
<source>Run</source>
<translation></translation>
</message>
<message>
<location filename="../src/prototypator/mainwindow.ui" line="63"/>
<location filename="../src/prototypator/mainwindow.ui" line="76"/>
<source>Result:</source>
<translation></translation>
</message>
<message>
<location filename="../src/prototypator/mainwindow.ui" line="87"/>
<source>Compilation</source>
<translation></translation>
</message>
<message>
<location filename="../src/prototypator/mainwindow.ui" line="138"/>
<source>Input/output</source>
<translation></translation>
</message>
<message>
<location filename="../src/prototypator/mainwindow.cpp" line="112"/>
<source>Process finished. Exit code: </source>
<translation></translation>
</message>
</context>
</TS>
......@@ -14,14 +14,29 @@
<translation>Code c++ :</translation>
</message>
<message>
<location filename="../src/prototypator/mainwindow.ui" line="52"/>
<location filename="../src/prototypator/mainwindow.ui" line="65"/>
<source>Run</source>
<translation>Démarrer</translation>
</message>
<message>
<location filename="../src/prototypator/mainwindow.ui" line="63"/>
<location filename="../src/prototypator/mainwindow.ui" line="76"/>
<source>Result:</source>
<translation>Résultat :</translation>
</message>
<message>
<location filename="../src/prototypator/mainwindow.ui" line="87"/>
<source>Compilation</source>
<translation>Compilation</translation>
</message>
<message>
<location filename="../src/prototypator/mainwindow.ui" line="138"/>
<source>Input/output</source>
<translation>Entrée/sortie</translation>
</message>
<message>
<location filename="../src/prototypator/mainwindow.cpp" line="112"/>
<source>Process finished. Exit code: </source>
<translation>Processus terminée. Code d&apos;erreur : </translation>
</message>
</context>
</TS>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment