void ArtistBiography::FetchInfo(int id, const Song& metadata) { if (metadata.artist().isEmpty()) { emit Finished(id); return; } QUrl url(kArtistBioUrl); url.addQueryItem("artist", metadata.artist()); url.addQueryItem("lang", GetLocale()); qLog(Debug) << "Biography url: " << url; QNetworkRequest request(url); QNetworkReply* reply = network_->get(request); NewClosure(reply, SIGNAL(finished()), [this, reply, id]() { reply->deleteLater(); QJson::Parser parser; QVariantMap response = parser.parse(reply).toMap(); QString body = response["articleBody"].toString(); QString url = response["url"].toString(); CountdownLatch* latch = new CountdownLatch; if (url.contains("wikipedia.org")) { FetchWikipediaImages(id, url, latch); FetchWikipediaArticle(id, url, latch); } else { latch->Wait(); // Use the simple article body from KG. if (!body.isEmpty()) { CollapsibleInfoPane::Data data; data.id_ = url; data.title_ = tr("Biography"); data.type_ = CollapsibleInfoPane::Data::Type_Biography; QString text; text += "<p><a href=\"" + url + "\">" + tr("Open in your browser") + "</a></p>"; text += body; SongInfoTextView* editor = new SongInfoTextView; editor->SetHtml(text); data.contents_ = editor; emit InfoReady(id, data); } latch->CountDown(); } NewClosure(latch, SIGNAL(Done()), [this, id, latch]() { latch->deleteLater(); emit Finished(id); }); }); }
void GPodderSearchPage::SearchClicked() { emit Busy(true); mygpo::PodcastListPtr list(api_->search(ui_->query->text())); NewClosure(list, SIGNAL(finished()), this, SLOT(SearchFinished(mygpo::PodcastListPtr)), list); NewClosure(list, SIGNAL(parseError()), this, SLOT(SearchFailed(mygpo::PodcastListPtr)), list); NewClosure(list, SIGNAL(requestError(QNetworkReply::NetworkError)), this, SLOT(SearchFailed(mygpo::PodcastListPtr)), list); }
void ArtistBiography::FetchWikipediaImages(int id, const QString& wikipedia_url, CountdownLatch* latch) { latch->Wait(); qLog(Debug) << wikipedia_url; QRegExp regex("([a-z]+)\\.wikipedia\\.org/wiki/(.*)"); if (regex.indexIn(wikipedia_url) == -1) { emit Finished(id); return; } QString wiki_title = QUrl::fromPercentEncoding(regex.cap(2).toUtf8()); QString language = regex.cap(1); QUrl url(QString(kWikipediaImageListUrl).arg(language)); url.addQueryItem("titles", wiki_title); qLog(Debug) << "Wikipedia images:" << url; QNetworkRequest request(url); QNetworkReply* reply = network_->get(request); NewClosure(reply, SIGNAL(finished()), [this, id, reply, language, latch]() { reply->deleteLater(); QJson::Parser parser; QVariantMap response = parser.parse(reply).toMap(); QStringList image_titles = ExtractImageTitles(response); for (const QString& image_title : image_titles) { latch->Wait(); QUrl url(QString(kWikipediaImageInfoUrl).arg(language)); url.addQueryItem("titles", image_title); qLog(Debug) << "Image info:" << url; QNetworkRequest request(url); QNetworkReply* reply = network_->get(request); NewClosure(reply, SIGNAL(finished()), [this, id, reply, latch]() { reply->deleteLater(); QJson::Parser parser; QVariantMap json = parser.parse(reply).toMap(); QUrl url = ExtractImageUrl(json); qLog(Debug) << "Found wikipedia image url:" << url; if (!url.isEmpty()) { emit ImageReady(id, url); } latch->CountDown(); }); } latch->CountDown(); }); }
void OAuthenticator::StartAuthorisation(const QString& oauth_endpoint, const QString& token_endpoint, const QString& scope) { token_endpoint_ = QUrl(token_endpoint); LocalRedirectServer* server = new LocalRedirectServer(this); server->Listen(); QUrl url = QUrl(oauth_endpoint); url.addQueryItem("response_type", "code"); url.addQueryItem("client_id", client_id_); QUrl redirect_url; const QString port = QString::number(server->url().port()); if (redirect_style_ == RedirectStyle::REMOTE) { redirect_url = QUrl(kRemoteURL); redirect_url.addQueryItem("port", port); } else if (redirect_style_ == RedirectStyle::REMOTE_WITH_STATE) { redirect_url = QUrl(kRemoteURL); url.addQueryItem("state", port); } else { redirect_url = server->url(); } url.addQueryItem("redirect_uri", redirect_url.toString()); url.addQueryItem("scope", scope); NewClosure(server, SIGNAL(Finished()), this, &OAuthenticator::RedirectArrived, server, redirect_url); QDesktopServices::openUrl(url); }
void DumbCallback::notify() { std::list<DumbCall *>::iterator i; for (i=calls_.begin() ; i!=calls_.end() ; i++) { (*i)->enqueue(); dispatcher_->add_job(NewClosure(*i, &DumbCall::notify)); } }
void SpotifyImages::FetchImagesForArtist(int id, const QString& spotify_id) { QUrl artist_url(QString(kSpotifyArtistUrl).arg(spotify_id)); qLog(Debug) << "Fetching images for artist:" << artist_url; QNetworkRequest request(artist_url); QNetworkReply* reply = network_->get(request); NewClosure(reply, SIGNAL(finished()), [this, id, reply]() { reply->deleteLater(); QJson::Parser parser; QVariantMap result = parser.parse(reply).toMap(); QVariantList images = result["images"].toList(); QList<QPair<QUrl, QSize>> image_candidates; for (QVariant i : images) { QVariantMap image = i.toMap(); int height = image["height"].toInt(); int width = image["width"].toInt(); QUrl url = image["url"].toUrl(); image_candidates.append(qMakePair(url, QSize(width, height))); } if (!image_candidates.isEmpty()) { QPair<QUrl, QSize> winner = *std::max_element( image_candidates.begin(), image_candidates.end(), [](const QPair<QUrl, QSize>& a, const QPair<QUrl, QSize>& b) { return (a.second.height() * a.second.width()) < (b.second.height() * b.second.width()); }); emit ImageReady(id, winner.first); } emit Finished(id); }); }
foreach ( ConfigStorage* cs, m_configStorageById ) { m_configStorageLoading.insert( cs->id() ); NewClosure( cs, SIGNAL( ready() ), this, SLOT( finishLoadingFromConfig( QString ) ), cs->id() ); cs->init(); }
static void HandleService( google::protobuf::Service *service, const google::protobuf::MethodDescriptor *method, const google::protobuf::Message *request_prototype, const google::protobuf::Message *response_prototype, const ProtobufDecoder *decoder, boost::shared_ptr<Connection> connection) { VLOG(2) << connection->name() << " : " << "HandleService: " << method->full_name(); const ProtobufLineFormat::MetaData &meta = decoder->meta(); boost::shared_ptr<google::protobuf::Message> request(request_prototype->New()); const string &content = decoder->meta().content(); VLOG(2) << connection->name() << " : " << "content size: " << content.size(); if (!request->ParseFromArray( content.c_str(), content.size())) { LOG(WARNING) << connection->name() << " : " << "HandleService but invalid format"; return; } boost::shared_ptr<google::protobuf::Message> response(response_prototype->New()); google::protobuf::Closure *done = NewClosure( boost::bind(CallServiceMethodDone, connection, decoder, request, response)); service->CallMethod(method, connection.get(), request.get(), response.get(), done); }
void GridItemDelegate::onPlayClicked( const QPersistentModelIndex& index ) { QPoint pos = m_playButton[ index ]->pos(); clearButtons(); AnimatedSpinner* spinner = new AnimatedSpinner( m_view ); spinner->setAutoCenter( false ); spinner->fadeIn(); spinner->move( pos ); spinner->setFocusPolicy( Qt::NoFocus ); spinner->installEventFilter( this ); m_spinner[ index ] = spinner; PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( index ) ); NewClosure( AudioEngine::instance(), SIGNAL( started( Tomahawk::result_ptr ) ), const_cast<GridItemDelegate*>(this), SLOT( onPlaybackStarted( QPersistentModelIndex ) ), QPersistentModelIndex( index ) ); if ( item ) { if ( !item->query().isNull() ) AudioEngine::instance()->playItem( m_model->playlistInterface(), item->query() ); else if ( !item->album().isNull() ) AudioEngine::instance()->playItem( item->album() ); else if ( !item->artist().isNull() ) AudioEngine::instance()->playItem( item->artist() ); } }
void EventLoop::cancel(uint64_t timerId) { Closure<void> *pCb = NewClosure(this, &EventLoop::innerCancel, uint64_t(timerId)); { SpinLockGuard lock(lock_); pendingFunctors_.push_back(pCb); } wakeup(); }
void SpotifyServer::StartPlaybackLater(const QString& uri, quint16 port) { QTimer* timer = new QTimer(this); connect(timer, SIGNAL(timeout()), timer, SLOT(deleteLater())); timer->start(100); // lol NewClosure(timer, SIGNAL(timeout()), this, SLOT(StartPlayback(QString, quint16)), uri, port); }
TagCompleter::TagCompleter(LibraryBackend* backend, Playlist::Column column, QLineEdit* editor) : QCompleter(editor), editor_(editor) { QFuture<TagCompletionModel*> future = QtConcurrent::run(&InitCompletionModel, backend, column); NewClosure(future, this, SLOT(ModelReady(QFuture<TagCompletionModel*>)), future); }
TEST(ClosureTest, ClosureCallsLambda) { TestQObject sender; bool called = false; NewClosure( &sender, SIGNAL(Emitted()), [&called] () { called = true; }); EXPECT_FALSE(called); sender.Emit(); EXPECT_TRUE(called); }
void GridItemDelegate::onPlayClicked( const QPersistentModelIndex& index ) { QPoint pos = m_playButton[ index ]->pos(); foreach ( ImageButton* button, m_playButton ) button->deleteLater(); m_playButton.clear(); AnimatedSpinner* spinner = new AnimatedSpinner( m_view ); spinner->setAutoCenter( false ); spinner->fadeIn(); spinner->move( pos ); spinner->setFocusPolicy( Qt::NoFocus ); spinner->installEventFilter( this ); m_spinner[ index ] = spinner; PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( index ) ); if ( item ) { NewClosure( AudioEngine::instance(), SIGNAL( loading( Tomahawk::result_ptr ) ), const_cast<GridItemDelegate*>(this), SLOT( onPlaybackStarted( QPersistentModelIndex ) ), QPersistentModelIndex( index ) ); m_closures.remove( index ); m_closures.insertMulti( index, NewClosure( AudioEngine::instance(), SIGNAL( started( Tomahawk::result_ptr ) ), const_cast<GridItemDelegate*>(this), SLOT( onPlaylistChanged( QPersistentModelIndex ) ), QPersistentModelIndex( index ) ) ); m_closures.insertMulti( index, NewClosure( AudioEngine::instance(), SIGNAL( stopped() ), const_cast<GridItemDelegate*>(this), SLOT( onPlaylistChanged( QPersistentModelIndex ) ), QPersistentModelIndex( index ) ) ); foreach ( _detail::Closure* closure, m_closures.values( index ) ) closure->setAutoDelete( false ); connect( AudioEngine::instance(), SIGNAL( stopped() ), SLOT( onPlaybackFinished() ) ); if ( !item->query().isNull() ) AudioEngine::instance()->playItem( Tomahawk::playlistinterface_ptr(), item->query() ); else if ( !item->album().isNull() ) AudioEngine::instance()->playItem( item->album() ); else if ( !item->artist().isNull() ) AudioEngine::instance()->playItem( item->artist() ); } }
TEST(ClosureTest, ClosureInvokesReceiver) { TestQObject sender; TestQObject receiver; _detail::ClosureBase* closure = NewClosure( &sender, SIGNAL(Emitted()), &receiver, SLOT(Invoke())); EXPECT_EQ(0, receiver.invoked()); sender.Emit(); EXPECT_EQ(1, receiver.invoked()); }
TEST(ClosureTest, ClosureWorksWithMemberFunctionPointers) { TestQObject sender; Bar receiver(42); int q = 1; NewClosure( &sender, SIGNAL(Emitted()), &receiver, &Bar::Foo, &q); EXPECT_EQ(1, q); sender.Emit(); EXPECT_EQ(42, q); }
void DeviceProperties::UpdateFormats() { QString id = index_.data(DeviceManager::Role_UniqueId).toString(); DeviceLister* lister = manager_->GetLister(index_.row()); std::shared_ptr<ConnectedDevice> device = manager_->GetConnectedDevice(index_.row()); // Transcode mode MusicStorage::TranscodeMode mode = MusicStorage::TranscodeMode( index_.data(DeviceManager::Role_TranscodeMode).toInt()); switch (mode) { case MusicStorage::Transcode_Always: ui_->transcode_all->setChecked(true); break; case MusicStorage::Transcode_Never: ui_->transcode_off->setChecked(true); break; case MusicStorage::Transcode_Unsupported: default: ui_->transcode_unsupported->setChecked(true); break; } // If there's no lister then the device is physically disconnected if (!lister) { ui_->formats_stack->setCurrentWidget(ui_->formats_page_not_connected); ui_->open_device->setEnabled(false); return; } // If there's a lister but no device then the user just needs to open the // device. This will cause a rescan so we don't do it automatically. if (!device) { ui_->formats_stack->setCurrentWidget(ui_->formats_page_not_connected); ui_->open_device->setEnabled(true); return; } if (!updating_formats_) { // Get the device's supported formats list. This takes a long time and it // blocks, so do it in the background. supported_formats_.clear(); QFuture<bool> future = QtConcurrent::run(std::bind( &ConnectedDevice::GetSupportedFiletypes, device, &supported_formats_)); NewClosure(future, this, SLOT(UpdateFormatsFinished(QFuture<bool>)), future); ui_->formats_stack->setCurrentWidget(ui_->formats_page_loading); updating_formats_ = true; } }
void EditTagDialog::accept() { // Show the loading indicator if (!SetLoading(tr("Saving tracks") + "...")) return; abortRequested_ = false; ui_->abortSaveButton->setEnabled(true); // Save tags in the background QFuture<void> future = QtConcurrent::run(this, &EditTagDialog::SaveData, data_); NewClosure(future, this, SLOT(AcceptFinished())); }
TinyThread::TinyThread(Closure<void>* func, const char* name) : mFunc(func), mHandle(0) { if (name != NULL) { mName = name; } Closure<void>* routine = NewClosure(this, &TinyThread::Routine); if (::pthread_create( &mHandle, NULL, ThreadFunc, reinterpret_cast<void*>(routine))) { ::abort(); } }
TEST(ClosureTest, ClosureWorksWithFunctionPointers) { TestQObject sender; bool called = false; int question = 42; int answer = 0; NewClosure( &sender, SIGNAL(Emitted()), &Foo, &called, question, &answer); EXPECT_FALSE(called); sender.Emit(); EXPECT_TRUE(called); EXPECT_EQ(question, answer); }
bool OrganiseDialog::SetFilenames(const QStringList& filenames) { songs_future_ = QtConcurrent::run(this, &OrganiseDialog::LoadSongsBlocking, filenames); QFutureWatcher<SongList>* watcher = new QFutureWatcher<SongList>(this); watcher->setFuture(songs_future_); NewClosure(watcher, SIGNAL(finished()), [=]() { SetSongs(songs_future_.result()); watcher->deleteLater(); }); SetLoadingSongs(true); return true; }
void OAuthenticator::StartAuthorisation() { server_.listen(QHostAddress::LocalHost); const quint16 port = server_.serverPort(); NewClosure(&server_, SIGNAL(newConnection()), this, SLOT(NewConnection())); QUrl url = QUrl(kGoogleOAuthEndpoint); url.addQueryItem("response_type", "code"); url.addQueryItem("client_id", kClientId); url.addQueryItem("redirect_uri", QString("http://localhost:%1").arg(port)); url.addQueryItem("scope", kGoogleOAuthScope); QDesktopServices::openUrl(url); }
TEST(ClosureTest, ClosureWorksWithStandardFunctions) { TestQObject sender; bool called = false; int question = 42; int answer = 0; boost::function<void(bool*,int,int*)> callback(&Foo); NewClosure( &sender, SIGNAL(Emitted()), callback, &called, question, &answer); EXPECT_FALSE(called); sender.Emit(); EXPECT_TRUE(called); EXPECT_EQ(question, answer); }
static int EvalCompound(expADT exp, environmentADT env){ char op; int lhs, rhs; valueADT lValue, rValue; op = ExpOperator(exp); lValue = Eval(ExpLHS(exp), NewClosure(env)); rValue = Eval(ExpRHS(exp), NewClosure(env)); lhs = GetIntValue(lValue); rhs = GetIntValue(rValue); switch (op) { case '+': return (lhs + rhs); case '-': return (lhs - rhs); case '*': return (lhs * rhs); case '/': if (rhs == 0) Error("Division by zero\n"); else return (lhs / rhs); default: Error("Illegal operator"); } }
void EditTagDialog::SetSongs(const SongList& s, const PlaylistItemList& items) { // Show the loading indicator if (!SetLoading(tr("Loading tracks") + "...")) return; data_.clear(); playlist_items_ = items; ui_->song_list->clear(); // Reload tags in the background QFuture<QList<Data>> future = QtConcurrent::run(this, &EditTagDialog::LoadData, s); NewClosure(future, this, SLOT(SetSongsFinished(QFuture<QList<EditTagDialog::Data>>)), future); }
void GoogleDriveService::ListChangesFinished( google_drive::ListChangesResponse* changes_response) { changes_response->deleteLater(); const QString cursor = changes_response->next_cursor(); if (is_indexing()) { // Only save the cursor after all the songs have been indexed - that way if // Clementine is closed it'll resume next time. NewClosure(this, SIGNAL(AllIndexingTasksFinished()), this, SLOT(SaveCursor(QString)), cursor); } else { SaveCursor(cursor); } }
void ArtistBiography::FetchWikipediaArticle(int id, const QString& wikipedia_url, CountdownLatch* latch) { latch->Wait(); QRegExp regex("([a-z]+)\\.wikipedia\\.org/wiki/(.*)"); if (regex.indexIn(wikipedia_url) == -1) { emit Finished(id); return; } QString wiki_title = QUrl::fromPercentEncoding(regex.cap(2).toUtf8()); QString language = regex.cap(1); QUrl url(QString(kWikipediaExtractUrl).arg(language)); url.addQueryItem("titles", wiki_title); QNetworkRequest request(url); QNetworkReply* reply = network_->get(request); qLog(Debug) << "Article url:" << url; NewClosure(reply, SIGNAL(finished()), [this, id, reply, wikipedia_url, latch]() { reply->deleteLater(); QJson::Parser parser; QVariantMap json = parser.parse(reply).toMap(); QString html = ExtractExtract(json); CollapsibleInfoPane::Data data; data.id_ = wikipedia_url; data.title_ = tr("Biography"); data.type_ = CollapsibleInfoPane::Data::Type_Biography; data.icon_ = IconLoader::Load("wikipedia", IconLoader::Provider); QString text; text += "<p><a href=\"" + wikipedia_url + "\">" + tr("Open in your browser") + "</a></p>"; text += html; SongInfoTextView* editor = new SongInfoTextView; editor->SetHtml(text); data.contents_ = editor; emit InfoReady(id, data); latch->CountDown(); }); }
TEST(ClosureTest, ClosureDeletesSelf) { TestQObject sender; TestQObject receiver; _detail::ClosureBase* closure = NewClosure( &sender, SIGNAL(Emitted()), &receiver, SLOT(Invoke())); _detail::ObjectHelper* helper = closure->helper(); QSignalSpy spy(helper, SIGNAL(destroyed())); EXPECT_EQ(0, receiver.invoked()); sender.Emit(); EXPECT_EQ(1, receiver.invoked()); EXPECT_EQ(0, spy.count()); QEventLoop loop; QObject::connect(helper, SIGNAL(destroyed()), &loop, SLOT(quit())); loop.exec(); EXPECT_EQ(1, spy.count()); }
void PrettyImage::ImageFetched(RedirectFollower* follower) { follower->deleteLater(); QNetworkReply* reply = follower->reply(); reply->deleteLater(); QImage image = QImage::fromData(reply->readAll()); if (image.isNull()) { qLog(Debug) << "Image failed to load" << reply->request().url(); deleteLater(); } else { state_ = State_CreatingThumbnail; image_ = image; QFuture<QImage> future = QtConcurrent::run(image_, &QImage::scaled, image_size(), Qt::KeepAspectRatio, Qt::SmoothTransformation); NewClosure(future, this, SLOT(ImageScaled(QFuture<QImage>)), future); } }
int main(int argc, char** argv) { FLAGS_alsologtostderr = true; google::ParseCommandLineFlags(&argc, &argv, true); google::InitGoogleLogging(argv[0]); LOG(INFO) << "begin main function."; ThreadPool th(4, 4); for (int idx = 0; idx < 5; ++idx) { th.AddTask(NewClosure(&Entery, idx)); } th.Terminate(); LOG(INFO) << "All is ok."; return 0; }