diff --git a/src/data/nodes/student_data.cpp b/src/data/nodes/student_data.cpp index d36f77158060906f29fd8b2d0bd14257e9497653..127b64f4c81b7d94818c10bb175f0df4a606953e 100644 --- a/src/data/nodes/student_data.cpp +++ b/src/data/nodes/student_data.cpp @@ -167,8 +167,8 @@ void StudentData::insertData( // Course title and semester are the same for all students // So just read them from the first student - mCourseTitle = c.data[1][courseTitleIdx]; - mSemester = c.data[1][semesterIdx]; + mCourseTitles.emplaceBack(c.data[1][courseTitleIdx]); + mSemesters.emplaceBack(c.data[1][semesterIdx]); // Read the registration number and attempt number from the csv-file to our // struct @@ -199,17 +199,11 @@ void StudentData::insertData( // Assert that course title and semester really are consistent among all // students - if (line[courseTitleIdx] != mCourseTitle) { - throw DynamiteException( - QString(str::error::inconsistentRwthOnlineData) - .arg("course title", mCourseTitle, line[courseTitleIdx], - line[regIdx])); + if (!mCourseTitles.contains(line[courseTitleIdx])) { + mCourseTitles.emplaceBack(line[courseTitleIdx]); } - if (line[semesterIdx] != mSemester) { - throw DynamiteException( - QString(str::error::inconsistentRwthOnlineData) - .arg("semester", mSemester, line[semesterIdx], - line[regIdx])); + if (!mSemesters.contains(line[semesterIdx])) { + mSemesters.emplaceBack(line[semesterIdx]); } } } diff --git a/src/data/nodes/student_data.hpp b/src/data/nodes/student_data.hpp index eb747e1076d21a963df0b73058df6f502eec6af5..b3cfb4521efb339f9a960504e3ceab1178c76039 100644 --- a/src/data/nodes/student_data.hpp +++ b/src/data/nodes/student_data.hpp @@ -20,8 +20,8 @@ struct StudentData : Node<> { */ explicit StudentData(const CsvDump &c) noexcept(false); - QString mCourseTitle; - QString mSemester; + QList<QString> mCourseTitles; + QList<QString> mSemesters; QList<QString> mRegistrationNr; QList<int> mAttemptNr; diff --git a/src/model/input_model.cpp b/src/model/input_model.cpp index 0b5ac21437d19687fb35ecac767516f20fd76699..23a6a079584777d700d3f7b106b9d552abd0ff42 100644 --- a/src/model/input_model.cpp +++ b/src/model/input_model.cpp @@ -46,6 +46,24 @@ FileOpenError InputModel::loadCsv(const QString &path, QWidget *parent) { case FileType::rwth: mLoadedData.emplace<QSharedPointer<StudentData>>( new StudentData(*dump)); + { + const auto &courseTitles = + std::get<QSharedPointer<StudentData>>(mLoadedData) + ->mCourseTitles; + if (courseTitles.size() > 1) { + error.mWarnings.append( + QString(str::error::multipleCourseTitles) + .arg(courseTitles.join("; "))); + } + const auto &semesters = + std::get<QSharedPointer<StudentData>>(mLoadedData) + ->mSemesters; + if (semesters.size() > 1) { + error.mWarnings.append( + QString(str::error::multipleSemesters) + .arg(semesters.join("; "))); + } + } break; case FileType::bonus: mLoadedData.emplace<QSharedPointer<BonusPoints>>( diff --git a/src/util/strings.hpp b/src/util/strings.hpp index 5a451089c968068f88db3b7fae4cb6ef3c4ac573..c5b585e8003efd37583511e75cd11a4164771984 100644 --- a/src/util/strings.hpp +++ b/src/util/strings.hpp @@ -277,9 +277,8 @@ constexpr auto noColumn = "No %1 column found."; constexpr auto parseFailure = "Failed to parse %1 %2"; -constexpr auto inconsistentRwthOnlineData = - "Inconsistent %1: \"%2\" in line 1, but \"%3\" for registration " - "number %4"; +constexpr auto multipleCourseTitles = "Multiple course titles: %1"; +constexpr auto multipleSemesters = "Multiple semesters: %1"; constexpr auto bonusArraySizeMismatch = "Internal error while reading bonus points (array size mismatch)."; diff --git a/src/view/input_window/input_tab_csv_single_cohort.cpp b/src/view/input_window/input_tab_csv_single_cohort.cpp index 9a479f3eb14a22094e10af07c81767d42586ace4..51f6eef98c3397e80c1ee83adcad7a6601403ea3 100644 --- a/src/view/input_window/input_tab_csv_single_cohort.cpp +++ b/src/view/input_window/input_tab_csv_single_cohort.cpp @@ -41,7 +41,6 @@ InputTabCsvSingleCohort::InputTabCsvSingleCohort(QWidget *parent) mMainLayout.addWidget(&mGradeBoundaryStepSize[s], boundaryStepRow[s], 1, 1, 1); - // mGradeBoundaryStepSize[s].setCheckable(false); } } // Don't enable the import button as long as no files are selected. @@ -120,15 +119,14 @@ void InputTabCsvSingleCohort::fileSelectChange() { mExamFileView.mFileState == FileSelectState::ok && mStudentFileView.mFileState == FileSelectState::ok; - // Update clickability of import button and grade boundary steps + // Display warning if the selected files don't reference the same students if (essentialFilesReady) { - // Display warning if the selected files don't reference the same - // students warnIfLowStudentIntersection( this, mExamFileView.model(), mStudentFileView.model(), mBonusFileView.model(), mBonusFileView.mFileState); } + // Update clickability of import button and grade boundary steps if (essentialFilesReady) { // Enable the import button mImportButton.setEnabled(true); @@ -136,7 +134,6 @@ void InputTabCsvSingleCohort::fileSelectChange() { // Enable grade boundary buttons, select the radio button the heuristic // suggests for (auto &r : mGradeBoundaryStepSize) { - r.setCheckable(true); r.setChecked(false); } const auto gradeBoundaryStepSize = @@ -145,11 +142,5 @@ void InputTabCsvSingleCohort::fileSelectChange() { } else { // Disable the import button mImportButton.setEnabled(false); - - // Disable the grade boundary buttons again. - // for (auto &r : mGradeBoundaryStepSize) { - // r.setChecked(false); - // r.setCheckable(false); - //} } } diff --git a/src/view/input_window/load_file_view.cpp b/src/view/input_window/load_file_view.cpp index 89b30770e859ad64347696efd93cf213e3d2f302..1bd85d109d05ce7d9be56ac231802c4879064fa2 100644 --- a/src/view/input_window/load_file_view.cpp +++ b/src/view/input_window/load_file_view.cpp @@ -147,9 +147,15 @@ void printGenericInfo(QTableWidget &table, } [[nodiscard]] auto printRwthOnlineInfo(const StudentData &students) { + + const auto titlePluralS = students.mCourseTitles.size() > 1 ? "s" : ""; + const auto semesterPluralS = students.mSemesters.size() > 1 ? "s" : ""; + QList<QPair<QVariant, QVariant>> tableEntries; - tableEntries.emplace_back("Course title", students.mCourseTitle); - tableEntries.emplace_back("Semester", students.mSemester); + tableEntries.emplace_back(QString("Course title%1").arg(titlePluralS), + students.mCourseTitles.join("; ")); + tableEntries.emplace_back(QString("Semester%1").arg(semesterPluralS), + students.mSemesters.join("; ")); tableEntries.emplace_back("# registered students", students.mRegistrationNr.size()); diff --git a/test/util/print_types.cpp b/test/util/print_types.cpp index 55631316d26855267312ce22902c51d4782194bd..4d5f8d22d9599b848327335c2282de53cea2acc5 100644 --- a/test/util/print_types.cpp +++ b/test/util/print_types.cpp @@ -21,8 +21,9 @@ std::ostream &operator<<(std::ostream &os, const Points &obj) { std::ostream &operator<<(std::ostream &os, const DAG &obj) { - os << "DAG(Title: " << obj.mStudents.mCourseTitle.toStdString() - << ", semester: " << obj.mStudents.mSemester.toStdString() << ")"; + os << "DAG(Title: " << obj.mStudents.mCourseTitles.join("; ").toStdString() + << ", semester: " << obj.mStudents.mSemesters.join("; ").toStdString() + << ")"; return os; }