RetroShare/retroshare-gui/src/gui/common/HashBox.cpp

260 lines
7.7 KiB
C++
Raw Normal View History

/****************************************************************
* 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 <QMessageBox>
#include <QDir>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QUrl>
#include <QTimer>
#include <iostream>
#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<QDragEnterEvent*>(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<QDropEvent*>(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<QUrl> urls = dropEvent->mimeData()->urls();
QList<QUrl>::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<HashingInfo>::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<HashedFile> 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);
}