/**************************************************************** * This file is distributed under the following license: * * Copyright (c) 2011, RetroShare Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. ****************************************************************/ #include #include #include #include #include #include #include #include "gui/feeds/AttachFileItem.h" #include "HashBox.h" #include "ui_HashBox.h" HashedFile::HashedFile() { size = 0; flag = NoFlag; } HashBox::HashBox(QWidget *parent) : QScrollArea(parent), ui(new Ui::HashBox) { ui->setupUi(this); mAutoHide = false; dropWidget = NULL; } HashBox::~HashBox() { delete ui; } void HashBox::setAutoHide(bool autoHide) { mAutoHide = autoHide; setVisible(!mAutoHide); } void HashBox::setDropWidget(QWidget* widget) { if (dropWidget) { dropWidget->removeEventFilter(this); } dropWidget = widget; if (dropWidget) { widget->installEventFilter(this); } } static void showFormats(const std::string& event, const QStringList& formats) { std::cerr << event << "() Formats" << std::endl; QStringList::const_iterator it; for (it = formats.begin(); it != formats.end(); ++it) { std::cerr << "Format: " << (*it).toStdString(); std::cerr << std::endl; } } bool HashBox::eventFilter(QObject* object, QEvent* event) { if (object == dropWidget) { if (event->type() == QEvent::DragEnter) { QDragEnterEvent* dragEnterEvent = static_cast(event); if (dragEnterEvent) { /* print out mimeType */ showFormats("HashBox::dragEnterEvent", dragEnterEvent->mimeData()->formats()); if (dragEnterEvent->mimeData()->hasUrls()) { std::cerr << "HashBox::dragEnterEvent() Accepting Urls" << std::endl; dragEnterEvent->acceptProposedAction(); } else { std::cerr << "HashBox::dragEnterEvent() No Urls" << std::endl; } } } else if (event->type() == QEvent::Drop) { QDropEvent* dropEvent = static_cast(event); if (dropEvent) { if (Qt::CopyAction & dropEvent->possibleActions()) { /* print out mimeType */ showFormats("HashBox::dropEvent", dropEvent->mimeData()->formats()); QStringList files; if (dropEvent->mimeData()->hasUrls()) { std::cerr << "HashBox::dropEvent() Urls:" << std::endl; QList urls = dropEvent->mimeData()->urls(); QList::iterator uit; for (uit = urls.begin(); uit != urls.end(); ++uit) { QString localpath = uit->toLocalFile(); std::cerr << "Whole URL: " << uit->toString().toStdString() << std::endl; std::cerr << "or As Local File: " << localpath.toStdString() << std::endl; if (localpath.isEmpty() == false) { //Check that the file does exist and is not a directory QDir dir(localpath); if (dir.exists()) { std::cerr << "HashBox::dropEvent() directory not accepted." << std::endl; QMessageBox mb(tr("Drop file error."), tr("Directory can't be dropped, only files are accepted."), QMessageBox::Information, QMessageBox::Ok, 0, 0, this); mb.exec(); } else if (QFile::exists(localpath)) { files.push_back(localpath); } else { std::cerr << "HashBox::dropEvent() file does not exists."<< std::endl; QMessageBox mb(tr("Drop file error."), tr("File not found or file name not accepted."), QMessageBox::Information, QMessageBox::Ok, 0, 0, this); mb.exec(); } } } } addAttachments(files); dropEvent->setDropAction(Qt::CopyAction); dropEvent->accept(); } else { std::cerr << "HashBox::dropEvent() Rejecting uncopyable DropAction" << std::endl; } } } } // pass the event on to the parent class return QScrollArea::eventFilter(object, event); } void HashBox::addAttachments(const QStringList& files, HashedFile::Flags flag) { /* add a AttachFileItem to the attachment section */ std::cerr << "HashBox::addExtraFile() hashing file." << std::endl; if (files.isEmpty()) { return; } if (mAutoHide) { show(); } QStringList::ConstIterator it; for (it = files.constBegin(); it != files.constEnd(); ++it) { /* add widget in for new destination */ AttachFileItem* file = new AttachFileItem(*it); QObject::connect(file, SIGNAL(fileFinished(AttachFileItem*)), this, SLOT(fileFinished(AttachFileItem*))); HashingInfo hashingInfo; hashingInfo.item = file; hashingInfo.flag = flag; mHashingInfos.push_back(hashingInfo); ui->verticalLayout->addWidget(file, 1, 0); } QApplication::processEvents(); // workaround for Qt bug, the size from the first call to QScrollArea::sizeHint() is stored in QWidgetItemV2 and // QScrollArea::sizeHint() is never called again so that widgetResizable of QScrollArea doesn't work // the next line clears the member QScrollArea::widgetSize for recalculation of the added children in QScrollArea::sizeHint() setWidget(takeWidget()); // the next line set the cache to dirty updateGeometry(); emit fileHashingStarted(); checkAttachmentReady(); } void HashBox::fileFinished(AttachFileItem* file) { std::cerr << "HashBox::fileHashingFinished() started." << std::endl; //check that the file is ok if (file->getState() == AFI_STATE_ERROR) { std::cerr << "HashBox::fileHashingFinished error file is not hashed."; return; } checkAttachmentReady(); } void HashBox::checkAttachmentReady() { if (mHashingInfos.isEmpty()) { return; } QList::iterator it; for (it = mHashingInfos.begin(); it != mHashingInfos.end(); ++it) { if (it->item->isHidden()) { continue; } if (!it->item->done()) { break; } } if (it != mHashingInfos.end()) { /* repeat... */ QTimer::singleShot(500, this, SLOT(checkAttachmentReady())); return; } if (mAutoHide) { hide(); } QList hashedFiles; for (it = mHashingInfos.begin(); it != mHashingInfos.end(); ++it) { HashingInfo& hashingInfo = *it; if (hashingInfo.item->done()) { HashedFile hashedFile; hashedFile.filename = hashingInfo.item->FileName(); hashedFile.filepath = hashingInfo.item->FilePath(); hashedFile.hash = hashingInfo.item->FileHash(); hashedFile.size = hashingInfo.item->FileSize(); hashedFile.flag = hashingInfo.flag; hashedFiles.push_back(hashedFile); ui->verticalLayout->removeWidget(hashingInfo.item); hashingInfo.item->deleteLater(); } } mHashingInfos.clear(); QApplication::processEvents(); // workaround for Qt bug, the size from the first call to QScrollArea::sizeHint() is stored in QWidgetItemV2 and // QScrollArea::sizeHint() is never called again so that widgetResizable of QScrollArea doesn't work // the next line clears the member QScrollArea::widgetSize for recalculation of the removed children in QScrollArea::sizeHint() setWidget(takeWidget()); // the next line set the cache to dirty updateGeometry(); emit fileHashingFinished(hashedFiles); }