Ejemplo n.º 1
0
void FileReader::loadFile(std::string file_path, size_t i){//, Page::PagePtr page) { 
  std::ifstream file_stream(file_path);
  file_stream.seekg(0, std::ios::end);
  size_t size = file_stream.tellg();
  std::string buffer(size, ' ');
  file_stream.seekg(0);
  file_stream.read(&buffer[0], size); 
  file_stream.close();
  Page::PagePtr p = getPages()[i];
  p->retrieveWords(buffer);
}
Ejemplo n.º 2
0
GGSearchResult GGAbstractModel::search(GGSearchRequest req) const
{
    GGSearchResult res(req, this);
    QList<GGPage*> pages;
    if (req.scene() == GG::InvalidSceneId) {
        pages = getPages();
    } else if (getScene(req.scene())) {
        pages = getScene(req.scene())->pages().toList();
    }

    foreach (const GGPage *p, pages) {
        if (p->match(req, res)) {
            // -1 mean find all
            if (req.maxResults() >= 0 && res.count() >= req.maxResults()) {
                break;
            }
        }
    }
    return res;
}
Ejemplo n.º 3
0
void Global::generatePDFs(QString dirname)
{
  size_t pageCount = 0;

  for (size_t s = 0; s < getNumStudents(); s++)
  {
    Student& student = db()->getStudent(s);
    // Use the student name to form the file name for the repot
    QString clean = student.getStudentName();
    // Convert all non alpha/num chars into an underscore
    for (QString::iterator i = clean.begin(); i != clean.end(); i++)
    {
      if (!i->isLetterOrNumber())
        *i = '_';
    }
    if (clean.length() == 0)
    {
      GINFODIALOG(QString("Cannot render PDF because student %1 does not have a name assigned").arg(s+1));
      return;
    }
    QString pdfname (dirname + "/report-" + clean + ".pdf");
    GDEBUG ("Generating PDF [%s] for student [%s]", qPrintable(pdfname), qPrintable(student.getStudentId()));

    QPrinter printer (QPrinter::HighResolution);
    printer.setOutputFormat (QPrinter::PdfFormat);
    printer.setOutputFileName (pdfname);
    printer.setPageSize(QPrinter::Letter);
    printer.setResolution(150); // DPI for the printing
    printer.setColorMode(QPrinter::GrayScale);

    QPainter painter;
    if (!painter.begin(&printer)) // Check for errors here
      GFATAL("Failed to do QPainter begin()");

    // Can use this code to change the text color, but causes larger PDF files
    // since it must use a color output format instead.
    //QPen penColor(QColor("#000090")); // Change text to dark blue
    //painter.setPen(penColor);

    for (size_t p = 0; p < getNumPagesPerStudent(); p++)
    {
      pageCount++;
      // Add spaces at the end so the widget can resize into the reserved space without a re-layout
      Global::getStatusLabel()->setText(QString("Generating PDF for student %1 of %2, page %3 of %4 (%5 percent)     ").
                                        arg(s+1).arg(getNumStudents()).arg(p+1).arg(getNumPagesPerStudent()).arg(rint(0.5+100.0*pageCount/(1.0*getNumPages()))));
      // Flush out Qt events so that the UI update occurs inside this handler
      Global::getQApplication()->processEvents();

      GDEBUG ("Printing page %zu of %zu for report [%s]", p+1, getNumPagesPerStudent(), qPrintable(pdfname));
      QPixmap pix = getPages()->getQPixmap(p+s*getNumPagesPerStudent());
      // Scale the pixmap to fit the printer
      pix = pix.scaled(printer.pageRect().width(), printer.pageRect().height(), Qt::KeepAspectRatio);
      // Draw the pixmap to the printer
      painter.drawPixmap (0, 0, pix);

      // Print out the student details at the top of the page
      QString title = QString("Name: %1  ID: %2  Page: %3 of %4  Final Grade: %5 of %6").arg(student.getStudentName()).arg(student.getStudentId()).arg(p+1).arg(getNumPagesPerStudent()).arg(student.getTotal()).arg(db()->getTotalMaximum());
      painter.drawText(0, 0, title);

      // Build up a results string to print onto the page
      QString grades ("Results:");
      size_t pageTotal = 0;
      size_t pageMax = 0;
      for (size_t q = 0; q < getNumQuestions(); q++)
      {
        // See if the question is on this page
        GASSERT(Global::db()->getQuestionPage(q) != 0, "Cannot have page 0 assigned for question %zu", q);
        if (Global::db()->getQuestionPage(q) < 0)
        {
          GINFODIALOG(QString("Cannot render PDF because question %1 does not have a page assigned").arg(q+1));
          return;
        }
        if (Global::db()->getQuestionPage(q) == ((int)p+1))
        {
          if (student.getGrade(q) < 0)
          {
            GINFODIALOG(QString("Cannot render PDF for student [%1] because question %2 has no grade assigned").arg(student.getStudentName()).arg(q+1));
            return;
          }
          pageTotal += student.getGrade(q);
          pageMax += Global::db()->getQuestionMaximum(q);
          grades += QString("  Q%1 = %2/%3").arg(q+1).arg(student.getGrade(q)).arg(Global::db()->getQuestionMaximum(q));
          if (student.getFeedback(q) != "")
            grades += QString(" [%1]").arg(student.getFeedback(q));
        }
      }
      grades += QString("  Totals = %1/%2").arg(pageTotal).arg(pageMax);
      if (pageMax == 0)
          grades = QString("No Results For This Page");
      // Wrap the text to fit a bounding box that is the width of the page, align to the bottom of the page
      painter.drawText(0, 30, printer.pageRect().width(), printer.pageRect().height()-30, Qt::TextWordWrap | Qt::AlignBottom, grades);

      // Insert a new page except on the last one
      if (p < getNumPagesPerStudent()-1)
        if (!printer.newPage()) // Check for errors here
          GFATAL("Failed to do newPage() call");
    }

    painter.end();
  }
  Global::getStatusLabel()->setText("");
}
Ejemplo n.º 4
0
void Global::initDatabase(QString filename)
{
  GASSERT(_db == NULL, "Cannot initialize database twice");

  QFile fd (filename);
  if (!fd.open(QIODevice::ReadOnly))
    GEXITDIALOG("Could not open project file for reading " + filename);
  QTextStream file (&fd);

  // The first five lines contain the following information
  // VERSION=%s
  // IMAGE_PATH=%s
  // QUESTIONS_PER_STUDENT=%d
  // PAGES_PER_STUDENT=%d
  // TOTAL_STUDENTS=%d
  // SAVE_DATE_TIME=%s
  // NUM_IMAGES=%d
  struct _keyvalue { QString key; QString string; size_t number; };
  _keyvalue intro[7];
  QString header_names[7] = { "VERSION", "IMAGE_PATH", "QUESTIONS_PER_STUDENT", "PAGES_PER_STUDENT", "TOTAL_STUDENTS", "SAVE_DATE_TIME", "NUM_IMAGES" };
  bool expect_numbers[7] = { false, false, true, true, true, false, true };
  for (size_t i = 0; i < 7; i++)
  {
    if (file.atEnd())
      GEXITDIALOG(QString("Encountered end of file reading line %1").arg(i));
    QString in = file.readLine();
    QStringList fields = in.split("=");
    if (fields.size() != 2)
      GEXITDIALOG(QString("Could not find key/value pair separated by = in [%1] reading line %2").arg(in).arg(i));
    intro[i].key = fields.at(0);
    if (header_names[i] != fields.at(0))
      GEXITDIALOG(QString("Line %1 header was not [%2] but found instead [%3]").arg(i).arg(header_names[i]).arg(intro[i].key));
    intro[i].string = fields.at(1);
    if (fields.at(0).size() == 0)
      GEXITDIALOG(QString("Key in [%1] was empty reading line %2").arg(in).arg(i));
    if (fields.at(1).size() == 0)
      GEXITDIALOG(QString("Value in [%1] was empty reading line %2").arg(in).arg(i));
    intro[i].number = -1;
    if (expect_numbers[i])
    {
      bool ok;
      int num = fields.at(1).toInt(&ok);
      if (!ok)
        GEXITDIALOG(QString("Value [%1] in [%2] was not an integer").arg(fields.at(1)).arg(in));
      if (num <= 0)
        GEXITDIALOG(QString("Value [%1] in [%2] was not a positive integer").arg(fields.at(1)).arg(in));
      intro[i].number = num;
    }
    if (expect_numbers[i])
      GDEBUG ("Parsed key [%s] = number [%zu]", qPrintable(intro[i].key), intro[i].number);
    else
      GDEBUG ("Parsed key [%s] = string [%s]", qPrintable(intro[i].key), qPrintable(intro[i].string));
  }

  QString version = intro[0].string;
  QString image_path = intro[1].string;
  size_t numQuestions = intro[2].number;
  size_t numPagesPerStudent = intro[3].number;
  size_t numStudents = intro[4].number;
  QString unused_date_time = intro[5].string;
  size_t numImages = intro[6].number;

  // Initialize the database since we know all the dimensions now
  initDatabase(numStudents, numQuestions, numPagesPerStudent);

  // Check the version is what we are expecting
  if (version != DB_VERSION)
    GEXITDIALOG(QString("Found version [%1] when only version [%2] is supported").arg(version).arg(DB_VERSION));

  // Image paths should always be . right now, nothing else is supported
  if (image_path != ".")
    GEXITDIALOG("Non-empty path found for image loading");
  int slash = filename.lastIndexOf("/");
  if (slash < 0)
    GEXITDIALOG("Could not find ending slash in file name");
  QString full_image_path = filename.left(slash);
  GDEBUG("Using image path [%s] from input file [%s]", qPrintable(full_image_path), qPrintable(filename));

  initPages(full_image_path);

  // Check that the number of images loaded matches what we are expecting
  GDEBUG ("Loaded in %zu images from [%s], input file says %zu images", getPages()->size(), qPrintable(image_path), numImages);
  if (getPages()->size() != numImages)
    GEXITDIALOG(QString("Found different number of images than was used for the save"));

  // Now populate the database. Each entry is of the following form:
  // IDNUM,STUDENTID,STUDENTNAME,TOTAL,Q0,Q1,..,QN,Feed0,Feed1,..,FeedN
  // All fields will contain something except for Feed0..FeedN
  for (int student = -2; student < (int)numStudents; student++)
  {
    if (file.atEnd())
      GEXITDIALOG(QString("Encountered end of file reading student %1 of %2").arg(student+1).arg(numStudents));
    QString in = file.readLine();
    QStringList fields = in.split("\t");
    if (fields.size() != (2*(int)numQuestions + 4))
      GEXITDIALOG(QString("Found only %1 columns in [%2] for student %3 of %4 when expected 2x%5+4 columns").arg(fields.size()).arg(in).arg(student+1).arg(numStudents).arg(numQuestions));
    for (size_t col = 4; col < numQuestions+4; col++) // Do not search student id/name, or any feedback, since these can be empty
      if (fields.at(col) == "")
        GEXITDIALOG(QString("Found empty column %1 for student %3 of %4").arg(col+1).arg(student+1).arg(numStudents));
    bool ok;
    {
      int num = fields.at(0).toInt(&ok);
      if ((!ok) || (num != student))
        GEXITDIALOG(QString("Expected row number %1 but found [%2] instead for student %3 of %4").arg(student).arg(fields.at(0)).arg(student+1).arg(numStudents));
    }

    if (student == -2)
    {
      if ((fields.at(1) != "PAGE") && (fields.at(2) != "PAGE"))
        GEXITDIALOG(QString("Expected PAGE headers for first row of data, but found [%1] [%2] instead").arg(fields.at(1).arg(fields.at(2))));
      for (size_t q = 0; q < numQuestions; q++)
      {
        int page = fields.at(q+4).toInt(&ok);
        if ((!ok) || (page < -1))
          GEXITDIALOG(QString("Page value [%1] for question %2 was not valid for maximum values").arg(fields.at(q+4)).arg(q+1));
        Global::db()->setQuestionPage(q, page, false);
      }
      int total = fields.at(3).toInt(&ok);
      if ((!ok) || (total != -1))
        GEXITDIALOG(QString("Page total in file [%1] was not -1").arg(fields.at(3)));
    }
    else if (student == -1)
    {
      if ((fields.at(1) != "MAX") && (fields.at(2) != "MAX"))
        GEXITDIALOG(QString("Expected MAX headers for first row of data, but found [%1] [%2] instead").arg(fields.at(1).arg(fields.at(2))));
      for (size_t q = 0; q < numQuestions; q++)
      {
        int score = fields.at(q+4).toInt(&ok);
        if ((!ok) || (score < -1))
          GEXITDIALOG(QString("Score value [%1] for question %2 was not valid for maximum values").arg(fields.at(q+4)).arg(q+1));
        Global::db()->setQuestionMaximum(q, score, false);
      }
      int total = fields.at(3).toInt(&ok);
      if ((!ok) || (total != Global::db()->getTotalMaximum()))
        GEXITDIALOG(QString("Maximum total in file [%1] did not match calculated maximum total %2").arg(fields.at(3)).arg(Global::db()->getTotalMaximum()));
    }
    else
    {
      Student &entry = Global::db()->getStudent(student);
      entry.setStudentId(fields.at(1), false);
      entry.setStudentName(fields.at(2), false);
      for (size_t q = 0; q < numQuestions; q++)
      {
        int score = fields.at(q+4).toInt(&ok);
        if ((!ok) || (score < -1) || (score > Global::db()->getQuestionMaximum(q)))
          GEXITDIALOG(QString("Score value [%1] for question %2 was not valid student %3 of %4").arg(fields.at(q+4)).arg(q+1).arg(student+1).arg(numStudents));
        entry.setGrade(q, score, false);
      }
      for (size_t q = 0; q < numQuestions; q++)
        entry.setFeedback(q, fields.at(q+4+numQuestions), false);
      int total = fields.at(3).toInt(&ok);
      if ((!ok) || (total != entry.getTotal()))
        GEXITDIALOG(QString("Total in file [%1] did not match calculated total %2").arg(fields.at(3)).arg(entry.getTotal()));
    }
  }
}