bool RunsTableModel::postRow(int row_no, bool throw_exc) { bool is_single_user = sqlConnection().driverName().endsWith(QLatin1String("SQLITE"), Qt::CaseInsensitive); if(is_single_user) return Super::postRow(row_no, throw_exc); int col_stime = columnIndex("startTimeMs"); QF_ASSERT(col_stime >= 0, "Bad startTimeMs column!", return false); if(isDirty(row_no, col_stime)) { int id = value(row_no, "runs.id").toInt(); int orig_msec = origValue(row_no, col_stime).toInt(); int db_msec = 0; qf::core::sql::Transaction transaction(sqlConnection()); QString qs = "SELECT id, startTimeMs FROM runs WHERE id=" QF_IARG(id) " FOR UPDATE"; qf::core::sql::Query q(transaction.connection()); q.exec(qs, qf::core::Exception::Throw); if(q.next()) { db_msec = q.value("startTimeMs").toInt(); } if(orig_msec == db_msec) { bool ret = Super::postRow(row_no, throw_exc); transaction.commit(); return ret; } else { QString err_msg = tr("Mid-air collision setting start time, reload table and try it again."); revertRow(row_no); if(throw_exc) QF_EXCEPTION(err_msg); return false; } } return Super::postRow(row_no, throw_exc); }
void ClassesWidget::import_ocad_iofxml() { qfLogFuncFrame(); QString fn = qfd::FileDialog::getOpenFileName(this, tr("Open file"), QString(), "XML files (*.xml);; All files (*)"); if(fn.isEmpty()) return; try { QFile f(fn); if(f.open(QFile::ReadOnly)) { QDomDocument xdoc; QString err_str; int err_line; if(!xdoc.setContent(&f, &err_str, &err_line)) QF_EXCEPTION(QString("Error parsing xml file '%1' at line: %2").arg(err_str).arg(err_line)); QDomNodeList xml_courses = xdoc.elementsByTagName(QStringLiteral("Course")); QList<CourseDef> defined_courses_list; for (int i = 0; i < xml_courses.count(); ++i) { QDomElement el_course = xml_courses.at(i).toElement(); if(el_course.isNull()) QF_EXCEPTION(QString("Xml file format error: bad element '%1'").arg("Course")); CourseDef coursedef; QString course_name = element_text(el_course, QStringLiteral("CourseName")); course_name.replace(' ', QString()); course_name.replace(';', '-'); course_name.replace(',', '-'); course_name.replace(':', '-'); course_name.replace('+', '-'); coursedef.setName(course_name); QStringList class_names; QDomNodeList xml_classes = el_course.elementsByTagName(QStringLiteral("ClassShortName")); for (int j = 0; j < xml_classes.count(); ++j) { QString class_name = xml_classes.at(j).toElement().text().trimmed(); class_names << class_name; } coursedef.setClasses(class_names); QDomElement el_course_variantion = el_course.firstChildElement(QStringLiteral("CourseVariation")); if(el_course_variantion.isNull()) QF_EXCEPTION(QString("Xml file format error: missing element '%1'").arg("CourseVariation")); coursedef.setLenght(element_text(el_course_variantion, QStringLiteral("CourseLength")).trimmed().toInt()); coursedef.setClimb(element_text(el_course_variantion, QStringLiteral("CourseClimb")).trimmed().toInt()); QMap<int, QVariant> codes; QDomNodeList xml_controls = el_course.elementsByTagName(QStringLiteral("CourseControl")); for (int j = 0; j < xml_controls.count(); ++j) { QDomElement el_control = xml_controls.at(j).toElement(); int no = element_text(el_control, QStringLiteral("Sequence")).trimmed().toInt(); if(no <= 0) QF_EXCEPTION(QString("Xml file format error: bad sequence number %1 in %2").arg(no).arg(dump_element(el_control))); int code = element_text(el_control, QStringLiteral("ControlCode")).trimmed().toInt(); if(code <= 0) QF_EXCEPTION(QString("Xml file format error: bad control code %1 in %2").arg(code).arg(dump_element(el_control))); codes[no] = code; } coursedef.setCodes(codes.values()); defined_courses_list << coursedef; } importCourses(defined_courses_list); } } catch (const qf::core::Exception &e) { qf::qmlwidgets::framework::MainWindow *fwk = qf::qmlwidgets::framework::MainWindow::frameWork(); qf::qmlwidgets::dialogs::MessageBox::showException(fwk, e); } }
void ClassesWidget::import_ocad_v8() { QString fn = qfd::FileDialog::getOpenFileName(this, tr("Open file")); if(fn.isEmpty()) return; QFile f(fn); if(f.open(QFile::ReadOnly)) { QStringList lines; while (true) { QByteArray ba = f.readLine(); if(ba.isEmpty()) break; lines << QString::fromUtf8(ba).trimmed(); } try { QMap<QString, CourseDef> defined_courses_map; for(QString line : lines) { // [classname];coursename;0;lenght_km;climb;S1;dist_1;code_1[;dist_n;code_n];dist_finish;F1 if(line.isEmpty()) continue; QStringList class_names; qfc::String course_name = normalize_course_name(line.section(';', 1, 1)); QString class_name = line.section(';', 0, 0); if(class_name.isEmpty()) { for(auto ch : {'-', ',', ':', '+'}) { if(course_name.contains(ch)) { class_names = course_name.splitAndTrim(ch); break; } } if(class_names.isEmpty() && !course_name.isEmpty()) class_names << course_name; } else { class_names << class_name; } if(class_names.isEmpty()) { //class_names << course_name; qfWarning() << "cannot deduce class name, skipping line:" << line; continue; } if(defined_courses_map.contains(course_name)) { CourseDef cd = defined_courses_map.value(course_name); QStringList classes = cd.classes() << class_names; defined_courses_map[course_name].setClasses(classes); continue; } CourseDef &cd = defined_courses_map[course_name]; cd.setName(course_name); cd.setClasses(class_names); { QString s = line.section(';', 3, 3).trimmed(); s.replace('.', QString()).replace(',', QString()); cd.setLenght(s.toInt()); } { QString s = line.section(';', 4, 4).trimmed(); s.replace('.', QString()).replace(',', QString()); cd.setClimb(s.toInt()); } { qfc::String s = line.section(';', 6); QVariantList codes; QStringList sl = s.splitAndTrim(';'); for (int i = 0; i < sl.count()-2; i+=2) { bool ok; int code = sl[i+1].toInt(&ok); if(ok) codes << code; else QF_EXCEPTION(QString("Invalid code definition '%1' at sequence no: %2 in '%3'\nline: %4").arg(sl[i+1]).arg(i).arg(s).arg(line)); } cd.setCodes(codes); } } importCourses(defined_courses_map.values()); } catch (const qf::core::Exception &e) { qf::qmlwidgets::framework::MainWindow *fwk = qf::qmlwidgets::framework::MainWindow::frameWork(); qf::qmlwidgets::dialogs::MessageBox::showException(fwk, e); } } }