[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: playground/network/videocatcher/src [POSSIBLY UNSAFE]
From: Jonas Emanuel Müller <zanoi () zanoi ! net>
Date: 2010-11-26 17:24:53
Message-ID: 20101126172453.4EA23AC8A2 () svn ! kde ! org
[Download RAW message or body]
SVN commit 1201071 by jonasemuller:
create dynamic play menu based on downloaded file's mime type
M +28 -12 configurewidget.ui
M +121 -9 mainwindowkde.cpp [POSSIBLY UNSAFE: KRun::runCommand]
M +2 -1 mainwindowkde.h
--- trunk/playground/network/videocatcher/src/configurewidget.ui #1201070:1201071
@@ -39,8 +39,8 @@
</layout>
</item>
<item>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout_6">
+ <item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -53,7 +53,7 @@
</property>
</spacer>
</item>
- <item row="0" column="1">
+ <item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -66,7 +66,11 @@
</property>
</spacer>
</item>
- <item row="1" column="0" rowspan="2">
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
<widget class="QLabel" name="label">
<property name="text">
<string>Video Folder</string>
@@ -76,10 +80,14 @@
</property>
</widget>
</item>
- <item row="1" column="1" rowspan="2">
+ <item>
<widget class="KLineEdit" name="kcfg_videoPath"/>
</item>
- <item row="3" column="0">
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -92,7 +100,7 @@
</property>
</spacer>
</item>
- <item row="3" column="1">
+ <item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -105,20 +113,28 @@
</property>
</spacer>
</item>
- <item row="4" column="0" rowspan="2">
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
<widget class="QLabel" name="label_2">
<property name="text">
- <string>Playback program</string>
+ <string>Use custom playback command</string>
</property>
<property name="buddy">
<cstring>kcfg_videoPlaybackCommand</cstring>
</property>
</widget>
</item>
- <item row="4" column="1" rowspan="2">
+ <item>
<widget class="KLineEdit" name="kcfg_videoPlaybackCommand"/>
</item>
- <item row="6" column="0">
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -131,7 +147,7 @@
</property>
</spacer>
</item>
- <item row="6" column="1">
+ <item>
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
--- trunk/playground/network/videocatcher/src/mainwindowkde.cpp #1201070:1201071
@@ -49,6 +49,10 @@
#include <KMenu>
#include <KFileDialog>
#include <KStandardShortcut>
+#include <KRun>
+#include <KMimeTypeTrader>
+#include <KMimeType>
+#include <KActionMenu>
#if KDE_IS_VERSION(4,4,0)
#include <KStatusNotifierItem>
@@ -103,6 +107,13 @@
QMap<KJob *, unsigned long> *m_downloadSpeeds;
// The search bar
KLineEdit *m_searchText;
+ // This stores the play menu for easy access
+ KActionMenu *m_playMenu;
+ // This is a list of the current actions in
+ // the play menu. The list is needed in order
+ // to be able to remove the actions from the
+ // menu.
+ QStringList *m_playMenuActions;
};
MainWindow::MainWindow(QWidget *parent) : KXmlGuiWindow(parent), d(new \
MainWindowPrivate) @@ -253,13 +264,15 @@
connect(cancelEpisodeDownloadAction, SIGNAL(triggered()), this,
SLOT(cancelEpisodeDownload()));
- KAction *playEpisodeAction = new KAction(i18n("&Play Episode"), this);
- playEpisodeAction->setShortcuts(KShortcut("Space"));
- playEpisodeAction->setIcon(KIcon("media-playback-start"));
- playEpisodeAction->setStatusTip(i18n("Play episode"));
- playEpisodeAction->setEnabled(false);
- actionCollection()->addAction("play", playEpisodeAction);
- connect(playEpisodeAction, SIGNAL(triggered()), this, SLOT(playEpisode()));
+ d->m_playMenu = new KActionMenu(i18n("&Play Episode"), this);
+ d->m_playMenu->setShortcuts(KShortcut("Space"));
+ d->m_playMenu->setIcon(KIcon("media-playback-start"));
+ d->m_playMenu->setStatusTip(i18n("Play episode"));
+ d->m_playMenu->setEnabled(false);
+ d->m_playMenu->setDelayed(true);
+ actionCollection()->addAction("play", d->m_playMenu);
+ connect(d->m_playMenu, SIGNAL(triggered()), this, SLOT(playEpisode()));
+ d->m_playMenuActions = new QStringList;
KAction *streamEpisodeAction = new KAction(i18n("&Stream Episode"), this);
//streamEpisodeAction->setShortcut(i18n(""));
@@ -360,7 +373,21 @@
d->m_episodeInformationWidget->setAttribute("Description:", \
d->m_episodeModel->description(current));
d->m_episodeInformationWidget->setAttribute("Size:", \
KIO::convertSize(d->m_episodeModel->videoSize(current))); }
+
+ //update the play menu to show all registered applications
+ //for the currently selected channels video mimetype
+ QString videoPath = d->m_episodeModel->videoPath(current);
+
+ if(videoPath != "") {
+ KMimeType::Ptr mimeType;
+ //note that the fourth parameter enables fast_mode
+ //which means that no disk access is allowed
+ //this is to prevent constant disk access, but might
+ //be changed later.
+ mimeType = KMimeType::findByUrl(videoPath, 0, true, true);
+ updatePlayMenu(mimeType.data()->name());
}
+}
void MainWindow::updateEpisodeView()
{
@@ -836,16 +863,32 @@
}
}
+/**
+ * This method will play the currently selected episode. If the action which
+ * called this slot has data set (with setData()) it will be interpreted as
+ * a QString name of the preferred service to play the episode with. Otherwise
+ * the default service for the episodes mime type will be used.
+ */
void MainWindow::playEpisode()
{
+ QString preferredService;
+ QAction *action = qobject_cast<QAction*>(sender());
+ if(action) {
+ preferredService = action->data().toString();
+ }
+
QModelIndex index = d->m_episodeView->currentIndex();
if (!index.isValid()) {
KMessageBox::information(this, i18n("No episode selected. Please select an \
episode."), i18n("Play Episode")); return;
}
+ if(preferredService.isEmpty()) {
playEpisode(index);
+ } else {
+ playEpisode(index, preferredService);
}
+}
void MainWindow::streamEpisode()
{
@@ -978,6 +1021,55 @@
submitChannelsAndEpisodes();
}
+/**
+ * This method updates the play menu to display all registered applications for the \
given + * mime type. If a custom command is specified in the applications \
configuration dialog + * it will be appended to the menu.
+ *
+ * @param mimeType the mime type for which the registered applications should be \
shown. + */
+void MainWindow::updatePlayMenu(const QString &mimeType)
+{
+ for(int i=0; i < d->m_playMenuActions->size(); ++i) {
+ kDebug() << "removing actions: " << d->m_playMenuActions->at(i);
+ d->m_playMenu->removeAction(actionCollection()->action(d->m_playMenuActions->at(i)));
+ }
+ d->m_playMenuActions->clear();
+
+ KService::List services = KMimeTypeTrader::self()->query(mimeType, \
"Application"); +
+ KService::List::ConstIterator it = services.constBegin();
+ const KService::List::ConstIterator end = services.constEnd();
+ for(; it != end; ++it) {
+ KAction *action;
+ const KService::Ptr service = *it;
+ kDebug() << "service: " << service->desktopEntryName();
+ action = new KAction((*it)->name(), this);
+ action->setIcon(KIcon((*it)->icon()));
+ action->setData((*it)->desktopEntryName());
+ connect(action, SIGNAL(triggered()), this, SLOT(playEpisode()));
+ actionCollection()->addAction((*it)->desktopEntryName(), action);
+ d->m_playMenu->addAction(action);
+ *d->m_playMenuActions << (*it)->desktopEntryName();
+ }
+
+ // append a custom command playback option, if a command is configured in \
the settings + QString videoPlaybackCommand = \
Configure::videoPlaybackCommand(); + if(!videoPlaybackCommand.isEmpty()) {
+ KAction *action;
+ kDebug() << "appending custom command: " << videoPlaybackCommand;
+ action = new KAction(videoPlaybackCommand, this);
+ //action->setIcon(KIcon((*it)->icon()));
+ action->setData("customCommand");
+ connect(action, SIGNAL(triggered()), this, SLOT(playEpisode()));
+ actionCollection()->addAction("customCommand", action);
+ d->m_playMenu->addAction(action);
+ *d->m_playMenuActions << "customCommand";
+
+ }
+
+}
+
KUrl MainWindow::calculateEpisodeVideoPath(QModelIndex index)
{
QString hostname;
@@ -1063,11 +1155,31 @@
}
}
-void MainWindow::playEpisode(const QModelIndex row) {
+/**
+ * This method plays a particular episode with an external application. If the \
external application + * is not specified or cannot be found the systems default \
application for the files' mimetype will + * be used.
+ *
+ * @param row a QModelIndex representing the row of the episode that is to be played
+ * @param preferredServiceName The name of the preferred service to play back the \
episode. + * In case the service is not found it will fall back to the default \
service. If "customCommand" + * is passed, the episode will be played back using the \
shell command specified by the user + * in the applications configuration dialog. \
This is in order to play back using applications which are not + * registered as a \
service. + */
+void MainWindow::playEpisode(const QModelIndex row, const QString \
&preferredServiceName) { + if(preferredServiceName == "customCommand") {
QString videoPlaybackCommand = Configure::videoPlaybackCommand();
kDebug() << "videoPlaybackCommand: " << videoPlaybackCommand << " " << \
QStringList(d->m_episodeModel->videoPath(row));
- QProcess::startDetached(videoPlaybackCommand, \
QStringList(d->m_episodeModel->videoPath(row))); + QString command = \
videoPlaybackCommand + " " + d->m_episodeModel->videoPath(row); + \
KRun::runCommand(command, this); + } else {
+ KRun::KRun *run = new KRun::KRun(d->m_episodeModel->videoPath(row), this);
+ if (preferredServiceName != "") {
+ run->setPreferredService(preferredServiceName);
}
+ }
+}
void MainWindow::searchChanged(const QString & str)
{
--- trunk/playground/network/videocatcher/src/mainwindowkde.h #1201070:1201071
@@ -59,7 +59,7 @@
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
- void playEpisode(const QModelIndex row);
+ void playEpisode(const QModelIndex row, const QString &preferredServiceName = \
""); void refreshChannel(QModelIndex index);
void cancelEpisodeDownload(QModelIndex index);
void cancelAllEpisodeDownloads();
@@ -95,6 +95,7 @@
void quit();
protected:
+ void updatePlayMenu(const QString &mimeType);
void closeEvent(QCloseEvent *event);
KUrl calculateEpisodeVideoPath(QModelIndex episode);
KUrl calculateChannelPath(QModelIndex channel);
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic