std::string Lyrics::GenerateFilename(const MPD::Song &s)
{
	std::string filename;
	if (Config.store_lyrics_in_song_dir)
	{
		if (s.isFromDatabase())
		{
			filename = Config.mpd_music_dir;
			filename += "/";
			filename += s.getURI();
		}
		else
			filename = s.getURI();
		// replace song's extension with .txt
		size_t dot = filename.rfind('.');
		assert(dot != std::string::npos);
		filename.resize(dot);
		filename += ".txt";
	}
	else
	{
		std::string file = s.getArtist();
		file += " - ";
		file += s.getTitle();
		file += ".txt";
		removeInvalidCharsFromFilename(file);
		filename = Config.lyrics_directory;
		filename += "/";
		filename += file;
	}
	return filename;
}
Exemple #2
0
std::string Lyrics::GenerateFilename(const MPD::Song &s)
{
	std::string filename;
	if (Config.store_lyrics_in_song_dir)
	{
		if (s.isFromDB())
		{
			filename = Config.mpd_music_dir;
			filename += "/";
			filename += s.GetFile();
		}
		else
			filename = s.GetFile();
		// replace song's extension with .txt
		size_t dot = filename.rfind('.');
		assert(dot != std::string::npos);
		filename.resize(dot);
		filename += ".txt";
	}
	else
	{
		std::string file = locale_to_utf_cpy(s.GetArtist());
		file += " - ";
		file += locale_to_utf_cpy(s.GetTitle());
		file += ".txt";
		EscapeUnallowedChars(file);
		filename = Config.lyrics_directory;
		filename += "/";
		filename += file;
	}
	return filename;
}
void Lyrics::update()
{
#	ifdef HAVE_CURL_CURL_H
	if (isReadyToTake)
		Take();
	
	if (isDownloadInProgress)
	{
		w.flush();
		w.refresh();
	}
#	endif // HAVE_CURL_CURL_H
	if (ReloadNP)
	{
		const MPD::Song s = myPlaylist->nowPlayingSong();
		if (!s.empty() && !s.getArtist().empty() && !s.getTitle().empty())
		{
			drawHeader();
			itsScrollBegin = 0;
			itsSong = s;
			Load();
		}
		ReloadNP = 0;
	}
}
void Lyrics::DownloadInBackground(const MPD::Song &s)
{
	if (s.empty() || s.getArtist().empty() || s.getTitle().empty())
		return;
	
	std::string filename = GenerateFilename(s);
	std::ifstream f(filename.c_str());
	if (f.is_open())
	{
		f.close();
		return;
	}
	Statusbar::msg("Fetching lyrics for \"%s\"...", s.toString(Config.song_status_format_no_colors, Config.tags_separator).c_str());
	
	MPD::Song *s_copy = new MPD::Song(s);
	pthread_mutex_lock(&itsDIBLock);
	if (itsWorkersNumber == itsMaxWorkersNumber)
		itsToDownload.push(s_copy);
	else
	{
		++itsWorkersNumber;
		pthread_t t;
		pthread_attr_t attr;
		pthread_attr_init(&attr);
		pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
		pthread_create(&t, &attr, DownloadInBackgroundImpl, s_copy);
	}
	pthread_mutex_unlock(&itsDIBLock);
}
Exemple #5
0
void Display::Tags(const MPD::Song &s, void *data, Menu<MPD::Song> *menu)
{
	size_t i = static_cast<Menu<std::string> *>(data)->Choice();
	if (i < 11)
	{
		ShowTag(*menu, s.GetTags(SongInfo::Tags[i].Get));
	}
	else if (i == 12)
	{
		if (s.GetNewName().empty())
			*menu << s.GetName();
		else
			*menu << s.GetName() << Config.color2 << " -> " << clEnd << s.GetNewName();
	}
}
void Lyrics::DownloadInBackgroundImplHelper(const MPD::Song &s)
{
	std::string artist = Curl::escape(s.getArtist());
	std::string title = Curl::escape(s.getTitle());
	
	LyricsFetcher::Result result;
	bool fetcher_defined = itsFetcher && *itsFetcher;
	for (LyricsFetcher **plugin = fetcher_defined ? itsFetcher : lyricsPlugins; *plugin != 0; ++plugin)
	{
		result = (*plugin)->fetch(artist, title);
		if (result.first)
			break;
		if (fetcher_defined)
			break;
	}
	if (result.first == true)
		Save(GenerateFilename(s), result.second);
}
  void Storage::loadNewSong(MPD::Song s) {
    // save current file
    currentArtist->saveArtist(filePath);

    if (Config::GetInstance()->isRemoteStorageEnabled()) {
      // save to shared storage
      if (remoteSaveArtist(filePath)) {
        currentArtist->setSynced(true);
      } else {
        currentArtist->setSynced(false);
      }

      // save with sync flags
      currentArtist->saveArtist(filePath);
    }

    // clear current Artist
    currentArtist->clear();

    // load new data to storage
    filePath = createArtistFilePath(s.GetArtist());


    currentArtist->name.set(s.GetArtist());
    currentArtist->album.set(s.GetAlbum());

    // check if file exists
    // search in local temp
    currentArtist->loadArtistFromFile(filePath);

    // if is enabled remote sharing, share
    if (Config::GetInstance()->isRemoteStorageEnabled()) {
      // remote load artist
      std::string remoteArtistContent = remoteLoadArtist(s.GetArtist());
      currentArtist->loadArtistFromRemoteContent(remoteArtistContent);
    }

    // classificate artist
    currentArtist->loadClassificator();

    currentArtist->classificateArtist();

    loadWidgets();
  }
Exemple #8
0
void Browser::LocateSong(const MPD::Song &s)
{
	if (s.GetDirectory().empty())
		return;
	
	itsBrowseLocally = !s.isFromDB();
	
	if (myScreen != this)
		SwitchTo();
	
	if (itsBrowsedDir != s.GetDirectory())
		GetDirectory(s.GetDirectory());
	for (size_t i = 0; i < w->Size(); ++i)
	{
		if ((*w)[i].type == itSong && s.GetHash() == (*w)[i].song->GetHash())
		{
			w->Highlight(i);
			break;
		}
	}
}
Exemple #9
0
void Lyrics::fetchInBackground(const MPD::Song &s)
{
	auto consumer = [this] {
		std::string lyrics_file;
		while (true)
		{
			MPD::Song qs;
			{
				auto queue = m_shared_queue.acquire();
				assert(queue->first);
				if (queue->second.empty())
				{
					queue->first = false;
					break;
				}
				lyrics_file = lyricsFilename(queue->second.front());
				if (!boost::filesystem::exists(lyrics_file))
					qs = queue->second.front();
				queue->second.pop();
			}
			if (!qs.empty())
			{
				auto lyrics = downloadLyrics(qs, nullptr, m_fetcher);
				if (lyrics)
					saveLyrics(lyrics_file, *lyrics);
			}
		}
	};

	auto queue = m_shared_queue.acquire();
	queue->second.push(s);
	// Start the consumer if it's not running.
	if (!queue->first)
	{
		std::thread t(consumer);
		t.detach();
		queue->first = true;
	}
}
void Browser::LocateSong(const MPD::Song &s)
{
	if (s.getDirectory().empty())
		return;
	
	itsBrowseLocally = !s.isFromDatabase();
	
	if (myScreen != this)
		switchTo();
	
	if (itsBrowsedDir != s.getDirectory())
		GetDirectory(s.getDirectory());
	for (size_t i = 0; i < w.size(); ++i)
	{
		if (w[i].value().type == itSong && s.getHash() == w[i].value().song->getHash())
		{
			w.highlight(i);
			break;
		}
	}
	drawHeader();
}
Exemple #11
0
void Browser::locateSong(const MPD::Song &s)
{
	if (s.getDirectory().empty())
		throw std::runtime_error("Song's directory is empty");
	
	m_local_browser = !s.isFromDatabase();
	
	if (myScreen != this)
		switchTo();
	
	// change to relevant directory
	if (m_current_directory != s.getDirectory())
	{
		getDirectory(s.getDirectory());
		drawHeader();
	}

	// highlight the item
	auto begin = w.beginV(), end = w.endV();
	auto it = std::find(begin, end, MPD::Item(s));
	if (it != end)
		w.highlight(it-begin);
}
bool addSongToPlaylist(const MPD::Song &s, bool play, size_t position)
{
	bool result = false;
	if (Config.ncmpc_like_songs_adding && myPlaylist->checkForSong(s))
	{
		auto &w = myPlaylist->main();
		if (play)
		{
			auto song = std::find(w.beginV(), w.endV(), s);
			assert(song != w.endV());
			Mpd.PlayID(song->getID());
			result = true;
		}
		else
		{
			Mpd.StartCommandsList();
			for (auto it = w.rbeginV(); it != w.rendV(); ++it)
				if (*it == s)
					Mpd.Delete(it->getPosition());
			Mpd.CommitCommandsList();
			// we return false in this case
		}
	}
	else
	{
		position = std::min(position, Mpd.GetPlaylistLength());
		int id = Mpd.AddSong(s, position);
		if (id >= 0)
		{
			Statusbar::msg("Added to playlist: %s",
				s.toString(Config.song_status_format_no_colors, Config.tags_separator).c_str()
			);
			if (play)
				Mpd.PlayID(id);
			result = true;
		}
	}
	return result;
}
Exemple #13
0
bool MPD::Song::SendQueue()
{
	ExtractQueue();
	
	if (!myHandshake.OK())
		return false;
	
	Log(llInfo, "Submitting songs...");
	
	string result, postdata;
	CURLcode code;
	
	postdata = "s=";
	postdata += myHandshake.SessionID;
	
	for (std::deque<string>::const_iterator it = Song::SubmitQueue.begin(); it != Song::SubmitQueue.end(); it++)
		postdata += *it;
	
	Log(llVerbose, "URL: %s", myHandshake.SubmissionURL.c_str());
	Log(llVerbose, "Post data: %s", postdata.c_str());
	
	CURL *submission = curl_easy_init();
	curl_easy_setopt(submission, CURLOPT_URL, myHandshake.SubmissionURL.c_str());
	curl_easy_setopt(submission, CURLOPT_POST, 1);
	curl_easy_setopt(submission, CURLOPT_POSTFIELDS, postdata.c_str());
	curl_easy_setopt(submission, CURLOPT_WRITEFUNCTION, write_data);
	curl_easy_setopt(submission, CURLOPT_WRITEDATA, &result);
	curl_easy_setopt(submission, CURLOPT_CONNECTTIMEOUT, curl_queue_connecttimeout);
	curl_easy_setopt(submission, CURLOPT_TIMEOUT, curl_queue_timeout);
	curl_easy_setopt(submission, CURLOPT_DNS_CACHE_TIMEOUT, 0);
	curl_easy_setopt(submission, CURLOPT_NOPROGRESS, 1);
	curl_easy_setopt(submission, CURLOPT_NOSIGNAL, 1);
	code = curl_easy_perform(submission);
	curl_easy_cleanup(submission);
	
	IgnoreNewlines(result);
	
	if (result == "OK")
	{
		Log(llInfo, "Number of submitted songs: %d", Song::SubmitQueue.size());
		SubmitQueue.clear();
		std::ofstream f(Config.file_cache.c_str(), std::ios::trunc);
		f.close();
		NowPlayingNotify = s.Data && !s.isStream();
		return true;
	}
	else
	{
		if (result.empty())
		{
			Log(llError, "Error while submitting songs: %s", curl_easy_strerror(code));
		}
		else
		{
			Log(llError, "Audioscrobbler returned status %s", result.c_str());
			// BADSESSION or FAILED was returned, handshake needs resetting.
			myHandshake.Clear();
			Log(llVerbose, "Handshake reset");
		}
		return false;
	}
}
Exemple #14
0
void Display::Songs(const MPD::Song &s, void *data, Menu<MPD::Song> *menu)
{
	if (!s.Localized())
		const_cast<MPD::Song *>(&s)->Localize();
	
	bool is_now_playing = menu == myPlaylist->Items && (menu->isFiltered() ? s.GetPosition() : menu->CurrentlyDrawedPosition()) == size_t(myPlaylist->NowPlaying);
	if (is_now_playing)
		*menu << Config.now_playing_prefix;
	
	assert(data);
	bool separate_albums = false;
	if (Config.playlist_separate_albums && menu->CurrentlyDrawedPosition()+1 < menu->Size())
	{
		MPD::Song *next = static_cast<ScreenFormat *>(data)->screen->GetSong(menu->CurrentlyDrawedPosition()+1);
		if (next && next->GetAlbum() != s.GetAlbum())
			separate_albums = true;
	}
	if (separate_albums)
	{
		*menu << fmtUnderline;
		mvwhline(menu->Raw(), menu->Y(), 0, ' ', menu->GetWidth());
	}
	
	bool discard_colors = Config.discard_colors_if_item_is_selected && menu->isSelected(menu->CurrentlyDrawedPosition());
	
	std::string line = s.toString(*static_cast<ScreenFormat *>(data)->format, "$");
	for (std::string::const_iterator it = line.begin(); it != line.end(); ++it)
	{
		if (*it == '$')
		{
			if (++it == line.end()) // end of format
			{
				*menu << '$';
				break;
			}
			else if (isdigit(*it)) // color
			{
				if (!discard_colors)
					*menu << Color(*it-'0');
			}
			else if (*it == 'R') // right align
			{
				basic_buffer<my_char_t> buf;
				buf << U(" ");
				String2Buffer(TO_WSTRING(line.substr(it-line.begin()+1)), buf);
				if (discard_colors)
					buf.RemoveFormatting();
				if (is_now_playing)
					buf << Config.now_playing_suffix;
				*menu << XY(menu->GetWidth()-buf.Str().length()-(menu->isSelected(menu->CurrentlyDrawedPosition()) ? Config.selected_item_suffix_length : 0), menu->Y()) << buf;
				if (separate_albums)
					*menu << fmtUnderlineEnd;
				return;
			}
			else // not a color nor right align, just a random character
				*menu << *--it;
		}
		else if (*it == MPD::Song::FormatEscapeCharacter)
		{
			// treat '$' as a normal character if song format escape char is prepended to it
			if (++it == line.end() || *it != '$')
				--it;
			*menu << *it;
		}
		else
			*menu << *it;
	}
	if (is_now_playing)
		*menu << Config.now_playing_suffix;
	if (separate_albums)
		*menu << fmtUnderlineEnd;
}
Exemple #15
0
void Display::SongsInColumns(const MPD::Song &s, void *data, Menu<MPD::Song> *menu)
{
	if (!s.Localized())
		const_cast<MPD::Song *>(&s)->Localize();
	
	/// FIXME: This function is pure mess, it needs to be
	/// rewritten and unified with Display::Columns() a bit.
	
	bool is_now_playing = menu == myPlaylist->Items && (menu->isFiltered() ? s.GetPosition() : menu->CurrentlyDrawedPosition()) == size_t(myPlaylist->NowPlaying);
	if (is_now_playing)
		*menu << Config.now_playing_prefix;
	
	if (Config.columns.empty())
		return;
	
	assert(data);
	bool separate_albums = false;
	if (Config.playlist_separate_albums && menu->CurrentlyDrawedPosition()+1 < menu->Size())
	{
		MPD::Song *next = static_cast<ScreenFormat *>(data)->screen->GetSong(menu->CurrentlyDrawedPosition()+1);
		if (next && next->GetAlbum() != s.GetAlbum())
			separate_albums = true;
	}
	if (separate_albums)
		*menu << fmtUnderline;
	
	std::vector<Column>::const_iterator next2last, last, it;
	size_t where = 0;
	int width;
	
	bool last_fixed = Config.columns.back().fixed;
	if (Config.columns.size() > 1)
		next2last = Config.columns.end()-2;
	last = Config.columns.end()-1;
	
	bool discard_colors = Config.discard_colors_if_item_is_selected && menu->isSelected(menu->CurrentlyDrawedPosition());
	
	for (it = Config.columns.begin(); it != Config.columns.end(); ++it)
	{
		if (where)
		{
			menu->GotoXY(where, menu->Y());
			*menu << ' ';
			if (!discard_colors && (it-1)->color != clDefault)
				*menu << clEnd;
		}
		
		if (it == Config.columns.end()-1)
			width = menu->GetWidth()-where;
		else if (last_fixed && it == next2last)
			width = menu->GetWidth()-where-1-(++next2last)->width;
		else
			width = it->width*(it->fixed ? 1 : menu->GetWidth()/100.0);
		
		MPD::Song::GetFunction get = 0;
		
		std::string tag;
		for (size_t i = 0; i < it->type.length(); ++i)
		{
			get = toGetFunction(it->type[i]);
			tag = get ? s.GetTags(get) : "";
			if (!tag.empty())
				break;
		}
		if (!discard_colors && it->color != clDefault)
			*menu << it->color;
		whline(menu->Raw(), 32, menu->GetWidth()-where);
		
		// last column might need to be shrinked to make space for np/sel suffixes
		if (it == last)
		{
			if (menu->isSelected(menu->CurrentlyDrawedPosition()))
				width -= Config.selected_item_suffix_length;
			if (is_now_playing)
				width -= Config.now_playing_suffix_length;
		}
		
		if (it->right_alignment)
		{
			if (width > 0 && (!tag.empty() || it->display_empty_tag))
			{
				int x, y;
				menu->GetXY(x, y);
				my_string_t wtag = TO_WSTRING(tag.empty() ? Config.empty_tag : tag).substr(0, width-!!x);
				*menu << XY(x+width-Window::Length(wtag)-!!x, y) << wtag;
			}
		}
		else
		{
			if (it == last)
			{
				if (width > 0)
				{
					my_string_t str;
					if (!tag.empty())
						str = TO_WSTRING(tag).substr(0, width-1);
					else if (it->display_empty_tag)
						str = TO_WSTRING(Config.empty_tag).substr(0, width-1);
					*menu << str;
				}
			}
			else
			{
				if (!tag.empty())
					*menu << tag;
				else if (it->display_empty_tag)
					*menu << Config.empty_tag;
			}
		}
		where += width;
	}
	if (!discard_colors && (--it)->color != clDefault)
		*menu << clEnd;
	if (is_now_playing)
		*menu << Config.now_playing_suffix;
	if (separate_albums)
		*menu << fmtUnderlineEnd;
}
Exemple #16
0
void MediaLibrary::LocateSong(const MPD::Song &s)
{
	std::string primary_tag = s.get(Config.media_lib_primary_tag);
	if (primary_tag.empty())
	{
		std::string item_type = boost::locale::to_lower(
			tagTypeToString(Config.media_lib_primary_tag));
		Statusbar::printf("Can't use this function because the song has no %s tag", item_type);
		return;
	}

	if (!s.isFromDatabase())
	{
		Statusbar::print("Song is not from the database");
		return;
	}
	
	if (myScreen != this)
		switchTo();
	Statusbar::put() << "Jumping to song...";
	Global::wFooter->refresh();

	if (!hasTwoColumns)
	{
		if (Tags.empty())
			update();

		if (!MoveToTag(Tags, primary_tag))
		{
			// The tag could not be found. Since this was called from an existing
			// song, the tag should exist in the library, but it was not listed by
			// list/listallinfo. This is the case with some players where it is not
			// possible to list all of the library, e.g. mopidy with mopidy-spotify.
			// To workaround this we simply insert the missing tag.
			Tags.addItem(PrimaryTag(primary_tag, s.getMTime()));
			std::sort(Tags.beginV(), Tags.endV(), SortPrimaryTags());
			Tags.refresh();
			MoveToTag(Tags, primary_tag);
		}
		Albums.clear();
	}
	
	if (Albums.empty())
		update();

	// When you locate a song in the media library, if no albums or no songs
	// are found, set the active column to the previous one (tags if no albums,
	// and albums if no songs). This makes sure that the active column is not
	// empty, which may make it impossible to move out of.
	//
	// The problem was if you highlight some song in the rightmost column in
	// the media browser and then go to some other window and select locate
	// song. If the tag or album it looked up in the media library was
	// empty, the selection would stay in the songs column while it was empty.
	// This made the selection impossible to change.
	//
	// This only is a problem if a song has some tag or album for which the
	// find command doesn't return any results. This should never really happen
	// unless there is some inconsistency in the player. However, it may
	// happen, so we need to handle it.
	//
	// Note: We don't want to return when no albums are found in two column
	// mode. In this case, we try to insert the album, as we do with tags when
	// they are not found.
	if (hasTwoColumns || !Albums.empty())
	{
		if (!MoveToAlbum(Albums, primary_tag, s))
		{
			// The album could not be found, insert it if in two column mode.
			// See comment about tags not found above. This is the equivalent
			// for two column mode.
			Albums.addItem(AlbumEntry(
				Album(primary_tag, s.getAlbum(), s.getDate(), s.getMTime())
			));
			std::sort(Albums.beginV(), Albums.endV(), SortAlbumEntries());
			Albums.refresh();
			MoveToAlbum(Albums, primary_tag, s);
		}

		Songs.clear();
		update();

		if (!Songs.empty())
		{
			if (s != Songs.current()->value())
			{
				auto begin = Songs.beginV(), end = Songs.endV();
				auto it = std::find(begin, end, s);
				if (it != end)
					Songs.highlight(it-begin);
			}
			nextColumn();
			nextColumn();
		}
		else // invalid album was added, clear the list
			Albums.clear();
	}
	else // invalid tag was added, clear the list
		Tags.clear();
	refresh();
}
Exemple #17
0
void MediaLibrary::LocateSong(const MPD::Song &s)
{
	std::string primary_tag = s.get(Config.media_lib_primary_tag);
	if (primary_tag.empty())
	{
		std::string item_type = boost::locale::to_lower(
			tagTypeToString(Config.media_lib_primary_tag));
		Statusbar::msg("Can't use this function because the song has no %s tag set", item_type.c_str());
		return;
	}
	
	if (myScreen != this)
		switchTo();
	Statusbar::put() << "Jumping to song...";
	Global::wFooter->refresh();
	
	if (!hasTwoColumns)
	{
		Tags.showAll();
		if (Tags.empty())
			update();
		if (primary_tag != Tags.current().value().tag())
		{
			for (size_t i = 0; i < Tags.size(); ++i)
			{
				if (primary_tag == Tags[i].value().tag())
				{
					Tags.highlight(i);
					Albums.clear();
					Songs.clear();
					break;
				}
			}
		}
	}
	
	Albums.showAll();
	if (Albums.empty())
		update();
	
	std::string album = s.getAlbum();
	std::string date = s.getDate();
	if ((hasTwoColumns && Albums.current().value().entry().tag() != primary_tag)
	||  album != Albums.current().value().entry().album()
	||  date != Albums.current().value().entry().date())
	{
		for (size_t i = 0; i < Albums.size(); ++i)
		{
			if ((!hasTwoColumns || Albums[i].value().entry().tag() == primary_tag)
			&&   album == Albums[i].value().entry().album()
			&&   date == Albums[i].value().entry().date())
			{
				Albums.highlight(i);
				Songs.clear();
				break;
			}
		}
	}
	
	Songs.showAll();
	if (Songs.empty())
		update();
	
	if (s.getHash() != Songs.current().value().getHash())
	{
		for (size_t i = 0; i < Songs.size(); ++i)
		{
			if (s.getHash()  == Songs[i].value().getHash())
			{
				Songs.highlight(i);
				break;
			}
		}
	}
	
	Tags.setHighlightColor(Config.main_highlight_color);
	Albums.setHighlightColor(Config.main_highlight_color);
	Songs.setHighlightColor(Config.active_column_color);
	w = &Songs;
	refresh();
}
void updatePlayer(MPD::Client *, MPD::StatusChanges changed, void *) {

  if (changed.SongID) {
    if (MPD::Client::GetInstance()->isPlaying()) {
#if DEBUG
      std::cout << "Song changed" << std::endl;
#endif

      MPD::Song song = MPD::Client::GetInstance()->GetCurrentSong();

      // set song parameters to storage
      Storage::GetInstance()->loadNewSong(song);

      // run agents
      AgentManager::GetInstance()->songChanged();

      // set text widgets
      GUI::MainWindow::GetInstance()->setSongLabel(song.GetArtist() + " - " + song.GetTitle());
      GUI::MainWindow::GetInstance()->setArtist(song.GetArtist());
      GUI::MainWindow::GetInstance()->setTitle(song.GetTitle());
      GUI::MainWindow::GetInstance()->setAlbum(song.GetAlbum());
      GUI::MainWindow::GetInstance()->setGenre(song.GetGenre());
      GUI::MainWindow::GetInstance()->setTimeScale(MPD::Client::GetInstance()->GetElapsedTime(), MPD::Client::GetInstance()->GetTotalTime());
    }
  }
  if (changed.ElapsedTime) {

    //    if (!Config::GetInstance()->isAgentsEnabled()) {
    //      AgentManager::GetInstance()->killAgents();
    //    }
    //
    //    AgentManager::GetInstance()->isSourcesChanged();

    // load new info to widgets
    GUI::MainWindow::GetInstance()->articlesWidget->updateArticlesWidget();
    GUI::MainWindow::GetInstance()->slideshowWidget->updateSlideshowWidget();
    //    GUI::MainWindow::GetInstance()->coverWidget->updateCoverWidget();


    GUI::MainWindow::GetInstance()->setTimeScale(MPD::Client::GetInstance()->GetElapsedTime(), MPD::Client::GetInstance()->GetTotalTime());

    if (MPD::Client::GetInstance()->isPlaying()) {
      MPD::Song song = MPD::Client::GetInstance()->GetCurrentSong();

      GUI::MainWindow::GetInstance()->setSongLabel(song.GetArtist() + " - " + song.GetTitle());

      GUI::MainWindow::GetInstance()->setStatusBar(_("IMPC Playing: ") + song.GetFile());
    }
  }
  if (changed.PlayerState) {

    MPD::PlayerState s = MPD::Client::GetInstance()->GetState();

    if (s == MPD::psPlay) {
      GUI::MainWindow::GetInstance()->on_play();
      GUI::MainWindow::GetInstance()->setPlayButtonActive(true);

      GUI::MainWindow::GetInstance()->setBitrate(MPD::Client::GetInstance()->GetBitrate());

    } else if (s == MPD::psPause) {
      GUI::MainWindow::GetInstance()->on_pause();
      GUI::MainWindow::GetInstance()->setPlayButtonActive(false);
    } else if (s == MPD::psStop) {
      GUI::MainWindow::GetInstance()->on_stop();
      GUI::MainWindow::GetInstance()->articlesWidget->clearArticlesWidget();
      GUI::MainWindow::GetInstance()->slideshowWidget->clearSlide();
    }
  }

  if (changed.DBUpdating) {
    GUI::MainWindow::GetInstance()->artistsWidget->reload();
  }

  if (changed.Volume) {
    // we set default volume
    GUI::MainWindow::GetInstance()->setVolume((double) MPD::Client::GetInstance()->GetVolume());
  }

  AgentManager::GetInstance()->checkIfAgentsEnabled();
}