Example #1
0
void MountTray::slotOpenAVDisk(QString type){
  if(MTINIT){ return; } //don't open the launcher during program initialization
  //Get the list of all AudioVideo Applications on the sytem
  QList<XDGFile> apps = XDGUtils::allApplications();
  apps = XDGUtils::filterAppsByCategory("AudioVideo", apps);
  apps = XDGUtils::sortAppsByName(apps);
  //Now generate the QStringList of application names
  QStringList names;
  for(int i=0; i<apps.length(); i++){
    //Filter out "invalid" applications (mixers, etc..)
    QString rname = apps[i].RawName();
    if(rname.contains("mixer", Qt::CaseInsensitive) || rname.contains("control", Qt::CaseInsensitive) ){ 
	//skip it
	apps.removeAt(i);
	i--;
    }else{
      QString txt;
      if( apps[i].Comment().isEmpty() ){ txt = apps[i].Name(); }
      else{ txt = apps[i].Name() +" ("+apps[i].Comment()+")"; }
      //Make sure that UMPlayer is listed first and recommended
      if(apps[i].RawName().toLower()=="umplayer"){
	 txt = apps[i].Name()+ "  **"+tr("Recommended")+"**"; 
	 names.prepend(txt); //put at the top
	 apps.move(i,0); //move the file to the front as well
      }else{
	 names << txt;
      }
    }
  }
  //Prompt for the user to select an application
  bool ok = false;
  QString appname = QInputDialog::getItem(0, QString(tr("%1 Disk")).arg(type) , tr("Open With:"), names,0, false, &ok);
  if(!ok || appname.isEmpty()){ return; }
  int index = names.indexOf(appname);
  if(index == -1){ return; }
  //Now start the application
  qDebug() << "Open "+type.toLower()+" disk:";
  qDebug() << " -- With:"<<appname;
  QString cmd = apps[index].Exec();
  //Only auto-start the disk with UMPlayer - no guarantee this method works for other apps
  if(apps[index].RawName().toLower()=="umplayer"){
    if(type.toLower()=="audio"){
      cmd.append(" cdda://1"); //audio cd
    }else{ //video DVD
      cmd.append(" dvd://1"); //video dvd
    }
  }
  qDebug() << " -- Exec:" << cmd;
  QProcess::startDetached( cmd );
}
Example #2
0
void ProcessModel::dynUpdateTopolSort(QList<ListDigraph::Node> &topolOrdering, const ListDigraph::Node &i, const ListDigraph::Node &k) {
	QTextStream out(stdout);

	/** Algorithm:
	 * 
	 * 1. Find the positions of i and k
	 * 2. IF posi < posk => no changes to the topological sorting needs to be performed. Return.
	 * 3. IF posi > posk => reorder the nodes. The affected region is [posi, posk]. Return.
	 */

	int posi = -1;
	int posk = -1;

	if (k == INVALID) {
		posk = (int) Math::MAX_INTUNI;
	} else {
		posk = topolOrdering.indexOf(k);
	}

	if (i == INVALID) {
		posi = 0;
	} else {
		posi = topolOrdering.indexOf(i);
	}

	if (posi < posk) { // No changes to perform
		return;
	}

	// #####################  DEBUG  ###########################################

	/*
	out << "Before DTO:" << endl;
	out << "posj = " << posj << " ID = " << ((j == INVALID) ? -1 : pm->ops[j]->ID) << endl;
	out << "posi = " << posi << " ID = " << ((i == INVALID) ? -1 : pm->ops[i]->ID) << endl;
	out << "posk = " << posk << " ID = " << ((k == INVALID) ? -1 : pm->ops[k]->ID) << endl;

	for (int l = 0; l < topolOrdering.size(); l++) {
		out << pm->ops[topolOrdering[l]]->ID << " ";
	}
	out << endl;

	//getchar();
	 */

	// #########################################################################

	if (posi == posk) {
		out << "posi = " << posi << " ID = " << ((i == INVALID) ? -1 : this->ops[i]->ID) << endl;
		out << "posk = " << posk << " ID = " << ((k == INVALID) ? -1 : this->ops[k]->ID) << endl;

		for (int l = 0; l < topolOrdering.size(); l++) {
			out << this->ops[topolOrdering[l]]->ID << " ";
		}
		out << endl;

		Debugger::err << "ProcessModel::dynUpdateTopolSort : posi == posk which is impossible!!!" << ENDL;
	}

	// Find the affected region
	int arbegin = -1;
	int arend = -1;
	ListDigraph::Node arstartnode = INVALID;
	ListDigraph::Node arendnode = INVALID;

	if (posi > posk) {
		arbegin = posk;
		arend = posi;
		arstartnode = k;
		arendnode = i;
	}

	// #####################  DEBUG  ###########################################
	/*
	out << "arbegin = " << arbegin << endl;
	out << "arend = " << arend << endl;
	out << "arstartnode = " << pm->ops[arstartnode]->ID << endl;
	out << "arendnode = " << pm->ops[arendnode]->ID << endl;
	 */
	// #########################################################################

	// Update the affected region

	// The nodes of the affected region
	QList<ListDigraph::Node> ar = topolOrdering.mid(arbegin, arend - arbegin + 1);
	QList<bool> visited;
	visited.reserve(ar.size());
	QQueue<ListDigraph::Node> q;
	ListDigraph::Node curnode;
	ListDigraph::Node tmpnode;
	int tmpidx;
	//QList<int> deltaBIdx;

	// #####################  DEBUG  ###########################################

	/*
	out << "ar:" << endl;
	for (int l = 0; l < ar.size(); l++) {
		out << pm->ops[ar[l]]->ID << " ";
	}
	out << endl;
	 */

	// #########################################################################

	// Find nodes which are contained in ar and are reachable from arstartnode
	//out << "Finding deltaF..." << endl;
	QList<ListDigraph::Node> deltaF;

	deltaF.reserve(ar.size());

	for (int l = 0; l < ar.size(); l++) {
		visited.append(false);
	}

	q.clear();
	q.enqueue(arstartnode);

	deltaF.append(arstartnode);
	while (q.size() != 0) {
		curnode = q.dequeue();

		// Check the successors of the current node
		for (ListDigraph::OutArcIt oait(this->graph, curnode); oait != INVALID; ++oait) {
			tmpnode = this->graph.target(oait);

			tmpidx = ar.indexOf(tmpnode);

			if (tmpidx >= 0 && !visited[tmpidx]) { // This successor is within the affected region
				q.enqueue(tmpnode);
				visited[tmpidx] = true;

				// Add the node to the deltaF
				deltaF.append(tmpnode);

			}

		}
	}

	//out << "Found deltaF." << endl;

	//######################  DEBUG  ###########################################
	/*
	out << "deltaF:" << endl;
	for (int l = 0; l < deltaF.size(); l++) {
		out << pm->ops[deltaF[l]]->ID << " ";
	}
	out << endl;
	 */
	//##########################################################################

	// IMPORTANT!!! Actually deltaB is not needed! If we find deltaF and move it to the end of the affected region then the elements
	// of deltaB preserve their initial positions and are placed directly before the elements of deltaF. Thus, the backward arc becomes a forward one
	/*
	// Find the nodes which are in ar and are BACKWARD reachable from arendnode
	QList<ListDigraph::Node> deltaB;

	deltaB.reserve(ar.size());

	for (int l = 0; l < visited.size(); l++) {
		visited[l] = false;
	}

	q.clear();
	q.enqueue(arendnode);

	deltaB.prepend(arendnode);
	deltaBIdx.prepend(ar.size() - 1);

	visited.clear();
	for (int l = 0; l < ar.size(); l++) {
		visited.append(false);
	}
	while (q.size() != 0) {
		curnode = q.dequeue();

		// Check the predecessors of the current node
		for (ListDigraph::InArcIt iait(pm->graph, curnode); iait != INVALID; ++iait) {
			tmpnode = pm->graph.source(iait);

			tmpidx = ar.indexOf(tmpnode);

			if (tmpidx >= 0 && !visited[tmpidx]) { // This successor is within the affected region
				q.enqueue(tmpnode);
				visited[tmpidx] = true;

				// Add the node to the deltaF
				deltaB.prepend(tmpnode); // IMPORTANT!!! PREpend!
				deltaBIdx.prepend(tmpidx);
			}

		}
	}
	 */

	// Move elements of deltaB to the left and the elements of deltaF to the right until the backward ark does not disappear
	//int posB = 0;
	//out << "Shifting deltaF to the right..." << endl;
	int posF = ar.size() - 1;

	// Move elements in deltaF to the right
	while (!deltaF.isEmpty()) {
		// Find the first element in ar starting from posB that is in deltaB
		tmpidx = -1;
		for (int l = posF; l >= 0; l--) {
			if (deltaF.contains(ar[l])) {
				tmpidx = l;
				break;
			}
		}

		if (tmpidx == -1) {
			Debugger::err << "ProcessModel::dynUpdateTopolSort : tmpidx = -1 while shifting deltaF. Probably the graph is NOT DAG! " << ENDL;
		}

		// Erase this element from deltaF
		deltaF.removeOne(ar[tmpidx]);

		// Move this element to the left
		ar.move(tmpidx, posF);
		posF--;
	}
	//out << "Shifted deltaF to the right." << endl;

	// Moving elements of deltaB is not necessary, since they are automatically found before any element of deltaF, since these were moved to the right

	/*
	// Move elements in deltaB to the left so that the last element of deltaB is on the position posF (right before elements of deltaF)
	while (!deltaB.isEmpty()) {
		// Find the first element in ar starting from posB that is in deltaB
		tmpidx = -1;
		for (int l = posB; l < ar.size(); l++) {
			if (deltaB.contains(ar[l])) {
				tmpidx = l;
				break;
			}
		}

		// Erase this element from deltaB
		deltaB.removeOne(ar[tmpidx]);

		// Move this element to the left
		ar.move(tmpidx, posB);
		posB++;
	}
	 */


	// Modify the final topological ordering
	for (int l = 0; l < ar.size(); l++) {
		topolOrdering[arbegin + l] = ar[l];
	}

	//######################  DEBUG  ###########################################

	/*
	out << "After DTO:" << endl;
	out << "posj = " << posj << " ID = " << ((j == INVALID) ? -1 : pm->ops[j]->ID) << endl;
	out << "posi = " << posi << " ID = " << ((i == INVALID) ? -1 : pm->ops[i]->ID) << endl;
	out << "posk = " << posk << " ID = " << ((k == INVALID) ? -1 : pm->ops[k]->ID) << endl;

	out << "ar later:" << endl;
	for (int l = 0; l < ar.size(); l++) {
		out << pm->ops[ar[l]]->ID << " ";
	}
	out << endl;

	//out << "deltaB:" << endl;
	//for (int l = 0; l < deltaB.size(); l++) {
	//out << pm->ops[deltaB[l]]->ID << " ";
	//}
	//out << endl;

	out << "deltaF:" << endl;
	for (int l = 0; l < deltaF.size(); l++) {
		out << pm->ops[deltaF[l]]->ID << " ";
	}
	out << endl;

	for (int l = 0; l < topolOrdering.size(); l++) {
		out << pm->ops[topolOrdering[l]]->ID << " ";
	}
	out << endl;
	 */

	// Check the correctness of the topological sorting

	/*
	QList<ListDigraph::Node> list;
	for (int i = 0; i < topolOrdering.size() - 1; i++) {
		for (int j = i + 1; j < topolOrdering.size(); j++) {
			list.clear();
			list.append(topolOrdering[j]);
			if (reachableFrom(list).contains(topolOrdering[i])) {
				out << *this << endl;
				out << this->ops[topolOrdering[j]]->ID << " -> " << this->ops[topolOrdering[i]]->ID << endl;
				Debugger::err << "Topological sorting is not correct after DTO!!!" << ENDL;
			}
		}
	}
	 */


	//getchar();

	//##########################################################################   
}
//----------------------------------------
//--- Primary playback control methods ---
//----------------------------------------
void Playlist::playItemAt(int row, Model model)
{
    bool isQueue = (model == QueueModel);
    MediaItem nextMediaItem = isQueue ? m_queue->mediaItemAt(row) :
                                        m_currentPlaylist->mediaItemAt(row);
    if (!isQueue) {
        nextMediaItem.playlistIndex = row;
    }
    nextMediaItem.nowPlaying = true;
    
    //Update Queue Model
    if (!m_shuffle) {
        //Just build a new queue from the row of the item in the playlist
        buildQueueFrom(nextMediaItem.playlistIndex);
    } else {
        int rowInQueue = isQueue ? row : m_queue->rowOfUrl(nextMediaItem.url);

        //Add currently playing item to history
        if (rowInQueue > 0 && m_nowPlaying->rowCount() > 0) {
            if (m_nowPlaying->mediaItemAt(0).type == "Audio" || m_nowPlaying->mediaItemAt(0).type == "Video") {
                int nowPlayingIndex = m_nowPlaying->mediaItemAt(0).playlistIndex;
                m_playlistIndicesHistory.append(nowPlayingIndex);
                m_playlistUrlHistory.append(m_nowPlaying->mediaItemAt(0).url);
                if (m_queue->rowCount() > 1) {
                    m_queue->removeMediaItemAt(0);
                    rowInQueue--;
                }
            }
        }

        //Remove requested item from history
        bool inHistory = (m_playlistIndicesHistory.indexOf(nextMediaItem.playlistIndex) != -1);
        if ( inHistory ) { //remove from history
            int idx = m_playlistIndicesHistory.indexOf(row);
            m_playlistIndicesHistory.removeAt(idx);
            m_playlistUrlHistory.removeAt(idx);
        }

        //Place requested item at front of queue
        QList<MediaItem> queueMediaList = m_queue->mediaList();
        if ( rowInQueue > 0 ) { //in queue, but not at first place, so move it
            queueMediaList.move(rowInQueue, 0);
        } else if (rowInQueue < 0) { //not in queue, so add it at first place
            queueMediaList.insert(0, nextMediaItem);
            if (queueMediaList.count() > m_queueDepth) {
                queueMediaList.removeLast();
            }
        } //else it is already at first place in the queue
        m_queue->clearMediaListData();
        m_queue->loadMediaList(queueMediaList, true);

        //Fill out queue
        shuffle();
    }
    
    //Play media Item
    m_mediaObject->clearQueue();
    m_currentStream.clear();
    QString subType;
    if (nextMediaItem.type == "Audio") {
        subType = nextMediaItem.fields["audioType"].toString();
    } else if(nextMediaItem.type == "Video") {
        subType = nextMediaItem.fields["videoType"].toString();
    }
    m_currentUrl = nextMediaItem.url;
    bool isDiscTitle = Utilities::isDisc( nextMediaItem.url );
    if (isDiscTitle) {
        Solid::Device device = Solid::Device( Utilities::deviceUdiFromUrl(nextMediaItem.url) );
        if (!device.isValid()) {
            stop();
            return;
        }
        const Solid::Block* block = device.as<const Solid::Block>();
        Phonon::DiscType discType = (subType == "CD Track") ? Phonon::Cd : Phonon::Dvd;
        Phonon::MediaSource src = Phonon::MediaSource(discType, block->device());
        int title = nextMediaItem.fields["trackNumber"].toInt();
        if (m_mediaObject->currentSource().discType() != src.discType() ||
            m_mediaObject->currentSource().deviceName() != src.deviceName()) {
            m_mediaObject->setCurrentSource(src);
        }
        if (title != -1) {
            m_mediaController->setCurrentTitle(title);
            m_mediaController->setAutoplayTitles(true);
        }
        m_mediaObject->play();
    } else if (subType == "Audio Stream") {
        m_currentStream = nextMediaItem.url;
        m_streamListUrls.clear();
        if (Utilities::isPls(nextMediaItem.url) || Utilities::isM3u(nextMediaItem.url)) {
            QList<MediaItem> streamList = Utilities::mediaListFromSavedList(nextMediaItem);
            for (int i = 0; i < streamList.count(); i++) {
                m_streamListUrls << streamList.at(i).url;
                if (i == 0) {
                    m_currentUrl = streamList.at(i).url;
                } else {
                    m_mediaObject->enqueue(Phonon::MediaSource(QUrl::fromPercentEncoding(streamList.at(i).url.toUtf8())));
                }
            }
        } else {
            m_streamListUrls << nextMediaItem.url;
        }
        m_mediaObject->setCurrentSource(Phonon::MediaSource(QUrl::fromPercentEncoding(m_currentUrl.toUtf8())));
        m_mediaObject->play();
    } else {
        m_mediaObject->setCurrentSource(Phonon::MediaSource(QUrl::fromEncoded(m_currentUrl.toUtf8())));
        m_mediaObject->play();
    }
    m_state = Playlist::Playing;
}