downloadobjectdialog.cpp
Go to the documentation of this file.
00001 
00046 #include "downloadobjectdialog.h"
00047 #include "ui_downloadobjectdialog.h"
00048 
00049 #include <re_object_recorder/qminizip.h>
00050 
00051 #include <ros/service.h>
00052 #include <re_srvs/QueryObjects.h>
00053 #include <re_srvs/SearchObjects.h>
00054 #include <re_srvs/GetObjectBinaryFile.h>
00055 
00056 #include <QDebug>
00057 #include <QFileDialog>
00058 #include <QMessageBox>
00059 #include <QtCore>
00060 #include <QProgressDialog>
00061 
00062 const QString DOWNLOAD_SERVICE = "/re_comm/get_object_binary_file";
00063 const QString QUERY_SERVICE = "/re_comm/search_objects";
00064 
00065 DownloadObjectDialog::DownloadObjectDialog(QWidget *parent) :
00066     QDialog(parent),
00067     ui(new Ui::DownloadObjectDialog)
00068 {
00069     ui->setupUi(this);
00070     ui->downloadDirEdit->setText(QDir::tempPath());
00071 }
00072 
00073 DownloadObjectDialog::~DownloadObjectDialog()
00074 {
00075     delete ui;
00076 }
00077 
00078 void DownloadObjectDialog::on_cancelButton_clicked() {
00079     emit reject();
00080 }
00081 
00082 void DownloadObjectDialog::addTableEntry(QString uid, QString filename, QString fileurl) {
00083     int row = ui->resultsTableWidget->rowCount();
00084     ui->resultsTableWidget->insertRow(row);
00085     QTableWidgetItem *checkItem = new QTableWidgetItem();
00086     checkItem->setCheckState(Qt::Unchecked);
00087     QTableWidgetItem *uidItem = new QTableWidgetItem(uid);
00088     QTableWidgetItem *filenameItem = new QTableWidgetItem(filename);
00089     QTableWidgetItem *fileURLItem = new QTableWidgetItem(fileurl);
00090 
00091     ui->resultsTableWidget->setItem(row, 0, checkItem);
00092     ui->resultsTableWidget->setItem(row, 1, uidItem);
00093     ui->resultsTableWidget->setItem(row, 2, filenameItem);
00094     ui->resultsTableWidget->setItem(row, 3, fileURLItem);
00095 }
00096 
00098 bool searchObjectsServiceCall(re_srvs::SearchObjectsRequest& req, re_srvs::SearchObjectsResponse* resp) {
00099     return ros::service::call(QUERY_SERVICE.toStdString(), req, *resp);
00100 }
00101 
00102 void DownloadObjectDialog::on_searchButton_clicked() {
00103     ui->resultsTableWidget->clearContents();
00104     ui->resultsTableWidget->setRowCount(0);
00105 
00106     QString searchQStr = ui->searchEdit->text().trimmed();
00107 
00108     // FIXME: re_comm seems to crash when a space (' ') is sent
00109     if (searchQStr.isEmpty()) {
00110         ui->queryFeedbackLbl->setText("Empty queries are not allowed");
00111         return;
00112     }
00113 
00114     if (!ros::service::exists(QUERY_SERVICE.toStdString(), true)) {
00115         QMessageBox::warning(this, "Error", "Could not reach syntactic query service. Is re_comm running?");
00116         return;
00117     }
00118 
00119     re_srvs::SearchObjectsRequest req;
00120     req.searchID = searchQStr.toStdString();
00121     re_srvs::SearchObjectsResponse resp;
00122     ui->queryFeedbackLbl->setText("Querying...");
00123 
00124     {
00125         QProgressDialog dlg("Querying RoboEarth...", "Cancel", 0, 0, this);
00126         dlg.setCancelButton(NULL);
00127         QFutureWatcher<bool> futureWatcher;
00128         QObject::connect(&futureWatcher, SIGNAL(finished()), &dlg, SLOT(reset()));
00129         QObject::connect(&dlg, SIGNAL(canceled()), &futureWatcher, SLOT(cancel()));
00130         // NOTE: QtConcurrent::run creates copies of its arguments before calling the function
00131         QFuture<bool> future = QtConcurrent::run(&searchObjectsServiceCall, req, &resp);
00132         futureWatcher.setFuture(future);
00133 
00134         dlg.exec();
00135 
00136         futureWatcher.waitForFinished();
00137         if (dlg.wasCanceled()) {
00138             ui->queryFeedbackLbl->setText("Query cancelled by user");
00139             return;
00140         } else if ((future.result() == true) && resp.success) {
00141             ui->queryFeedbackLbl->setText("Query successful");
00142         } else {
00143             ui->queryFeedbackLbl->setText("Query failed");
00144             return;
00145         }
00146     }
00147 
00148     for(unsigned int i=0; i<resp.objects.size(); i++) {
00149         QString uid = QString::fromStdString(resp.uids.at(i));
00150         re_msgs::StringArray filenames = resp.filenames.at(i);
00151         re_msgs::StringArray fileURLS = resp.fileURLs.at(i);
00152 
00153         for (unsigned int j=0; j<filenames.list.size(); j++) {
00154             addTableEntry(uid, QString::fromStdString(filenames.list.at(j)), QString::fromStdString(fileURLS.list.at(j)));
00155         }
00156     }
00157 }
00158 
00159 void DownloadObjectDialog::on_chooseDownloadDirButton_clicked() {
00160     QString dir = QFileDialog::getExistingDirectory(this, "Choose a target directory", ui->downloadDirEdit->text());
00161     if (dir.isEmpty())
00162         return;
00163 
00164     ui->downloadDirEdit->setText(dir);
00165 }
00166 
00168 bool downloadObjectsServiceCall(re_srvs::GetObjectBinaryFileRequest& req, re_srvs::GetObjectBinaryFileResponse *resp) {
00169     return ros::service::call(DOWNLOAD_SERVICE.toStdString(), req, *resp);
00170 }
00171 
00172 bool DownloadObjectDialog::downloadFile(QString uid, QString filename, QDir target_path) {
00173     re_srvs::GetObjectBinaryFileRequest req;
00174     req.objectUID = uid.toStdString();
00175     req.filename = filename.toStdString();
00176     re_srvs::GetObjectBinaryFileResponse resp;
00177     {
00178         QProgressDialog dlg("Downloading Objects", "Cancel", 0, 0, this);
00179         dlg.setCancelButton(NULL);
00180         QFutureWatcher<bool> futureWatcher;
00181         QObject::connect(&futureWatcher, SIGNAL(finished()), &dlg, SLOT(reset()));
00182         QObject::connect(&dlg, SIGNAL(canceled()), &futureWatcher, SLOT(cancel()));
00183         // NOTE: QtConcurrent::run creates copies of its arguments before calling the function
00184         QFuture<bool> future = QtConcurrent::run(&downloadObjectsServiceCall, req, &resp);
00185         futureWatcher.setFuture(future);
00186 
00187         dlg.exec();
00188 
00189         futureWatcher.waitForFinished();
00190         if (dlg.wasCanceled()) {
00191             QMessageBox::warning(this, "Download cancelled", "Download cancelled by user.");
00192             return false;
00193         } else if ((future.result() == true) && resp.success) {
00194             // download successful
00195         } else {
00196             QMessageBox::warning(this, "Download failed", "Downloading of '" + uid + "' failed!");
00197             return false;
00198         }
00199     }
00200 
00201     QFile out_file(target_path.filePath(QString::fromStdString(resp.file.name)));
00202     if (!out_file.open(QIODevice::WriteOnly)) {
00203         QMessageBox::warning(this, "Download failed", "Could not open '" + out_file.fileName() + "' for writing.");
00204         return false;
00205     }
00206     qDebug() << "writing to " << out_file.fileName();
00207 
00208     // TOOD: what if memory full?
00209     char *buffer = new char[resp.file.data.size()];
00210     std::copy(resp.file.data.begin(), resp.file.data.end(), buffer);
00211     qint64 written = out_file.write(buffer, resp.file.data.size());
00212     delete [] buffer;
00213 
00214     if (written < resp.file.data.size()) {
00215         QMessageBox::warning(this, "Download failed", "Wrote only " + QString::number(written) + " of "
00216                              + QString::number(resp.file.data.size()) + " bytes to " + out_file.fileName() + "!");
00217         return false;
00218     }
00219 
00220     return true;
00221 }
00222 
00223 void DownloadObjectDialog::on_downloadButton_clicked() {
00224     bool service_checked = false;
00225     QDir target_path(ui->downloadDirEdit->text());
00226     for(int i=0; i<ui->resultsTableWidget->rowCount(); i++) {
00227         QTableWidgetItem *checkboxItem = ui->resultsTableWidget->item(i, 0);
00228         QTableWidgetItem *uidItem = ui->resultsTableWidget->item(i, 1);
00229         QTableWidgetItem *fileURLItem = ui->resultsTableWidget->item(i, 3);
00230         if (checkboxItem->checkState() == Qt::Checked) {
00231             // get actual file name (i.e. last part of URL)
00232             QStringList fileURLSplitted = fileURLItem->text().split('/', QString::SkipEmptyParts);
00233             QString realFilename = fileURLSplitted.last();
00234 
00235             if (!service_checked && !ros::service::exists(DOWNLOAD_SERVICE.toStdString(), true)) {
00236                 QMessageBox::warning(this, "Error", "Could not reach download service. Is re_comm running?");
00237                 return;
00238             }
00239             service_checked = true;
00240 
00241             bool downloaded = downloadFile(uidItem->text(), realFilename, target_path);
00242             if (downloaded && realFilename.endsWith(".zip", Qt::CaseInsensitive)) {
00243                 qDebug() << "extracting into " << target_path;
00244                 // unpack
00245                 QMiniZip mz(target_path.filePath(realFilename), QMiniZip::UNZIP);
00246                 mz.unzip(target_path);
00247 
00248                 QStringList zipContents = mz.getContents();
00249                 qDebug() << zipContents;
00250                 QString created_dir_name = zipContents.first().split('/', QString::SkipEmptyParts).first();
00251 
00252                 this->downloaded_models.append(target_path.filePath(created_dir_name));
00253             }
00254         }
00255     }
00256 
00257     emit accept();
00258 }


re_object_detector_gui
Author(s): Daniel Di Marco
autogenerated on Sun Jan 5 2014 11:39:57