/** Download finished! */
void DownloadManager::endData(UserConnection* aSource) {
    dcassert(aSource->getState() == UserConnection::STATE_RUNNING);
    Download* d = aSource->getDownload();
    dcassert(d != NULL);

    if(d->getType() == Transfer::TYPE_TREE) {
        d->getFile()->flush();

        int64_t bl = 1024;
        while(bl * (int64_t)d->getTigerTree().getLeaves().size() < d->getTigerTree().getFileSize())
            bl *= 2;
        d->getTigerTree().setBlockSize(bl);
        d->getTigerTree().calcRoot();

        if(!(d->getTTH() == d->getTigerTree().getRoot())) {
            // This tree is for a different file, remove from queue...
            removeDownload(d);
            fire(DownloadManagerListener::Failed(), d, _("Full tree does not match TTH root"));

            QueueManager::getInstance()->removeSource(d->getPath(), aSource->getUser(), QueueItem::Source::FLAG_BAD_TREE, false);

            QueueManager::getInstance()->putDownload(d, false);

            checkDownloads(aSource);
            return;
        }
        d->setTreeValid(true);
    } else {
        // First, finish writing the file (flushing the buffers and closing the file...)
        try {
            d->getFile()->flush();
                } catch(const Exception& e) {
                        d->resetPos();
            failDownload(aSource, e.getError());
            return;
        }

        aSource->setSpeed(d->getAverageSpeed());
        aSource->updateChunkSize(d->getTigerTree().getBlockSize(), d->getSize(), GET_TICK() - d->getStart());

        dcdebug("Download finished: %s, size " I64_FMT ", downloaded " I64_FMT "\n", d->getPath().c_str(),
                static_cast<long long int>(d->getSize()), static_cast<long long int>(d->getPos()));

        if(BOOLSETTING(LOG_DOWNLOADS) && (BOOLSETTING(LOG_FILELIST_TRANSFERS) || d->getType() == Transfer::TYPE_FILE)) {
            logDownload(aSource, d);
        }
    }

    removeDownload(d);
    fire(DownloadManagerListener::Complete(), d);

    QueueManager::getInstance()->putDownload(d, true);
    checkDownloads(aSource);
}
void DownloadManager::downloadRequested(const QNetworkRequest& request) {
    std::cout << "DownloadManager::DownloadRequested()\n";
    QString src = request.url().toString();
    QString dest = request.attribute(QNetworkRequest::User, "~").toString();

    QFile* fileDestination = new QFile(dest);
    fileDestination->open(QIODevice::ReadWrite);
    QNetworkReply* reply = mNetworkAccess.get(request);
    reply->setReadBufferSize(0);
    mActiveDownloads.insert(reply, fileDestination);

    connect(reply, SIGNAL(finished()), this, SLOT(downloadFinished()));
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadError(QNetworkReply::NetworkError)));
    connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadProgress(qint64, qint64)));
    connect(reply, SIGNAL(readyRead()), this, SLOT(downloadReadyRead()));

    DownloadData* data = new DownloadData();
    data->mRemotePath = src;
    data->mLocalPath = dest;

    connect(reply, SIGNAL(finished()), data, SLOT(finished()));

    connect(reply, SIGNAL(downloadProgress(qint64, qint64)), data, SLOT(catchProgress(qint64, qint64)));
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), data, SIGNAL(error(QNetworkReply::NetworkError)));
    connect(data, SIGNAL(stopMe()), this, SLOT(stopDownload()));
    connect(data, SIGNAL(removeMe()), this, SLOT(removeDownload()));
    //connect(data, SIGNAL(reloadMe()), this, SLOT(reloadDownload()));

    emit downloadStarted(data);
    emit controller_showSystemTrayMessage("", "Download Started: " + data->localName());
    mModel.addDownload(data);
    mDownloads.insert(data, reply);
}
void DownloadManager::on(UserConnectionListener::FileNotAvailable, UserConnection* aSource) throw() {
	Download* d = aSource->getDownload();
	dcassert(d != NULL);

	if(d->isSet(Download::FLAG_TREE_DOWNLOAD)) {
		// No tree, too bad...
		aSource->setDownload(d->getOldDownload());
		delete d->getFile();
		d->setFile(NULL);
		delete d;
		checkDownloads(aSource);
		return;
	}

	dcdebug("File Not Available: %s\n", d->getTarget().c_str());

	if(d->getFile()) {
		delete d->getFile();
		d->setFile(NULL);
		d->setCrcCalc(NULL);
	}

	fire(DownloadManagerListener::Failed(), d, d->getTargetFileName() + ": " + STRING(FILE_NOT_AVAILABLE));

	aSource->setDownload(NULL);

	QueueManager::getInstance()->removeSource(d->getTarget(), aSource->getUser(), QueueItem::Source::FLAG_FILE_NOT_AVAILABLE, false);
	removeDownload(d, false, false);
	checkDownloads(aSource);
}
void DownloadListWidgetCompactDelegate::issueRemoveFromViewCompleted()
{
  if (QMessageBox::question(nullptr, tr("Are you sure?"),
                            tr("This will permanently remove all installed downloads from this list (but NOT from disk)."),
                            QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
    emit removeDownload(-2, false);
  }
}
void DownloadListWidgetCompactDelegate::issueDeleteCompleted()
{
  if (QMessageBox::question(nullptr, tr("Are you sure?"),
                            tr("This will remove all installed downloads from this list and from disk."),
                            QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
    emit removeDownload(-2, true);
  }
}
void DownloadManager::on(UserConnectionListener::Data, UserConnection* aSource, const u_int8_t* aData, size_t aLen) throw() {
	Download* d = aSource->getDownload();
	dcassert(d != NULL);

	try {
		d->addPos(d->getFile()->write(aData, aLen), aLen);

		if(d->getPos() > d->getSize()) {
			throw Exception(STRING(TOO_MUCH_DATA));
		} else if(d->getPos() == d->getSize()) {
			handleEndData(aSource);
			aSource->setLineMode();
		}
	} catch(const RollbackException& e) {
		string target = d->getTarget();
		QueueManager::getInstance()->removeSource(target, aSource->getUser(), QueueItem::Source::FLAG_ROLLBACK_INCONSISTENCY);
		fire(DownloadManagerListener::Failed(), d, e.getError());

		d->resetPos();
		aSource->setDownload(NULL);
		removeDownload(d, true);
		removeConnection(aSource);
		return;
	} catch(const FileException& e) {
		fire(DownloadManagerListener::Failed(), d, e.getError());

		d->resetPos();
		aSource->setDownload(NULL);
		removeDownload(d, true);
		removeConnection(aSource);
		return;
	} catch(const Exception& e) {
		fire(DownloadManagerListener::Failed(), d, e.getError());
		// Nuke the bytes we have written, this is probably a compression error
		d->resetPos();
		aSource->setDownload(NULL);
		removeDownload(d, true);
		removeConnection(aSource);
		return;
	}
}
void DownloadManager::failDownload(UserConnection* aSource, const string& reason) {

    Download* d = aSource->getDownload();

    if(d) {
        removeDownload(d);
        fire(DownloadManagerListener::Failed(), d, reason);

        QueueManager::getInstance()->putDownload(d, false);
    }

    removeConnection(aSource);
}
void DownloadManager::on(UserConnectionListener::MaxedOut, UserConnection* aSource) throw() { 
	if(aSource->getState() != UserConnection::STATE_FILELENGTH && aSource->getState() != UserConnection::STATE_TREE) {
		dcdebug("DM::onMaxedOut Bad state, ignoring\n");
		return;
	}

	Download* d = aSource->getDownload();
	dcassert(d != NULL);

	fire(DownloadManagerListener::Failed(), d, STRING(NO_SLOTS_AVAILABLE));

	aSource->setDownload(NULL);
	removeDownload(d, true);
	removeConnection(aSource);
}
void DownloadManager::on(UserConnectionListener::Failed, UserConnection* aSource, const string& aError) throw() {
	Download* d = aSource->getDownload();

	if(d == NULL) {
		removeConnection(aSource);
		return;
	}
	
	fire(DownloadManagerListener::Failed(), d, aError);

	string target = d->getTarget();
	aSource->setDownload(NULL);
	removeDownload(d, true);
	
	if(aError.find("File Not Available") != string::npos || aError.find(" no more exists") != string::npos) { //solved DCTC
		QueueManager::getInstance()->removeSource(target, aSource->getUser(), QueueItem::Source::FLAG_FILE_NOT_AVAILABLE, false);
	}

	removeConnection(aSource);
}
void DownloadManager::fileNotAvailable(UserConnection* aSource) {
    if(aSource->getState() != UserConnection::STATE_SND) {
        dcdebug("DM::fileNotAvailable Invalid state, disconnecting");
        aSource->disconnect();
        return;
    }

    Download* d = aSource->getDownload();
    dcassert(d != NULL);
    dcdebug("File Not Available: %s\n", d->getPath().c_str());

    removeDownload(d);
    fire(DownloadManagerListener::Failed(), d, str(F_("%1%: File not available") % d->getTargetFileName()));

    QueueManager::getInstance()->removeSource(d->getPath(), aSource->getUser(), d->getType() == Transfer::TYPE_TREE ? QueueItem::Source::FLAG_NO_TREE : QueueItem::Source::FLAG_FILE_NOT_AVAILABLE, false);

    QueueManager::getInstance()->putDownload(d, false);

    checkDownloads(aSource);
}
void DownloadListWidgetCompactDelegate::issueRemoveFromView()
{
  emit removeDownload(m_ContextIndex.row(), false);
}
void DownloadListWidgetCompactDelegate::issueDelete()
{
  emit removeDownload(m_ContextIndex.row(), true);
}
/** Download finished! */
void DownloadManager::handleEndData(UserConnection* aSource) {

	dcassert(aSource->getState() == UserConnection::STATE_DONE);
	Download* d = aSource->getDownload();
	dcassert(d != NULL);

	if(d->isSet(Download::FLAG_TREE_DOWNLOAD)) {
		d->getFile()->flush();
		delete d->getFile();
		d->setFile(NULL);

		Download* old = d->getOldDownload();

		size_t bl = 1024;
		while(bl * old->getTigerTree().getLeaves().size() < old->getSize())
			bl *= 2;
		old->getTigerTree().setBlockSize(bl);
		dcassert(old->getSize() != -1);
		old->getTigerTree().setFileSize(old->getSize());

		old->getTigerTree().calcRoot();

		if(!(*old->getTTH() == old->getTigerTree().getRoot())) {
			// This tree is for a different file, remove from queue...
			fire(DownloadManagerListener::Failed(), old, STRING(INVALID_TREE));

			string target = old->getTarget();

			aSource->setDownload(NULL);
			removeDownload(old, true);

			QueueManager::getInstance()->removeSource(target, aSource->getUser(), QueueItem::Source::FLAG_BAD_TREE, false);
			checkDownloads(aSource);
			return;
		}

		d->getOldDownload()->setTreeValid(true);

		HashManager::getInstance()->addTree(old->getTarget(), old->getTigerTree());

		aSource->setDownload(d->getOldDownload());

		delete d;

		// Ok, now we can continue to the actual file...
		checkDownloads(aSource);
		return;
	}

	u_int32_t crc = 0;
	bool hasCrc = (d->getCrcCalc() != NULL);

	// First, finish writing the file (flushing the buffers and closing the file...)
	try {
		d->getFile()->flush();
		if(hasCrc)
			crc = d->getCrcCalc()->getFilter().getValue();
		delete d->getFile();
		d->setFile(NULL);
		d->setCrcCalc(NULL);

		// Check if we're anti-fragging...
		if(d->isSet(Download::FLAG_ANTI_FRAG)) {
			// Ok, rename the file to what we expect it to be...
			try {
				const string& tgt = d->getTempTarget().empty() ? d->getTarget() : d->getTempTarget();
				File::renameFile(d->getDownloadTarget(), tgt);
				d->unsetFlag(Download::FLAG_ANTI_FRAG);
			} catch(const FileException& e) {
				dcdebug("AntiFrag: %s\n", e.getError().c_str());
				// Now what?
			}
		}
	} catch(const FileException& e) {
		fire(DownloadManagerListener::Failed(), d, e.getError());
		
		aSource->setDownload(NULL);
		removeDownload(d, true);
		removeConnection(aSource);
		return;
	}
	
	dcassert(d->getPos() == d->getSize());
	dcdebug("Download finished: %s, size " I64_FMT ", downloaded " I64_FMT "\n", d->getTarget().c_str(), d->getSize(), d->getTotal());

	// Check if we have some crc:s...
	if(BOOLSETTING(SFV_CHECK)) {
		SFVReader sfv(d->getTarget());
		if(sfv.hasCRC()) {
			bool crcMatch;
			string tgt = d->getDownloadTarget();
			if(hasCrc) {
				crcMatch = (crc == sfv.getCRC());
			} else {
				// More complicated, we have to reread the file
				try {
					
					File ff(tgt, File::READ, File::OPEN);
					CalcInputStream<CRC32Filter, false> f(&ff);

					const size_t BUF_SIZE = 16 * 65536;
					AutoArray<u_int8_t> b(BUF_SIZE);
					size_t n = BUF_SIZE;
					while(f.read((u_int8_t*)b, n) > 0)
						;		// Keep on looping...

					crcMatch = (f.getFilter().getValue() == sfv.getCRC());
				} catch (FileException&) {
					// Nope; read failed...
					goto noCRC;
				}
			}

			if(!crcMatch) {
				File::deleteFile(tgt);
				dcdebug("DownloadManager: CRC32 mismatch for %s\n", d->getTarget().c_str());
				LogManager::getInstance()->message(STRING(SFV_INCONSISTENCY) + " (" + STRING(FILE) + ": " + d->getTarget() + ")");
				fire(DownloadManagerListener::Failed(), d, STRING(SFV_INCONSISTENCY));
				
				string target = d->getTarget();
				
				aSource->setDownload(NULL);
				removeDownload(d, true);				
				
				QueueManager::getInstance()->removeSource(target, aSource->getUser(), QueueItem::Source::FLAG_CRC_WARN, false);
				checkDownloads(aSource);
				return;
			} 

			d->setFlag(Download::FLAG_CRC32_OK);
			
			dcdebug("DownloadManager: CRC32 match for %s\n", d->getTarget().c_str());
		}
	}
noCRC:
	if(BOOLSETTING(LOG_DOWNLOADS) && (BOOLSETTING(LOG_FILELIST_TRANSFERS) || !d->isSet(Download::FLAG_USER_LIST))) {
		StringMap params;
		params["target"] = d->getTarget();
		params["user"] = aSource->getUser()->getNick();
		params["hub"] = aSource->getUser()->getLastHubName();
		params["hubip"] = aSource->getUser()->getLastHubAddress();
		params["size"] = Util::toString(d->getSize());
		params["sizeshort"] = Util::formatBytes(d->getSize());
		params["chunksize"] = Util::toString(d->getTotal());
		params["chunksizeshort"] = Util::formatBytes(d->getTotal());
		params["actualsize"] = Util::toString(d->getActual());
		params["actualsizeshort"] = Util::formatBytes(d->getActual());
		params["speed"] = Util::formatBytes(d->getAverageSpeed()) + "/s";
		params["time"] = Util::formatSeconds((GET_TICK() - d->getStart()) / 1000);
		params["sfv"] = Util::toString(d->isSet(Download::FLAG_CRC32_OK) ? 1 : 0);
		LOG(DOWNLOAD_AREA, Util::formatParams(SETTING(LOG_FORMAT_POST_DOWNLOAD), params));
	}

	// Check if we need to move the file
	if( !d->getTempTarget().empty() && (Util::stricmp(d->getTarget().c_str(), d->getTempTarget().c_str()) != 0) ) {
		try {
			File::ensureDirectory(d->getTarget());
			if(File::getSize(d->getTempTarget()) > MOVER_LIMIT) {
				mover.moveFile(d->getTempTarget(), d->getTarget());
			} else {
				File::renameFile(d->getTempTarget(), d->getTarget());
			}
			d->setTempTarget(Util::emptyString);
		} catch(const FileException&) {
			try {
				if(!SETTING(DOWNLOAD_DIRECTORY).empty()) {
					File::renameFile(d->getTempTarget(), SETTING(DOWNLOAD_DIRECTORY) + d->getTargetFileName());
				} else {
					File::renameFile(d->getTempTarget(), Util::getFilePath(d->getTempTarget()) + d->getTargetFileName());
				}
			} catch(const FileException&) {
				try {
					File::renameFile(d->getTempTarget(), Util::getFilePath(d->getTempTarget()) + d->getTargetFileName());
				} catch(const FileException&) {
					// Ignore...
				}
			}
		}
	}

	fire(DownloadManagerListener::Complete(), d);
	
	aSource->setDownload(NULL);
	removeDownload(d, true, true);
	checkDownloads(aSource);
}
bool DownloadManager::prepareFile(UserConnection* aSource, int64_t newSize /* = -1 */) {
	Download* d = aSource->getDownload();
	dcassert(d != NULL);

	if(newSize != -1) {
		d->setSize(newSize);
	}
	if(d->getPos() >= d->getSize()) {
		// Already finished?
		aSource->setDownload(NULL);
		removeDownload(d, true, true);
		removeConnection(aSource);
		return false;
	}

	dcassert(d->getSize() != -1);

	string target = d->getDownloadTarget();
	File::ensureDirectory(target);
	if(d->isSet(Download::FLAG_USER_LIST)) {
		if(aSource->isSet(UserConnection::FLAG_SUPPORTS_XML_BZLIST)) {
			target += ".xml.bz2";
		} else {
			target += ".DcLst";
		}
	}

	File* file = NULL;
	try {
		// Let's check if we can find this file in a any .SFV...
		int trunc = d->isSet(Download::FLAG_RESUME) ? 0 : File::TRUNCATE;
		file = new File(target, File::RW, File::OPEN | File::CREATE | trunc);
		if(d->isSet(Download::FLAG_ANTI_FRAG)) {
			file->setSize(d->getSize());
		}
		file->setPos(d->getPos());
	} catch(const FileException& e) {
		delete file;
		fire(DownloadManagerListener::Failed(), d, STRING(COULD_NOT_OPEN_TARGET_FILE) + e.getError());
		aSource->setDownload(NULL);
		removeDownload(d, true);
		removeConnection(aSource);
		return false;
	} catch(const Exception& e) {
		delete file;
		fire(DownloadManagerListener::Failed(), d, e.getError());
		aSource->setDownload(NULL);
		removeDownload(d, true);
		removeConnection(aSource);
		return false;
	}

	d->setFile(file);

	if(d->isSet(Download::FLAG_ROLLBACK)) {
		d->setFile(new RollbackOutputStream<true>(file, d->getFile(), (size_t)min((int64_t)SETTING(ROLLBACK), d->getSize() - d->getPos())));
	}

	if(SETTING(BUFFER_SIZE) != 0) {
		d->setFile(new BufferedOutputStream<true>(d->getFile()));
	}

	bool sfvcheck = BOOLSETTING(SFV_CHECK) && (d->getPos() == 0) && (SFVReader(d->getTarget()).hasCRC());

	if(sfvcheck) {
		d->setFlag(Download::FLAG_CALC_CRC32);
		Download::CrcOS* crc = new Download::CrcOS(d->getFile());
		d->setCrcCalc(crc);
		d->setFile(crc);
	}

	if(d->getPos() == 0) {
		if(!d->getTreeValid() && d->getTTH() != NULL && d->getSize() < numeric_limits<size_t>::max()) {
			// We make a single node tree...
			d->getTigerTree().setFileSize(d->getSize());
			d->getTigerTree().setBlockSize((size_t)d->getSize());

			d->getTigerTree().getLeaves().push_back(*d->getTTH());
			d->getTigerTree().calcRoot();
			d->setTreeValid(true);
		}
		if(d->getTreeValid()) {
			d->setFile(new TigerCheckOutputStream<true>(d->getTigerTree(), d->getFile()));
		}
	}

	if(d->isSet(Download::FLAG_ZDOWNLOAD)) {
		d->setFile(new FilteredOutputStream<UnZFilter, true>(d->getFile()));
	}
	dcassert(d->getPos() != -1);
	d->setStart(GET_TICK());
	aSource->setState(UserConnection::STATE_DONE);
	
	fire(DownloadManagerListener::Starting(), d);
	
	return true;
}	
Exemple #15
0
void CMainWindow::connectSignals()
{
    CChatManager *Manager = CChatManager::instance();
    CNetworkClient *Network = CNetworkClient::instance();
    CBattleManager *BattleManager = CBattleManager::instance();

    connect(ui->ChatTabWidget->tabBar(), SIGNAL(tabCloseRequested(int)), Manager, SLOT(closeChannel(int)));
    connect(ui->ChatTabWidget->tabBar(), SIGNAL(currentChanged(int)), Manager, SLOT(changeCurrentChannel(int)));
    connect(ui->ChatTabWidget->tabBar(), SIGNAL(tabMoved(int,int)), Manager, SLOT(moveChannel(int,int)));
    connect(Manager, SIGNAL(joined(CChannel*)), this, SLOT(createTab(CChannel*)));
    connect(Manager, SIGNAL(closeTab(int)), this, SLOT(removeTab(int)));
    connect(Manager, SIGNAL(currentChanged(CChannel*)), ui->ChatTabWidget->chatView(), SLOT(loadChannel(CChannel*)));
    connect(ui->ChannelsView, SIGNAL(doubleClicked(QModelIndex)), CChatManager::instance(), SLOT(doubleClicked(QModelIndex)));
    connect(ui->ChannelUserView, SIGNAL(doubleClicked(QModelIndex)),
            CUserManager::instance()->chatModel(), SLOT(doubleClicked(QModelIndex)));
    connect(ui->actionChatSend, SIGNAL(triggered()), this, SLOT(sendChat()));
    connect(ui->actionBattleSend, SIGNAL(triggered()), this, SLOT(sendBattle()));
    connect(Manager, SIGNAL(currentChanged(int)), ui->ChatTabWidget->tabBar(), SLOT(setCurrentIndex(int)));
    connect(ui->BattleListView->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
            CBattleManager::instance(), SLOT(battleSelected(QModelIndex)));
    connect(ui->BattleListView, SIGNAL(doubleClicked(QModelIndex)), CBattleManager::instance(), SLOT(doubleClicked(QModelIndex)));
    connect(ui->BattlePreviewView, SIGNAL(doubleClicked(QModelIndex)),
            CBattleManager::instance()->battlePreviewModel(), SLOT(doubleClicked(QModelIndex)));
    connect(ui->actionConnect, SIGNAL(triggered()), this, SLOT(showConnectDialog()));
    connect(&ConnectDialog, SIGNAL(connect(QString,int,QString,QString)), Network, SLOT(connectToServer(QString,int,QString,QString)));
    connect(Network, SIGNAL(disconnected()), this, SLOT(networkDisconnected()));
    connect(Network, SIGNAL(connected()), this, SLOT(networkConnected()));
    connect(Network, SIGNAL(multiplayerDisabled()), this, SLOT(disableMultiplayerGUI()));
    connect(Network, SIGNAL(multiplayerEnabled()), this, SLOT(enableMultiplayerGUI()));
    connect(ui->actionDisconnect, SIGNAL(triggered()), Network, SLOT(disconnect()));
    connect(CBattleManager::instance(), SIGNAL(currentMapChanged(CMap*)), ui->MapInfo, SLOT(setMap(CMap*)));
    connect(CBattleroomManager::instance(), SIGNAL(mapChanged(CMap*)), ui->BattleMapInfo, SLOT(setMap(CMap*)));
    connect(CBattleroomManager::instance(), SIGNAL(updateChat(CChannel*)), ui->BattleChatText, SLOT(loadChannel(CChannel*)));
    connect(CBattleroomManager::instance(), SIGNAL(error(int,QString)), this, SLOT(error(int,QString)));
    connect(ui->LeaveBattleButton, SIGNAL(clicked()), CBattleroomManager::instance(), SLOT(leaveBattle()));
    connect(ui->DownloadButton, SIGNAL(clicked()), this, SLOT(execDownload()));

    connect(ui->actionDeleteDownload, SIGNAL(triggered()), this, SLOT(removeDownload()));

    connect(ui->actionDownloadMap, SIGNAL(triggered()), BattleManager, SLOT(downloadMapForBattle()));
    connect(ui->actionDownloadMod, SIGNAL(triggered()), BattleManager, SLOT(downloadModForBattle()));

    connect(ui->DownloadView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showDownloadContextMenu(QPoint)));
    connect(ui->BattleListView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showBattleContextMenu(QPoint)));

    connect(Network, SIGNAL(error(int,QString)), this, SLOT(error(int,QString)));
    connect(CDownloadManager::instance(), SIGNAL(error(int,QString)), this, SLOT(error(int,QString)));
    connect(Manager, SIGNAL(error(int,QString)), this, SLOT(error(int,QString)));
    connect(CDownloadManager::instance(), SIGNAL(error(int,QString)), this, SLOT(error(int,QString)));
    connect(Network, SIGNAL(agreement(QString)), this, SLOT(showAgreement(QString)));

    connect(ui->actionReloadUnitSync, SIGNAL(triggered()), CUnitSync::instance(), SLOT(reload()));
    connect(CUnitSync::instance(), SIGNAL(error(int,QString)), this, SLOT(error(int,QString)));
    connect(CUserManager::instance(), SIGNAL(lobbyUserBattleStatusChanged(CBattleStatus*)),
            this, SLOT(updateBattleStatus(CBattleStatus*)));

    connect(CUnitSync::instance(), SIGNAL(loaded()), this, SLOT(unitsyncLoaded()));
    connect(CUnitSync::instance(), SIGNAL(unloaded()), this, SLOT(unitsyncUnloaded()));

    connect(ui->actionUpdateStatus, SIGNAL(triggered()), this, SLOT(changeBattleStatus()));

    connect(CBattleroomManager::instance(), SIGNAL(battleJoined(CBattle*)), this, SLOT(enableBattleroom(CBattle*)));
    connect(CBattleroomManager::instance(), SIGNAL(battleClosed()), this, SLOT(disableBattleroom()));
    connect(CBattleroomManager::instance(), SIGNAL(gameStarted()), this, SLOT(lockBattleroom()));
    connect(CBattleroomManager::instance(), SIGNAL(gameEnded()), this, SLOT(unlockBattleroom()));
    connect(CBattleroomManager::instance(), SIGNAL(battleStarted()), this, SLOT(onBattleStarted()));
    connect(CBattleroomManager::instance(), SIGNAL(battleEnded()), this, SLOT(onBattleEnded()));
    connect(ui->SelectColorButton, SIGNAL(clicked()), this, SLOT(selectColor()));
    connect(ui->StartBattleButton, SIGNAL(clicked()), CBattleroomManager::instance(), SLOT(startGame()));

    connect(&ColorDialog, SIGNAL(colorSelected(QColor)), this, SLOT(colorSelected(QColor)));
}