diff --git a/Undo.h b/Undo.h new file mode 100644 index 0000000..e4ad16d --- /dev/null +++ b/Undo.h @@ -0,0 +1,21 @@ +#ifndef UNDO_H +#define UNDO_H + +#include +#include + +class LineEditCommand : public QUndoCommand { +public: + LineEditCommand(QLineEdit* edit, const QString& oldText, const QString& newText) + : m_edit(edit), m_oldText(oldText), m_newText(newText) {} + + void undo() override { m_edit->setText(m_oldText); } + void redo() override { m_edit->setText(m_newText); } + +private: + QLineEdit* m_edit; + QString m_oldText; + QString m_newText; +}; + +#endif // UNDO_H diff --git a/data/images/d.json b/data/images/d.json new file mode 100644 index 0000000..e69de29 diff --git a/data/parcours2.json b/data/parcours2.json index 08f7f8f..8e4e563 100644 --- a/data/parcours2.json +++ b/data/parcours2.json @@ -1,44 +1,75 @@ { - "name": "parcours2", - "city": "Paris", - "departement": 1, - "difficulty": 2, - "duration": 2.3, - "length": 17.3, - "image": "../data/parcours1.png", - "steps": [ - { - "numero": 1, - "title": "Première étape", - "GPS": "N 45 37.199 W 1 2.009", - "reponse": -1, - "dialogue": [ - { - "personnage": "Quentin", - "texte": "ligne de dialogue 1 HJDDDZJJJJJJJJJJJJJJJJJJJDBJBDJZBZJDBJ" - }, - { - "personnage": "Malo", - "texte": "ligne de dialogue 2BDJJHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHBDHDBHBZHVZDHVHVHEDHJVHVDHEDJD" - } - ] - }, - { - "numero": 2, - "title": "Deuxième étape", - "GPS": "S 45 37.199 E 1 2.009", - "reponse": 4156, - "dialogue": [ - { - "personnage": "Antoine", - "texte": "ligne de dialogue 1" - }, - { - "personnage": "Giovanni", - "texte": "ligne de dialogue 2" - } - ] + "city": "Bourg en Bresse", + "departement": "1", + "difficulty": 3, + "duration": 3.8, + "image": "data/parcours1.png", + "length": 24.6, + "name": "Chemin des", + "steps": [ + { + "GPS": "N 46 12.321 E 5 13.245", + "dialogue": [ + { + "personnage": "Clémentine", + "texte": "Bienvenue à tous, voici le centre historique !" + }, + { + "personnage": "Léo", + "texte": "Regardez cette magnifique horloge, elle date du XIXe siècle !" } - ] - + ], + "numero": 1, + "reponse": 0, + "title": "Départ au centre-ville" + }, + { + "GPS": "N 46 12.500 E 5 13.800", + "dialogue": [ + { + "personnage": "Aurélie", + "texte": "Ici, on trouve les meilleurs fromages de la région !" + }, + { + "personnage": "Sami", + "texte": "Combien de colonnes vois-tu à l'entrée ?" + } + ], + "numero": 2, + "reponse": 6, + "title": "Marché couvert" + }, + { + "GPS": "N 46 12.900 E 5 13.900", + "dialogue": [ + { + "personnage": "Juliette", + "texte": "La Reyssouze apporte de la fraîcheur en été." + }, + { + "personnage": "Marc", + "texte": "Regarde cette inscription ancienne sur la pierre, tu arrives à la lire ?" + } + ], + "numero": 3, + "reponse": 0, + "title": "Au bord de la Reyssouze" + }, + { + "GPS": "N 46 13.024 E 5 14.160", + "dialogue": [ + { + "personnage": "Claire", + "texte": "Voilà l'abbaye ! Admire l'architecture." + }, + { + "personnage": "Nathalie", + "texte": "C'est ici la dernière étape. Observez bien la date !" + } + ], + "numero": 4, + "reponse": 1655, + "title": "Arrivée à l'abbaye" + } + ] } diff --git a/mainwindow.cpp b/mainwindow.cpp index e95726d..47b40a9 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,19 +1,59 @@ #include "mainwindow.h" #include "ui_mainwindow.h" #include "path.h" - +#include "step.h" +#include "Undo.h" #include #include #include +#include +#include +#include +#include +#include +#include int MainWindow::indexPath = 0; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) + , undoStack(new QUndoStack(this)) + , Clipboard(QGuiApplication::clipboard()) { ui->setupUi(this); indexPath++; + //currentPath = new Path(); + + connect(ui->titleEdit, &QLineEdit::editingFinished, this, [this]() { + static QString previousText; + QString currentText = ui->titleEdit->text(); + if(previousText != currentText) { + undoStack->push(new LineEditCommand(ui->titleEdit, previousText, currentText)); + previousText = currentText; + } + }); + + connect(ui->locEdit, &QLineEdit::editingFinished, this, [this]() { + static QString previousText; + QString currentText = ui->locEdit->text(); + if(previousText != currentText) { + undoStack->push(new LineEditCommand(ui->locEdit, previousText, currentText)); + previousText = currentText; + } + }); + + connect(ui->imagePath, &QLineEdit::editingFinished, this, [this]() { + static QString previousText; + QString currentText = ui->imagePath->text(); + if(previousText != currentText) { + undoStack->push(new LineEditCommand(ui->imagePath, previousText, currentText)); + previousText = currentText; + } + }); + + connect(ui->actionEditUndo, &QAction::triggered, undoStack, &QUndoStack::undo); + connect(ui->actionEditRedo, &QAction::triggered, undoStack, &QUndoStack::redo); } MainWindow::~MainWindow() @@ -36,7 +76,7 @@ void MainWindow::onTextChanged() textChanged = true; } -void MainWindow::loadPath() +void MainWindow::loadNewPath() { QString fileName = QFileDialog::getOpenFileName(this, "Open the file"); if(fileName.isEmpty()) return; @@ -50,6 +90,19 @@ void MainWindow::loadPath() Path* p = new Path(&file); currentPath = p; path.append(p); + loadPath(p); + currentFile = fileName; + + int pathCount = path.length(); + ui->pathNumber->setMaximum(pathCount); + ui->pathNumber->setSuffix("/" + QString::number(pathCount)); + ui->pathNumber->setValue(path.indexOf(currentPath)+1); +} + +void MainWindow::loadPath(Path* p) { + + QList steps = p->getStep(); + ui->titleEdit->setText(p->getName()); ui->locEdit->setText(p->getCity()); @@ -57,8 +110,39 @@ void MainWindow::loadPath() ui->lengthSpin->setValue(p->getLength()); ui->durationSpin->setValue(p->getDuration()); ui->imagePath->setText(p->getImage()); - + ui->depSpin->setValue(p->getDepartement()); loadImage(p->getImage()); + + + ui->dialogEdit->clear(); + + if(!steps.isEmpty()) { + Step firstStep = p->getStep().first(); + ui->stepTitle->setText(firstStep.getTitle()); + ui->LatitudeSpin->setValue(firstStep.getLatitude()); + ui->longitudeSpin->setValue(firstStep.getLongitude()); + + for(int i = 0; i < firstStep.getTexte().length(); i++) { + QString q = firstStep.getPersonnage().at(i) + ": " + firstStep.getTexte().at(i); + ui->dialogEdit->appendPlainText(q); + } + + ui->stepNumber->setValue(1); + ui->stepNumber->setSuffix("/" + QString::number(steps.length())); + ui->stepNumber->setMaximum(steps.length()); + } +} + +void MainWindow::loadStep(Step s) { + ui->stepTitle->setText(s.getTitle()); + ui->LatitudeSpin->setValue(s.getLatitude()); + ui->longitudeSpin->setValue(s.getLongitude()); + ui->responseSpin->setValue(s.getResponse()); + + for(int i = 0; i < s.getTexte().length(); i++) { + QString q = s.getPersonnage().at(i) + ": " + s.getTexte().at(i); + ui->dialogEdit->appendPlainText(q); + } } void MainWindow::addNewPath() @@ -267,36 +351,35 @@ void MainWindow::exportHTMLMap(int index) void MainWindow::loadImage(QString fileName) { - QString ext[] = {"png", "jpeg", "jpg"}; QFile file(fileName); if (!file.open(QIODevice::ReadOnly | QFile::Text)) { - QMessageBox::warning(this, "Warning", "Cannot open file: " + + QMessageBox::warning(this, "Warning", "Cannot open image: " + file.errorString()); - return; - } - QString text = file.fileName(); - bool acceptedExt = false; - for(QString e : ext) { - if(text.endsWith(e)) acceptedExt = true; + }else{ + QString text = file.fileName(); + bool acceptedExt = false; + for(QString e : ext) { + if(text.endsWith(e)) acceptedExt = true; + } + if(!acceptedExt) { + QMessageBox::warning(this, "Warning", "Format de fichier incorrect"); + return; + } + + + ui->imagePath->setText(text); + + + QPixmap px(fileName); + + ui->imageLbl->setPixmap(px); + + file.close(); } - if(!acceptedExt) { - QMessageBox::warning(this, "Warning", "Format de fichier incorrect"); - return; - } - - - ui->imagePath->setText(text); - - - QPixmap px(fileName); - - ui->imageLbl->setPixmap(px); - - file.close(); } @@ -310,7 +393,7 @@ void MainWindow::on_pushButton_clicked() void MainWindow::on_actionOpen_triggered() { - this->loadPath(); + this->loadNewPath(); } void MainWindow::on_toolButton_clicked() @@ -320,6 +403,7 @@ void MainWindow::on_toolButton_clicked() loadImage(fileName); } +<<<<<<< mainwindow.cpp int MainWindow::getIndexPath() const { return indexPath; @@ -358,5 +442,132 @@ Path *MainWindow::getCurrentPath() const void MainWindow::setCurrentPath(Path *newCurrentPath) { currentPath = newCurrentPath; +======= + +void MainWindow::saveFile(){ + QString fileName; + if (currentFile.isEmpty()) { + fileName = QFileDialog::getSaveFileName(this, "Save"); + currentFile = fileName; + } else { + fileName = currentFile; + } + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly | QFile::Text)) { + QMessageBox::warning(this, "Warning", "Cannot save file: " + file.errorString()); + return; + } + setWindowTitle(fileName); + QJsonObject json; + json["name"] = ui->titleEdit->text(); + json["city"] =ui->locEdit->text(); + json["departement"] = ui->depSpin->text(); + json["difficulty"] = ui->diffSpin->value(); + json["duration"] = ui->durationSpin->value(); + json["length"] = ui->lengthSpin->value(); + json["image"] = ui->imagePath->text(); + + QJsonArray steps; + int cpt=0; + for(Step step: currentPath->getStep()){ + cpt++; + QJsonObject stepObject; + stepObject["numero"] = cpt; + stepObject["title"] = step.getTitle(); + stepObject["GPS"] = step.toGPSFormat(); + stepObject["reponse"] = step.getResponse(); + QJsonArray dialogues; + for(int i=0; isaveFile(); +} + +void MainWindow::on_actionopenFile_triggered() +{ + this->loadNewPath(); +} + +void MainWindow::on_actionEditCopy_triggered() +{ + QWidget *focused = QApplication::focusWidget(); + QLineEdit* lineEdit = qobject_cast(focused); + + if(lineEdit) { + Clipboard->setText(lineEdit->selectedText()); + } +} + + +void MainWindow::on_actionEditPaste_triggered() +{ + QWidget *focused = QApplication::focusWidget(); + QLineEdit* lineEdit = qobject_cast(focused); + + if(lineEdit) { + QString text = lineEdit->text(); + int pos = lineEdit->cursorPosition(); + text.insert(pos, Clipboard->text()); + lineEdit->setText(text); + } +} + + +void MainWindow::on_actionEditCut_triggered() +{ + QWidget *focused = QApplication::focusWidget(); + QLineEdit* lineEdit = qobject_cast(focused); + + if(lineEdit) { + QString text = lineEdit->text(); + QString selectedText = lineEdit->selectedText(); + int pos = lineEdit->selectionStart(); + text.remove(pos, selectedText.length()); + Clipboard->setText(selectedText); + lineEdit->setText(text); + } +} + + +void MainWindow::on_pathNumber_valueChanged(int arg1) +{ + this->loadPath(path.at(ui->pathNumber->value()-1)); + currentPath = path.at(arg1-1); +} + + +void MainWindow::on_stepNumber_valueChanged(int arg1) +{ + this->loadStep(currentPath->getStep().at(arg1-1)); +} + + +void MainWindow::on_validateBtn_clicked() +{ + currentPath->setName(ui->titleEdit->text()); + currentPath->setCity(ui->locEdit->text()); + currentPath->setImage(ui->imagePath->text()); + currentPath->setLength(ui->lengthSpin->value()); + currentPath->setDifficulty(ui->diffSpin->value()); + currentPath->setDuration(ui->durationSpin->value()); + + currentPath->getStep()[ui->stepNumber->value()-1].setTitle(ui->stepTitle->text()); + currentPath->getStep()[ui->stepNumber->value()-1].setResponse(ui->responseSpin->value()); + } diff --git a/mainwindow.h b/mainwindow.h index abe0783..84ff04c 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -2,7 +2,8 @@ #define MAINWINDOW_H #include - +#include +#include #include "path.h" QT_BEGIN_NAMESPACE @@ -21,7 +22,9 @@ public: void updatePathView(); void updateStepView(size_t num); void onTextChanged(); - void loadPath(); + void loadNewPath(); + void loadPath(Path* p); + void loadStep(Step s); void addNewPath(); void addNewStep(); void exportHTMLMap(int index); @@ -35,6 +38,8 @@ public: int getIndexPath() const; void setIndexPath(int newIndexPath); + void exportHTMLMap(); + void saveFile(); private slots: void on_pushButton_clicked(); @@ -43,6 +48,22 @@ private slots: void on_toolButton_clicked(); + void on_actionSave_triggered(); + + void on_actionopenFile_triggered(); + + void on_actionEditCopy_triggered(); + + void on_actionEditPaste_triggered(); + + void on_actionEditCut_triggered(); + + void on_pathNumber_valueChanged(int arg1); + + void on_stepNumber_valueChanged(int arg1); + + void on_validateBtn_clicked(); + private: Ui::MainWindow *ui; QString currentFile; @@ -51,5 +72,7 @@ private: QList path; Path* currentPath; void loadImage(QString fileName); + QUndoStack *undoStack; + QClipboard* Clipboard; }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui index 95edce2..d69d464 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -7,17 +7,41 @@ 0 0 800 - 626 + 868 + + + 0 + 0 + + + + + 0 + 0 + + MainWindow + + + 0 + 30 + + + + + 0 + 0 + + 800 - 521 + 1000 @@ -38,13 +62,16 @@ Path information - - Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop - + + + 0 + 0 + + 16777215 @@ -52,217 +79,230 @@ - QFrame::Shape::StyledPanel + QFrame::Shape::NoFrame - - QFrame::Shadow::Raised - - - - - 10 - 20 - 45 - 27 - - - - - - - 60 - 20 - 391 - 26 - - - - - - - 10 - 60 - 441 - 45 - - - - - 0 - - - 0 - - - - - Localisation - - - - - - - - - - - - - - - 470 - 20 - 281 - 191 - - - - - - - - - - 0 - 110 - 451 - 63 - - - - - 0 - - - 0 - - - - - - - - Difficulty + + + + + + + + + + + 1 + + + 1 + + + + + + + + + + + + + + 0 - - - - - - /5 + + 0 - - 5 + + + + Localisation + + + + + + + + + + + + + + + + + 0 - - - - - - - - - - - - Duration + + 0 - - - - - - h + + + + + 0 + + + 0 + + + + + Difficulty + + + + + + + /5 + + + 5 + + + + + + + + + + + 0 + + + 0 + + + + + Duration + + + + + + + h + + + 1 + + + 0.100000000000000 + + + + + + + + + + + 0 + + + 0 + + + + + Length + + + + + + + Km + + + 1 + + + 500.000000000000000 + + + 0.100000000000000 + + + + + + + + + + + + + + 9 - - 1 + + 0 - - 0.100000000000000 - - - - - - - - - - - - - Length - - - - - - - Km - - - 1 - - - 500.000000000000000 - - - 0.100000000000000 - - - - - - - - - - - - 0 - 180 - 451 - 44 - - - - - 9 - - - 0 - - - - - Image - - - - - - - - - - ... - - - - :/data/images/data/images/add.png:/data/images/data/images/add.png - - - - - - - Select Image File - - - - - + + + + Image + + + + + + + + + + ... + + + + :/data/images/data/images/add.png:/data/images/data/images/add.png + + + + + + + Select Image File + + + + + + + + + + + + + + 300 + 0 + + + + + 16777215 + 200 + + + + + + + true + + + + @@ -276,19 +316,160 @@ Step information - - Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop - - + + + + 0 + 0 + + + + + 0 + 0 + + - QFrame::Shape::StyledPanel - - - QFrame::Shadow::Raised + QFrame::Shape::NoFrame + + + + + + + + 1 + + + + + + + + + + ... + + + + :/data/images/data/images/add.png:/data/images/data/images/add.png + + + + + + + + + + + + + + + + Latitude + + + Qt::AlignmentFlag::AlignCenter + + + + + + + 6 + + + 90.000000000000000 + + + + + + + + + + + + + Longitude + + + Qt::AlignmentFlag::AlignCenter + + + + + + + 6 + + + -180.000000000000000 + + + 180.000000000000000 + + + + + + + + + + + + + Response + + + Qt::AlignmentFlag::AlignCenter + + + + + + + + + + + + + + + + + 0 + 255 + + + + + 0 + 0 + + + + false + + + + + + + Valider + + + + @@ -310,15 +491,8 @@ - - - Edit - - - - toolBar @@ -330,7 +504,7 @@ false - + @@ -368,11 +542,11 @@ - + :/data/images/data/images/new.png:/data/images/data/images/new.png - NewFile + New File QAction::MenuRole::NoRole @@ -380,11 +554,11 @@ - + :/data/images/data/images/save_as.png:/data/images/data/images/save_as.png - SaveFile + Save QAction::MenuRole::NoRole @@ -392,11 +566,11 @@ - + :/data/images/data/images/save.png:/data/images/data/images/save.png - SaveAsFile + Save as QAction::MenuRole::NoRole @@ -404,11 +578,11 @@ - + :/data/images/data/images/print.png:/data/images/data/images/print.png - PrintFile + Print QAction::MenuRole::NoRole @@ -416,11 +590,11 @@ - + :/data/images/data/images/copy.png:/data/images/data/images/copy.png - EditCopy + Copy QAction::MenuRole::NoRole @@ -428,11 +602,11 @@ - + :/data/images/data/images/paste.png:/data/images/data/images/paste.png - EditPaste + Paste QAction::MenuRole::NoRole @@ -440,11 +614,11 @@ - + :/data/images/data/images/cut.png:/data/images/data/images/cut.png - EditCut + Cut QAction::MenuRole::NoRole @@ -452,11 +626,11 @@ - + :/data/images/data/images/edit_undo.png:/data/images/data/images/edit_undo.png - EditUndo + Undo QAction::MenuRole::NoRole @@ -464,23 +638,23 @@ - + :/data/images/data/images/edit_redo.png:/data/images/data/images/edit_redo.png - EditRedo + Redo QAction::MenuRole::NoRole - + - - :/data/images/data/images/new.png:/data/images/data/images/new.png + + :/data/images/data/images/open.png:/data/images/data/images/open.png - New + Open file QAction::MenuRole::NoRole @@ -488,7 +662,7 @@ - + diff --git a/path.cpp b/path.cpp index 26a2558..d4ed62b 100644 --- a/path.cpp +++ b/path.cpp @@ -45,11 +45,46 @@ QString Path::getImage() const return image; } -QList Path::getStep() const +QList& Path::getStep() { return step; } +void Path::setCity(const QString &newCity) +{ + city = newCity; +} + +void Path::setDepartement(int newDepartement) +{ + departement = newDepartement; +} + +void Path::setName(const QString &newName) +{ + name = newName; +} + +void Path::setDifficulty(unsigned int newDifficulty) +{ + difficulty = newDifficulty; +} + +void Path::setDuration(float newDuration) +{ + duration = newDuration; +} + +void Path::setLength(float newLength) +{ + length = newLength; +} + +void Path::setImage(const QString &newImage) +{ + image = newImage; +} + Path::Path(QFile *file){ if (!file->open(QIODevice::ReadOnly)) { qWarning() << "Could not open file:" << file->errorString(); diff --git a/path.h b/path.h index 7eb9315..fef7334 100644 --- a/path.h +++ b/path.h @@ -28,7 +28,14 @@ public: float getDuration() const; float getLength() const; QString getImage() const; - QList getStep() const; + QList& getStep(); + void setCity(const QString &newCity); + void setDepartement(int newDepartement); + void setName(const QString &newName); + void setDifficulty(unsigned int newDifficulty); + void setDuration(float newDuration); + void setLength(float newLength); + void setImage(const QString &newImage); }; #endif // PATH_H diff --git a/sae201.pro b/sae201.pro index e43f61e..e046919 100644 --- a/sae201.pro +++ b/sae201.pro @@ -16,6 +16,7 @@ SOURCES += \ web.cpp HEADERS += \ + Undo.h \ mainwindow.h \ step.h \ path.h \ diff --git a/step.cpp b/step.cpp index 6b81de9..c8aaa5a 100644 --- a/step.cpp +++ b/step.cpp @@ -64,6 +64,16 @@ Step::Step() { } +QList Step::getPersonnage() const +{ + return personnage; +} + +QList Step::getTexte() const +{ + return texte; +} + Step::Step( QJsonObject &in) { title = in["title"].toString(); @@ -71,7 +81,7 @@ Step::Step( QJsonObject &in) QString gps = in["GPS"].toString(); QStringList parts = gps.split(" ", Qt::SkipEmptyParts); - QChar latDir = parts[0][0]; // c'est le premier QChar du QString t'as capté + QChar latDir = parts[0][0]; int latDeg = parts[1].toInt(); float latMin = parts[2].toFloat(); setLatitude(latDeg, latMin, latDir); @@ -110,3 +120,25 @@ void Step::setLongitude(int degree, float minute, QChar EW) if (EW.toUpper() == 'W') longitude = -longitude; } + +QString Step::toGPSFormat(){ + int latDeg = static_cast(latitude); + float latMin = (latitude - latDeg) * 60.0; + QChar latDir = latitude >= 0 ? 'N' : 'S'; + latDeg = abs(latDeg); + + int lonDeg = static_cast(longitude); + float lonMin = (longitude - lonDeg) * 60.0; + QChar lonDir = longitude >= 0 ? 'E' : 'W'; + lonDeg = abs(lonDeg); + + QString gpsString = QString("%1 %2 %3 %4 %5 %6") + .arg(latDir) + .arg(latDeg, 2) + .arg(latMin, 5, 'f', 3) + .arg(lonDir) + .arg(lonDeg, 2) + .arg(lonMin, 5, 'f', 3); + + return gpsString; +}