/*
Enregistreur SDcard
Programme écrit par Silicium628
ce logiciel est libre et open source
*/
#include "mainwindow.h"
#include "math.h"
#include <QFile>
#include <QFileDialog>
#include <QTextStream>
#include <QDebug>
#include "boutonled.cpp"
#include "qled.cpp"
#include <QMessageBox>
#include <QTextCodec>
#include <QTimer>
#include <QMouseEvent>
QString version = "3.5";
QColor blanc = QColor::fromRgb(0xFFFFFF);
QColor noir = QColor::fromRgb(0x000000);
QColor gris_fonce = QColor::fromRgb(0x4D4D4D);
QColor gris_clair = QColor::fromRgb(0xBFBFBF);
QColor rouge = QColor::fromRgb(0xFF0000);
QColor vert = QColor::fromRgb(0x008000);
QColor vert_clair = QColor::fromRgb(0x90EE90);
QColor vert_fonce = QColor::fromRgb(0x003300);
QColor vert_tres_fonce = QColor::fromRgb(0x001A00);
QColor bleu = QColor::fromRgb(0x0000FF);
QColor bleu_clair = QColor::fromRgb(0x1E90FF);
QColor bleu_fonce = QColor::fromRgb(0x000066);
QColor bleu_tres_fonce = QColor::fromRgb(0x00001A);
QColor orange = QColor::fromRgb(0xFF9500);
QColor jaune = QColor::fromRgb(0xFFFF00);
QColor jaune_clair = QColor::fromRgb(0xFFFFBF);
QColor jaune_fonce = QColor::fromRgb(0xB9B100);
QColor cyan = QColor::fromRgb(0x00FFFF);
QColor cyan_fonce = QColor::fromRgb(0x00CCCC);
QColor violet = QColor::fromRgb(0x800080);
QColor rose_pale = QColor::fromRgb(0xFFC0CB);
//----------------------------------------------
QColor couleur_ecran = bleu_tres_fonce;
QColor couleur_piste = jaune;
//QColor couleur_piste = gris_fonce;
QColor couleur_quadrillage1 = QColor::fromRgb(0x303030);
QColor couleur_quadrillage2 = QColor::fromRgb(0x508888);
QColor couleur_texte = QColor::fromRgb(0x888888);
QPen pen_trace(couleur_piste, 0, Qt::SolidLine);
QPen pen_texte(couleur_texte, 1, Qt::SolidLine);
QPen pen_quadrillage(couleur_quadrillage1,0, Qt::SolidLine);
//--------------------;--------------------------
int x_scene, y_scene;
QList <Element> liste_elements; // tous types confondus, segments et pastilles
QString fileName_en_cours;
float zoom;
quint8 ech; // echelle = 4, 8, 80 pour 1/4, 1/8, 1/80 ; 1/4 signifie 4 pas pour 1 pixel à lécran.
quint8 systeme_mesure; // 1 (mm) ou 2 (mils US)
char datas_in[2000000];
quint32 nb_octets=1000; // ajusté à la valeur exacte plus bas
quint32 compteur_pas=0;
qint32 pos_moteur1, pos_moteur2;
QPointF pos_actuelle;
qint32 X_max =0;
qint32 Y_max =0;
qint16 offset_X =800;
qint16 offset_Y =800;
int x_0, y_0;
int x_clic_scene, y_clic_scene; // coordonnees du pixel clique
int x_dyn, y_dyn, delta_x, delta_y;
qint32 y_max = 10000;
QString msg ="";
qreal sqr(qreal r1)
{
return r1 * r1;
}
QString valeur2txt2(int v1)
{
QString s;
s.setNum(v1); // conversion num -> txt
s = "00"+s;
s = s.right(2);
return s;
}
QString valeur2txt4(int v1)
{
QString s;
s.setNum(v1); // conversion num -> txt
s = "0000"+s;
s = s.right(4);
return s;
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
setupUi(this);
setWindowTitle("Traceur SDcard v:" + version + " - Silicium628");
window()->setGeometry(0,0,1280,900);
pixmap1 = new QPixmap(10300,10300 );
scene1 = new SceneCliquable(this);
// QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
// QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
// QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
pen_trace.setCapStyle(Qt::RoundCap); // plume ronde
lecture_fichier_init();
lineEdit_1->setText(fileName_en_cours);
lire_fichier(fileName_en_cours);
systeme_mesure = 1;
zoom = 1;
ech=8;
effacer_ecran(); // et crée les groupes héritiers de la scene ainsi que la connexion entre les clics et le slot ici concerné
}
MainWindow::~MainWindow()
{
}
void MainWindow::effacer_ecran()
{
pixmap1->fill(vert_tres_fonce); // rappel : pixmap1 = 12010,12010
scene1->clear();
scene1 = new SceneCliquable(this);
connect(scene1, SIGNAL(envoiPosition_survol(int, int) ), this, SLOT (onReceptPos_survol(int, int) ));
connect(scene1, SIGNAL(envoiPosition_clic(int, int) ), this, SLOT (onReceptPos_clic(int, int) ));
connect(scene1, SIGNAL(envoiPosition_release(int, int) ), this, SLOT (onReceptPos_release(int, int) ));
scene1->setBackgroundBrush(couleur_ecran);
scene1->setSceneRect(-100,-100,10500,10500); // plus grand que la partie affichée
graphicsView1->setScene(scene1);
graphicsView1->setGeometry(5,25,1000,800); // POSITION et dimensions de l'écran
graphicsView1->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
scene1->addPixmap(*pixmap1);
groupe_quadrillage = new QGraphicsItemGroup();
scene1->addItem(groupe_quadrillage);
tracer_quadrillage();
groupe_quadrillage->setZValue(1);
QPointF P(600,y_max);
graphicsView1->centerOn(P);
}
void MainWindow::effacer_quadrillage()
{
foreach( QGraphicsItem *item, groupe_quadrillage->childItems() )
{
delete item;
}
}
/**
void MainWindow::tracer_mire_origine()
{ // à l'écran
QPoint P;
P.setX(0);
P.setY(0);
P /= ech;
QGraphicsLineItem *segment_pointage1 = new QGraphicsLineItem(groupe_pointage);
segment_pointage1->setPen(pen_pointage);
segment_pointage1->setLine(P.x()-10, P.x()-10, P.x()+10, P.x()+10);
QGraphicsLineItem *segment_pointage2 = new QGraphicsLineItem(groupe_pointage);
segment_pointage2->setPen(pen_pointage);
segment_pointage2->setLine(P.x()-10, P.x()+10, P.x()+10, P.x()-10);
tracer_texte(-20, -20, "(x=0; y=0)");
}
**/
/**
void MainWindow::tracer_texte(int x, int y, QString texte_i)
{ // à l'écran
y=-y;
x /= ech;
y /= ech;
QGraphicsTextItem *gtexte = new QGraphicsTextItem(groupe_trace);
gtexte->setDefaultTextColor(bleu);
gtexte->setPos(x,y);
gtexte->setPlainText(texte_i);
}
**/
void MainWindow::tracer_quadrillage()
{
int n, n_max;
int c;
float x,dx, x_max;
float y,dy;
float facteur=1;
float offset_x, offset_y;
quint8 gradu_bold;
quint16 unite;
quint16 step_grad; // nb de lignes d'espacement pour les textes de graduation
quint16 grad_max;
QString sti;
QPainter painter1(pixmap1); // rappel: pixmap1 = 12010,12010
// painter1.setPen(pen_quadrillage);
// valeurs par defaut :
facteur = 8; // largeur des cases
gradu_bold=10;
unite = 10;
n_max = 100;
step_grad =10;
y_max = 8000;
grad_max=10;
if (systeme_mesure == 1) // mm
{
if (ech == 1)
{
facteur = 8; // largeur des cases
gradu_bold=10;
unite = 10;
n_max = 100;
step_grad =10;
y_max = 8000;
grad_max=10;
}
if (ech == 4)
{
facteur = 2; // largeur des cases
gradu_bold=10;
unite = 10;
n_max = 500;
y_max = 10000;
step_grad =10;
grad_max=50;
}
if (ech == 8)
{
facteur = 10;
gradu_bold=10;
unite = 10;
n_max =100;
y_max = 10000;
step_grad =1;
grad_max=100;
}
if (ech == 80)
{
facteur = 10;
gradu_bold=10;
unite = 100;
n_max =10;
y_max = 1000;
step_grad =1;
grad_max=100;
}
}
if (systeme_mesure == 2) // 25mils
{
facteur = 6.35;
gradu_bold=4;
unite=250;
n_max = 160; // 1000 /facteur;
step_grad =1;
y_max = 10160; // 3110;
grad_max=4000;
}
if(systeme_mesure == 3) // grille en 0.8mm pour vérifier les smd en 0.8
{
facteur = 8;
gradu_bold=10;
unite = 0;
n_max =100;
step_grad =1;
}
// n_max = 1000 /facteur;
dx=10*facteur; // largeur des cases
x_max = dx * n_max;
dy=10*facteur; // hauteur des cases
//y_max = dy * n_max;
offset_x = 100+spinBox_X->value();
offset_y = 100+spinBox_Y->value();
ellipse_i = new QGraphicsEllipseItem(100-1,y_max+100-2,3,3);
pen_quadrillage.setColor(rouge);
ellipse_i->setPen(pen_quadrillage);
groupe_quadrillage->addToGroup(ellipse_i);
//painter1.setPen(pen_quadrillage);
//painter1.drawEllipse(0,0,3,3);
// lignes verticales
for (n=0; n<=n_max; n++)
{
if ((n % gradu_bold) == 0) {pen_quadrillage.setColor(couleur_quadrillage2);} else {pen_quadrillage.setColor(couleur_quadrillage1);}
x = dx * n;
ligne_i = new QGraphicsLineItem(x+offset_x, offset_y, x+offset_x, y_max+offset_y);
ligne_i->setPen(pen_quadrillage);
groupe_quadrillage->addToGroup(ligne_i);
//painter1.drawLine(x+offset, offset, x+offset, y_max+offset);
sti.setNum((unite * n)/10);
if (((unite * n)/10) == 1 ) {sti += "mm";}
//painter1.setPen(pen_texte);
text_gradu = new QGraphicsTextItem(sti);
text_gradu->setDefaultTextColor(couleur_texte);
text_gradu->setPos(step_grad*x +offset_x+2, y_max+offset_y+1 );
groupe_quadrillage->addToGroup(text_gradu);
if (ech == 1)
{
for (c=0; c<=n_max; c++)
{
y = dy * c;
text_gradu = new QGraphicsTextItem(sti);
text_gradu->setDefaultTextColor(couleur_texte);
text_gradu->setPos(step_grad*x +offset_x+2, offset_y+1 + step_grad*y );
groupe_quadrillage->addToGroup(text_gradu);
//painter1.drawText(step_grad*x +offset+2, step_grad*y +offset+20, sti);
}
}
}
// lignes horizontales
for (n=0; n<=n_max; n++)
{
if (((n_max-n) % gradu_bold) == 0) {pen_quadrillage.setColor(couleur_quadrillage2);} else {pen_quadrillage.setColor(couleur_quadrillage1);}
painter1.setPen(pen_quadrillage);
y = dy * n;
//painter1.drawLine(offset, y+offset, x_max+offset, y+offset);
ligne_i = new QGraphicsLineItem(offset_x, y+offset_y, x_max+offset_x, y+offset_y);
ligne_i->setPen(pen_quadrillage);
groupe_quadrillage->addToGroup(ligne_i);
sti.setNum(grad_max-((unite * n)/10));
//painter1.setPen(pen_texte);
//painter1.drawText(offset+10, step_grad*y +offset+20, sti);
text_gradu = new QGraphicsTextItem(sti);
text_gradu->setDefaultTextColor(couleur_texte);
text_gradu->setPos(offset_x+10, step_grad*y +offset_y+1);
groupe_quadrillage->addToGroup(text_gradu);
}
//scene1->addPixmap(*pixmap1);
scene1->addItem(groupe_quadrillage);
}
void MainWindow::tracer1pas()
{
quint32 x, y;
float z1, z2, z3;
quint8 R1,G1,B1, R2, G2, B2;
QColor couleur_piste2;
QPainter painter1(pixmap1);
painter1.setPen(pen_trace);
x = pos_moteur1;
y = pos_moteur2;
x /= ech;
y /= ech;
y=y_max-y;
if (checkBox_1->isChecked()) // couleur évolutive afin de repérer le parcours du tracé.
{
R1=130;
G1=130;
B1=130;
z3=124*cos((float)compteur_pas/10000.0);
z2=124*cos((float)(compteur_pas/10000.0)+(M_PI/3.0));
z1=124*cos((float)(compteur_pas/10000.0)+(2*M_PI/3.0));
R2= R1+z1;
G2= G1+z2;
B2= B1+z3;
couleur_piste2 = QColor::fromRgb(R2,G2,B2);
pen_trace.setColor(couleur_piste2);
}
else { pen_trace.setColor(couleur_piste); }
// if (((x % 100)==0) || ((y % 100)==0)) {pen_trace.setColor(blanc);}
if( ! checkBox_2->isChecked()){pen_trace.setWidth(30);} else {pen_trace.setWidth(1);}
painter1.drawPoint(x+100,y+100);
compteur_pas++;
}
void MainWindow::tracer_circuit()
{
compteur_pas=0;
quint32 i, i_max, k;
quint8 octet_i;
quint8 evt[4]; //chaque octet du fichier code pour 4 evenements codés sur deux bits chacun
quint8 evt_k;
quint8 fin_trace;
quint8 stop;
QString s1;
pos_moteur1=0;
pos_moteur2=0;
i_max = 800000; // nb_octets; // 4000000 et plus... A VOIR
if (radioButton_6->isChecked()) {i_max=60000;} // tracer début seulement (pour gagner du temps...)
i=512; // pour commencer la lecture au block_n; le block0 est réservé pour une entête
fin_trace=0;
stop=0;
while ((i<i_max) && (stop == 0) )
{
octet_i= datas_in[i];
i++;
// detection fin de trace
if(octet_i == '=') {fin_trace++ ;} else {fin_trace=0;}
if(fin_trace>10) {stop = 1;} // se produit si 10x '=' à la suite, ce qui fera sortir de la boucle
evt[0] = octet_i & 0b00000011;
evt[1] = (octet_i & 0b00001100) >>2;
evt[2] = (octet_i & 0b00110000 )>>4;
evt[3] = (octet_i & 0b11000000) >>6;
for (k=0; k<4; k++)
{
evt_k=evt[k];
if (evt_k == 0b00) {pos_moteur1++; }
if (evt_k == 0b01) {pos_moteur1--; }
if (evt_k == 0b10) {pos_moteur2++; }
if (evt_k == 0b11) {pos_moteur2--; }
//qDebug() << "M1=" << pos_moteur1 << " M2=" << pos_moteur2;
tracer1pas();
}
}
s1.setNum(i);
lineEdit_3->setText(s1);
scene1->addPixmap(*pixmap1);
QPointF P(600,y_max);
graphicsView1->centerOn(P);
}
void MainWindow::lecture_fichier_init()
{
QString line, tx1, tx2;
int p2;
tx1 = "";
QFile file1(QDir::homePath() + "/.cnc_traces/traces.ini");
if (file1.open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream in(&file1);
in.reset();
while ( !in.atEnd() )
{
line = in.readLine();
if (line.left(1) !="#")
{
if (line.indexOf("fileName_en_cours") != -1)
{
if ( (p2 = line.indexOf('=')) != -1)
{
line.remove(0,p2+1);
fileName_en_cours = line;
}
}
}
}
file1.close();
} else { fileName_en_cours = ""; tx1 = "fichier .ini non trouve, ce n'est pas grave !"; }
if (tx1 !="")
{
QMessageBox msgBox;
msgBox.setText(tx1);
msgBox.exec();
}
// statusBar1->showMessage(tx1 + " "+ tx2);
}
void MainWindow::enregistrer_fichier_init()
{
QDir dossierIni(QDir::homePath() + "/.cnc_traces/");
if (!dossierIni.exists())
{
QMessageBox msgBox;
msgBox.setText("Le repertoire : ~/" + dossierIni.dirName() + " n'existe pas, je vais le creer, et y placer le fichier de configuration 'cnc_gerber.ini' ");
msgBox.exec();
QDir dossierPerso(QDir::homePath());
dossierPerso.mkdir(".cnc_traces");
}
QFile file1(QDir::homePath() + "/.cnc_traces/traces.ini");
if (file1.open(QIODevice::WriteOnly | QIODevice::Text))
{
QTextStream out(&file1);
QString V;
out << "# les lignes commeneant par # sont ignorees";
out << '\n';
out << "# Ce fichier est genere automatiquement par le programme";
out << '\n';
out << "#";
out << '\n';
out << "fileName_en_cours=" << fileName_en_cours;
out << '\n';
}
file1.close();
}
int MainWindow::lire_fichier(QString nom_fichier1)
{
QFile file1(nom_fichier1);
QString s1;
if( !file1.exists() )
{
qDebug() << "Le fichier (" << nom_fichier1<< ") n'existe pas.";
return 1;
}
if (!file1.open(QIODevice::ReadOnly )) return 1;
QDataStream in1(&file1);
nb_octets = file1.size();
if (nb_octets> 2000000) {nb_octets = 2000000;}
s1.setNum(nb_octets);
lineEdit_2->setText(s1);
in1.readRawData(datas_in, nb_octets);
file1.close();
return 0;
}
int MainWindow::on_actionOuvrir_triggered() // menu "Fichier/ouvrir.."
{
int fich_charge_ok;
// fileName_en_cours = lineEdit_6->text();
fileName_en_cours = QFileDialog::getOpenFileName(this, tr("Open File"), fileName_en_cours, tr("Files (*.bin *.dat)"));
lineEdit_1->setText(fileName_en_cours);
fich_charge_ok = lire_fichier(fileName_en_cours); // <<------------
qDebug() << fich_charge_ok;
if (fich_charge_ok != 0) {return 1;}
enregistrer_fichier_init();
effacer_ecran();
tracer_quadrillage();
tracer_circuit();
return 0;
}
int MainWindow::on_actionRecharger_triggered()
{
int fich_charge_ok;
// lineEdit_6->setText(fileName_en_cours);
fich_charge_ok = lire_fichier(fileName_en_cours); // <<------------
if (fich_charge_ok != 0) {return 1;}
effacer_ecran();
tracer_quadrillage();
tracer_circuit();
return 0;
}
void MainWindow::onReceptPos_clic(int px, int py) // emis depuis un clic sur scene1, voir ma class "scene_cliquable"
{
QString s1,s2;
QPoint P;
x_clic_scene = px; // ne change qu'ici lors du clic
y_clic_scene = py; // ne change qu'ici lors du clic
s1.setNum(px);// conversion num -> txt
s2.setNum(-py);
// lineEdit_4->setText("x="+s1+" y="+s2);
P.setX(px);
P.setY(py);
graphicsView1->centerOn(P);
// P.setX(px * ech);
// P.setY(-py*ech);
}
void MainWindow::onReceptPos_release(int px, int py)
{
px=px; // pour éviter les warnings à la compilation. c'est ce que j'ai trouvé de mieux...
py=py;
}
void MainWindow::onReceptPos_survol(int px, int py) // emis lors d'un survol avec clic appuyé de scene1, voir ma class "scene_cliquable"
{
QString s1,s2;
QPoint P;
x_dyn = px;
y_dyn = py;
delta_x = x_clic_scene - x_dyn;
delta_y = y_clic_scene - y_dyn;
s1.setNum(delta_x);// conversion num -> txt
s2.setNum(delta_y);
lineEdit_4->setText("dx="+s1+" dy="+s2);
P.setX(delta_x);
P.setY(delta_y);
}
void MainWindow::on_Btn_tracer_clicked()
{
tracer_quadrillage();
tracer_circuit();
}
void MainWindow::on_Btn_effacer_clicked()
{
effacer_ecran();
}
void MainWindow::on_Btn_redessiner_clicked()
{
effacer_ecran();
tracer_quadrillage();
tracer_circuit();
}
void MainWindow::on_spinBox_posX_valueChanged(int arg1)
{
arg1=arg1;
}
void MainWindow::on_Btn_test_clicked()
{
QPointF P;
P.setX(delta_x);
P.setY(delta_y);
// graphicsView1->translate(delta_x, delta_y);
graphicsView1->centerOn(P);
}
void MainWindow::on_radioButton_1_clicked()
{
ech=4;
effacer_ecran();
}
void MainWindow::on_radioButton_2_clicked()
{
ech=8;
effacer_ecran();
}
void MainWindow::on_radioButton_3_toggled(bool checked)
{
checked=checked;
if (radioButton_3->isChecked()) {systeme_mesure = 1;} // mm
if (radioButton_4->isChecked()) {systeme_mesure = 2;} // mils
if (radioButton_8->isChecked()) {systeme_mesure = 3;} // mils
effacer_ecran();
}
void MainWindow::on_radioButton_4_clicked()
{
radioButton_2->setChecked(true);
on_radioButton_2_clicked();
}
void MainWindow::on_radioButton_5_clicked()
{
ech=80;
effacer_ecran();
}
void MainWindow::on_radioButton_8_clicked()
{
systeme_mesure = 3;
effacer_ecran();
}
void MainWindow::on_radioButton_9_clicked()
{
ech=1;
effacer_ecran();
}
void MainWindow::on_Btn_eff_quadrillage_clicked()
{
effacer_quadrillage();
}
void MainWindow::on_Btn_tracer_quadrillage_clicked()
{
tracer_quadrillage();
}
void MainWindow::on_spinBox_X_valueChanged(int arg1)
{
arg1=arg1;
effacer_quadrillage();
tracer_quadrillage();
}
void MainWindow::on_spinBox_Y_valueChanged(int arg1)
{
arg1=arg1;
effacer_quadrillage();
tracer_quadrillage();
}