Skip to content

Commit 888c3cf

Browse files
authored
Merge pull request #53 from iTrace-Dev/develop
0.2.1 Merge
2 parents c0cfd5a + 93c46a3 commit 888c3cf

16 files changed

+255127
-225
lines changed

Filter.qml

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import QtQuick.Dialogs 1.2
1818
Popup {
1919
id: filter
2020
property var margin: 15 // TODO: Make this property in a config file or something that way if we want to change it we only change it in one spot
21+
property string output_folder: "."
2122
x: margin; y: margin
2223
height: parent.height - 2 * margin
2324
width: parent.width - 2 * margin
@@ -376,20 +377,29 @@ Popup {
376377
}
377378
GridLayout {
378379
id: buttonGrid
379-
columns: 2
380+
columns: 3
380381
Button {
381382
id: closeButton
382383
Layout.fillWidth: true
383384
text: "Close"
384385
onClicked: filter.close()
385386
}
387+
Button {
388+
id: setOutputFolderButton
389+
Layout.fillWidth: true
390+
text: "Output Folder"
391+
onClicked: {
392+
folderSelect.open();
393+
}
394+
}
395+
386396
Button {
387397
id: filterButton
388398
Layout.fillWidth: true
389399
text: "Filter"
390400
onClicked: {
391401
filter.close()
392-
control.generateQueriedData(control.generateQuery(fixationTargetFilter.text,fixationTokenFilter.text,fixationDurationFilterMin.text,fixationDurationFilterMax.text,fixationLineFilterMin.text,fixationLineFilterMax.text,fixationColFilterMin.text,fixationColFilterMax.text,rightMin.text,rightMax.text,leftMin.text,leftMax.text),exportBox.model[exportBox.currentIndex])
402+
control.generateQueriedData(control.generateQuery(fixationTargetFilter.text,fixationTokenFilter.text,fixationDurationFilterMin.text,fixationDurationFilterMax.text,fixationLineFilterMin.text,fixationLineFilterMax.text,fixationColFilterMin.text,fixationColFilterMax.text,rightMin.text,rightMax.text,leftMin.text,leftMax.text),exportBox.model[exportBox.currentIndex],filter.output_folder)
393403
}
394404
}
395405
}
@@ -400,7 +410,7 @@ Popup {
400410
selectExisting: true
401411
nameFilters: ["Query Files (*.sql)","All Files (*.*)"]
402412
onAccepted: {
403-
control.loadQueryFile(fileUrl,exportBox.model[exportBox.currentIndex])
413+
control.loadQueryFile(fileUrl,exportBox.model[exportBox.currentIndex],output_folder)
404414
}
405415
}
406416
FileDialog {
@@ -411,6 +421,15 @@ Popup {
411421
control.saveQueryFile(control.generateQuery(fixationTargetFilter.text,fixationTokenFilter.text,fixationDurationFilterMin.text,fixationDurationFilterMax.text,fixationLineFilterMin.text,fixationLineFilterMax.text,fixationColFilterMin.text,fixationColFilterMax.text,rightMin.text,rightMax.text,leftMin.text,leftMax.text),fileUrl);
412422
}
413423
}
424+
425+
FileDialog {
426+
id: folderSelect
427+
selectFolder: true
428+
onAccepted: {
429+
filter.output_folder = fileUrl
430+
}
431+
}
432+
414433
FileDialog {
415434
id: filterFileSave
416435
selectExisting: true

Mapping.qml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ Popup {
6565
anchors.horizontalCenter: parent.horizontalCenter
6666
onClicked: {
6767
mappingMenu.close()
68-
control.mapTokens(srcmlOpen.fileUrl, overwriteCheck.checked)
68+
control.mapTokens(srcmlOpen.fileUrl, participantList.model.getModelList().getSelected(), overwriteCheck.checked)
6969
}
7070
}
7171

controller.cpp

Lines changed: 89 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,20 @@ void Controller::importXMLFile(QString file_path) {
160160
}
161161
}
162162

163+
void Controller::importDatabaseFile(QString file_path) {
164+
changeFilePathOS(file_path);
165+
166+
std::cout << "Importing DB : " << file_path << std::endl;
167+
168+
idb.importExistingDatabase(file_path);
169+
170+
for(auto i : idb.getSessions()) { emit taskAdded(i); }
171+
172+
log->writeLine("INFO","Successfully imported database " + file_path);
173+
emit outputToScreen("black","Successfully imported database.");
174+
175+
}
176+
163177
void Controller::batchAddXML(QString folder_path) {
164178
log->writeLine("INFO","Scanning and adding all XML files in: "+folder_path);
165179
if(!idb.isDatabaseOpen()) {
@@ -170,24 +184,39 @@ void Controller::batchAddXML(QString folder_path) {
170184
emit setProgressBarToIndeterminate();
171185

172186
changeFilePathOS(folder_path);
187+
188+
QDirIterator counter(folder_path, QDir::Files, QDirIterator::Subdirectories);
189+
int count = 0;
190+
191+
while(counter.hasNext()) {
192+
++count;
193+
counter.next();
194+
if(count > 1000) {
195+
emit stopProgressBar();
196+
emit warning("File Search Too Large","The selected folder contained too many sub items.");
197+
return;
198+
}
199+
}
200+
201+
173202
std::map<QString,std::pair<std::vector<QString>,bool>> files;
174-
QDirIterator dir(folder_path);
203+
QDirIterator dir(folder_path, QStringList() << "*.xml", QDir::Files, QDirIterator::Subdirectories);;
175204
while(dir.hasNext()) {
176205
QString filename = dir.next();
177-
if(filename.endsWith(".xml")) {
178-
changeFilePathOS(filename);
179-
XMLHandler xml_file(filename);
180-
QString type = xml_file.getXMLFileType();
181-
if(type == "itrace_core" || type == "itrace_plugin") {
182-
QString id = xml_file.getElementAttribute("session_id");
183-
if(files.count(id) == 0) {
184-
auto insert = files.emplace(id,std::make_pair(std::vector<QString>(),false));
185-
insert.first->second.first.push_back(filename);
186-
}
187-
else { (files.find(id))->second.first.push_back(filename); }
188-
if(type == "itrace_core") { files.find(id)->second.second = true; }
206+
//if(filename.endsWith(".xml")) {
207+
changeFilePathOS(filename);
208+
XMLHandler xml_file(filename);
209+
QString type = xml_file.getXMLFileType();
210+
if(type == "itrace_core" || type == "itrace_plugin") {
211+
QString id = xml_file.getElementAttribute("session_id");
212+
if(files.count(id) == 0) {
213+
auto insert = files.emplace(id,std::make_pair(std::vector<QString>(),false));
214+
insert.first->second.first.push_back(filename);
189215
}
216+
else { (files.find(id))->second.first.push_back(filename); }
217+
if(type == "itrace_core") { files.find(id)->second.second = true; }
190218
}
219+
//}
191220
QApplication::processEvents();
192221
}
193222
QString badPairWarn, alreadyInWarn;
@@ -285,11 +314,11 @@ void Controller::importCoreXML(const QString& file_path) {
285314
// Insert gaze
286315
idb.insertGaze(core_file.getElementAttribute("event_id"),session_id,calibration_id,participant_id,core_file.getElementAttribute("tracker_time"),core_file.getElementAttribute("core_time"),core_file.getElementAttribute("x"),core_file.getElementAttribute("y"),core_file.getElementAttribute("left_x"),core_file.getElementAttribute("left_y"),core_file.getElementAttribute("left_pupil_diameter"),core_file.getElementAttribute("left_validation"),core_file.getElementAttribute("right_x"),core_file.getElementAttribute("right_y"),core_file.getElementAttribute("right_pupil_diameter"),core_file.getElementAttribute("right_validation"),core_file.getElementAttribute("user_left_x"),core_file.getElementAttribute("user_left_y"),core_file.getElementAttribute("user_left_z"),core_file.getElementAttribute("user_right_x"),core_file.getElementAttribute("user_right_y"),core_file.getElementAttribute("user_right_z"));
287316
}
288-
QString report = idb.checkAndReturnError();
317+
/*QString report = idb.checkAndReturnError();
289318
if(report != "") {
290319
log->writeLine("WARNING","The followng SQLite Error occured while handling core file: "+report);
291-
}
292-
report = core_file.checkAndReturnError();
320+
}*/
321+
QString report = core_file.checkAndReturnError();
293322
if(report != "") {
294323
log->writeLine("WARNING","The following XML Error occured while handling core file: "+report);
295324
}
@@ -322,8 +351,12 @@ void Controller::importPluginXML(const QString& file_path) {
322351
QString session_id,
323352
ide_plugin_type;
324353

354+
// Used for checking for duplicate data
355+
QVector<QString> all_ids;// = idb.getAllIDEContextIDs();
356+
325357
while(!plugin_file.isAtEnd()) {
326358
QString element = plugin_file.getNextElementName();
359+
//std::cout << element << std::endl;
327360

328361
if(element == "itrace_plugin") {
329362
session_id = plugin_file.getElementAttribute("session_id");
@@ -342,7 +375,8 @@ void Controller::importPluginXML(const QString& file_path) {
342375
// Insert ide_context
343376

344377
// Check if we are inserting duplicate data
345-
if(idb.pluginResponseExists(plugin_file.getElementAttribute(("event_id")))) {
378+
//if(idb.pluginResponseExists(plugin_file.getElementAttribute(("event_id")))) {
379+
if (all_ids.contains(plugin_file.getElementAttribute("event_id"))) {
346380
QString output = "Duplicate Plugin Context data in file: "+file_path+" with event_id: " + plugin_file.getElementAttribute(("event_id"));
347381
emit outputToScreen("#F55904",output);
348382
emit outputToScreen("#F55904",plugin_file.getElementAttribute(("event_id")));
@@ -351,13 +385,14 @@ void Controller::importPluginXML(const QString& file_path) {
351385
}
352386

353387
// The last 4 parameters are unused for the moment
354-
idb.insertIDEContext(plugin_file.getElementAttribute("event_id"),plugin_file.getElementAttribute("plugin_time"),ide_plugin_type,plugin_file.getElementAttribute("gaze_target"),plugin_file.getElementAttribute("gaze_target_type"),plugin_file.getElementAttribute("source_file_path"),plugin_file.getElementAttribute("source_file_line"),plugin_file.getElementAttribute("source_file_col"),plugin_file.getElementAttribute("editor_line_height"),plugin_file.getElementAttribute("editor_font_height"),plugin_file.getElementAttribute("editor_line_base_x"),plugin_file.getElementAttribute("editor_line_base_y"),"","","","",plugin_file.getElementAttribute("x"),plugin_file.getElementAttribute("y"));
388+
idb.insertIDEContext(plugin_file.getElementAttribute("event_id"),session_id,plugin_file.getElementAttribute("plugin_time"),ide_plugin_type,plugin_file.getElementAttribute("gaze_target"),plugin_file.getElementAttribute("gaze_target_type"),plugin_file.getElementAttribute("source_file_path"),plugin_file.getElementAttribute("source_file_line"),plugin_file.getElementAttribute("source_file_col"),plugin_file.getElementAttribute("editor_line_height"),plugin_file.getElementAttribute("editor_font_height"),plugin_file.getElementAttribute("editor_line_base_x"),plugin_file.getElementAttribute("editor_line_base_y"),"","","","",plugin_file.getElementAttribute("x"),plugin_file.getElementAttribute("y"));
389+
all_ids.push_back(plugin_file.getElementAttribute("event_id"));
355390
}
356-
QString report = idb.checkAndReturnError();
391+
/*QString report = idb.checkAndReturnError();
357392
if(report != "") {
358393
log->writeLine("WARNING","The followng SQLite Error occured while handling plugin file: "+report);
359-
}
360-
report = plugin_file.checkAndReturnError();
394+
}*/
395+
QString report = plugin_file.checkAndReturnError();
361396
if(report != "") {
362397
log->writeLine("WARNING","The following XML Error occured while handling plugin file: "+report);
363398
}
@@ -449,19 +484,36 @@ void Controller::generateFixationData(QVector<QString> tasks, QString algSetting
449484
}
450485
QApplication::processEvents();
451486
}
487+
452488
idb.commit();
453489
emit stopProgressBar();
454490
emit outputToScreen("black",QString("Fixation data generated. Elapsed time: %1").arg(time.elapsed() / 1000.0));
455491
}
456492

457-
void Controller::mapTokens(QString srcml_file_path, bool overwrite = true) {
493+
void Controller::mapTokens(QString srcml_file_path, QVector<QString> tasks, bool overwrite = true) {
458494
QElapsedTimer timer;
459495
timer.start();
460496

497+
QVector<QString> sessions;
498+
for(auto i : tasks) { // Get the sessions that the user wants to use
499+
QStringList values = i.split(" - ");
500+
if(values[2] == "1") {
501+
sessions.push_back(idb.getSessionFromParticipantAndTask(values[0],values[1]));
502+
}
503+
}
504+
461505
changeFilePathOS(srcml_file_path);
462506

463507
SRCMLHandler srcml(srcml_file_path);
508+
if(!srcml.isPositional()) {
509+
emit warning("srcML Error","The provided srcML File does not contain positional data. Tokens will not be mapped without it. Re-generate the srcML Archive file with the --position flag");
510+
return;
511+
}
464512

513+
// Add srcML Archive to Files table
514+
if(!idb.fileExists(QCryptographicHash::hash(srcml.getFilePath().toUtf8().constData(),QCryptographicHash::Sha1).toHex())) {
515+
idb.insertFile(QCryptographicHash::hash(srcml.getFilePath().toUtf8().constData(),QCryptographicHash::Sha1).toHex(),"null",srcml.getFilePath(),"srcml_archive");
516+
}
465517
QVector<QString> all_files = srcml.getAllFilenames();
466518

467519
idb.startTransaction();
@@ -487,8 +539,8 @@ void Controller::mapTokens(QString srcml_file_path, bool overwrite = true) {
487539
continue;
488540
}
489541

490-
mapper.mapSyntax(srcml,unit_path,file->second,overwrite);
491-
mapper.mapToken(srcml,unit_path,file->second,overwrite);
542+
mapper.mapSyntax(srcml,unit_path,file->second,overwrite,sessions);
543+
mapper.mapToken(srcml,unit_path,file->second,overwrite,sessions);
492544
}
493545
emit outputToScreen("black",QString("%1 / %2 Targets Mapped. Time elasped: %3").arg(counter).arg(files_viewed.size()).arg(inner_timer.elapsed() / 1000.0));
494546
emit setProgressBarValue(counter); ++counter;
@@ -523,16 +575,17 @@ QString Controller::findMatchingPath(QVector<QString> all_files, QString file) {
523575
QString shortest = "";
524576
int passes = 1;
525577

526-
QVector<QStringList> candidates;
578+
527579
while(possible.size() != 1) {
580+
QVector<QStringList> candidates;
528581
if(passes > file_split.size()) { return shortest; }
529582
for(auto unit_path : possible) {
530583
if(passes > unit_path.size()) {
531584
if(shortest == "") { shortest = unit_path.join("/"); }
532585
continue;
533586
}
534587
QString unit_check = unit_path[unit_path.size() - passes].toLower();
535-
QString file_check = file_split[file_split.size() - 1];
588+
QString file_check = file_split[file_split.size() - passes];
536589
if(unit_check == file_check) {
537590
candidates.push_back(unit_path);
538591
}
@@ -541,13 +594,13 @@ QString Controller::findMatchingPath(QVector<QString> all_files, QString file) {
541594
++passes;
542595
QApplication::processEvents();
543596
}
544-
if(candidates.size() == 0) { return ""; }
545-
return candidates[0].join("/");
597+
if(possible.size() == 0) { return ""; }
598+
return possible[0].join("/");
546599
}
547600

548601

549602
void Controller::highlightFixations(QString dir, QString srcml_file_path) {
550-
if(!idb.isDatabaseOpen()) {
603+
/*if(!idb.isDatabaseOpen()) {
551604
emit warning("Database Error","There is no Database currently loaded.");
552605
return;
553606
}
@@ -561,7 +614,7 @@ void Controller::highlightFixations(QString dir, QString srcml_file_path) {
561614
emit outputToScreen("black","Fixation Run: " + id);
562615
highlightTokens(idb.getFixationsFromRunID(id),SRCMLHandler(srcml_file_path),dir,id);
563616
}
564-
emit outputToScreen("black",QString("Done Highlighting! Time elapsed: %1").arg(timer.elapsed() / 1000.0));
617+
emit outputToScreen("black",QString("Done Highlighting! Time elapsed: %1").arg(timer.elapsed() / 1000.0));*/
565618
}
566619

567620
// WIP
@@ -696,7 +749,7 @@ QString Controller::generateQuery(QString targets, QString token_types, QString
696749
return query;
697750
}
698751

699-
void Controller::loadQueryFile(QString file_path, QString output_type) {
752+
void Controller::loadQueryFile(QString file_path, QString output_type, QString output_url) {
700753
changeFilePathOS(file_path);
701754
QFile file(file_path);
702755
if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
@@ -708,7 +761,7 @@ void Controller::loadQueryFile(QString file_path, QString output_type) {
708761

709762
file.close();
710763

711-
generateQueriedData(data,output_type);
764+
generateQueriedData(data,output_type,output_url);
712765
}
713766

714767
void Controller::saveQueryFile(QString query, QString file_path) {
@@ -718,10 +771,12 @@ void Controller::saveQueryFile(QString query, QString file_path) {
718771
file.close();
719772
}
720773

721-
void Controller::generateQueriedData(QString query, QString output_type) {
774+
void Controller::generateQueriedData(QString query, QString output_type, QString output_url) {
722775
QVector<QVector<QString>> data = idb.runFilterQuery(query);
723776
QString safeQuery = query.replace("\"", "\\\"");
724-
QString savename = "fixation_query_"+QString::number(std::time(nullptr))+output_type;
777+
QString savename = output_url+"/fixation_query_"+QString::number(std::time(nullptr))+output_type;
778+
changeFilePathOS(savename);
779+
std::cout << savename << std::endl;
725780
/////// DATABASE
726781
if(output_type == ".db3") {
727782
QSqlDatabase output = QSqlDatabase::addDatabase("QSQLITE","output");

controller.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class Controller : public QObject {
7272
Q_INVOKABLE void loadDatabaseFile(QString);
7373
Q_INVOKABLE void closeDatabase();
7474
Q_INVOKABLE void importXMLFile(QString);
75+
Q_INVOKABLE void importDatabaseFile(QString);
7576
Q_INVOKABLE void batchAddXML(QString);
7677
void importCoreXML(const QString&);
7778
void importPluginXML(const QString&);
@@ -80,7 +81,7 @@ class Controller : public QObject {
8081
Q_INVOKABLE void generateFixationData(QVector<QString>,QString);
8182

8283
//srcML Functions
83-
Q_INVOKABLE void mapTokens(QString,bool);
84+
Q_INVOKABLE void mapTokens(QString,QVector<QString>,bool);
8485
QString findMatchingPath(QVector<QString>,QString);
8586

8687
//Highlight Functions
@@ -90,9 +91,9 @@ class Controller : public QObject {
9091

9192
//Query Functions
9293
Q_INVOKABLE QString generateQuery(QString,QString,QString,QString,QString,QString,QString,QString,QString,QString,QString,QString);
93-
Q_INVOKABLE void loadQueryFile(QString, QString);
94-
Q_INVOKABLE void saveQueryFile(QString, QString);
95-
Q_INVOKABLE void generateQueriedData(QString,QString);
94+
Q_INVOKABLE void loadQueryFile(QString,QString,QString);
95+
Q_INVOKABLE void saveQueryFile(QString,QString);
96+
Q_INVOKABLE void generateQueriedData(QString,QString,QString);
9697

9798

9899
signals:

0 commit comments

Comments
 (0)