diff options
Diffstat (limited to 'kaffeine/src/player-parts/xine-part/xine_part.cpp')
-rw-r--r-- | kaffeine/src/player-parts/xine-part/xine_part.cpp | 2111 |
1 files changed, 2111 insertions, 0 deletions
diff --git a/kaffeine/src/player-parts/xine-part/xine_part.cpp b/kaffeine/src/player-parts/xine-part/xine_part.cpp new file mode 100644 index 0000000..920a2ac --- /dev/null +++ b/kaffeine/src/player-parts/xine-part/xine_part.cpp @@ -0,0 +1,2111 @@ +/* + * xine_part.cpp + * + * Copyright (C) 2004-2005 Jürgen Kofler <kaffeine@gmx.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "xine_part.h" + +#include <kapplication.h> +#include <kinstance.h> +#include <kiconloader.h> +#include <kaction.h> +#include <kstdaction.h> +#include <kfiledialog.h> +#include <kmessagebox.h> +#include <kinputdialog.h> +#include <kxmlguifactory.h> +#include <kpopupmenu.h> +#include <kparts/genericfactory.h> +#include <kprogress.h> +#include <kio/netaccess.h> +#include <kstandarddirs.h> +#include <dcopclient.h> +#include <kprocess.h> +#include <kprotocolinfo.h> +#include <ktoolbar.h> + +#include <qvbox.h> +#include <qlabel.h> +#include <qpushbutton.h> +#include <qimage.h> +#include <qfontmetrics.h> +#include <qregexp.h> +#include <qtooltip.h> +#include <qdatetimeedit.h> + +#include <xine/xineutils.h> + +#include "mrl.h" +#include "kxinewidget.h" +#include "videosettings.h" +#include "equalizer.h" +#include "deinterlacequality.h" +#include "filterdialog.h" +#include "screenshotpreview.h" +#include "xineconfig.h" +#include "positionslider.h" +#include "playlistimport.h" +#include "version.h" + +typedef KParts::GenericFactory<XinePart> XinePartFactory; +K_EXPORT_COMPONENT_FACTORY (libxinepart, XinePartFactory) + + +XinePart::XinePart(QWidget* parentWidget, const char* widgetName, QObject* parent, const char* name, const QStringList& args) + : DCOPObject("XinePartIface"), + KaffeinePart(parent, name ? name : "XinePart"), + m_current(0), m_xine(NULL), m_pictureSettings(NULL), m_deinterlacerConfigWidget(NULL), + m_filterDialog(NULL), m_embeddedContext(NULL) +{ + kdDebug() << "XinePart: Creating new XinePart..." << endl; + + /* + * Parsing parameter given by kaffeine (audiodriver, videodriver, verbose) + * or parameters of <embed>...</embed> + * + * format: param="value" + */ + QString audioDriver = QString::null; + QString videoDriver = QString::null; + bool verbose = false; + TimeShiftFilename = ""; + + for (uint i=0; i<args.count(); i++) + { + kdDebug() << "XinePart: Argument: " << args[i] << endl; + if (args[i].left(11).lower() == "audiodriver") + { + audioDriver = args[i].section( '"',1, 1 ); + kdDebug() << "XinePart: Found audiodriver parameter, value: " << audioDriver << endl; + + } + if (args[i].left(11).lower() == "videodriver") + { + videoDriver = args[i].section( '"',1, 1 ); + kdDebug() << "XinePart: Found videodriver parameter, value: " << videoDriver << endl; + } + if (args[i].left(7).lower() == "verbose") + { + if (args[i].section( '"', 1, 1 ).lower() == "true") + { + kdDebug() << "XinePart: Found parameter verbose, set xine engine verbosity to max..." << endl; + verbose = true; + } + } + } + + // we need an instance + setInstance(XinePartFactory::instance()); + + // be careful - we may be embedded + QString configPath = locate("data", "kaffeine/xine-config"); + QString logoPath = locate("data", "kaffeine/logo"); + + kdDebug() << "XinePart: Using xine-config file: " << configPath << endl; + + m_xine = new KXineWidget(parentWidget, widgetName, configPath, logoPath, + audioDriver, videoDriver, /* start xine manual*/true, verbose); + connect(m_xine, SIGNAL(signalXineFatal(const QString&)), this, SIGNAL(canceled(const QString&))); + connect(m_xine, SIGNAL(stopDvb()), this, SIGNAL(stopDvb())); + connect(m_xine, SIGNAL(signalDvbOSDHidden()), this, SIGNAL(dvbOSDHide())); + m_xine->setFocusPolicy(QWidget::ClickFocus); + setWidget(m_xine); + + // set our XML-UI resource file + setXMLFile("xine_part.rc"); + initActions(); + initConnections(); + + QTimer::singleShot(0, this, SLOT(slotDisableAllActions())); + m_oldPosition = m_xine->mapToGlobal(QPoint(0,0)); + m_posCheckTimer.start(333); +} + +XinePart::~XinePart() +{ + kdDebug() << "XinePart: destructor" << endl; + kdDebug() << "XinePart destructor: calling saveConfig()" << endl; + saveConfig(); + if (m_embeddedContext) + delete m_embeddedContext; +} + +KAboutData *XinePart::createAboutData() +{ + KAboutData* aboutData = new KAboutData( "kaffeine", I18N_NOOP("XinePart"), + KAFFEINE_VERSION, I18N_NOOP("A xine based player part for Kaffeine."), + KAboutData::License_GPL, + "(c) 2003-2004, Jürgen Kofler.", 0, "http://kaffeine.sourceforge.net"); + aboutData->addAuthor("Jürgen Kofler.",0, "kaffeine@gmx.net"); + + return aboutData; +} + +bool XinePart::openURL(const MRL& mrl) +{ + kdDebug() << "XinePart::openURL(): " << mrl.url() << endl; + + // if (!mrl.kurl().isValid()) + // return false; + + m_mrl = mrl; + m_playlist.clear(); + m_current = 0; + bool playlist = false; + + QString ext = m_mrl.kurl().fileName(); + ext = ext.remove( 0 , ext.findRev('.')+1 ).lower(); + + if (!m_mrl.mime().isNull()) + { + KMimeType::Ptr mime = KMimeType::findByURL(m_mrl.kurl().path()); + m_mrl.setMime(mime->name()); + } + + /* is m_mrl a playlist? */ + if ((m_mrl.mime() == "text/plain") || (m_mrl.mime() == "text/xml") || (m_mrl.mime() == "application/x-kaffeine") + || (m_mrl.mime() == "audio/x-scpls") || (m_mrl.mime() == "audio/x-mpegurl") || (m_mrl.mime() == "audio/mpegurl") + || (m_mrl.mime() == "application/smil") + || (ext == "asx") || (ext == "asf") || (ext == "wvx") || (ext == "wax")) /* windows meta files */ + { + kdDebug() << "XinePart: Check for kaffeine/noatun/m3u/pls/asx playlist\n"; + QString localFile; + if (KIO::NetAccess::download(m_mrl.kurl(), localFile, widget())) + { + QFile file(localFile); + file.open(IO_ReadOnly); + QTextStream stream(&file); + QString firstLine = stream.readLine(); + QString secondLine = stream.readLine(); + file.close(); + + if (secondLine.contains("kaffeine", false)) + { + kdDebug() << "KafeinePart: Try loading kaffeine playlist\n"; + playlist = PlaylistImport::kaffeine(localFile, m_playlist); + } + if (secondLine.contains("noatun", false)) + { + kdDebug() << "XinePart: Try loading noatun playlist\n"; + playlist = PlaylistImport::noatun(localFile, m_playlist); + } + if (firstLine.contains("asx", false)) + { + kdDebug() << "XinePart: Try loading asx playlist\n"; + playlist = PlaylistImport::asx(localFile, m_playlist); + } + if (firstLine.contains("smil", false)) + { + kdDebug() << "XinePart: Try loading smil playlist\n"; + if (KMessageBox::warningYesNo(0, i18n("SMIL (Synchronized Multimedia Integration Language) support is rudimentary!\nXinePart can now try to playback contained video sources without any layout. Proceed?"), QString::null, KStdGuiItem::yes(), KStdGuiItem::no(), "smil_warning") == KMessageBox::Yes) + { + if (!PlaylistImport::smil(localFile, m_mrl, m_playlist)) + { + emit signalTrackFinished(); + return false; + } + } + else + return false; + } + if (firstLine.contains("[playlist]", false)) + { + kdDebug() << "XinePart: Try loading pls playlist\n"; + playlist = PlaylistImport::pls(localFile, m_playlist); + } + if (ext == "m3u") //indentify by extension + { + kdDebug() << "XinePart: Try loading m3u playlist\n"; + playlist = PlaylistImport::m3u(localFile, m_playlist); + } + } + else + kdError() << "XinePart: " << KIO::NetAccess::lastErrorString() << endl; + } + /* check for ram playlist */ + if ( (ext == "ra") || (ext == "rm") || (ext == "ram") || (ext == "lsc") || (ext == "pl") ) + { + kdDebug() << "XinePart: Try loading ram playlist\n"; + playlist = PlaylistImport::ram(m_mrl, m_playlist, widget()); + } + /* urls from audiocd kio-slave */ + if (m_mrl.kurl().protocol() == "audiocd") + { + QString audioTrack = QString::number(m_mrl.kurl().fileName().remove( QRegExp("\\D" ) ).left(2).toUInt()); + m_mrl = MRL(audioTrack.prepend( "cdda:/" )); + } + + if (!playlist) + { + kdDebug() << "XinePart: Got single track\n"; + m_playlist.append(m_mrl); + } + + slotPlay(true); + + return true; +} + +bool XinePart::closeURL() +{ + kdDebug() << "XinePart::closeURL()" << endl; + // m_playlist.clear(); + // m_mrl = MRL(); + slotStop(); + + return true; +} + +void XinePart::slotPlay(bool forcePlay) +{ + kdDebug() << "XinePart::slotPlay()" << endl; + + m_pauseButton->setChecked(false); + if (m_xine->isPlaying()) + { + if ( (m_xine->getSpeed() != KXineWidget::Normal) && !forcePlay ) + { + m_xine->slotSpeedNormal(); + slotEnablePlayActions(); + return; + } + else + emit stopDvb(); + } + + if (m_playlist.count() == 0) + { + emit signalRequestCurrentTrack(); + return; + } + + MRL mrl = m_playlist[m_current]; + + /* + * is protocol supported by xine or not known by KIO? + */ + if ((QString(SUPPORTED_PROTOCOLS).contains(mrl.kurl().protocol())) + || (!KProtocolInfo::isKnownProtocol(mrl.kurl()))) + { + QString sub; + if ((!mrl.subtitleFiles().isEmpty()) && (mrl.currentSubtitle() > -1)) + sub = QString("#subtitle:%1").arg(mrl.subtitleFiles()[mrl.currentSubtitle()]); + + m_xine->clearQueue(); + m_xine->appendToQueue(mrl.url() + sub ); + if (!m_xine->isXineReady()) + { + if (!m_xine->initXine()) + return; + } + else + QTimer::singleShot(0, m_xine, SLOT(slotPlay())); + } + else + { + kdDebug() << "XinePart: Protocol not supported by xine, try to download it..." << endl; + + QString localFile; + if (KIO::NetAccess::download(mrl.kurl(), localFile, widget())) + { + m_xine->clearQueue(); + m_xine->appendToQueue(localFile); + if (!m_xine->isXineReady()) + { + if (!m_xine->initXine()) + return; + } + else + QTimer::singleShot(0, m_xine, SLOT(slotPlay())); + } + else + kdError() << "XinePart: " << KIO::NetAccess::lastErrorString() << endl; + } +} + +void XinePart::slotStop() +{ + if (!m_xine->isXineReady()) + return; + + emit stopDvb(); + + /* if we play a DVD we cache current title and chapter */ + if (m_playlist[m_current].url().startsWith("dvd:/")) + { + uint title = m_xine->currentDVDTitleNumber(); + uint chapter = m_xine->currentDVDChapterNumber(); + + m_playlist[m_current] = MRL("dvd://" + QString::number(title) + "." + QString::number(chapter)); + } + + QTimer::singleShot(0, m_xine, SLOT(slotStop())); + stateChanged("not_playing"); + m_pauseButton->setChecked(false); + m_playTime->setText("0:00:00"); + emit setWindowCaption(""); +} + +void XinePart::slotNext() +{ + if (m_xine->hasChapters()) + { + m_xine->playNextChapter(); + return; + } + + if ((m_playlist.count() > 0) && (m_current < m_playlist.count()-1)) + { + m_current++; + slotPlay(); + } + else + { + emit signalRequestNextTrack(); + } +} + +void XinePart::slotPrevious() +{ + if (m_xine->hasChapters()) + { + m_xine->playPreviousChapter(); + return; + } + + if (m_current > 0) + { + m_current--; + slotPlay(); + } + else + { + emit signalRequestPreviousTrack(); + } +} + +void XinePart::requestForOSD( const QString &text, int duration, int priority ) +{ + m_xine->showOSDMessage( text, duration, priority ); +} + +void XinePart::setDvbCurrentNext( const QString &channelName, const QStringList &list ) +{ + m_xine->setDvbCurrentNext( channelName, list ); +} + +void XinePart::slotDvbOpen( const QString &filename, const QString &chanName, int haveVideo ) +{ + if (!m_xine->isXineReady()) + if (!m_xine->initXine()) + return; + m_playlist.clear(); + m_xine->setDvb( filename, chanName, haveVideo ); + QTimer::singleShot(0, m_xine, SLOT(openDvb())); + //m_xine->openDvb( filename, chanName, haveVideo ); +} + +void XinePart::getTimeShiftFilename( const QString &filename ) +{ + TimeShiftFilename = filename; + m_xine->TimeShiftFilename = TimeShiftFilename; +} + +void XinePart::slotTogglePause( bool pauseLive ) +{ + kdDebug() << "slotSpeedPause()" << endl; + if (!m_xine->isXineReady()) + return; + + if (m_xine->getSpeed() == KXineWidget::Pause) + { + m_xine->slotSpeedNormal(); + slotEnablePlayActions(); + m_pauseButton->setChecked(false); + } + else + { + if ( pauseLive ) + emit playerPause(); + m_xine->slotSpeedPause(); + // kdDebug() << "XinePart: Set state to paused" << endl; + stateChanged("paused"); + m_pauseButton->setChecked(true); + } +} + +void XinePart::speedFaster() +{ + slotFastForward(); +} + +void XinePart::slotFastForward() +{ + if (m_xine->getSpeed() == KXineWidget::Pause) + { + m_pauseButton->setChecked(false); + slotEnablePlayActions(); + } + m_xine->slotSpeedFaster(); +} + +void XinePart::speedSlower() +{ + slotSlowMotion(); +} + +void XinePart::slotSlowMotion() +{ + if (m_xine->getSpeed() == KXineWidget::Pause) + { + m_pauseButton->setChecked(false); + slotEnablePlayActions(); + } + + m_xine->slotSpeedSlower(); +} + +void XinePart::slotMute() +{ + if (!m_xine->isXineReady()) + return; + + m_xine->slotToggleMute(); +} + +void XinePart::slotVolumeUp() +{ + int newVol = volume() + 5; + if (newVol >100) + newVol = 100; + slotSetVolume(newVol); +} + +void XinePart::slotVolumeDown() +{ + int newVol = volume() - 5; + if (newVol <0) + newVol = 0; + slotSetVolume(newVol); +} + +void XinePart::slotPosPlusSmall() +{ + slotJumpIncrement( 20 ); +} + +void XinePart::slotPosMinusSmall() +{ + slotJumpIncrement( -20 ); +} + +void XinePart::slotPosPlusMedium() +{ + slotJumpIncrement( 60 ); +} + +void XinePart::slotPosMinusMedium() +{ + slotJumpIncrement( -60 ); +} + +void XinePart::slotPosPlusLarge() +{ + slotJumpIncrement( 600 ); +} + +void XinePart::slotPosMinusLarge() +{ + slotJumpIncrement( -600 ); +} + +void XinePart::slotJumpIncrement(int increment) +{ + if (!m_xine->isSeekable()) + return; + + QTime timeNow; + QTime projectedTime; + QTime startTime; + + if (!m_xine->getLength().isNull()) + { + timeNow = m_xine->getPlaytime(); + if ( increment < 0 && timeNow.msecsTo(startTime) > increment * 1000 ) + { + m_xine->slotSeekToTime(startTime); + } + else + { + projectedTime = timeNow.addSecs(increment); + m_xine->slotSeekToTime(projectedTime); + } + } +} + +void XinePart::slotAdvanceSubTitle() +{ + int spuOffset; + m_xine->getspuOffset(spuOffset); + m_xine->slotSetSpuOffset(spuOffset+45000); +} + +void XinePart::slotDelaySubTitle() +{ + int spuOffset; + m_xine->getspuOffset(spuOffset); + m_xine->slotSetSpuOffset(spuOffset-45000); +} + +void XinePart::slotSaveStream() +{ + if (m_mrl.isEmpty()) + return; + + QString saveDir = m_xine->getStreamSaveDir(); + + KURL kurl = KFileDialog::getSaveURL(saveDir + "/" + m_playlist[m_current].kurl().fileName(), QString::null, 0, i18n("Save Stream As")); + if (!kurl.isValid()) + return; + + if ( saveDir != kurl.directory() ) + m_xine->setStreamSaveDir(kurl.directory()); + + m_xine->clearQueue(); + m_xine->appendToQueue(m_playlist[m_current].url() + "#save:" + kurl.path()); + QTimer::singleShot(0, m_xine, SLOT(slotPlay())); + m_pauseButton->setChecked(false); +} + +void XinePart::slotSetSubtitle(int channel) +{ + if (m_playlist[m_current].subtitleFiles().isEmpty()) + { + m_xine->slotSetSubtitleChannel(channel); + } + else + { + m_playlist[m_current].setCurrentSubtitle(channel - 1); + emit signalNewMeta(m_mrl); + m_xine->savePosition(m_xine->getPosition()-200); + slotPlay(true); //force load of new subtitle + } + emit setStatusBarText(i18n("Subtitle") + ": " + m_subtitles->items()[channel]); + m_xine->showOSDMessage(i18n("Subtitle") + ": " + m_subtitles->items()[channel], DEFAULT_OSD_DURATION); +} + +void XinePart::slotAddSubtitle(void) +{ + QString subtitleURL = KFileDialog::getOpenURL(m_mrl.kurl().directory(), + i18n("*.smi *.srt *.sub *.txt *.ssa *.asc|Subtitle Files\n*.*|All Files"), + 0, i18n("Select Subtitle File")).path(); + + if (!(subtitleURL.isEmpty())) + { + if (!m_playlist[m_current].subtitleFiles().contains(subtitleURL)) + { + m_playlist[m_current].addSubtitleFile(subtitleURL); + } + + int subchannel = m_playlist[m_current].subtitleFiles().size() - 1; + m_playlist[m_current].setCurrentSubtitle(subchannel); + emit signalNewMeta(m_mrl); + m_xine->savePosition(m_xine->getPosition()-200); + slotPlay(true); //force load of new subtitle + + emit setStatusBarText(i18n("Subtitle") + ": " + m_subtitles->items()[subchannel]); + m_xine->showOSDMessage(i18n("Subtitle") + ": " + m_subtitles->items()[subchannel], DEFAULT_OSD_DURATION); + } + +} + +void XinePart::slotSetAudioChannel(int channel) +{ + m_xine->slotSetAudioChannel(channel); + emit setStatusBarText(i18n("Audiochannel") + ": " + m_audioChannels->items()[channel]); + m_xine->showOSDMessage(i18n("Audiochannel") + ": " + m_audioChannels->items()[channel], DEFAULT_OSD_DURATION); +} + +void XinePart::slotSetDVDTitle(const QString& titleStr) +{ + bool ok; + uint title = titleStr.toInt(&ok); + if (ok && title > 0 && title <= m_xine->getDVDTitleCount()) + { + KURL url = m_mrl.kurl(); + url.addPath(QString::number(title)); + m_playlist[m_current] = MRL(url); + slotPlay(true); + } +} + +void XinePart::slotSetDVDChapter(const QString& chapterStr) +{ + bool ok; + uint chapter = chapterStr.toInt(&ok); + if (ok) + setDVDChapter(chapter); +} + +void XinePart::slotSetDVDAngle(const QString& angleStr) +{ + bool ok; + uint angle = angleStr.toInt(&ok); + if (ok && angle > 0 && angle <= m_xine->getDVDAngleCount()) + { + uint title = m_xine->currentDVDTitleNumber(); + uint chapter = m_xine->currentDVDChapterNumber(); + KURL url = m_mrl.kurl(); + + url.addPath(QString::number(title) + "." + QString::number(chapter) + "." + QString::number(angle)); + m_playlist[m_current] = MRL(url); + slotPlay(true); + } +} + +void XinePart::setDVDChapter(uint chapter) +{ + if (chapter > 0 && chapter <= m_xine->getDVDChapterCount()) + { + uint title = m_xine->currentDVDTitleNumber(); + KURL url = m_mrl.kurl(); + + url.addPath(QString::number(title) + "." + QString::number(chapter)); + m_playlist[m_current] = MRL(url); + slotPlay(true); + } +} + +void XinePart::slotChannelInfo(const QStringList& audio, const QStringList& sub, int currentAudio, int currentSub) +{ + kdDebug() << "XinePart: slotChannelInfo: currentAudio="<<currentAudio<< " currentSub="<<currentSub<<"\n"; + m_audioChannels->setItems(audio); + m_audioChannels->setCurrentItem(currentAudio+1); + + if (m_playlist[m_current].subtitleFiles().isEmpty()) + { + m_subtitles->setItems(sub); + m_subtitles->setCurrentItem(currentSub+1); + } + else + { + QStringList subFiles = m_playlist[m_current].subtitleFiles(); + QStringList subs(i18n("off")); + QString sub; + QStringList::ConstIterator end(subFiles.end()); + for (QStringList::ConstIterator it = subFiles.begin(); it != end; ++it) + { + sub = (*it); + sub = sub.remove(0 , sub.findRev('/')+1); + subs.append(sub); + } + m_subtitles->setItems(subs); + m_subtitles->setCurrentItem(m_playlist[m_current].currentSubtitle() + 1); + } + + /* if we play a DVD enable and fill menus */ + if (m_playlist[m_current].url().startsWith("dvd:/")) + { + QStringList titles; + QStringList chapters; + QStringList angles; + uint titlesCount = m_xine->getDVDTitleCount(); + uint chaptersCount = m_xine->getDVDChapterCount(); + uint anglesCount = m_xine->getDVDAngleCount(); + + for (uint i = 1; i <= titlesCount; i++) + titles.append(QString::number(i)); + for (uint i = 1; i <= chaptersCount; i++) + chapters.append(QString::number(i)); + for (uint i = 1; i <= anglesCount; i++) + angles.append(QString::number(i)); + + m_dvdTitles->setItems(titles); + m_dvdTitles->setCurrentItem(m_xine->currentDVDTitleNumber() - 1); + m_dvdChapters->setItems(chapters); + m_dvdChapters->setCurrentItem(m_xine->currentDVDChapterNumber() - 1); + m_dvdAngles->setItems(angles); + m_dvdAngles->setCurrentItem(m_xine->currentDVDAngleNumber() - 1); + stateChanged("dvd_playback"); + } + else + { + stateChanged("dvd_playback", StateReverse); + } +} + +void XinePart::slotNewPosition(int pos, const QTime& playtime) +{ + QTime length = m_xine->getLength(); + QTime calcLength; + + //if (!m_xine->isSeekable() || length.isNull() || length < playtime) + if (!m_xine->isSeekable() ) + { + m_position->setPosition(0,false); + m_position->setEnabled(false); + } + else + { + m_position->setPosition(pos, false); + m_position->setEnabled(true); + } + + if (m_timerDirection == BACKWARD_TIMER && !length.isNull() && length >= playtime) + calcLength = length.addSecs(-playtime.second()-playtime.minute()*60-playtime.hour()*60*60); + else + calcLength = playtime; + + if (m_timerDirection == BACKWARD_TIMER) + m_playTime->setText("-" + calcLength.toString("h:mm:ss")); + else + m_playTime->setText(calcLength.toString("h:mm:ss")); + + QString timeMessage; + if (m_isOsdTimer) + { + if (m_timerDirection == BACKWARD_TIMER || length.isNull() || length < playtime) + { + timeMessage = calcLength.toString("h:mm:ss"); + m_xine->showOSDMessage("-" + timeMessage, 600, OSD_MESSAGE_LOW_PRIORITY); + } + else + { + timeMessage = i18n("%1 of %2").arg(calcLength.toString("h:mm:ss")).arg(length.toString("h:mm:ss")); + m_xine->showOSDMessage(timeMessage, 600, OSD_MESSAGE_LOW_PRIORITY); + } + } + currentPosition = (playtime.hour()*3600)+(playtime.minute()*60)+playtime.second(); +} + +QString XinePart::screenShot() +{ + QString filename = QDir::homeDirPath()+"/kaffeinedcopshot.jpg"; + QImage shot = m_xine->getScreenshot(); + if ( shot.save( filename, "JPEG" ) ) + return filename; + else + return ""; +} + +void XinePart::slotScreenshot() +{ + QImage shot = m_xine->getScreenshot(); + + KFileDialog dlg(":kaffeineMain_Screenshot", i18n("*.png|PNG-File\n*.bmp|BMP-File\n*.xbm|XBM-File"), + 0, "save screenshot", true); + dlg.setOperationMode(KFileDialog::Saving); + dlg.setCaption(i18n("Save Screenshot As")); + dlg.setSelection("screenshot.png"); + + ScreenshotPreview* prev = new ScreenshotPreview(shot, &dlg); + dlg.setPreviewWidget(prev); + + dlg.exec(); + QString fileName = dlg.selectedFile(); + + if (fileName.isEmpty()) + return; + + QString type = dlg.currentFilter(); + type = (type.remove(0,2)).upper(); + + kdDebug() << "XinePart: Save screenshot as " << type << "\n"; + if (!shot.save(fileName, type.ascii())) + kdError() << "XinePart: Screenshot not saved successfully!" << endl; +} + +void XinePart::slotFilterDialog() +{ + if (!m_filterDialog) + { + m_filterDialog = new FilterDialog(m_xine->getAudioFilterNames(), m_xine->getVideoFilterNames()); + connect(m_filterDialog, SIGNAL(signalCreateAudioFilter(const QString&, QWidget*)), + m_xine, SLOT(slotCreateAudioFilter(const QString&, QWidget*))); + connect(m_filterDialog, SIGNAL(signalCreateVideoFilter(const QString&, QWidget*)), + m_xine, SLOT(slotCreateVideoFilter(const QString&, QWidget*))); + connect(m_filterDialog, SIGNAL(signalRemoveAllAudioFilters()), m_xine, SLOT(slotRemoveAllAudioFilters())); + connect(m_filterDialog, SIGNAL(signalRemoveAllVideoFilters()), m_xine, SLOT(slotRemoveAllVideoFilters())); + connect(m_filterDialog, SIGNAL(signalUseAudioFilters(bool)), m_xine, SLOT(slotEnableAudioFilters(bool))); + connect(m_filterDialog, SIGNAL(signalUseVideoFilters(bool)), m_xine, SLOT(slotEnableVideoFilters(bool))); + } + m_filterDialog->show(); + m_filterDialog->raise(); +} + +void XinePart::slotDeinterlaceQuality() +{ + if (!m_deinterlacerConfigWidget) + return; + DeinterlaceQuality* deinterlaceQuality = new DeinterlaceQuality((QWidget*)m_deinterlacerConfigWidget); + deinterlaceQuality->setQuality(m_lastDeinterlaceQuality); + connect(deinterlaceQuality, SIGNAL(signalSetDeinterlaceConfig(const QString&)), + m_xine, SLOT(slotSetDeinterlaceConfig(const QString&))); + + deinterlaceQuality->exec(); + + m_lastDeinterlaceQuality = deinterlaceQuality->getQuality(); + m_lastDeinterlacerConfig = m_xine->getDeinterlaceConfig(); + delete deinterlaceQuality; +} + +void XinePart::slotSetHue( int i ) +{ + m_hue = i; + if ( i==-1 ) + return; + m_xine->slotSetHue( i ); +} + +void XinePart::slotSetSaturation( int i ) +{ + m_saturation = i; + if ( i==-1 ) + return; + m_xine->slotSetSaturation( i ); +} + +void XinePart::slotSetContrast( int i ) +{ + m_contrast = i; + if ( i==-1 ) + return; + m_xine->slotSetContrast( i ); +} + +void XinePart::slotSetBrightness( int i ) +{ + m_brightness = i; + if ( i==-1 ) + return; + m_xine->slotSetBrightness( i ); +} + +void XinePart::slotPictureSettings() +{ + if (!m_pictureSettings) + { + int hue, sat, contrast, bright, avOffset, spuOffset; + m_xine->getVideoSettings(hue, sat, contrast, bright, avOffset, spuOffset); + m_pictureSettings = new VideoSettings(hue, sat, contrast, bright, avOffset, spuOffset); + connect(m_pictureSettings, SIGNAL(signalNewHue(int)), this, SLOT(slotSetHue(int))); + connect(m_pictureSettings, SIGNAL(signalNewSaturation(int)), this, SLOT(slotSetSaturation(int))); + connect(m_pictureSettings, SIGNAL(signalNewContrast(int)), this, SLOT(slotSetContrast(int))); + connect(m_pictureSettings, SIGNAL(signalNewBrightness(int)), this, SLOT(slotSetBrightness(int))); + connect(m_pictureSettings, SIGNAL(signalNewAVOffset(int)), m_xine, SLOT(slotSetAVOffset(int))); + connect(m_pictureSettings, SIGNAL(signalNewSpuOffset(int)), m_xine, SLOT(slotSetSpuOffset(int))); + } + m_pictureSettings->show(); + m_pictureSettings->raise(); +} + +void XinePart::slotEqualizer() +{ + m_equalizer->show(); + m_equalizer->raise(); +} + +void XinePart::slotToggleBroadcastSend() +{ + bool ok = false; + + if (m_broadcastSend->isChecked()) + { + m_broadcastPort = (uint)KInputDialog::getInteger( QString::null, i18n("Broadcasting port:"), m_broadcastPort, 0, 1000000, 1, &ok); + if (!ok) + { + m_broadcastSend->setChecked(false); + return; + } + m_xine->setBroadcasterPort(m_broadcastPort); + } + else + { + m_xine->setBroadcasterPort(0); /* disable */ + } +} + +void XinePart::slotBroadcastReceive() +{ + if (!m_xine->isXineReady()) + { + if (!m_xine->initXine()) + return; + } + + KDialogBase* dialog = new KDialogBase(0, "configmaster", true, i18n("Configure Receive Broadcast Stream"), KDialogBase::Ok|KDialogBase::Cancel); + QVBox* page = dialog->makeVBoxMainWidget(); + new QLabel(i18n("Sender address:"), page); + KLineEdit* address = new KLineEdit(m_broadcastAddress, page); + new QLabel(i18n("Port:"), page); + QSpinBox* port = new QSpinBox(0, 1000000, 1, page); + port->setValue(m_broadcastPort); + + if (dialog->exec() == KDialogBase::Accepted) + { + m_broadcastPort = port->value(); + m_broadcastAddress = address->text(); + openURL(MRL(QString("slave://") + m_broadcastAddress + ":" + QString::number(m_broadcastPort))); + } + delete dialog; +} + +void XinePart::slotJumpToPosition() +{ + if (!m_xine->isSeekable()) + return; + + KDialogBase* dialog = new KDialogBase( 0, "configmaster", true, QString::null, KDialogBase::Ok|KDialogBase::Cancel ); + QVBox* page = dialog->makeVBoxMainWidget(); + page->setMargin(5); + page->setSpacing(5); + dialog->disableResize(); + new QLabel(i18n("Jump to position:"), page); + QTimeEdit* timeEdit = new QTimeEdit(page); + if (!m_xine->getLength().isNull()) + { + timeEdit->setMaxValue(m_xine->getLength()); + timeEdit->setTime(m_xine->getPlaytime()); + } + + if (dialog->exec() == KDialogBase::Accepted) + { + m_xine->slotSeekToTime(timeEdit->time()); + } + delete dialog; +} + +void XinePart::slotButtonTimerPressed() +{ + m_osdTimerEnabler.start(500, true); /* Long Click is 500ms */ +} + +void XinePart::slotButtonTimerReleased() +{ + if (!m_osdTimerEnabler.isActive()) + return; /* If short click toggle timer Mode*/ + m_osdTimerEnabler.stop(); + //kdDebug() << "XinePart: Toggling forward/backward Timer." << endl; + QTime length = m_xine->getLength(); + + if (!length.isNull()) /* if length not available counting backwards has no meaning */ + { + if (m_timerDirection == FORWARD_TIMER) + m_timerDirection = BACKWARD_TIMER; + else + m_timerDirection = FORWARD_TIMER; + slotNewPosition(m_xine->getPosition(),m_xine->getPlaytime()); + } +} + +void XinePart::slotToggleOsdTimer() +{ + kdDebug() << "XinePart: Toggling Osd Timer." << endl; + m_isOsdTimer = !m_isOsdTimer; +} + +void XinePart::slotConfigXine() +{ + if (!m_xine->isXineReady()) + { + if (!m_xine->initXine()) + return; + } + + XineConfig* xineConfigDialog = new XineConfig(m_xine->getXineEngine()); + xineConfigDialog->exec(); + delete xineConfigDialog; +} + +void XinePart::slotError(const QString& errMessage) +{ + if ((m_playlist.count() > 0) && (m_current < m_playlist.count() - 1)) + { + slotNext(); // try next before aborting playback; e.g. we play a PLS playlist, primary server is full, now try secondary + } + else + { + //KMessageBox::detailedError(0, errMessage, m_xine->getXineLog(), i18n("xine Error")); + stateChanged("not_playing"); + KMessageBox::detailedError(0, errMessage, m_xine->getXineLog(), i18n("xine Error")); + emit signalPlaybackFailed(); + } +} + +void XinePart::slotMessage(const QString& message) +{ + QString msg = message; + if ( msg.startsWith("@") ) { + if ( m_xine->isPlaying() && m_xine->getURL().contains("#") ) // do not warn for url containing # + return; + msg.remove(0,1); + } + KMessageBox::information(0, msg, i18n("xine Message")); +} + +void XinePart::slotStatus(const QString& status) +{ + emit setStatusBarText(status); + if ((status != i18n("Ready")) && (status != i18n("Playing"))) + { + m_xine->showOSDMessage(status, DEFAULT_OSD_DURATION); + } +} + +void XinePart::slotTrackPlaying() +{ + QString caption; + + kdDebug() << "XinePart: xine is playing" << endl; + m_pauseButton->setChecked(false); + QTimer::singleShot(100, this, SLOT(slotEnablePlayActions())); + + if ( m_xine->getURL()=="DVB" ) + { + caption = m_xine->getTitle(); + emit setWindowCaption(caption); + m_xine->showOSDMessage(caption, DEFAULT_OSD_DURATION); + return; + } + + /* fill current mrl with meta info */ + MRL mrl = m_playlist[m_current]; + + if (mrl.length().isNull()) /* no meta */ + { + if ((!m_xine->getTitle().isEmpty()) && (!m_xine->getTitle().contains('/')) + && (m_xine->getTitle().contains(QRegExp("\\w")) > 2) && (m_xine->getTitle().left(5).lower() != "track")) + mrl.setTitle(m_xine->getTitle()); + if ((mrl.artist().isEmpty()) && (!m_xine->getArtist().isEmpty())) + mrl.setArtist(m_xine->getArtist()); + if ((mrl.album().isEmpty()) && (!m_xine->getAlbum().isEmpty())) + mrl.setAlbum(m_xine->getAlbum()); + if ((mrl.year().isEmpty()) && (!m_xine->getYear().isEmpty())) + mrl.setYear(m_xine->getYear()); + if ((mrl.genre().isEmpty()) && (!m_xine->getGenre().isEmpty())) + mrl.setGenre(m_xine->getGenre()); + if ((mrl.comment().isEmpty()) && (!m_xine->getComment().isEmpty())) + mrl.setComment(m_xine->getComment()); + mrl.setLength(m_xine->getLength()); + m_playlist[m_current] = mrl; + } + /* if we don't have a playlist emit signalNewMeta() */ + if (mrl.url() == m_mrl.url()) + { + m_mrl = mrl; + emit signalNewMeta(m_mrl); + } + + caption = mrl.title(); + if (!mrl.artist().isEmpty()) + caption.append(QString(" (") + mrl.artist() + ")"); + emit setWindowCaption(caption); + m_xine->showOSDMessage(caption, DEFAULT_OSD_DURATION); + //emit signalNewFrameSize(m_xine->getVideoSize()); +} + +void XinePart::slotPlaybackFinished() +{ + if ((m_playlist.count() > 0) && (m_current < m_playlist.count()-1)) + { + slotNext(); + } + else + { + stateChanged("not_playing"); + emit signalTrackFinished(); + } +} + +void XinePart::slotNewLength() +{ + m_mrl.setLength(m_xine->getLength()); + emit signalNewMeta(m_mrl); +} + +void XinePart::slotNewTitle() +{ + m_mrl.setTitle(m_xine->getTitle()); + emit signalNewMeta(m_mrl); + emit setWindowCaption(m_mrl.title()); +} + +void XinePart::slotNewFrameSize() +{ + kdDebug() << "XinePart: got new frame size from xine" << endl; + emit signalNewFrameSize(m_xine->getVideoSize()); +} + +void XinePart::slotContextMenu(const QPoint& pos) +{ + if (factory()) + { + KPopupMenu *pop = (KPopupMenu*)factory()->container("context_menu", this); + if (pop) + pop->popup(pos); + } + else + { + if (m_embeddedContext) + m_embeddedContext->popup(pos); + } +} + +void XinePart::slotDVDMenuLeft() +{ + if (m_xine) + m_xine->slotDVDMenuLeft(); +} + +void XinePart::slotDVDMenuRight() +{ + if (m_xine) + m_xine->slotDVDMenuRight(); +} + +void XinePart::slotDVDMenuUp() +{ + if (m_xine) + m_xine->slotDVDMenuUp(); +} + +void XinePart::slotDVDMenuDown() +{ + if (m_xine) + m_xine->slotDVDMenuDown(); +} + +void XinePart::slotDVDMenuSelect() +{ + if (m_xine) + m_xine->slotDVDMenuSelect(); +} + +void XinePart::slotInfo() +{ + MRL mrl; + if ( m_xine->getURL()=="DVB" ) + mrl=MRL( QString("DVB"), m_xine->getTitle() ); + else + { + if ((m_mrl.isEmpty()) || (m_xine->getTitle().isNull())) + return; + mrl = m_playlist[m_current]; + } + + QString info; + QTextStream ts(&info, IO_WriteOnly); + ts << "<qt><table width=\"90%\">"; + ts << "<tr><td colspan=\"2\"><center><b>" << mrl.title() << "</b></center></td></tr>"; + if (!mrl.artist().isNull()) + ts << "<tr><td><b>" << i18n("Artist") << ":</b></td><td> " << mrl.artist() << "</td></tr>"; + if (!mrl.album().isNull()) + ts << "<tr><td><b>" << i18n("Album") << ":</b></td><td> " << mrl.album() << "</td></tr>"; + if (!mrl.track().isNull()) + ts << "<tr><td><b>" << i18n("Track") << ":</b></td><td> " << mrl.track() << "</td></tr>"; + if (!mrl.year().isNull()) + ts << "<tr><td><b>" << i18n("Year") << ":</b></td><td> " << mrl.year() << "</td></tr>"; + if (!mrl.genre().isNull()) + ts << "<tr><td><b>" << i18n("Genre") << ":</b></td><td> " << mrl.genre() << "</td></tr>"; + if (!(mrl.length().isNull())) + ts << "<tr><td><b>" << i18n("Length") << ":</b></td><td> " << mrl.length().toString("h:mm:ss") << "</td></tr>"; + + ts << "<br>"; + ts << "<tr><td><b>" << i18n("Mime") << ":</b></td><td> " << mrl.mime() << "</td></tr>"; + if (m_xine->hasAudio()) + ts << "<tr><td><b>" << i18n("Audio") << ":</b></td><td> " << m_xine->getAudioCodec() << " " << QString::number(m_xine->getAudioBitrate()/1000) + << "kb/s</td></tr>"; + if (m_xine->hasVideo()) + ts << "<tr><td><b>" << i18n("Video") << ":</b></td><td> " << m_xine->getVideoCodec() << " " << m_xine->getVideoSize().width() << "x" + << m_xine->getVideoSize().height() << "(" << m_xine->getVideoWidth() << "x" << m_xine->getVideoHeight() << ")"<< "</td></tr>"; + + ts << "<br>"; + if (m_xine->hasSubtitleURL()) + ts << "<tr><td><b>" << i18n("Subtitle File") << ":</b></td><td> " << m_xine->getSubtitleURL() << "</td></tr>"; + if (m_xine->hasSaveURL()) + ts << "<tr><td><b>" << i18n("Save Stream as") << ":</b></td><td> " << m_xine->getSaveURL() << "</td></tr>"; + + ts << "<tr><td></td><td></td></tr>"; // added for better layout + ts << "</table></qt>"; + KMessageBox::information(0, info, i18n("Track info") ); +} + +void XinePart::slotFinalize() +{ + if (factory()) + { + KToolBar *pos = (KToolBar*)factory()->container("positionToolBar", this); + if (pos) + { + // pos->alignItemRight(pos->idAt(1), true); //align time widget right + pos->setItemAutoSized(pos->idAt(0), true); //set position slider to maximum width + } + else + kdWarning("Position toolbar not found"); + } + else + { + kdDebug() << "XinePart: no xmlguifactory, will create a simple context menu..." << endl; + KAction* action = NULL; + m_embeddedContext = new KPopupMenu(0); + m_embeddedContext->insertTitle(instance()->iconLoader()->loadIcon("kaffeine", KIcon::Small), i18n("Kaffeine Player")); + actionCollection()->action("player_play")->plug(m_embeddedContext); + actionCollection()->action("player_pause")->plug(m_embeddedContext); + actionCollection()->action("player_stop")->plug(m_embeddedContext); + actionCollection()->action("volume_increase")->plug(m_embeddedContext); + actionCollection()->action("volume_decrease")->plug(m_embeddedContext); + actionCollection()->action("audio_mute")->plug(m_embeddedContext); + m_embeddedContext->insertSeparator(); + actionCollection()->action("player_track_info")->plug(m_embeddedContext); + m_embeddedContext->insertSeparator(); + actionCollection()->action("file_save_screenshot")->plug(m_embeddedContext); + actionCollection()->action("file_save_stream")->plug(m_embeddedContext); + m_embeddedContext->insertSeparator(); + action = new KAction(i18n("Copy URL to Clipboard"), "editcopy", 0, this, SLOT(slotCopyToClipboard()), actionCollection(), "copy_to_clipboard"); + action->plug(m_embeddedContext); + action = new KAction(i18n("Play in Kaffeine Externally"), "gear", 0, this, SLOT(slotLaunchExternally()), actionCollection(), "play_externally"); + action->plug(m_embeddedContext); + } + + QStringList visuals = m_xine->getVisualPlugins(); + visuals.prepend("none"); + m_audioVisual->setItems(visuals); + + loadConfig(); + QTimer::singleShot(0, this, SLOT(slotEnableAllActions())); +} + +void XinePart::slotCopyToClipboard() +{ + kdDebug() << "XinePart: Send URL to klipper: " << m_mrl.url() << endl; + DCOPClient* client = KApplication::dcopClient(); + if (!client->send("klipper", "klipper", "setClipboardContents(QString)", m_mrl.url())) + kdError() << "Can't send current URL to klipper" << endl; +} + +void XinePart::slotLaunchExternally() +{ + slotStop(); + + QTimer::singleShot(1000, this, SLOT(slotLaunchDelayed())); +} + +void XinePart::slotLaunchDelayed() +{ + kdDebug() << "XinePart: Start Kaffeine with argument: " << m_mrl.url() << endl; + KProcess process; + process << "kaffeine" << m_mrl.url(); + kdDebug() << "XinePart: Launching Kaffeine externaly..." << endl; + process.start(KProcess::DontCare); + process.detach(); +} + +void XinePart::initActions() +{ + KAction* action = NULL; + /* file menu */ + m_broadcastSend = new KToggleAction(i18n("&Send Broadcast Stream..."), 0, 0, this, SLOT(slotToggleBroadcastSend()), actionCollection(), "network_send"); + new KAction(i18n("&Receive Broadcast Stream..."), "network", 0, this, SLOT(slotBroadcastReceive()), actionCollection(), "network_receive"); + new KAction(i18n("&Save Screenshot..."), "frame_image", CTRL|Key_S, this, SLOT(slotScreenshot()), actionCollection(), "file_save_screenshot"); + action = new KAction(i18n("Save Stream..."), "player_record", Key_R, this, SLOT(slotSaveStream()), actionCollection(), "file_save_stream"); + action->setWhatsThis(i18n("Saves current stream to harddisc. This feature was disabled for some formats (e.g. Real Media) to prevent potential legal problems.")); + + /* player menu */ + + new KAction(i18n("Toggle Minimal Mode"), 0, 0, this, SIGNAL(signalToggleMinimalMode()), actionCollection(), "player_minimal_mode"); + + new KAction(i18n("Play"), "player_play", 0, this, SLOT(slotPlay()), actionCollection(), "player_play"); + m_pauseButton = new KToggleAction(i18n("Pause"), "player_pause", Key_Space, this, SLOT(slotTogglePause()), actionCollection(), "player_pause"); + new KAction(i18n("&Next"), "player_end", Key_PageDown, this, SLOT(slotNext()), actionCollection(), "player_next"); + new KAction(i18n("&Previous"), "player_start", Key_PageUp, this, SLOT(slotPrevious()), actionCollection(), "player_previous"); + new KAction(i18n("Stop"), "player_stop", Key_Backspace, this, SLOT(slotStop()), actionCollection(), "player_stop"); + + new KAction(i18n("&Fast Forward"), "player_fwd", ALT|Key_Right, this, SLOT(slotFastForward()), actionCollection(), "player_ff"); + new KAction(i18n("Slow &Motion"), 0, ALT|Key_Left, this, SLOT(slotSlowMotion()), actionCollection(), "player_slowmotion"); + + new KAction(i18n("Skip Forward (20s)"), NULL, Key_Right, this, SLOT(slotPosPlusSmall()), actionCollection(), "player_posplus_small"); + new KAction(i18n("Skip Backward (20s)"), NULL, Key_Left, this, SLOT(slotPosMinusSmall()), actionCollection(), "player_posminus_small"); + new KAction(i18n("Skip Forward (1m)"), NULL, CTRL|Key_PageUp, this, SLOT(slotPosPlusMedium()), actionCollection(), "player_posplus_medium"); + new KAction(i18n("Skip Backward (1m)"), NULL, CTRL|Key_PageDown, this, SLOT(slotPosMinusMedium()), actionCollection(), "player_posminus_medium"); + new KAction(i18n("Skip Forward (10m)"), NULL, ALT|Key_PageUp, this, SLOT(slotPosPlusLarge()), actionCollection(), "player_posplus_large"); + new KAction(i18n("Skip Backward (10m)"), NULL, ALT|Key_PageDown, this, SLOT(slotPosMinusLarge()), actionCollection(), "player_posminus_large"); + new KAction(i18n("Jump to Position..."), "goto", CTRL|Key_J, this, SLOT(slotJumpToPosition()), actionCollection(), "player_jump_to"); + + new KAction(i18n("DVD Menu Left"), 0, CTRL|Key_Left, this, SLOT(slotDVDMenuLeft()), actionCollection(), "dvdmenuleft"); + new KAction(i18n("DVD Menu Right"), 0, CTRL|Key_Right, this, SLOT(slotDVDMenuRight()), actionCollection(), "dvdmenuright"); + new KAction(i18n("DVD Menu Up"), 0, CTRL|Key_Up, this, SLOT(slotDVDMenuUp()), actionCollection(), "dvdmenuup"); + new KAction(i18n("DVD Menu Down"), 0, CTRL|Key_Down, this, SLOT(slotDVDMenuDown()), actionCollection(), "dvdmenudown"); + new KAction(i18n("DVD Menu Select"), 0, CTRL|Key_Return, this, SLOT(slotDVDMenuSelect()), actionCollection(), "dvdmenuselect"); + + m_audioChannels = new KSelectAction(i18n("Audio Channel"), 0, actionCollection(), "audio_channels"); + m_audioChannels->setToolTip(i18n("Select audio channel")); + m_audioChannels->setComboWidth( 50 ); + connect(m_audioChannels, SIGNAL(activated(int)), this, SLOT(slotSetAudioChannel(int ))); + new KAction(i18n("&Next Audio Channel"), 0, 0, this, SLOT(slotNextAudioChannel()), actionCollection(), "next_audio_channels"); + m_audioVisual = new KSelectAction(i18n("Audio &Visualization"), 0, actionCollection(), "audio_visualization"); + connect(m_audioVisual, SIGNAL(activated(const QString&)), m_xine, SLOT(slotSetVisualPlugin(const QString&))); + new KAction(i18n("&Mute"), "player_mute", Key_U, this, SLOT(slotMute()), actionCollection(), "audio_mute"); + new KAction(i18n("Volume Up"), NULL, Key_Plus, this, SLOT(slotVolumeUp()), actionCollection(), "volume_increase"); + new KAction(i18n("Volume Down"), NULL, Key_Minus, this, SLOT(slotVolumeDown()), actionCollection(), "volume_decrease"); + + m_deinterlaceEnabled = new KToggleAction(i18n("&Deinterlace"), 0, Key_I, m_xine, SLOT(slotToggleDeinterlace()), actionCollection(), "video_deinterlace"); + m_deinterlaceEnabled->setWhatsThis(i18n("Activate this for interlaced streams, some DVD's for example.")); + new KAction(i18n("&Auto"), "viewmagfit", Key_F5, m_xine, SLOT(slotAspectRatioAuto()), actionCollection(), "aspect_auto"); + new KAction(i18n("&4:3"), "viewmagfit", Key_F6, m_xine, SLOT(slotAspectRatio4_3()), actionCollection(), "aspect_43"); + new KAction(i18n("A&namorphic"), "viewmagfit", Key_F7, m_xine, SLOT(slotAspectRatioAnamorphic()), actionCollection(), "aspect_anamorphic"); + new KAction(i18n("&DVB"), "viewmagfit", Key_F8, m_xine, SLOT(slotAspectRatioDVB()), actionCollection(), "aspect_dvb"); + new KAction(i18n("&Square"), "viewmagfit", Key_F9, m_xine, SLOT(slotAspectRatioSquare()), actionCollection(), "aspect_square"); + KStdAction::zoomIn(m_xine, SLOT(slotZoomIn()), actionCollection(), "zoom_in"); + KStdAction::zoomOut(m_xine, SLOT(slotZoomOut()), actionCollection(), "zoom_out"); + KStdAction::fitToPage(m_xine, SLOT(slotZoomOff()), actionCollection(), "zoom_off"); + new KAction(i18n("Zoom In Horizontal"), NULL, CTRL|Key_H, m_xine, SLOT(slotZoomInX()), actionCollection(), "zoom_in_x"); + new KAction(i18n("Zoom Out Horizontal"), NULL, CTRL|SHIFT|Key_H, m_xine, SLOT(slotZoomOutX()), actionCollection(), "zoom_out_x"); + new KAction(i18n("Zoom In Vertical"), NULL, CTRL|Key_V, m_xine, SLOT(slotZoomInY()), actionCollection(), "zoom_in_y"); + new KAction(i18n("Zoom Out Vertical"), NULL, CTRL|SHIFT|Key_V, m_xine, SLOT(slotZoomOutY()), actionCollection(), "zoom_out_y"); + new KAction(i18n("Deinterlace &Quality"), "blend", CTRL|Key_I, this, SLOT(slotDeinterlaceQuality()), actionCollection(), "video_deinterlace_quality"); + new KAction(i18n("&Video Settings"), "configure", Key_V, this, SLOT(slotPictureSettings()), actionCollection(), "video_picture"); + new KAction(i18n("&Equalizer"), NULL, Key_E, this, SLOT(slotEqualizer()), actionCollection(), "equalizer"); + + + m_subtitles = new KSelectAction(i18n("Subtitle"), 0, actionCollection(), "player_subtitles"); + m_subtitles->setToolTip(i18n("Select Subtitle")); + m_subtitles->setComboWidth( 50 ); + connect(m_subtitles, SIGNAL(activated(int)), this, SLOT(slotSetSubtitle(int))); + new KAction(i18n("&Next Subtitle Channel"), 0, 0, this, SLOT(slotNextSubtitleChannel()), actionCollection(), "next_player_subtitles"); + new KAction(i18n("Delay Subtitle"), 0, CTRL|ALT|Key_Left, this, SLOT(slotDelaySubTitle()), actionCollection(), "adv_sub"); + new KAction(i18n("Advance Subtitle"), 0, CTRL|ALT|Key_Right, this, SLOT(slotAdvanceSubTitle()), actionCollection(), "delay_sub"); + new KAction(i18n("Add subtitle..."), 0, 0, this, SLOT(slotAddSubtitle()), actionCollection(), "add_subtitle"); + + new KAction(i18n("&Menu Toggle"), "view_detailed", Key_D, m_xine, SLOT(slotMenuToggle()), actionCollection(), "dvd_toggle"); + new KAction(i18n("&Title"), NULL, 0, m_xine, SLOT(slotMenuTitle()), actionCollection(), "dvd_title"); + new KAction(i18n("&Root"), NULL, 0, m_xine, SLOT(slotMenuRoot()), actionCollection(), "dvd_root"); + new KAction(i18n("&Subpicture"), NULL, 0, m_xine, SLOT(slotMenuSubpicture()), actionCollection(), "dvd_subpicture"); + new KAction(i18n("&Audio"), NULL, 0, m_xine, SLOT(slotMenuAudio()), actionCollection(), "dvd_audio"); + new KAction(i18n("An&gle"), NULL, 0, m_xine, SLOT(slotMenuAngle()), actionCollection(), "dvd_angle"); + new KAction(i18n("&Part"), NULL, 0, m_xine, SLOT(slotMenuPart()), actionCollection(), "dvd_part"); + + m_dvdTitles = new KSelectAction(i18n("Titles"), 0, actionCollection(), "dvd_title_menu"); + connect(m_dvdTitles, SIGNAL(activated(const QString&)), this, SLOT(slotSetDVDTitle(const QString&))); + m_dvdChapters = new KSelectAction(i18n("Chapters"), 0, actionCollection(), "dvd_chapter_menu"); + connect(m_dvdChapters, SIGNAL(activated(const QString&)), this, SLOT(slotSetDVDChapter(const QString&))); + m_dvdAngles = new KSelectAction(i18n("Angles"), 0, actionCollection(), "dvd_angle_menu"); + connect(m_dvdAngles, SIGNAL(activated(const QString&)), this, SLOT(slotSetDVDAngle(const QString&))); + + new KAction(i18n("Track &Info"), "info", 0 , this, SLOT(slotInfo()), actionCollection(), "player_track_info"); + new KAction(i18n("Effect &Plugins..."), "filter", Key_X, this, SLOT(slotFilterDialog()), actionCollection(), "player_post_filters"); + + /* settings menu */ + new KAction(i18n("&xine Engine Parameters"), "edit", 0, this, SLOT(slotConfigXine()), actionCollection(), "settings_xine_parameter"); + + m_volume = new VolumeSlider(); + QToolTip::add + (m_volume, i18n("Volume")); + m_volume->setRange(0, 100); + m_volume->setSteps(1, 10); + m_volume->setFocusPolicy(QWidget::NoFocus); + m_volume->setFixedWidth(75); + connect(m_volume, SIGNAL(valueChanged(int)), this, SLOT(slotVolumeChanged(int))); + connect(m_xine, SIGNAL(signalSyncVolume()), this, SLOT(slotSyncVolume())); + new KWidgetAction(m_volume, i18n("Volume"), 0, 0, 0, actionCollection(), "audio_volume"); + + m_position = new PositionSlider(Horizontal); + QToolTip::add + (m_position, i18n("Position")); + m_position->setRange(0, 65535); + m_position->setSteps(100, 1000); + m_position->setTracking(false); + m_position->setFocusPolicy(QWidget::NoFocus); + m_position->setMinimumWidth(180); + connect(m_position, SIGNAL(sliderMoved(int)), m_xine, SLOT(slotSeekToPosition(int))); + connect(m_position, SIGNAL(sliderLastMove(int)), m_xine, SLOT(slotSeekToPositionBlocking(int))); + connect(m_position, SIGNAL(signalStartSeeking()), m_xine, SLOT(slotStartSeeking())); + connect(m_position, SIGNAL(signalStopSeeking()), m_xine, SLOT(slotStopSeeking())); + new KWidgetAction(m_position, i18n("Position"), 0, 0, 0, actionCollection(), "player_position"); + + m_playTime = new QPushButton(0); + QToolTip::add + (m_playTime, i18n("Short click: Toggle Timer Forward/Backward\nLong click: Toggle Timer OSD")); + QFontMetrics met(KGlobalSettings::generalFont()); + m_playTime->setFixedWidth(met.width("-55:55:55") + 6); + m_playTime->setSizePolicy(QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed)); + m_playTime->setFocusPolicy(QWidget::NoFocus); + new KWidgetAction(m_playTime, i18n("Playtime"), 0, 0, 0, actionCollection(), "player_playtime"); + connect(m_playTime, SIGNAL(pressed()), this, SLOT(slotButtonTimerPressed())); + connect(m_playTime, SIGNAL(released()), this, SLOT(slotButtonTimerReleased())); + m_playTime->setText("0:00:00"); + + m_equalizer = new Equalizer(); + connect(m_equalizer, SIGNAL(signalNewEq30(int)), m_xine, SLOT(slotSetEq30(int))); + connect(m_equalizer, SIGNAL(signalNewEq60(int)), m_xine, SLOT(slotSetEq60(int))); + connect(m_equalizer, SIGNAL(signalNewEq125(int)), m_xine, SLOT(slotSetEq125(int))); + connect(m_equalizer, SIGNAL(signalNewEq250(int)), m_xine, SLOT(slotSetEq250(int))); + connect(m_equalizer, SIGNAL(signalNewEq500(int)), m_xine, SLOT(slotSetEq500(int))); + connect(m_equalizer, SIGNAL(signalNewEq1k(int)), m_xine, SLOT(slotSetEq1k(int))); + connect(m_equalizer, SIGNAL(signalNewEq2k(int)), m_xine, SLOT(slotSetEq2k(int))); + connect(m_equalizer, SIGNAL(signalNewEq4k(int)), m_xine, SLOT(slotSetEq4k(int))); + connect(m_equalizer, SIGNAL(signalNewEq8k(int)), m_xine, SLOT(slotSetEq8k(int))); + connect(m_equalizer, SIGNAL(signalNewEq16k(int)), m_xine, SLOT(slotSetEq16k(int))); + connect(m_equalizer, SIGNAL(signalSetVolumeGain(bool)), m_xine, SLOT(slotSetVolumeGain(bool))); + +} + +void XinePart::initConnections() +{ + connect(&m_posCheckTimer, SIGNAL(timeout()), this, SLOT(slotCheckMoved())); + connect(&m_osdTimerEnabler, SIGNAL(timeout()), this, SLOT(slotToggleOsdTimer())); + connect(m_xine, SIGNAL(signalXineReady()), this, SLOT(slotFinalize())); + connect(m_xine, SIGNAL(signalNewChannels(const QStringList&, const QStringList&, int, int )), + this, SLOT(slotChannelInfo(const QStringList&, const QStringList&, int, int ))); + connect(m_xine, SIGNAL(signalXinePlaying()), this, SLOT(slotTrackPlaying())); + connect(m_xine, SIGNAL(signalNewPosition(int, const QTime&)), this, SLOT(slotNewPosition(int, const QTime&))); + connect(m_xine, SIGNAL(signalXineStatus(const QString&)), this, SLOT(slotStatus(const QString&))); + connect(m_xine, SIGNAL(signalXineError(const QString&)), this, SLOT(slotError(const QString&))); + connect(m_xine, SIGNAL(signalXineMessage(const QString&)), this, SLOT(slotMessage(const QString&))); + connect(m_xine, SIGNAL(signalPlaybackFinished()), this, SLOT(slotPlaybackFinished())); + connect(m_xine, SIGNAL(signalTitleChanged()), this, SLOT(slotNewTitle())); + connect(m_xine, SIGNAL(signalLengthChanged()), this, SLOT(slotNewLength())); + connect(m_xine, SIGNAL(signalVideoSizeChanged()), this, SLOT(slotNewFrameSize())); + connect(m_xine, SIGNAL(signalRightClick(const QPoint&)), this, SLOT(slotContextMenu(const QPoint&))); +} + +void XinePart::loadConfig() +{ + kdDebug() << "XinePart: load config" << endl; + + KConfig* config = instance()->config(); + + config->setGroup("General Options"); + if (m_xine->SoftwareMixing()) + { + int vol = config->readNumEntry("Volume", 70); + slotSetVolume(vol); + } + else + slotSyncVolume(); + m_timerDirection = config->readNumEntry("Timer Direction", FORWARD_TIMER); + m_isOsdTimer = config->readBoolEntry("Osd Timer", false); + + config->setGroup("Visualization"); + QString visual = config->readEntry("Visual Plugin", "goom"); + m_audioVisual->setCurrentItem(m_audioVisual->items().findIndex(visual)); + m_xine->slotSetVisualPlugin(visual); + + config->setGroup("Deinterlace"); + m_lastDeinterlaceQuality = config->readNumEntry("Quality Level", 4); + m_lastDeinterlacerConfig = config->readEntry("Config String", DEFAULT_TVTIME_CONFIG); + DeinterlacerConfigDialog* deinterlacerConfigDialog = new DeinterlacerConfigDialog(); + m_xine->createDeinterlacePlugin(m_lastDeinterlacerConfig, deinterlacerConfigDialog->getMainWidget()); + m_deinterlacerConfigWidget = (QWidget*)deinterlacerConfigDialog; + bool deinterlaceEnabled = config->readBoolEntry("Enabled", true); + if (deinterlaceEnabled) + { + m_deinterlaceEnabled->setChecked(deinterlaceEnabled); + m_xine->slotToggleDeinterlace(); + } + + config->setGroup("Broadcasting Options"); + m_broadcastPort = config->readNumEntry("Port", 8080); + m_broadcastAddress = config->readEntry("Master Address", "localhost"); + + config->setGroup( "Video Settings" ); + slotSetHue(config->readNumEntry( "Hue", -1)); + slotSetSaturation(config->readNumEntry( "Saturation", -1)); + slotSetContrast(config->readNumEntry( "Contrast", -1)); + slotSetBrightness(config->readNumEntry( "Brigthness", -1)); + + m_equalizer->ReadValues(config); +} + +void XinePart::saveConfig() +{ + if (!m_audioVisual->items().count()) // no config loaded + return; + + kdDebug() << "XinePart: save config" << endl; + + KConfig* config = instance()->config(); + + config->setGroup("General Options"); + config->writeEntry("Volume", m_volume->value()); + config->writeEntry("Timer Direction", m_timerDirection); + config->writeEntry("Osd Timer", m_isOsdTimer); + + config->setGroup("Visualization"); + config->writeEntry("Visual Plugin", m_audioVisual->currentText()); + + config->setGroup("Deinterlace"); + config->writeEntry("Quality Level", m_lastDeinterlaceQuality); + config->writeEntry("Config String", m_lastDeinterlacerConfig); + config->writeEntry("Enabled", m_deinterlaceEnabled->isChecked()); + + config->setGroup("Broadcasting Options"); + config->writeEntry("Port", m_broadcastPort); + config->writeEntry("Master Address", m_broadcastAddress); + + config->setGroup( "Video Settings" ); + config->writeEntry( "Hue", m_hue ); + config->writeEntry( "Saturation", m_saturation ); + config->writeEntry( "Contrast", m_contrast ); + config->writeEntry( "Brigthness", m_brightness ); + + m_equalizer->SaveValues(config); +} + +/* check if shell was moved, send new global position + of the part to xine */ +void XinePart::slotCheckMoved() +{ + QPoint newPos = m_xine->mapToGlobal(QPoint(0,0)); + if (newPos != m_oldPosition) + { + m_xine->globalPosChanged(); + m_oldPosition = newPos; + } +} + +bool XinePart::isPlaying() +{ + return m_xine->isPlaying(); +} + +bool XinePart::isPaused() +{ + return (m_xine->getSpeed() == KXineWidget::Pause); +} + +#if 0 +void XinePart::audiocdMRLS(MRL::List& mrls, bool& ok, bool& supported, const QString& device) +{ + if (!m_xine->isXineReady()) + { + if (!m_xine->initXine()) + { + supported = false; + return; + } + } + supported = true; + + if (!device.isNull()) + m_xine->slotSetAudiocdDevice(device); + + QStringList list; + if (!m_xine->getAutoplayPluginURLS("CD", list)) + { + ok = false; + return; + } + + MRL mrl; + /* use xine to connect to CDDB */ + xine_stream_t* xineStreamForMeta = xine_stream_new((xine_t*)m_xine->getXineEngine(), NULL, NULL); + + KProgressDialog* progress = new KProgressDialog(0, "cddbprogress", QString::null, i18n("Looking for CDDB entries...")); + progress->progressBar()->setTotalSteps(list.count()); + progress->show(); + QString title; + bool cddb = true; + for (uint i = 0; i < list.count(); i++) + { + mrl = MRL(list[i]); + mrl.setTitle(i18n("AudioCD Track %1").arg(i+1)); + mrl.setTrack(QString::number(i+1)); + if (xine_open(xineStreamForMeta, QFile::encodeName(mrl.url()))) + { + if (cddb) + { + title = QString::fromUtf8(xine_get_meta_info(xineStreamForMeta, XINE_META_INFO_TITLE)); + if ((!title.isNull()) && (!title.isEmpty()) ) //no meta info + { + mrl.setTitle(title); + mrl.setArtist(QString::fromUtf8(xine_get_meta_info(xineStreamForMeta, XINE_META_INFO_ARTIST))); + mrl.setAlbum(QString::fromUtf8(xine_get_meta_info(xineStreamForMeta, XINE_META_INFO_ALBUM))); + mrl.setYear(QString::fromUtf8(xine_get_meta_info(xineStreamForMeta, XINE_META_INFO_YEAR))); + mrl.setGenre(QString::fromUtf8(xine_get_meta_info(xineStreamForMeta, XINE_META_INFO_GENRE))); + mrl.setTrack(QString::number(i+1)); + } + else + cddb = false; + } + + int pos, time, len; + int t = 0, ret = 0; + while(((ret = xine_get_pos_length(xineStreamForMeta, &pos, &time, &len)) == 0) && (++t < 5)) + xine_usec_sleep(100000); + if ( ( ret != 0 ) && (len > 0) ) + mrl.setLength(QTime().addMSecs(len)); + + xine_close( xineStreamForMeta ); + } + + mrl.setMime("audio/cd"); + mrls.append(mrl); + if (progress->wasCancelled()) + break; + progress->progressBar()->setProgress(i+1); + KApplication::kApplication()->processEvents(); + } + + xine_dispose(xineStreamForMeta); + delete progress; + if (mrls.count()) + ok = true; +} + +void XinePart::vcdMRLS(MRL::List& mrls, bool& ok, bool& supported, const QString& device) +{ + if (!m_xine->isXineReady()) + { + if (!m_xine->initXine()) + { + supported = false; + return; + } + } + supported = true; + + if (!device.isNull()) + m_xine->slotSetVcdDevice(device); + + QStringList list; + if (!m_xine->getAutoplayPluginURLS("VCD", list)) + { + if (!m_xine->getAutoplayPluginURLS("VCDO", list)) + { + ok = false; + return; + } + } + + MRL mrl; + for (uint i = 0; i < list.count(); i++) + { + mrl = MRL(list[i]); + mrl.setMime("video/vcd"); + mrl.setTrack(QString::number(i+1)); + mrl.setTitle(i18n("VCD Track %1").arg(i+1)); + mrls.append(mrl); + } + if (mrls.count()) + ok = true; +} + +void XinePart::dvdMRLS(MRL::List& mrls, bool& ok, bool& supported, const QString& device) +{ + if (!m_xine->isXineReady()) + { + if (!m_xine->initXine()) + { + supported = false; + return; + } + } + supported = true; + + if (!device.isNull()) + m_xine->slotSetDvdDevice(device); + + QStringList list; + if (!m_xine->getAutoplayPluginURLS("DVD", list)) + { + ok = false; + return; + } + + MRL mrl; + for (uint i = 0; i < list.count(); i++) + { + mrl = MRL(list[i]); + mrl.setMime("video/dvd"); + mrl.setTitle("DVD"); + mrl.setTrack(QString::number(i+1)); + mrls.append(mrl); + } + if (mrls.count()) + ok = true; +} +#endif + +bool XinePart::hasChapters() +{ + if (m_xine->isXineReady()) + return m_xine->hasChapters(); + else + return false; +} + +bool XinePart::hasVideo() +{ + return m_xine->hasVideo(); +} + +void XinePart::playNextChapter() +{ + if (m_xine->isXineReady()) + m_xine->playNextChapter(); +} + +void XinePart::playPreviousChapter() +{ + if (m_xine->isXineReady()) + m_xine->playPreviousChapter(); +} + +void XinePart::slotPrepareForFullscreen(bool fullscreen) +{ + if (fullscreen) + m_xine->startMouseHideTimer(); + else + m_xine->stopMouseHideTimer(); +} + +uint XinePart::volume() const +{ + if (!m_xine->isXineReady()) + return 0; + + return m_xine->getVolume(); +} + +uint XinePart::position() const +{ + if (!m_xine->isXineReady()) + return 0; + + if ( m_xine->isPlaying() ) + return currentPosition; + else + return 0; +} + +void XinePart::slotSetVolume(uint vol) +{ + if (!m_xine->isXineReady()) + return; + + kdDebug() << "Set volume to: " << vol << endl; + m_volume->setValue(vol); +} + +void XinePart::slotVolumeChanged(int vol) +{ + m_xine->slotSetVolume(vol); +} + +void XinePart::slotSyncVolume() +{ + if (!m_xine->isXineReady()) + return; + + uint vol = volume(); + slotSetVolume(vol); +} + +void XinePart::slotSetPosition(uint pos) +{ + if (!m_xine->isXineReady()) + return; + + m_xine->slotSeekToPosition((int)(pos * 655.35)); +} + +QString XinePart::supportedExtensions() +{ + if (!m_xine->isXineReady()) + return QString::null; + + QString ext = m_xine->getSupportedExtensions(); + ext = ext.remove("txt"); + ext = "*." + ext; + ext.append(" smil"); + ext = ext.replace( ' ', " *." ); + ext = ext + " " + ext.upper(); + + return ext; +} + +void* XinePart::engine() +{ + if (!m_xine->isXineReady()) + return NULL; + + return (void*)m_xine->getXineEngine(); +} + +void XinePart::slotDisableAllActions() +{ + stateChanged("xine_not_ready"); +} + +void XinePart::slotEnableAllActions() +{ + stateChanged("xine_not_ready", StateReverse); + stateChanged("not_playing"); +} + +void XinePart::slotEnablePlayActions() +{ + if ((m_playlist.count() > 1) || (m_xine->hasChapters())) // we need next/previous buttons + stateChanged("play_multiple_tracks"); + else + stateChanged("play_single_track"); +} + +void XinePart::slotNextAudioChannel() +{ + nextAudioChannel(); +} + +void XinePart::slotNextSubtitleChannel() +{ + nextSubtitleChannel(); +} + +/********* DCOP INTERFACE *********/ + +void XinePart::nextAudioChannel() +{ + int num = m_audioChannels->items().count(); + int index = m_audioChannels->currentItem()+1; + if ( index>=num ) + index = 0; + m_audioChannels->setCurrentItem( index ); + slotSetAudioChannel( index ); +} + +void XinePart::nextSubtitleChannel() +{ + int num = m_subtitles->items().count(); + int index = m_subtitles->currentItem()+1; + if ( index>=num ) + index = 0; + m_subtitles->setCurrentItem( index ); + slotSetSubtitle( index ); +} + +int XinePart::getContrast() +{ + int hue, sat, contrast, bright, avOffset, spuOffset; + if (!m_xine->isXineReady()) + return -1; + m_xine->getVideoSettings(hue, sat, contrast, bright, avOffset, spuOffset); + return contrast; +} + +void XinePart::setContrast(int c) +{ + if (!m_xine->isXineReady()) + return; + m_xine->slotSetContrast(c); +} + +int XinePart::getBrightness() +{ + int hue, sat, contrast, bright, avOffset, spuOffset; + if (!m_xine->isXineReady()) + return -1; + m_xine->getVideoSettings(hue, sat, contrast, bright, avOffset, spuOffset); + return bright; +} + +void XinePart::setBrightness(int b) +{ + if (!m_xine->isXineReady()) + return; + m_xine->slotSetBrightness(b); +} + +void XinePart::dvdMenuUp() +{ + if (!m_xine->isXineReady()) + return; + m_xine->slotDVDMenuUp(); +} + +void XinePart::dvdMenuDown() +{ + if (!m_xine->isXineReady()) + return; + m_xine->slotDVDMenuDown(); +} + +void XinePart::dvdMenuLeft() +{ + if (!m_xine->isXineReady()) + return; + m_xine->slotDVDMenuLeft(); +} + +void XinePart::dvdMenuRight() +{ + if (!m_xine->isXineReady()) + return; + m_xine->slotDVDMenuRight(); +} + +void XinePart::dvdMenuSelect() +{ + if (!m_xine->isXineReady()) + return; + m_xine->slotDVDMenuSelect(); +} + +void XinePart::dvdMenuToggle() +{ + if (!m_xine->isXineReady()) + return; + m_xine->slotMenuToggle(); +} + +void XinePart::aspectRatioAuto() +{ + if (!m_xine->isXineReady()) + return; + m_xine->slotAspectRatioAuto(); +} + +void XinePart::aspectRatio4_3() +{ + if (!m_xine->isXineReady()) + return; + m_xine->slotAspectRatio4_3(); +} + +void XinePart::aspectRatioAnamorphic() +{ + if (!m_xine->isXineReady()) + return; + m_xine->slotAspectRatioAnamorphic(); +} + +void XinePart::aspectRatioSquare() +{ + if (!m_xine->isXineReady()) + return; + m_xine->slotAspectRatioSquare(); +} + +void XinePart::aspectRatioDVB() +{ + if (!m_xine->isXineReady()) + return; + m_xine->slotAspectRatioDVB(); +} + +void XinePart::zoomInX() +{ + if (!m_xine->isXineReady()) + return; + m_xine->slotZoomInX(); +} + +void XinePart::zoomOutX() +{ + if (!m_xine->isXineReady()) + return; + m_xine->slotZoomOutX(); +} + +void XinePart::zoomInY() +{ + if (!m_xine->isXineReady()) + return; + m_xine->slotZoomInY(); +} + +void XinePart::zoomOutY() +{ + if (!m_xine->isXineReady()) + return; + m_xine->slotZoomOutY(); +} + +void XinePart::zoomIn() +{ + if (!m_xine->isXineReady()) + return; + m_xine->slotZoomIn(); +} + +void XinePart::zoomOut() +{ + if (!m_xine->isXineReady()) + return; + m_xine->slotZoomOut(); +} + +void XinePart::zoomOff() +{ + if (!m_xine->isXineReady()) + return; + m_xine->slotZoomOff(); +} + + + +/********** volume slider ****************/ + + +VolumeSlider::VolumeSlider() : QSlider(Horizontal, 0) +{ + installEventFilter(this); +} + +VolumeSlider::~VolumeSlider() +{} + +void VolumeSlider::wheelEvent(QWheelEvent* e) +{ + int newVal = value(); + if (e->delta() > 0) + newVal -= 5; + else if (e->delta() < 0) + newVal += 5; + setValue(newVal); + e->accept(); +} + +/*bool VolumeSlider::eventFilter(QObject *obj, QEvent *ev) +{ + if( obj == this && (ev->type() == QEvent::MouseButtonPress || + ev->type() == QEvent::MouseButtonDblClick) ) + { + QMouseEvent *e = (QMouseEvent *)ev; + QRect r = sliderRect(); + + if( r.contains( e->pos() ) || e->button() != LeftButton ) + return FALSE; + + int range = maxValue() - minValue(); + int pos = (orientation() == Horizontal) ? e->pos().x() : e->pos().y(); + int maxpos = (orientation() == Horizontal) ? width() : height(); + int value = pos * range / maxpos + minValue(); + + if (QApplication::reverseLayout()) + value = maxValue() - (value - minValue()); + + setValue(value); + return TRUE; + } + else + { + return FALSE; + } +}*/ + +#include "xine_part.moc" |