00001 #include "NeovisionII/NeoAnnotate/DBManager.qt.H"
00002 #include "NeovisionII/NeoAnnotate/MainWindow.qt.H"
00003 #include <Qt/QtCore>
00004 #include <QtSql/QSqlDatabase>
00005 #include <QtSql/QSqlError>
00006 #include <QtSql/QSqlQuery>
00007 #include <Qt3Support/q3urloperator.h>
00008 #include <Qt3Support/q3network.h>
00009 #include "NeovisionII/NeoAnnotate/AnnotationObjectManager.qt.H"
00010 #include "NeovisionII/NeoAnnotate/AnnotationObject.qt.H"
00011 #include <set>
00012
00013
00014 ConnectionDialog::ConnectionDialog(QWidget* parent)
00015 : QDialog(parent)
00016 {
00017 QFormLayout *layout = new QFormLayout;
00018
00019 serverNameEdit = new QLineEdit("isvn.usc.edu");
00020 layout->addRow(tr("&Server Name"), serverNameEdit);
00021
00022 dbNameEdit = new QLineEdit("neo2annotations");
00023 layout->addRow(tr("&Database Name"), dbNameEdit);
00024
00025 userNameEdit = new QLineEdit("neo2");
00026 layout->addRow(tr("&User Name"), userNameEdit);
00027
00028 passwordEdit = new QLineEdit("neo2!");
00029 passwordEdit->setEchoMode(QLineEdit::Password);
00030 layout->addRow(tr("&Password"), passwordEdit);
00031
00032 QPushButton* cancelButton = new QPushButton("&Cancel", this);
00033 connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
00034 layout->addRow(cancelButton);
00035
00036 QPushButton* connectButton = new QPushButton("&Connect", this);
00037 connect(connectButton, SIGNAL(clicked()), this, SLOT(accept()));
00038 layout->addRow(connectButton);
00039
00040 setLayout(layout);
00041 }
00042
00043
00044 NewDBEntryDialog::NewDBEntryDialog(QWidget* parent, DBManager *mgr, QSqlDatabase* _db)
00045 : QDialog(parent),
00046 itsDBManager(mgr),
00047 db(_db),
00048 itsSceneUid("-1")
00049 {
00050 setMinimumSize(QSize(500, 200));
00051 QFormLayout *layout = new QFormLayout;
00052
00053 labComboBox = new QComboBox(this);
00054 layout->addRow(tr("Lab"), labComboBox);
00055 connect(labComboBox, SIGNAL(activated(int)), this, SLOT(fillInCameraOperator(int)));
00056
00057 QHBoxLayout* fileChooserLayout = new QHBoxLayout;
00058 fileNameLabel = new QLabel;
00059 QPushButton* fileNameButton = new QPushButton("Browse...");
00060 connect(fileNameButton, SIGNAL(clicked()), this, SLOT(browse()));
00061 fileChooserLayout->addWidget(fileNameLabel);
00062 fileChooserLayout->addWidget(fileNameButton);
00063 layout->addRow(tr("FileName"), fileChooserLayout);
00064
00065 cameraComboBox = new QComboBox(this);
00066 layout->addRow(tr("Camera"), cameraComboBox);
00067
00068 startDateTimeEdit = new QDateTimeEdit(this);
00069 layout->addRow(tr("Start Time"), startDateTimeEdit);
00070
00071 endDateTimeEdit = new QDateTimeEdit(this);
00072 layout->addRow(tr("End Time"), endDateTimeEdit);
00073
00074 timeZoneBox = new QComboBox(this);
00075 timeZoneBox->addItem("NST Newfoundland Standard Time", "NST");
00076 timeZoneBox->addItem("NDT Newfoundland Daylight Time", "NDT");
00077 timeZoneBox->addItem("AST Atlantic Standard Time", "AST");
00078 timeZoneBox->addItem("ADT Atlantic Daylight Time", "ADT");
00079 timeZoneBox->addItem("EST Eastern Standard Time", "EST");
00080 timeZoneBox->addItem("EDT Eastern Daylight Time", "EDT");
00081 timeZoneBox->addItem("CST Central Standard Time", "CST");
00082 timeZoneBox->addItem("CDT Central Daylight Time", "CDT");
00083 timeZoneBox->addItem("MST Mountain Standard Time", "MST");
00084 timeZoneBox->addItem("MDT Mountain Daylight Time", "MDT");
00085 timeZoneBox->addItem("PST Pacific Standard Time", "PST");
00086 timeZoneBox->addItem("PDT Pacific Daylight Time", "PDT");
00087 timeZoneBox->addItem("AKST Alaska Standard Time", "AKST");
00088 timeZoneBox->addItem("AKDT Alaska Daylight Time", "AKDT");
00089 timeZoneBox->addItem("HAST Hawaii-Aleutian Standard Time", "HAST");
00090 timeZoneBox->addItem("HADT Hawaii-Aleutian Daylight Time", "HADT");
00091 layout->addRow(tr("Time Zone"), timeZoneBox);
00092
00093 operatorComboBox = new QComboBox(this);
00094 layout->addRow(tr("Operator"), operatorComboBox);
00095
00096 weatherComboBox = new QComboBox(this);
00097 layout->addRow(tr("Weather"), weatherComboBox);
00098
00099 startFrameEdit = new QLineEdit(this);
00100 startFrameEdit->setValidator(new QIntValidator(0, 9999999, this));
00101 layout->addRow(tr("Start Frame"), startFrameEdit);
00102
00103 numFramesEdit = new QLineEdit(this);
00104 numFramesEdit->setValidator(new QIntValidator(0, 9999999, this));
00105 layout->addRow(tr("Number of Frames"), numFramesEdit);
00106
00107 frameRateEdit = new QLineEdit(this);
00108 frameRateEdit->setValidator(new QIntValidator(1, 300, this));
00109 layout->addRow(tr("Frame Rate"), frameRateEdit);
00110
00111 sceneNameEdit = new QLineEdit(this);
00112 layout->addRow(tr("Scene Name"), sceneNameEdit);
00113
00114 QPushButton* createButton = new QPushButton("&Create", this);
00115 connect(createButton, SIGNAL(clicked()), this, SLOT(commitNewScene()));
00116 layout->addRow(createButton);
00117
00118 QPushButton* cancelButton = new QPushButton("&Cancel", this);
00119 connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
00120 layout->addRow(cancelButton);
00121
00122 setLayout(layout);
00123 }
00124
00125
00126 void NewDBEntryDialog::browse()
00127 {
00128 QString fileName = QFileDialog::getOpenFileName(this,
00129 tr("Select Video File"), QString(VIDEO_INCOMING_LOCATION), tr("Video Files (*.MTS *.AVI *.MPG *.MPEG)"));
00130 QFileInfo inputFileInfo(fileName);
00131 QFileInfo mgzJFileInfo(inputFileInfo.dir().path() + "/" + inputFileInfo.baseName() + ".mgzJ");
00132 if(!mgzJFileInfo.exists())
00133 {
00134 QMessageBox msgBox(QMessageBox::Critical, "No mgzJ File Found",
00135 "The input file you selected does not have a corresponding .mgzJ file in the same directory.\n"
00136 "Please create a .mgzJ file for this video, and try again.",
00137 QMessageBox::Ok);
00138 msgBox.exec();
00139 }
00140 else
00141 {
00142 fileNameLabel->setText(fileName);
00143 }
00144 }
00145
00146
00147 void NewDBEntryDialog::commitNewScene()
00148 {
00149
00150 QDateTime startTime = startDateTimeEdit->dateTime();
00151 QDateTime endTime = endDateTimeEdit->dateTime();
00152 if(startTime >= endTime)
00153 {
00154 QMessageBox msgBox(QMessageBox::Critical, "Bad Dates!",
00155 "Start date/time cannot be after end date/time!",
00156 QMessageBox::Ok);
00157 msgBox.exec();
00158 }
00159 else
00160 {
00161 QString timeZone = timeZoneBox->itemData(timeZoneBox->currentIndex()).toString();
00162 QString startDateTime = startTime.toString("yyyy-MM-dd hh:mm ") + timeZone;
00163 QString endDateTime = endTime.toString("yyyy-MM-dd hh:mm ") + timeZone;
00164
00165 QString sourceFileName = fileNameLabel->text();
00166 QString fileSuffix = QFileInfo(sourceFileName).suffix();
00167
00168 QString insertStatement;
00169 insertStatement += "INSERT INTO scene ";
00170 insertStatement += "(starttime, endtime, camera, operator, url, numframes, framerate, weather, startframe, name) ";
00171 insertStatement += "VALUES (";
00172 insertStatement += "\'" + startDateTime + "\', ";
00173 insertStatement += "\'" + endDateTime + "\', ";
00174 insertStatement += cameraComboBox->itemData(cameraComboBox->currentIndex()).toString() + ", ";
00175 insertStatement += operatorComboBox->itemData(operatorComboBox->currentIndex()).toString() + ", ";
00176 insertStatement += "\'ext://" + fileSuffix + "\', ";
00177 insertStatement += numFramesEdit->text() + ", ";
00178 insertStatement += frameRateEdit->text() + ", ";
00179 insertStatement += weatherComboBox->itemData(weatherComboBox->currentIndex()).toString() + ", ";
00180 insertStatement += startFrameEdit->text() + ", ";
00181 insertStatement += "\'" + sceneNameEdit->text() + "\'";
00182 insertStatement += ")";
00183
00184 db->exec(insertStatement);
00185
00186 if(db->lastError().isValid())
00187 {
00188 QMessageBox msgBox(QMessageBox::Critical, "Database Insert Error",
00189 "Error inserting into database. Reason:\n" + db->lastError().text() + "\n\n" +
00190 "Insert Statement Was:\n"+insertStatement,
00191 QMessageBox::Ok);
00192 msgBox.exec();
00193 }
00194 else
00195 {
00196
00197
00198 QSqlQuery query = db->exec("select currval('scene_uid_seq')");
00199
00200 if(db->lastError().isValid())
00201 {
00202 QMessageBox msgBox(QMessageBox::Critical, "Database Select Error",
00203 "Error retrieving last insertion UID. Reason:\n" + db->lastError().text(),
00204 QMessageBox::Ok);
00205 msgBox.exec();
00206 }
00207 else
00208 {
00209
00210 query.next();
00211 itsSceneUid = query.value(0).toString();
00212
00213 {
00214 QString destinationFileName = itsDBManager->itsArchiveLoc + "/" + itsSceneUid + "." + fileSuffix;
00215 QProcess copyProc;
00216 QString execString("/bin/mv " + sourceFileName + " " + destinationFileName);
00217 qDebug() << execString;
00218 QProgressDialog progressDialog(this);
00219 progressDialog.setAutoClose(false);
00220 progressDialog.setAutoReset(false);
00221 progressDialog.setLabel(new QLabel("Copying File, Please Wait...", this));
00222 progressDialog.setCancelButton(0);
00223 progressDialog.setRange(0, 0);
00224 connect(©Proc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(copyFinished(int, QProcess::ExitStatus)));
00225 connect(this, SIGNAL(closeProgressDialog()), &progressDialog, SLOT(cancel()));
00226 copyProc.start(execString);
00227 progressDialog.exec();
00228 copyProc.waitForFinished(-1);
00229 }
00230 {
00231 QFileInfo inputFileInfo(sourceFileName);
00232 QString sourceMgzJFileName = inputFileInfo.dir().path() + "/" + inputFileInfo.baseName() + ".mgzJ";
00233 itsMgzJFileName = itsDBManager->itsWorkingLoc + "/" + itsSceneUid + ".mgzJ";
00234
00235 qDebug() << "Setting mgzJ filename: " << itsMgzJFileName;
00236
00237 QProcess copyProc;
00238 QString execString("/bin/mv " + sourceMgzJFileName + " " + itsMgzJFileName);
00239 qDebug() << execString;
00240 QProgressDialog progressDialog(this);
00241 progressDialog.setAutoClose(false);
00242 progressDialog.setAutoReset(false);
00243 progressDialog.setLabel(new QLabel("Copying File, Please Wait...", this));
00244 progressDialog.setCancelButton(0);
00245 progressDialog.setRange(0, 0);
00246 connect(©Proc, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(copyFinished(int, QProcess::ExitStatus)));
00247 connect(this, SIGNAL(closeProgressDialog()), &progressDialog, SLOT(cancel()));
00248 copyProc.start(execString);
00249 progressDialog.exec();
00250 copyProc.waitForFinished(-1);
00251 }
00252 accept();
00253 }
00254 }
00255 }
00256 }
00257
00258
00259 void NewDBEntryDialog::copyFinished(int exitCode, QProcess::ExitStatus exitStatus)
00260 {
00261 emit closeProgressDialog();
00262 }
00263
00264
00265 void NewDBEntryDialog::showEvent(QShowEvent* event)
00266 {
00267
00268
00269 labComboBox->clear();
00270 QSqlQuery labsQuery = db->exec("SELECT uid, name, institution FROM lab");
00271 while(labsQuery.next())
00272 {
00273 int uid = labsQuery.value(0).toInt();
00274 QString name = labsQuery.value(1).toString();
00275 QString institution = labsQuery.value(2).toString();
00276 labComboBox->addItem(name + " @ " + institution, uid);
00277 }
00278
00279 QSqlQuery weatherQuery = db->exec("SELECT uid, name FROM weather");
00280 while(weatherQuery.next())
00281 {
00282 int uid = weatherQuery.value(0).toInt();
00283 QString name = weatherQuery.value(1).toString();
00284 weatherComboBox->addItem(name, uid);
00285 }
00286
00287 fillInCameraOperator(0);
00288
00289 QDialog::showEvent(event);
00290 }
00291
00292
00293 void NewDBEntryDialog::fillInCameraOperator(int labComboBoxRow)
00294 {
00295 int labUID = labComboBox->itemData(labComboBoxRow).toInt();
00296 cameraComboBox->clear();
00297 operatorComboBox->clear();
00298
00299 QSqlQuery cameraQuery =
00300 db->exec("SELECT uid, name, manufacturer, model FROM camera WHERE lab="+QString::number(labUID));
00301 while(cameraQuery.next())
00302 {
00303 int uid = cameraQuery.value(0).toInt();
00304 QString name = cameraQuery.value(1).toString();
00305 QString manufacturer = cameraQuery.value(2).toString();
00306 QString model = cameraQuery.value(3).toString();
00307 cameraComboBox->addItem(name + ": " + manufacturer + " " + model, uid);
00308 }
00309
00310 QSqlQuery operatorQuery =
00311 db->exec("SELECT uid, firstname, lastname, jobtitle FROM operator WHERE lab="+QString::number(labUID));
00312 while(operatorQuery.next())
00313 {
00314 int uid = operatorQuery.value(0).toInt();
00315 QString firstname = operatorQuery.value(1).toString();
00316 QString lastname = operatorQuery.value(2).toString();
00317 QString jobtitle = operatorQuery.value(3).toString();
00318 operatorComboBox->addItem(lastname + ", " + firstname + " : " + jobtitle, uid);
00319 }
00320 qDebug() << "Getting Operator!: " << db->lastError();
00321 }
00322
00323
00324 SelectAnnotationSourceDialog::SelectAnnotationSourceDialog(QWidget* parent, QSqlDatabase* _db) :
00325 QDialog(parent),
00326 itsSourceUid("-1"),
00327 db(_db)
00328 {
00329 setMinimumSize(QSize(500, 200));
00330 QVBoxLayout *layout = new QVBoxLayout;
00331
00332 itsSourceTree = new QTreeWidget(this);
00333 QStringList headerList;
00334 headerList << "UID" << "Name" << "Validation Level";
00335 itsSourceTree->setHeaderLabels(headerList);
00336
00337 layout->addWidget(itsSourceTree);
00338
00339 QPushButton* openButton = new QPushButton("&Select", this);
00340 connect(openButton, SIGNAL(clicked()), this, SLOT(selectSource()));
00341 layout->addWidget(openButton);
00342
00343 QPushButton* cancelButton = new QPushButton("&Cancel", this);
00344 connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
00345 layout->addWidget(cancelButton);
00346
00347 setLayout(layout);
00348 }
00349
00350 void SelectAnnotationSourceDialog::showEvent(QShowEvent* event)
00351 {
00352 itsSourceTree->clear();
00353 QSqlQuery sourceQuery =
00354 db->exec("SELECT uid, name, validationlevel FROM annotationsource WHERE categ=2");
00355 while(sourceQuery.next())
00356 {
00357 QString uid = sourceQuery.value(0).toString();
00358 QString name = sourceQuery.value(1).toString();
00359 QString level = sourceQuery.value(2).toString();
00360 QStringList source;
00361 source << uid << name << level;
00362 itsSourceTree->addTopLevelItem(new QTreeWidgetItem(source));
00363 }
00364
00365 QDialog::showEvent(event);
00366 }
00367
00368
00369 void SelectAnnotationSourceDialog::selectSource()
00370 {
00371
00372 QTreeWidgetItem* selectedSource = itsSourceTree->currentItem();
00373 if(selectedSource == NULL) return;
00374
00375 itsSourceUid = selectedSource->text(0);
00376
00377 if(itsSourceUid != "-1")
00378 static_cast<MainWindow*>(parent())->setAnnotatorLabel("Annotating As " + selectedSource->text(1));
00379 else
00380 static_cast<MainWindow*>(parent())->setAnnotatorLabel("No Annotator Selected");
00381
00382 accept();
00383 }
00384
00385
00386 OpenDBEntryDialog::OpenDBEntryDialog(QWidget* parent, DBManager *mgr, QSqlDatabase* _db) :
00387 QDialog(parent),
00388 itsDBManager(mgr),
00389 itsSceneUid("-1"),
00390 db(_db)
00391 {
00392 setMinimumSize(QSize(500, 200));
00393 QVBoxLayout *layout = new QVBoxLayout;
00394
00395 itsSceneTree = new QTreeWidget(this);
00396 QStringList headerList;
00397 headerList << "UID" << "Name" << "Operator" << "Camera" << "Start Time" << "End Time";
00398 itsSceneTree->setHeaderLabels(headerList);
00399 layout->addWidget(itsSceneTree);
00400
00401 QPushButton* openButton = new QPushButton("&Open", this);
00402 connect(openButton, SIGNAL(clicked()), this, SLOT(openEntry()));
00403 layout->addWidget(openButton);
00404
00405 QPushButton* cancelButton = new QPushButton("&Cancel", this);
00406 connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
00407 layout->addWidget(cancelButton);
00408
00409 setLayout(layout);
00410 }
00411
00412 void OpenDBEntryDialog::showEvent(QShowEvent* event)
00413 {
00414 itsSceneTree->clear();
00415
00416 QSqlQuery sceneQuery =
00417 db->exec("SELECT uid, name, operator, camera, starttime, endtime FROM scene ORDER BY name");
00418
00419 while(sceneQuery.next())
00420 {
00421 QString uid = sceneQuery.value(0).toString();
00422 QString name = sceneQuery.value(1).toString();
00423 QString operatorId = sceneQuery.value(2).toString();
00424 QString cameraId = sceneQuery.value(3).toString();
00425 QString startTime = sceneQuery.value(4).toString();
00426 QString endTime = sceneQuery.value(5).toString();
00427
00428 QSqlQuery cameraQuery =
00429 db->exec("SELECT name FROM camera WHERE uid="+cameraId);
00430 QString cameraName = "";
00431 if(cameraQuery.size() > 0)
00432 {
00433 cameraQuery.next();
00434 cameraName = cameraQuery.value(0).toString();
00435 }
00436
00437 QSqlQuery operatorQuery =
00438 db->exec("SELECT firstname,lastname FROM operator WHERE uid="+operatorId);
00439 QString operatorName = "";
00440 if(operatorQuery.size() > 0)
00441 {
00442 operatorQuery.next();
00443 operatorName = operatorQuery.value(1).toString() + ", " + operatorQuery.value(0).toString();
00444 }
00445
00446 QStringList sceneItem;
00447 sceneItem << uid << name << operatorName << cameraName << startTime << endTime;
00448
00449 QTreeWidgetItem* newItem = new QTreeWidgetItem(sceneItem);
00450
00451 QString mgzJFileName = itsDBManager->itsWorkingLoc + "/" + uid + ".mgzJ";
00452 QFileInfo mgzJFileInfo(mgzJFileName);
00453 if(mgzJFileInfo.exists() == false)
00454 newItem->setDisabled(true);
00455
00456 itsSceneTree->addTopLevelItem(newItem);
00457 }
00458
00459 QDialog::showEvent(event);
00460 }
00461
00462 void OpenDBEntryDialog::openEntry()
00463 {
00464 QTreeWidgetItem* selectedScene = itsSceneTree->currentItem();
00465 if(selectedScene)
00466 {
00467 itsSceneUid = selectedScene->text(0);
00468
00469 QString mgzJFileName = itsDBManager->itsWorkingLoc + "/" + itsSceneUid + ".mgzJ";
00470 QFileInfo mgzJFileInfo(mgzJFileName);
00471 if(mgzJFileInfo.exists())
00472 {
00473 itsMgzJFileName = mgzJFileName;
00474 accept();
00475 }
00476 else
00477 {
00478 QMessageBox msgBox(QMessageBox::Warning, "Could Not Open MgzJ File",
00479 "No .mgzJ file found for this scene.\n\n"
00480 "You must ensure that the cached .mgzJ file (" + mgzJFileName + ") "
00481 "exists before trying to reopen an annotation.\n\n"
00482 "**** This error should not have occured! Please file a bug report with the following info:\n"
00483 "File: " + QString(__FILE__) + " Line: " + QString(__LINE__),
00484 QMessageBox::Ok);
00485 msgBox.exec();
00486 }
00487 }
00488 else
00489 {
00490 QMessageBox msgBox(QMessageBox::Warning, "No Scene Selected",
00491 "You did not select a scene!\n\n"
00492 "If all scenes are greyed out, then you must reconvert some original "
00493 "footage into the .mgzJ format. Please see Dr. Itti or Rand for "
00494 "instructions on doing this.",
00495 QMessageBox::Ok);
00496 msgBox.exec();
00497 }
00498 }
00499
00500
00501
00502
00503 void DBManager::connectToDb()
00504 {
00505 if(itsConnDialog.exec())
00506 {
00507 db = QSqlDatabase::addDatabase("QPSQL");
00508 db.setHostName(itsConnDialog.serverNameEdit->text());
00509 db.setDatabaseName(itsConnDialog.dbNameEdit->text());
00510 db.setUserName(itsConnDialog.userNameEdit->text());
00511 db.setPassword(itsConnDialog.passwordEdit->text());
00512
00513 connected = db.open();
00514
00515
00516 if(!connected)
00517 {
00518 QMessageBox msgBox(QMessageBox::Warning, "Could Not Connect",
00519 "Could Not Connect To The Database.\nReason:" + db.lastError().text(),
00520 QMessageBox::Ok);
00521 msgBox.exec();
00522 }
00523 }
00524
00525
00526 if(connected)
00527 {
00528 static_cast<MainWindow*>(parent())->setDBStatusLabel("Connected To " + db.hostName());
00529 chooseAnnotationSource();
00530 }
00531 else
00532 static_cast<MainWindow*>(parent())->setDBStatusLabel("Not Connected To DB");
00533 }
00534
00535 void DBManager::chooseAnnotationSource()
00536 {
00537 while(!connected) connectToDb();
00538
00539 while(!itsSelectAnnotationSourceDialog.exec())
00540 {
00541 QMessageBox msgBox(QMessageBox::Warning, "No Annotation Source Selected",
00542 "You must select yourself as an annotation source to save or load any work.",
00543 QMessageBox::Ok);
00544 msgBox.exec();
00545 }
00546 }
00547
00548
00549 namespace
00550 {
00551 struct PolygonKeyframe
00552 {
00553 int scene;
00554 std::vector<QPointF> vertices;
00555 std::vector<bool> verticesVisible;
00556 std::vector<bool> verticesKeyframe;
00557 int annotationSource;
00558 int object;
00559 QPointF pos;
00560 bool visible;
00561 bool keyframe;
00562 };
00563 }
00564 void DBManager::saveAnnotation()
00565 {
00566
00567 if(!connected) connectToDb();
00568 if(!connected)
00569 {
00570 QMessageBox msgBox(QMessageBox::Warning, "Not connected to a database",
00571 "Your work has not been saved!\n\n"
00572 "You must connect to a database before saving your work.",
00573 QMessageBox::Ok);
00574 msgBox.exec();
00575 return;
00576 }
00577
00578 QString sourceUid = itsSelectAnnotationSourceDialog.getSourceUid();
00579 if(sourceUid == "-1")
00580 {
00581 QMessageBox msgBox(QMessageBox::Warning, "No source selected!",
00582 "Your work has not been saved!\n\n"
00583 "You must choose yourself as an annotation source before you can save your work.",
00584 QMessageBox::Ok);
00585 msgBox.exec();
00586 return;
00587 }
00588
00589
00590 if(itsSceneUid == "-1")
00591 {
00592 QMessageBox msgBox(QMessageBox::Warning, "Work not saved!",
00593 "Your work has not been saved!\n\n"
00594 "You must choose a valid scene in order to save your work.",
00595 QMessageBox::Ok);
00596 msgBox.exec();
00597 return;
00598 }
00599
00600
00601 db.exec("DELETE from Polygon WHERE scene="+itsSceneUid+" AND annotationSource="+sourceUid);
00602 db.exec("DELETE from PolygonKeyframe WHERE scene="+itsSceneUid+" AND annotationSource="+sourceUid);
00603
00604 AnnotationObjectManager* mgr = static_cast<MainWindow*>(parent())->getObjectManager();
00605
00606
00607 std::map<int, QString> objIdMap;
00608 QList<AnnotationObject *> objects = mgr->getAnnotationObjects();
00609 QList<AnnotationObject *>::iterator objIt;
00610 for(objIt = objects.begin(); objIt != objects.end(); ++objIt)
00611 {
00612 AnnotationObject* obj = *objIt;
00613 ObjectAnimation* mainAnimation = obj->getAnimation();
00614 QList<AnnotationObjectVertex*> vertices = *(obj->getVertices());
00615
00616
00617 std::map<int, PolygonKeyframe> keyframes;
00618
00619
00620 size_t numVertices = obj->getVertices()->size();
00621
00622 QMap<int, ObjectAnimation::FrameState> keyFrames = mainAnimation->getKeyFrames();
00623
00624
00625 QMap<int, ObjectAnimation::FrameState>::iterator keyIt;
00626 for(keyIt = mainAnimation->getKeyFrames().begin(); keyIt != mainAnimation->getKeyFrames().end(); ++keyIt)
00627 {
00628 int frameNum = keyIt.key();
00629 ObjectAnimation::FrameState frameState = keyIt.value();
00630
00631 keyframes[frameNum].keyframe = true;
00632 keyframes[frameNum].visible = frameState.visible;
00633 keyframes[frameNum].pos = frameState.pos;
00634
00635 keyframes[frameNum].vertices.resize(numVertices);
00636 keyframes[frameNum].verticesVisible.resize(numVertices);
00637 keyframes[frameNum].verticesKeyframe.resize(numVertices);
00638
00639 }
00640
00641
00642 for(int vertIdx=0; vertIdx < vertices.size(); ++vertIdx)
00643 {
00644 AnnotationObjectVertex* vertex = vertices[vertIdx];
00645 for(keyIt=vertex->getAnimation()->getKeyFrames().begin(); keyIt!=vertex->getAnimation()->getKeyFrames().end(); ++keyIt)
00646 {
00647 int frameNum = keyIt.key();
00648 ObjectAnimation::FrameState frameState = keyIt.value();
00649
00650
00651 if(keyframes[frameNum].vertices.size() != numVertices)
00652 {
00653 keyframes[frameNum].vertices.resize(numVertices);
00654 keyframes[frameNum].verticesVisible.resize(numVertices);
00655 keyframes[frameNum].verticesKeyframe.resize(numVertices);
00656 }
00657
00658 keyframes[frameNum].vertices[vertIdx] = frameState.pos;
00659 keyframes[frameNum].verticesVisible[vertIdx] = frameState.visible;
00660 keyframes[frameNum].verticesKeyframe[vertIdx] = true;
00661 }
00662 }
00663
00664
00665 db.exec("INSERT into Object (category) VALUES ("+QString::number(obj->getType())+")");
00666
00667
00668
00669 QSqlQuery query = db.exec("select currval('object_uid_seq')");
00670 query.next();
00671 QString objDbId = query.value(0).toString();
00672 objIdMap[obj->getId()] = objDbId;
00673
00674
00675 QSqlQuery descPropUidQuery = db.exec("SELECT uid FROM objectproptype WHERE name='Description'");
00676 descPropUidQuery.next();
00677 QString descPropUid = descPropUidQuery.value(0).toString();
00678 QSqlQuery insertDescQuery = db.exec("INSERT into objectproperties (object, type, value) VALUES ("
00679 +objDbId+", "
00680 +descPropUid+", "
00681 + "'" + obj->getDescription()+"')"
00682 );
00683
00684
00685 std::map<int, PolygonKeyframe>::iterator keyframeIt;
00686 for(keyframeIt=keyframes.begin();keyframeIt!=keyframes.end(); ++keyframeIt)
00687 {
00688 int frameNum = keyframeIt->first;
00689 PolygonKeyframe polyData = keyframeIt->second;
00690
00691 QString queryString = "INSERT into PolygonKeyframe ";
00692 queryString += "(scene, frame, vertices, verticesVisible, verticesKeyframe, "
00693 "annotationSource, object, pos, visible, keyframe, time)";
00694 queryString += " VALUES (";
00695 queryString += itsSceneUid + ", ";
00696 queryString += QString::number(frameNum) + ", ";
00697 queryString += "'(";
00698 for(size_t i=0; i<polyData.vertices.size(); ++i)
00699 {
00700 queryString += "(" + QString::number(polyData.vertices[i].x()) + "," + QString::number(polyData.vertices[i].y()) + ")";
00701 if(i < polyData.vertices.size()-1) queryString += ",";
00702 }
00703 queryString += ")', ";
00704 queryString += "'{";
00705 for(size_t i=0; i<polyData.verticesVisible.size(); ++i)
00706 {
00707 queryString += polyData.verticesVisible[i] ? "t" : "f";
00708 if(i < polyData.vertices.size()-1) queryString += ",";
00709 }
00710 queryString += "}', ";
00711 queryString += "'{";
00712 for(size_t i=0; i<polyData.verticesKeyframe.size(); ++i)
00713 {
00714 queryString += polyData.verticesKeyframe[i] ? "t" : "f";
00715 if(i < polyData.vertices.size()-1) queryString += ",";
00716 }
00717 queryString += "}', ";
00718 queryString += sourceUid + ", ";
00719 queryString += objDbId + ", ";
00720 queryString += "'(" + QString::number(polyData.pos.x()) + "," + QString::number(polyData.pos.y()) + ")', ";
00721 queryString += polyData.visible ? "'t'" : "'f'";
00722 queryString += ", ";
00723 queryString += polyData.keyframe ? "'t'" : "'f'";
00724 queryString += ", ";
00725 queryString += "NOW()";
00726 queryString += ")";
00727
00728 db.exec(queryString);
00729 }
00730 }
00731
00732
00733
00734 std::set<int> insertedObjects;
00735 std::map<int, std::map<int,AnnotationObjectFrame> > animation = mgr->renderAnimations();
00736 std::map<int, std::map<int,AnnotationObjectFrame> >::iterator animIt = animation.begin();
00737 for(;animIt!=animation.end(); ++animIt)
00738 {
00739 int frameNum = animIt->first;
00740 std::map<int,AnnotationObjectFrame>::iterator objectIt = animIt->second.begin();
00741 for(;objectIt!=animIt->second.end(); ++objectIt)
00742 {
00743 QString objId = objIdMap[objectIt->first];
00744 AnnotationObjectFrame objFrame = objectIt->second;
00745 ObjectAnimation::FrameState objFrameState = objFrame.ObjectFrameState;
00746 if(objFrameState.visible)
00747 {
00748
00749 QPointF center(0, 0); int numVisVert = 0;
00750 QString verticesString = "(";
00751 std::map<int, ObjectAnimation::FrameState>::iterator vertIt = objFrame.VertexFrames.begin();
00752 for(; vertIt!=objFrame.VertexFrames.end(); ++vertIt)
00753 {
00754 ObjectAnimation::FrameState vertState = vertIt->second;
00755 if(vertState.visible)
00756 {
00757 QPointF pos = vertState.pos;
00758 center += pos; numVisVert++;
00759 verticesString += "("+QString::number(pos.x())+","+QString::number(pos.y())+"),";
00760 }
00761 }
00762 verticesString.chop(1);
00763 verticesString+=")";
00764 if(numVisVert == 0) continue;
00765
00766
00767 center/=numVisVert;
00768 QString centerString = "("+QString::number(center.x())+","+QString::number(center.y())+")";
00769
00770 QString queryString = "INSERT INTO polygon (scene, frame, vertices, annotationsource, object, time) VALUES (";
00771 queryString += itsSceneUid + ", ";
00772 queryString += QString::number(frameNum) + ", ";
00773 queryString += "'" + verticesString + "', ";
00774 queryString += sourceUid + ", ";
00775 queryString += objId + ", ";
00776 queryString += "NOW()";
00777 queryString += ")";
00778 db.exec(queryString);
00779 }
00780
00781 }
00782 }
00783
00784 }
00785
00786
00787 void DBManager::openAnnotation()
00788 {
00789 if(!connected) connectToDb();
00790 if(!connected)
00791 {
00792 return;
00793 }
00794
00795 QString sourceUid = itsSelectAnnotationSourceDialog.getSourceUid();
00796 while(sourceUid == "-1")
00797 {
00798 chooseAnnotationSource();
00799 sourceUid = itsSelectAnnotationSourceDialog.getSourceUid();
00800 }
00801
00802 if(!itsOpenDBEntryDialog.exec()) return;
00803 itsSceneUid = itsOpenDBEntryDialog.getSceneUid();
00804 if(itsSceneUid == "-1") return;
00805
00806
00807 emit openVideo(itsOpenDBEntryDialog.getMgzJFileName());
00808
00809 MainWindow* mw = static_cast<MainWindow*>(parent());
00810 AnnotationObjectManager* mgr = mw->getObjectManager();
00811
00812
00813 mgr->clear();
00814
00815 FrameRange frameRange = mw->getFrameRange();
00816
00817 QSqlQuery objectQuery =
00818 db.exec("SELECT DISTINCT object from PolygonKeyframe WHERE scene="+itsSceneUid+" and annotationsource="+sourceUid);
00819 while(objectQuery.next())
00820 {
00821 QString objId = objectQuery.value(0).toString();
00822 QString keyframeQueryString = "SELECT frame, vertices, verticesVisible, verticesKeyFrame, pos, visible, keyframe " +
00823 QString("from PolygonKeyframe WHERE scene=")+itsSceneUid+
00824 " and object="+objId+
00825 " order by frame";
00826 QSqlQuery keyframeQuery = db.exec(keyframeQueryString);
00827 if(keyframeQuery.size() == 0) continue;
00828
00829 AnnotationObject* obj = NULL;
00830
00831 while(keyframeQuery.next())
00832 {
00833
00834 int frame = keyframeQuery.value(0).toInt();
00835
00836
00837 std::vector<QPointF> vertices;
00838 QString verticesString = keyframeQuery.value(1).toString().mid(1, keyframeQuery.value(1).toString().size()-2);
00839 int stringpos = verticesString.indexOf("(")+1;
00840 int stringendpos;
00841 while((stringendpos = verticesString.indexOf(")", stringpos)) != -1)
00842 {
00843 QString vertexString = verticesString.mid(stringpos, stringendpos-stringpos);
00844 stringpos = verticesString.indexOf("(",stringendpos)+1;
00845
00846 QStringList coordStrings = vertexString.split(",");
00847 QPointF vPos(coordStrings[0].toFloat(), coordStrings[1].toFloat());
00848 vertices.push_back(vPos);
00849
00850 if(stringpos == 0) break;
00851 }
00852
00853
00854 QStringList verticesVisible =
00855 keyframeQuery.value(2).toString().mid(1, keyframeQuery.value(2).toString().size()-2).split(",");
00856
00857
00858 QStringList verticesKeyframe =
00859 keyframeQuery.value(3).toString().mid(1, keyframeQuery.value(3).toString().size()-2).split(",");
00860
00861
00862 QStringList posStringCoords =
00863 keyframeQuery.value(4).toString().mid(1, keyframeQuery.value(4).toString().size()-2).split(",");
00864 QPointF pos(posStringCoords[0].toFloat(), posStringCoords[1].toFloat());
00865
00866
00867 QString visible = keyframeQuery.value(5).toString();
00868
00869
00870 QString keyframe = keyframeQuery.value(6).toString();
00871
00872
00873 if(obj == NULL)
00874 {
00875
00876 QSqlQuery objInfoQuery = db.exec("SELECT category FROM object WHERE uid="+objId);
00877 objInfoQuery.next();
00878 int category = objInfoQuery.value(0).toInt();
00879
00880 QSqlQuery descPropUidQuery = db.exec("SELECT uid FROM objectproptype WHERE name='Description'");
00881 descPropUidQuery.next();
00882 QString descPropUid = descPropUidQuery.value(0).toString();
00883 QSqlQuery descQuery = db.exec("SELECT value FROM objectproperties WHERE object="+objId+" and type="+descPropUid);
00884 descQuery.next();
00885 QString description = descQuery.value(0).toString();
00886
00887
00888
00889 obj = new AnnotationObject(frame, frameRange, pos, description, category);
00890
00891
00892 for(int vIdx=0; vIdx < obj->getVertices()->size(); ++vIdx)
00893 delete obj->getVertices()->at(vIdx);
00894 obj->getVertices()->clear();
00895
00896
00897 for(size_t vIdx=0; vIdx<vertices.size(); ++vIdx)
00898 {
00899 AnnotationObjectVertex* vert = new AnnotationObjectVertex(obj, frame, frameRange, vertices[vIdx]);
00900
00901 obj->addVertex(vIdx, vert);
00902 }
00903 }
00904
00905 if(keyframe[0] == 't')
00906 obj->setKeyframe(frame, pos, (visible[0] == 't'));
00907
00908 for(size_t vIdx=0; vIdx<vertices.size(); ++vIdx)
00909 if(verticesKeyframe[vIdx][0] == 't')
00910 obj->getVertexById(vIdx)->setKeyframe(frame, vertices[vIdx], (verticesVisible[vIdx][0] == 't'));
00911 }
00912
00913
00914 mgr->addObject(obj);
00915 mw->getMainDisplay()->addObject(obj);
00916 connect(mw->getTimeline(), SIGNAL(frameChanged(int)), obj, SLOT(frameChanged(int)));
00917 }
00918 mw->getTimeline()->setCurrentTime(0);
00919 }
00920
00921 QMap<int, QString> DBManager::getObjCategories()
00922 {
00923
00924 QSqlQuery catQuery =
00925 db.exec("SELECT uid, name FROM objectcategory");
00926
00927 QMap<int, QString> categories;
00928 while(catQuery.next())
00929 categories[catQuery.value(0).toInt()] = catQuery.value(1).toString();
00930
00931 return categories;
00932 }
00933
00934 void DBManager::updateSettings(QSettings *settings)
00935 {
00936 qDebug() << "Loading Settings:";
00937 if(settings->contains("archiveLoc"))
00938 {
00939 itsArchiveLoc = settings->value("archiveLoc").toString();
00940 qDebug() << " itsArchiveLoc " << itsArchiveLoc;
00941 }
00942 if(settings->contains("workingLoc"))
00943 {
00944 itsWorkingLoc = settings->value("workingLoc").toString();
00945 qDebug() << " itsWorkingLoc " << itsWorkingLoc;
00946 }
00947 if(settings->contains("incomingLoc"))
00948 {
00949 itsIncomingLoc = settings->value("incomingLoc").toString();
00950 qDebug() << " itsIncomingLoc " << itsIncomingLoc;
00951 }
00952 }