/** 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; }
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))); }