kylin-video/0000775000175000017500000000000013261126064011733 5ustar fengfengkylin-video/src/0000775000175000017500000000000013261115371012521 5ustar fengfengkylin-video/src/qtsingleapplication/0000775000175000017500000000000013261113470016571 5ustar fengfengkylin-video/src/qtsingleapplication/qtlockedfile_win.cpp0000664000175000017500000001466113214347337022641 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qtlockedfile.h" #include #include #define MUTEX_PREFIX "QtLockedFile mutex " // Maximum number of concurrent read locks. Must not be greater than MAXIMUM_WAIT_OBJECTS #define MAX_READERS MAXIMUM_WAIT_OBJECTS #if QT_VERSION >= 0x050000 #define QT_WA(unicode, ansi) unicode #endif Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate) { if (mutexname.isEmpty()) { QFileInfo fi(*this); mutexname = QString::fromLatin1(MUTEX_PREFIX) + fi.absoluteFilePath().toLower(); } QString mname(mutexname); if (idx >= 0) mname += QString::number(idx); Qt::HANDLE mutex; if (doCreate) { QT_WA( { mutex = CreateMutexW(NULL, FALSE, (TCHAR*)mname.utf16()); }, { mutex = CreateMutexA(NULL, FALSE, mname.toLocal8Bit().constData()); } ); if (!mutex) { qErrnoWarning("QtLockedFile::lock(): CreateMutex failed"); return 0; } } else { QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (TCHAR*)mname.utf16()); }, { mutex = OpenMutexA(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, mname.toLocal8Bit().constData()); } ); if (!mutex) { if (GetLastError() != ERROR_FILE_NOT_FOUND) qErrnoWarning("QtLockedFile::lock(): OpenMutex failed"); return 0; } } return mutex; } bool QtLockedFile::waitMutex(Qt::HANDLE mutex, bool doBlock) { Q_ASSERT(mutex); DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0); switch (res) { case WAIT_OBJECT_0: case WAIT_ABANDONED: return true; break; case WAIT_TIMEOUT: break; default: qErrnoWarning("QtLockedFile::lock(): WaitForSingleObject failed"); } return false; } bool QtLockedFile::lock(LockMode mode, bool block) { if (!isOpen()) { qWarning("QtLockedFile::lock(): file is not opened"); return false; } if (mode == NoLock) return unlock(); if (mode == m_lock_mode) return true; if (m_lock_mode != NoLock) unlock(); if (!wmutex && !(wmutex = getMutexHandle(-1, true))) return false; if (!waitMutex(wmutex, block)) return false; if (mode == ReadLock) { int idx = 0; for (; idx < MAX_READERS; idx++) { rmutex = getMutexHandle(idx, false); if (!rmutex || waitMutex(rmutex, false)) break; CloseHandle(rmutex); } bool ok = true; if (idx >= MAX_READERS) { qWarning("QtLockedFile::lock(): too many readers"); rmutex = 0; ok = false; } else if (!rmutex) { rmutex = getMutexHandle(idx, true); if (!rmutex || !waitMutex(rmutex, false)) ok = false; } if (!ok && rmutex) { CloseHandle(rmutex); rmutex = 0; } ReleaseMutex(wmutex); if (!ok) return false; } else { Q_ASSERT(rmutexes.isEmpty()); for (int i = 0; i < MAX_READERS; i++) { Qt::HANDLE mutex = getMutexHandle(i, false); if (mutex) rmutexes.append(mutex); } if (rmutexes.size()) { DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(), TRUE, block ? INFINITE : 0); if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) { if (res != WAIT_TIMEOUT) qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed"); m_lock_mode = WriteLock; // trick unlock() to clean up - semiyucky unlock(); return false; } } } m_lock_mode = mode; return true; } bool QtLockedFile::unlock() { if (!isOpen()) { qWarning("QtLockedFile::unlock(): file is not opened"); return false; } if (!isLocked()) return true; if (m_lock_mode == ReadLock) { ReleaseMutex(rmutex); CloseHandle(rmutex); rmutex = 0; } else { foreach(Qt::HANDLE mutex, rmutexes) { ReleaseMutex(mutex); CloseHandle(mutex); } rmutexes.clear(); ReleaseMutex(wmutex); } m_lock_mode = QtLockedFile::NoLock; return true; } QtLockedFile::~QtLockedFile() { if (isOpen()) unlock(); if (wmutex) CloseHandle(wmutex); } kylin-video/src/qtsingleapplication/qtlocalpeer.h0000664000175000017500000000520513214347337021270 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QTLOCALPEER_H #define QTLOCALPEER_H #include #include #include #include "qtlockedfile.h" class QtLocalPeer : public QObject { Q_OBJECT public: QtLocalPeer(QObject *parent = 0, const QString &appId = QString()); bool isClient(); bool sendMessage(const QString &message, int timeout); QString applicationId() const { return id; } Q_SIGNALS: void messageReceived(const QString &message); protected Q_SLOTS: void receiveConnection(); protected: QString id; QString socketName; QLocalServer* server; QtLP_Private::QtLockedFile lockFile; private: static const char* ack; }; #endif // QTLOCALPEER_H kylin-video/src/qtsingleapplication/qtlockedfile.cpp0000664000175000017500000001374213214347337021763 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qtlockedfile.h" /*! \class QtLockedFile \brief The QtLockedFile class extends QFile with advisory locking functions. A file may be locked in read or write mode. Multiple instances of \e QtLockedFile, created in multiple processes running on the same machine, may have a file locked in read mode. Exactly one instance may have it locked in write mode. A read and a write lock cannot exist simultaneously on the same file. The file locks are advisory. This means that nothing prevents another process from manipulating a locked file using QFile or file system functions offered by the OS. Serialization is only guaranteed if all processes that access the file use QLockedFile. Also, while holding a lock on a file, a process must not open the same file again (through any API), or locks can be unexpectedly lost. The lock provided by an instance of \e QtLockedFile is released whenever the program terminates. This is true even when the program crashes and no destructors are called. */ /*! \enum QtLockedFile::LockMode This enum describes the available lock modes. \value ReadLock A read lock. \value WriteLock A write lock. \value NoLock Neither a read lock nor a write lock. */ /*! Constructs an unlocked \e QtLockedFile object. This constructor behaves in the same way as \e QFile::QFile(). \sa QFile::QFile() */ QtLockedFile::QtLockedFile() : QFile() { #ifdef Q_OS_WIN wmutex = 0; rmutex = 0; #endif m_lock_mode = NoLock; } /*! Constructs an unlocked QtLockedFile object with file \a name. This constructor behaves in the same way as \e QFile::QFile(const QString&). \sa QFile::QFile() */ QtLockedFile::QtLockedFile(const QString &name) : QFile(name) { #ifdef Q_OS_WIN wmutex = 0; rmutex = 0; #endif m_lock_mode = NoLock; } /*! Opens the file in OpenMode \a mode. This is identical to QFile::open(), with the one exception that the Truncate mode flag is disallowed. Truncation would conflict with the advisory file locking, since the file would be modified before the write lock is obtained. If truncation is required, use resize(0) after obtaining the write lock. Returns true if successful; otherwise false. \sa QFile::open(), QFile::resize() */ bool QtLockedFile::open(OpenMode mode) { if (mode & QIODevice::Truncate) { qWarning("QtLockedFile::open(): Truncate mode not allowed."); return false; } return QFile::open(mode); } /*! Returns \e true if this object has a in read or write lock; otherwise returns \e false. \sa lockMode() */ bool QtLockedFile::isLocked() const { return m_lock_mode != NoLock; } /*! Returns the type of lock currently held by this object, or \e QtLockedFile::NoLock. \sa isLocked() */ QtLockedFile::LockMode QtLockedFile::lockMode() const { return m_lock_mode; } /*! \fn bool QtLockedFile::lock(LockMode mode, bool block = true) Obtains a lock of type \a mode. The file must be opened before it can be locked. If \a block is true, this function will block until the lock is aquired. If \a block is false, this function returns \e false immediately if the lock cannot be aquired. If this object already has a lock of type \a mode, this function returns \e true immediately. If this object has a lock of a different type than \a mode, the lock is first released and then a new lock is obtained. This function returns \e true if, after it executes, the file is locked by this object, and \e false otherwise. \sa unlock(), isLocked(), lockMode() */ /*! \fn bool QtLockedFile::unlock() Releases a lock. If the object has no lock, this function returns immediately. This function returns \e true if, after it executes, the file is not locked by this object, and \e false otherwise. \sa lock(), isLocked(), lockMode() */ /*! \fn QtLockedFile::~QtLockedFile() Destroys the \e QtLockedFile object. If any locks were held, they are released. */ kylin-video/src/qtsingleapplication/qtlocalpeer.cpp0000664000175000017500000001507013214347337021624 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qtlocalpeer.h" #include #include #include #if defined(Q_OS_WIN) #include #include typedef BOOL(WINAPI*PProcessIdToSessionId)(DWORD,DWORD*); static PProcessIdToSessionId pProcessIdToSessionId = 0; #endif #if defined(Q_OS_UNIX) #include #include #include #endif namespace QtLP_Private { #include "qtlockedfile.cpp" #if defined(Q_OS_WIN) #include "qtlockedfile_win.cpp" #else #include "qtlockedfile_unix.cpp" #endif } const char* QtLocalPeer::ack = "ack"; QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId) : QObject(parent), id(appId) { QString prefix = id; if (id.isEmpty()) { id = QCoreApplication::applicationFilePath(); #if defined(Q_OS_WIN) id = id.toLower(); #endif prefix = id.section(QLatin1Char('/'), -1); } prefix.remove(QRegExp("[^a-zA-Z]")); prefix.truncate(6); QByteArray idc = id.toUtf8(); quint16 idNum = qChecksum(idc.constData(), idc.size()); socketName = QLatin1String("qtsingleapp-") + prefix + QLatin1Char('-') + QString::number(idNum, 16); #if defined(Q_OS_WIN) if (!pProcessIdToSessionId) { QLibrary lib("kernel32"); pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId"); } if (pProcessIdToSessionId) { DWORD sessionId = 0; pProcessIdToSessionId(GetCurrentProcessId(), &sessionId); socketName += QLatin1Char('-') + QString::number(sessionId, 16); } #else socketName += QLatin1Char('-') + QString::number(::getuid(), 16); #endif server = new QLocalServer(this); QString lockName = QDir(QDir::tempPath()).absolutePath() + QLatin1Char('/') + socketName + QLatin1String("-lockfile"); lockFile.setFileName(lockName); lockFile.open(QIODevice::ReadWrite); } bool QtLocalPeer::isClient() { if (lockFile.isLocked()) return false; if (!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false)) return true; bool res = server->listen(socketName); #if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(4,5,0)) // ### Workaround if (!res && server->serverError() == QAbstractSocket::AddressInUseError) { QFile::remove(QDir::cleanPath(QDir::tempPath())+QLatin1Char('/')+socketName); res = server->listen(socketName); } #endif if (!res) qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString())); QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection())); return false; } bool QtLocalPeer::sendMessage(const QString &message, int timeout) { if (!isClient()) return false; QLocalSocket socket; bool connOk = false; for(int i = 0; i < 2; i++) { // Try twice, in case the other instance is just starting up socket.connectToServer(socketName); connOk = socket.waitForConnected(timeout/2); if (connOk || i) break; int ms = 250; #if defined(Q_OS_WIN) Sleep(DWORD(ms)); #else struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; nanosleep(&ts, NULL); #endif } if (!connOk) return false; QByteArray uMsg(message.toUtf8()); QDataStream ds(&socket); ds.writeBytes(uMsg.constData(), uMsg.size()); bool res = socket.waitForBytesWritten(timeout); if (res) { res &= socket.waitForReadyRead(timeout); // wait for ack if (res) res &= (socket.read(qstrlen(ack)) == ack); } return res; } void QtLocalPeer::receiveConnection() { QLocalSocket* socket = server->nextPendingConnection(); if (!socket) return; while (socket->bytesAvailable() < (int)sizeof(quint32)) socket->waitForReadyRead(); QDataStream ds(socket); QByteArray uMsg; quint32 remaining; ds >> remaining; uMsg.resize(remaining); int got = 0; char* uMsgBuf = uMsg.data(); do { got = ds.readRawData(uMsgBuf, remaining); remaining -= got; uMsgBuf += got; } while (remaining && got >= 0 && socket->waitForReadyRead(2000)); if (got < 0) { qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData()); delete socket; return; } QString message(QString::fromUtf8(uMsg)); socket->write(ack, qstrlen(ack)); socket->waitForBytesWritten(1000); socket->waitForDisconnected(1000); // make sure client reads ack delete socket; emit messageReceived(message); //### (might take a long time to return) } kylin-video/src/qtsingleapplication/QtSingleApplication0000664000175000017500000000004113214347337022432 0ustar fengfeng#include "qtsingleapplication.h" kylin-video/src/qtsingleapplication/qtsinglecoreapplication.pri0000664000175000017500000000050413214347337024240 0ustar fengfengINCLUDEPATH += $$PWD DEPENDPATH += $$PWD HEADERS += $$PWD/qtsinglecoreapplication.h $$PWD/qtlocalpeer.h SOURCES += $$PWD/qtsinglecoreapplication.cpp $$PWD/qtlocalpeer.cpp QT *= network win32:contains(TEMPLATE, lib):contains(CONFIG, shared) { DEFINES += QT_QTSINGLECOREAPPLICATION_EXPORT=__declspec(dllexport) } kylin-video/src/qtsingleapplication/qtsingleapplication.pri0000664000175000017500000000111013214347337023361 0ustar fengfenginclude(../common.pri) INCLUDEPATH += $$PWD DEPENDPATH += $$PWD QT *= network greaterThan(QT_MAJOR_VERSION, 4): QT *= widgets qtsingleapplication-uselib:!qtsingleapplication-buildlib { LIBS += -L$$QTSINGLEAPPLICATION_LIBDIR -l$$QTSINGLEAPPLICATION_LIBNAME } else { SOURCES += $$PWD/qtsingleapplication.cpp $$PWD/qtlocalpeer.cpp HEADERS += $$PWD/qtsingleapplication.h $$PWD/qtlocalpeer.h } win32 { contains(TEMPLATE, lib):contains(CONFIG, shared):DEFINES += QT_QTSINGLEAPPLICATION_EXPORT else:qtsingleapplication-uselib:DEFINES += QT_QTSINGLEAPPLICATION_IMPORT } kylin-video/src/qtsingleapplication/qtsingleapplication.h0000664000175000017500000000761713214347337023040 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QTSINGLEAPPLICATION_H #define QTSINGLEAPPLICATION_H #include class QtLocalPeer; #if defined(Q_OS_WIN) # if !defined(QT_QTSINGLEAPPLICATION_EXPORT) && !defined(QT_QTSINGLEAPPLICATION_IMPORT) # define QT_QTSINGLEAPPLICATION_EXPORT # elif defined(QT_QTSINGLEAPPLICATION_IMPORT) # if defined(QT_QTSINGLEAPPLICATION_EXPORT) # undef QT_QTSINGLEAPPLICATION_EXPORT # endif # define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllimport) # elif defined(QT_QTSINGLEAPPLICATION_EXPORT) # undef QT_QTSINGLEAPPLICATION_EXPORT # define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllexport) # endif #else # define QT_QTSINGLEAPPLICATION_EXPORT #endif class QT_QTSINGLEAPPLICATION_EXPORT QtSingleApplication : public QApplication { Q_OBJECT public: QtSingleApplication(int &argc, char **argv, bool GUIenabled = true); QtSingleApplication(const QString &id, int &argc, char **argv); #if QT_VERSION < 0x050000 QtSingleApplication(int &argc, char **argv, Type type); # if defined(Q_WS_X11) QtSingleApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0); QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0); QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0); # endif // Q_WS_X11 #endif // QT_VERSION < 0x050000 bool isRunning(); QString id() const; void setActivationWindow(QWidget* aw, bool activateOnMessage = true); QWidget* activationWindow() const; // Obsolete: void initialize(bool dummy = true) { isRunning(); Q_UNUSED(dummy) } public Q_SLOTS: bool sendMessage(const QString &message, int timeout = 5000); void activateWindow(); Q_SIGNALS: void messageReceived(const QString &message); private: void sysInit(const QString &appId = QString()); QtLocalPeer *peer; QWidget *actWin; }; #endif // QTSINGLEAPPLICATION_H kylin-video/src/qtsingleapplication/qtsingleapplication.cpp0000664000175000017500000002701013214347337023360 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qtsingleapplication.h" #include "qtlocalpeer.h" #include /*! \class QtSingleApplication qtsingleapplication.h \brief The QtSingleApplication class provides an API to detect and communicate with running instances of an application. This class allows you to create applications where only one instance should be running at a time. I.e., if the user tries to launch another instance, the already running instance will be activated instead. Another usecase is a client-server system, where the first started instance will assume the role of server, and the later instances will act as clients of that server. By default, the full path of the executable file is used to determine whether two processes are instances of the same application. You can also provide an explicit identifier string that will be compared instead. The application should create the QtSingleApplication object early in the startup phase, and call isRunning() to find out if another instance of this application is already running. If isRunning() returns false, it means that no other instance is running, and this instance has assumed the role as the running instance. In this case, the application should continue with the initialization of the application user interface before entering the event loop with exec(), as normal. The messageReceived() signal will be emitted when the running application receives messages from another instance of the same application. When a message is received it might be helpful to the user to raise the application so that it becomes visible. To facilitate this, QtSingleApplication provides the setActivationWindow() function and the activateWindow() slot. If isRunning() returns true, another instance is already running. It may be alerted to the fact that another instance has started by using the sendMessage() function. Also data such as startup parameters (e.g. the name of the file the user wanted this new instance to open) can be passed to the running instance with this function. Then, the application should terminate (or enter client mode). If isRunning() returns true, but sendMessage() fails, that is an indication that the running instance is frozen. Here's an example that shows how to convert an existing application to use QtSingleApplication. It is very simple and does not make use of all QtSingleApplication's functionality (see the examples for that). \code // Original int main(int argc, char **argv) { QApplication app(argc, argv); MyMainWidget mmw; mmw.show(); return app.exec(); } // Single instance int main(int argc, char **argv) { QtSingleApplication app(argc, argv); if (app.isRunning()) return !app.sendMessage(someDataString); MyMainWidget mmw; app.setActivationWindow(&mmw); mmw.show(); return app.exec(); } \endcode Once this QtSingleApplication instance is destroyed (normally when the process exits or crashes), when the user next attempts to run the application this instance will not, of course, be encountered. The next instance to call isRunning() or sendMessage() will assume the role as the new running instance. For console (non-GUI) applications, QtSingleCoreApplication may be used instead of this class, to avoid the dependency on the QtGui library. \sa QtSingleCoreApplication */ void QtSingleApplication::sysInit(const QString &appId) { actWin = 0; peer = new QtLocalPeer(this, appId); connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); } /*! Creates a QtSingleApplication object. The application identifier will be QCoreApplication::applicationFilePath(). \a argc, \a argv, and \a GUIenabled are passed on to the QAppliation constructor. If you are creating a console application (i.e. setting \a GUIenabled to false), you may consider using QtSingleCoreApplication instead. */ QtSingleApplication::QtSingleApplication(int &argc, char **argv, bool GUIenabled) : QApplication(argc, argv, GUIenabled) { sysInit(); } /*! Creates a QtSingleApplication object with the application identifier \a appId. \a argc and \a argv are passed on to the QAppliation constructor. */ QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char **argv) : QApplication(argc, argv) { sysInit(appId); } #if QT_VERSION < 0x050000 /*! Creates a QtSingleApplication object. The application identifier will be QCoreApplication::applicationFilePath(). \a argc, \a argv, and \a type are passed on to the QAppliation constructor. */ QtSingleApplication::QtSingleApplication(int &argc, char **argv, Type type) : QApplication(argc, argv, type) { sysInit(); } # if defined(Q_WS_X11) /*! Special constructor for X11, ref. the documentation of QApplication's corresponding constructor. The application identifier will be QCoreApplication::applicationFilePath(). \a dpy, \a visual, and \a cmap are passed on to the QApplication constructor. */ QtSingleApplication::QtSingleApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE cmap) : QApplication(dpy, visual, cmap) { sysInit(); } /*! Special constructor for X11, ref. the documentation of QApplication's corresponding constructor. The application identifier will be QCoreApplication::applicationFilePath(). \a dpy, \a argc, \a argv, \a visual, and \a cmap are passed on to the QApplication constructor. */ QtSingleApplication::QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap) : QApplication(dpy, argc, argv, visual, cmap) { sysInit(); } /*! Special constructor for X11, ref. the documentation of QApplication's corresponding constructor. The application identifier will be \a appId. \a dpy, \a argc, \a argv, \a visual, and \a cmap are passed on to the QApplication constructor. */ QtSingleApplication::QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap) : QApplication(dpy, argc, argv, visual, cmap) { sysInit(appId); } # endif // Q_WS_X11 #endif // QT_VERSION < 0x050000 /*! Returns true if another instance of this application is running; otherwise false. This function does not find instances of this application that are being run by a different user (on Windows: that are running in another session). \sa sendMessage() */ bool QtSingleApplication::isRunning() { return peer->isClient(); } /*! Tries to send the text \a message to the currently running instance. The QtSingleApplication object in the running instance will emit the messageReceived() signal when it receives the message. This function returns true if the message has been sent to, and processed by, the current instance. If there is no instance currently running, or if the running instance fails to process the message within \a timeout milliseconds, this function return false. \sa isRunning(), messageReceived() */ bool QtSingleApplication::sendMessage(const QString &message, int timeout) { return peer->sendMessage(message, timeout); } /*! Returns the application identifier. Two processes with the same identifier will be regarded as instances of the same application. */ QString QtSingleApplication::id() const { return peer->applicationId(); } /*! Sets the activation window of this application to \a aw. The activation window is the widget that will be activated by activateWindow(). This is typically the application's main window. If \a activateOnMessage is true (the default), the window will be activated automatically every time a message is received, just prior to the messageReceived() signal being emitted. \sa activateWindow(), messageReceived() */ void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessage) { actWin = aw; if (activateOnMessage) connect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow())); else disconnect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow())); } /*! Returns the applications activation window if one has been set by calling setActivationWindow(), otherwise returns 0. \sa setActivationWindow() */ QWidget* QtSingleApplication::activationWindow() const { return actWin; } /*! De-minimizes, raises, and activates this application's activation window. This function does nothing if no activation window has been set. This is a convenience function to show the user that this application instance has been activated when he has tried to start another instance. This function should typically be called in response to the messageReceived() signal. By default, that will happen automatically, if an activation window has been set. \sa setActivationWindow(), messageReceived(), initialize() */ void QtSingleApplication::activateWindow() { if (actWin) { actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized); actWin->raise(); actWin->activateWindow(); } } /*! \fn void QtSingleApplication::messageReceived(const QString& message) This signal is emitted when the current instance receives a \a message from another instance of this application. \sa sendMessage(), setActivationWindow(), activateWindow() */ /*! \fn void QtSingleApplication::initialize(bool dummy = true) \obsolete */ kylin-video/src/qtsingleapplication/qtsinglecoreapplication.h0000664000175000017500000000502513214347337023700 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QTSINGLECOREAPPLICATION_H #define QTSINGLECOREAPPLICATION_H #include class QtLocalPeer; class QtSingleCoreApplication : public QCoreApplication { Q_OBJECT public: QtSingleCoreApplication(int &argc, char **argv); QtSingleCoreApplication(const QString &id, int &argc, char **argv); bool isRunning(); QString id() const; public Q_SLOTS: bool sendMessage(const QString &message, int timeout = 5000); Q_SIGNALS: void messageReceived(const QString &message); private: QtLocalPeer* peer; }; #endif // QTSINGLECOREAPPLICATION_H kylin-video/src/qtsingleapplication/QtLockedFile0000664000175000017500000000003213214347337021026 0ustar fengfeng#include "qtlockedfile.h" kylin-video/src/qtsingleapplication/qtsinglecoreapplication.cpp0000664000175000017500000001235513214347337024237 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qtsinglecoreapplication.h" #include "qtlocalpeer.h" /*! \class QtSingleCoreApplication qtsinglecoreapplication.h \brief A variant of the QtSingleApplication class for non-GUI applications. This class is a variant of QtSingleApplication suited for use in console (non-GUI) applications. It is an extension of QCoreApplication (instead of QApplication). It does not require the QtGui library. The API and usage is identical to QtSingleApplication, except that functions relating to the "activation window" are not present, for obvious reasons. Please refer to the QtSingleApplication documentation for explanation of the usage. A QtSingleCoreApplication instance can communicate to a QtSingleApplication instance if they share the same application id. Hence, this class can be used to create a light-weight command-line tool that sends commands to a GUI application. \sa QtSingleApplication */ /*! Creates a QtSingleCoreApplication object. The application identifier will be QCoreApplication::applicationFilePath(). \a argc and \a argv are passed on to the QCoreAppliation constructor. */ QtSingleCoreApplication::QtSingleCoreApplication(int &argc, char **argv) : QCoreApplication(argc, argv) { peer = new QtLocalPeer(this); connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); } /*! Creates a QtSingleCoreApplication object with the application identifier \a appId. \a argc and \a argv are passed on to the QCoreAppliation constructor. */ QtSingleCoreApplication::QtSingleCoreApplication(const QString &appId, int &argc, char **argv) : QCoreApplication(argc, argv) { peer = new QtLocalPeer(this, appId); connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); } /*! Returns true if another instance of this application is running; otherwise false. This function does not find instances of this application that are being run by a different user (on Windows: that are running in another session). \sa sendMessage() */ bool QtSingleCoreApplication::isRunning() { return peer->isClient(); } /*! Tries to send the text \a message to the currently running instance. The QtSingleCoreApplication object in the running instance will emit the messageReceived() signal when it receives the message. This function returns true if the message has been sent to, and processed by, the current instance. If there is no instance currently running, or if the running instance fails to process the message within \a timeout milliseconds, this function return false. \sa isRunning(), messageReceived() */ bool QtSingleCoreApplication::sendMessage(const QString &message, int timeout) { return peer->sendMessage(message, timeout); } /*! Returns the application identifier. Two processes with the same identifier will be regarded as instances of the same application. */ QString QtSingleCoreApplication::id() const { return peer->applicationId(); } /*! \fn void QtSingleCoreApplication::messageReceived(const QString& message) This signal is emitted when the current instance receives a \a message from another instance of this application. \sa sendMessage() */ kylin-video/src/qtsingleapplication/qtlockedfile.h0000664000175000017500000000630713214347337021427 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QTLOCKEDFILE_H #define QTLOCKEDFILE_H #include #ifdef Q_OS_WIN #include #endif #if defined(Q_OS_WIN) # if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT) # define QT_QTLOCKEDFILE_EXPORT # elif defined(QT_QTLOCKEDFILE_IMPORT) # if defined(QT_QTLOCKEDFILE_EXPORT) # undef QT_QTLOCKEDFILE_EXPORT # endif # define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport) # elif defined(QT_QTLOCKEDFILE_EXPORT) # undef QT_QTLOCKEDFILE_EXPORT # define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport) # endif #else # define QT_QTLOCKEDFILE_EXPORT #endif namespace QtLP_Private { class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile { public: enum LockMode { NoLock = 0, ReadLock, WriteLock }; QtLockedFile(); QtLockedFile(const QString &name); ~QtLockedFile(); bool open(OpenMode mode); bool lock(LockMode mode, bool block = true); bool unlock(); bool isLocked() const; LockMode lockMode() const; private: #ifdef Q_OS_WIN Qt::HANDLE wmutex; Qt::HANDLE rmutex; QVector rmutexes; QString mutexname; Qt::HANDLE getMutexHandle(int idx, bool doCreate); bool waitMutex(Qt::HANDLE mutex, bool doBlock); #endif LockMode m_lock_mode; }; } #endif kylin-video/src/qtsingleapplication/qtlockedfile_unix.cpp0000664000175000017500000000661413214347337023026 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include #include "qtlockedfile.h" bool QtLockedFile::lock(LockMode mode, bool block) { if (!isOpen()) { qWarning("QtLockedFile::lock(): file is not opened"); return false; } if (mode == NoLock) return unlock(); if (mode == m_lock_mode) return true; if (m_lock_mode != NoLock) unlock(); struct flock fl; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK; int cmd = block ? F_SETLKW : F_SETLK; int ret = fcntl(handle(), cmd, &fl); if (ret == -1) { if (errno != EINTR && errno != EAGAIN) qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); return false; } m_lock_mode = mode; return true; } bool QtLockedFile::unlock() { if (!isOpen()) { qWarning("QtLockedFile::unlock(): file is not opened"); return false; } if (!isLocked()) return true; struct flock fl; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; fl.l_type = F_UNLCK; int ret = fcntl(handle(), F_SETLKW, &fl); if (ret == -1) { qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); return false; } m_lock_mode = NoLock; return true; } QtLockedFile::~QtLockedFile() { if (isOpen()) unlock(); } kylin-video/src/merge/0000775000175000017500000000000013261113374013621 5ustar fengfengkylin-video/src/merge/playlist.cpp0000664000175000017500000011100613233751662016174 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 "playlist.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../smplayer/myaction.h" #include "../smplayer/filedialog.h" #include "../smplayer/helper.h" #include "../smplayer/preferences.h" #include "../smplayer/version.h" #include "../smplayer/global.h" #include "../smplayer/core.h" #include "../smplayer/extensions.h" #include "../kylin/playlistitem.h" #include "../kylin/playlistview.h" #include "../kylin/messagedialog.h" #include #include #include #include "../smplayer/infoprovider.h" using namespace Global; Playlist::Playlist(Core *c, QWidget * parent, Qt::WindowFlags f) : QFrame(parent, Qt::SubWindow) { this->setWindowFlags(Qt::FramelessWindowHint); this->setAutoFillBackground(true); this->setFixedWidth(220); setObjectName("PlaylistWidget"); setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred); setAcceptDrops(true); setAttribute(Qt::WA_NoMousePropagation); automatically_play_next = true; modified = false; core = c; playlist_path = ""; playlist_load_latest_dir = ""; titleLabel = 0; btDel = 0; btAdd = 0; novideo_icon = 0; novideo_text = 0; add_Btn = 0; title_layout = NULL; createNoVideo(); createTable(); createToolbar(); QVBoxLayout *layout = new QVBoxLayout(this); setFocusPolicy(Qt::ClickFocus); layout->setContentsMargins(0, 0, 0, 15); layout->setSpacing(16); btAddFrame = new QFrame; // btAddFrame->setFixedSize(156, 36); btAddFrame->setFixedSize(120, 36); btAddFrame->setObjectName("PlaylistWidgetAddFrame"); btAddFrame->setFocusPolicy(Qt::NoFocus); QHBoxLayout *btAddFameLayout = new QHBoxLayout(btAddFrame); btAddFameLayout->setMargin(0); btAddFameLayout->setSpacing(0); btAddFameLayout->addWidget(btAdd, 0, Qt::AlignVCenter); btAddFameLayout->addWidget(btDel, 0, Qt::AlignVCenter); // btAddFameLayout->addWidget(btClose, 0, Qt::AlignVCenter); title_layout = new QHBoxLayout(); title_layout->setSpacing(0); title_layout->setMargin(0); title_layout->addWidget(titleLabel, 0, Qt::AlignHCenter); // title_layout->addStretch(); title_layout->addWidget(btAddFrame, 0, Qt::AlignHCenter); noVideoFrame = new QFrame(); noVideoFrame->setFocusPolicy(Qt::NoFocus); QVBoxLayout *noVideoFameLayout = new QVBoxLayout(noVideoFrame); noVideoFameLayout->setMargin(0); noVideoFameLayout->setSpacing(30); noVideoFameLayout->addStretch(); noVideoFameLayout->addWidget(novideo_icon, 0, Qt::AlignHCenter); noVideoFameLayout->addWidget(novideo_text, 0, Qt::AlignHCenter); noVideoFameLayout->addWidget(add_Btn, 0, Qt::AlignHCenter); noVideoFameLayout->addStretch(); layout->addLayout(title_layout); layout->addWidget(listView, 0, Qt::AlignHCenter); // layout->addWidget(btAddFrame, 0, Qt::AlignHCenter | Qt::AlignBottom); layout->addWidget(noVideoFrame, 0, Qt::AlignHCenter); layout->addStretch(); setLayout(layout); clear(); connect(core, SIGNAL(mediaFinished()), this, SLOT(playNext()), Qt::QueuedConnection); connect(core, SIGNAL(mplayerFailed(QProcess::ProcessError)), this, SLOT(playerFailed(QProcess::ProcessError)) ); connect(core, SIGNAL(mplayerFinishedWithError(int)), this, SLOT(playerFinishedWithError(int)) ); connect(core, SIGNAL(mediaLoaded()), this, SLOT(getMediaInfo()) ); // Random seed QTime t; t.start(); srand( t.hour() * 3600 + t.minute() * 60 + t.second() ); loadSettings(); // Ugly hack to avoid to play next item automatically if (!automatically_play_next) { disconnect( core, SIGNAL(mediaFinished()), this, SLOT(playNext()) ); } // Save config every 5 minutes. save_timer = new QTimer(this); connect(save_timer, SIGNAL(timeout()), this, SLOT(maybeSaveSettings())); save_timer->start(5 * 60000); if (this->count() > 0) { noVideoFrame->hide(); listView->show(); } else { noVideoFrame->show(); listView->hide(); } } Playlist::~Playlist() { if (popup) { delete popup; popup = NULL; } if (titleLabel != NULL) { delete titleLabel; titleLabel = NULL; } if (btDel != NULL) { delete btDel; btDel = NULL; } if (btAdd != NULL) { delete btAdd; btAdd = NULL; } if (novideo_icon != NULL) { delete novideo_icon; novideo_icon = NULL; } if (novideo_text != NULL) { delete novideo_text; novideo_text = NULL; } if (add_Btn != NULL) { delete add_Btn; add_Btn = NULL; } if (noVideoFrame != NULL) { delete noVideoFrame; noVideoFrame = NULL; } if (btAddFrame != NULL) { delete btAddFrame; btAddFrame = NULL; } for(int i=0; ichildren()) { // QWidget *widget = static_cast(child); // widget->deleteLater(); // } // if (listView->count() > 0) // listView->clear();//kobe:WTF 会发生段错误 if (listView != NULL) { delete listView; listView = NULL; } if (save_timer != NULL) { disconnect(save_timer, SIGNAL(timeout()), this, SLOT(maybeSaveSettings())); if(save_timer->isActive()) { save_timer->stop(); } delete save_timer; save_timer = NULL; } } void Playlist::setTransparent(bool transparent) { if (transparent) { setAttribute(Qt::WA_TranslucentBackground); setWindowFlags(windowFlags() | Qt::FramelessWindowHint|Qt::X11BypassWindowManagerHint); set_widget_opacity(0.5); } else { setAttribute(Qt::WA_TranslucentBackground,false); setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint); } } void Playlist::set_widget_opacity(const float &opacity) { QGraphicsOpacityEffect* opacityEffect = new QGraphicsOpacityEffect; this->setGraphicsEffect(opacityEffect); opacityEffect->setOpacity(opacity); } void Playlist::setModified(bool mod) { modified = mod; // emit modifiedChanged(modified); } void Playlist::createTable() { listView = new PlayListView(this); // listView->setFixedHeight(430); // QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Preferred); // sp.setVerticalStretch(100); // listView->setSizePolicy(sp); connect(listView, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(doubleclicked(QListWidgetItem*))); connect(listView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(showPopupMenu(const QPoint &)) ); } void Playlist::setViewHeight() { listView->setFixedHeight(this->height()-36-16);//36为顶部按钮和label的高度,16为顶部和列表的间隔 } void Playlist::createNoVideo() { novideo_icon = new QLabel(); novideo_icon->setFixedSize(70, 70); novideo_icon->setPixmap(QPixmap(":/res/no-video.png")); novideo_text = new QLabel(); novideo_text->setObjectName("VideoText"); novideo_text->setText(tr("Playlist is empty")); add_Btn = new QPushButton(); add_Btn->setFocusPolicy(Qt::NoFocus); add_Btn->setFixedSize(140, 38); add_Btn->setObjectName("PlaylistAddButton"); add_Btn->setText(tr("Add File")); connect(add_Btn, SIGNAL(clicked(bool)), SLOT(popupDialogtoSelectFiles())); } void Playlist::createToolbar() { titleLabel = new QLabel(); titleLabel->setAlignment(Qt::AlignCenter); // titleLabel->setFixedSize(220-156, 36); titleLabel->setFixedSize(220-120, 36); titleLabel->setStyleSheet("QLabel{font-size:12px;color:#ffffff;background:transparent;}"); titleLabel->setText(tr("PlayList")); btDel = new QPushButton(); btDel->setFocusPolicy(Qt::NoFocus); btDel->setFixedSize(60, 36); btDel->setText(tr("Clear")); btDel->setObjectName("PlaylistButton"); connect(btDel, SIGNAL(clicked(bool)), SLOT(removeAll())); btAdd = new QPushButton(); btAdd->setFocusPolicy(Qt::NoFocus); btAdd->setFixedSize(60, 36); btAdd->setObjectName("PlaylistButton"); btAdd->setText(tr("Add")); // connect(btAdd, SIGNAL(clicked(bool)), SIGNAL(addPlaylist(bool)));//emit this->addPlaylist(true); connect(btAdd, SIGNAL(clicked(bool)), SLOT(popupDialogtoSelectFiles())); playAct = new MyAction(this, "pl_play", false); connect(playAct, SIGNAL(triggered()), this, SLOT(playCurrent()) ); playAct->change(tr("Play")); playAct->setIcon(QPixmap(":/res/playing_normal.png"));//playAct->setIcon(Images::icon("playing_normal")); // Remove actions removeSelectedAct = new MyAction(this, "pl_remove_selected", false); connect( removeSelectedAct, SIGNAL(triggered()), this, SLOT(removeTheSelected()) ); removeSelectedAct->change(tr("Remove &selected")); removeSelectedAct->setIcon(QPixmap(":/res/delete.png")); deleteSelectedFileFromDiskAct = new MyAction(this, "pl_delete_from_disk"); connect( deleteSelectedFileFromDiskAct, SIGNAL(triggered()), this, SLOT(deleteSelectedFileFromDisk())); deleteSelectedFileFromDiskAct->change(tr("&Delete file from disk") ); deleteSelectedFileFromDiskAct->setIcon(QPixmap(":/res/delete.png")); // Popup menu popup = new QMenu(this); popup->addAction(playAct); popup->addAction(removeSelectedAct); popup->addAction(deleteSelectedFileFromDiskAct); } void Playlist::doubleclicked(QListWidgetItem *item) { // qDebug() << item->text(); } void Playlist::updateView() { QString time; for (int n=0; n < pl.count(); n++) { // name = pl[n]->name(); // if (name.isEmpty()) name = pl[n]->filename(); time = Helper::formatTime( (int) pl[n]->duration()); if (listView) { QListWidgetItem *item = listView->item(n); PlayListItem *playlistItem = qobject_cast(listView->itemWidget(item)); playlistItem->update_time(time);//更新视频的时长 } } setListCurrentItem(current_item); } void Playlist::setListCurrentItem(int current) { listView->setCurrentItem(listView->item(current));//启动加载时设置播放列表的默认选中项 current_item = current; if ((current_item > -1) && (current_item < pl.count())) { pl[current_item]->setPlayed(true); // pl[current_item]->setActive(true); } } void Playlist::clear() { for(int i=0; ireset();//kobe resolve segmentation fault listView->clearSelection(); listView->clearFocus(); listView->clear();//kobe:必须执行该语句,否则切换视频后点击显示播放列表会发生段错误 listView->updateScrollbar(); setListCurrentItem(0); setModified(false); emit this->update_playlist_count(0); noVideoFrame->show(); listView->hide(); } int Playlist::count() { return pl.count(); } bool Playlist::isEmpty() { return pl.isEmpty(); } void Playlist::addOneItem(QString filename, QString name, double duration) { // Test if already is in the list bool exists = false; for (int n = 0; n < pl.count(); n++) { // qDebug() << "pl[n]->filename()=" << pl[n]->filename(); if ( pl[n]->filename() == filename.toUtf8().data()) { exists = true; // int last_item = pl.count()-1; // pl.move(n, last_item); // qDebug("Playlist::addOneItem: item already in list (%d), moved to %d and current_item=%d", n, last_item, current_item); current_item = n;//20170712 qDebug() << "WTF CCC current_item="< -1) { // if (current_item > n) current_item--; // else // if (current_item == n) current_item = last_item; // } break; } } if (!exists) { if (name.isEmpty()) { QFileInfo fi(filename.toUtf8().data()); // Let's see if it looks like a file (no dvd://1 or something) if (filename.indexOf(QRegExp("^.*://.*")) == -1) { // Local file name = fi.fileName(); //fi.baseName(true); } else { // Stream name = filename; } } QListWidgetItem *item = new QListWidgetItem(listView); item->setSizeHint(QSize(220, 32)); //// item->setText(filename); listView->addItem(item); listView->setItemWidget(item, new PlayListItem("vedio", filename/*.toUtf8().data()*/, name/*.toUtf8().data()*/, duration)); PlayListItem *playlistItem = qobject_cast(listView->itemWidget(item)); pl.append(playlistItem);//?????????????TODO:0518 connect(playlistItem, SIGNAL(remove(QString)), this, SLOT(onPlayListItemDeleteBtnClicked(QString))); connect(playlistItem, SIGNAL(sig_doubleclicked_resource(QString)), this, SLOT(slot_doubleclicked_resource(QString))); setModified(true); // Better set the modified on a higher level listView->setCurrentItem(item); emit this->update_playlist_count(pl.count()); if (pl.count() > 0) { noVideoFrame->hide(); listView->show(); } else { noVideoFrame->show(); listView->hide(); } // current_item = pl.count() - 1;//0526 // this->setListCurrentItem(pl.count() - 1);//0526 } else { this->setListCurrentItem(current_item);//20170712 正播放的文件存在播放列表中时更新播放列表的选择项 // listView->setCurrentItem(listView->item(current_item));//20170712 正播放的文件存在播放列表中时更新播放列表的选择项 qDebug("Playlist::addOneItem: item not added, already in the list current_item=%d", current_item); } } void Playlist::slot_listview_current_item_changed(QListWidgetItem *current, QListWidgetItem *previous) {//kobe:此函数在启动加载配置时,会让配置的最后一个播放文件在列表中被选中 PlayListItem *itemWidget = qobject_cast(listView->itemWidget(previous)); if (itemWidget) { itemWidget->setActive(false); } itemWidget = qobject_cast(listView->itemWidget(current)); if (itemWidget) { itemWidget->setActive(true); } } //双击播放列表的一项时进行播放 void Playlist::slot_doubleclicked_resource(QString filename) { QFileInfo fi(filename); if (fi.exists()) { // Local file QString name = fi.fileName(); emit this->sig_playing_title(name); core->open(filename/*, 0*/);//每次从头开始播放文件 } else { emit this->playListFinishedWithError(filename); } } void Playlist::playCurrent() { int current = listView->currentRow(); if (current > -1) { playItem(current); } // this->slot_doubleclicked_resource(); } void Playlist::itemDoubleClicked(int row) { // qDebug("Playlist::itemDoubleClicked: row: %d", row ); playItem(row); } void Playlist::showPopupMenu(const QPoint & pos) { // qDebug("Playlist::showPopupMenu: x: %d y: %d", pos.x(), pos.y() ); // get select QList items = listView->selectedItems(); if (items.length() != 1) { return; } PlayListItem *item = qobject_cast(listView->itemWidget(items.first())); if (!item) { return; } QString m_data = item->data(); if (m_data.isEmpty()) { return; } // current_item = 1; QPoint itemPos = item->mapFromParent(pos); if (!item->rect().contains(itemPos)) { return; } // QPoint globalPos = this->mapToGlobal(pos); if (!popup->isVisible()) { playAct->setDisabled(0 == m_data.length()); popup->move(listView->viewport()->mapToGlobal(pos) ); popup->show(); } } //kobe:添加多个文件文件夹或拖拽进多个文件文件夹时才会走这里,如果是支持乱序,则乱序选择一个开始播放20170725 void Playlist::startPlay() { // Start to play if (pref->play_order == Preferences::RandomPlay) {//随机播放 playItem(chooseRandomItem()); } else {//顺序播放 列表循环 playItem(0); } } void Playlist::playItem( int n ) { // qDebug("Playlist::playItem: %d (count:%d)", n, pl.count()); if ( (n >= pl.count()) || (n < 0) ) { qDebug("Playlist::playItem: out of range"); emit playlistEnded(); emit this->sig_playing_title(""); return; } // qDebug("######playlist_path: '%s'", playlist_path.toUtf8().data() ); QString filename = pl[n]->filename(); // qDebug("######filename: '%s'", filename); // QString filename_with_path = playlist_path + "/" + filename; if (!filename.isEmpty()) { //pl[n].setPlayed(true); // setListCurrentItem(n);//0527 n - 1 QFileInfo fi(filename); if (fi.exists()) { setListCurrentItem(n);//0527 n - 1 // Local file QString name = fi.fileName(); emit this->sig_playing_title(name); core->open(filename/*, 0*/);//每次从头开始播放文件 } else { emit this->playListFinishedWithError(filename); } //0621 kobe: core->open(filename, 0): 每次从头开始播放文件, core->open(filename):每次从上次播放停止位置开始播放文件 // core->open(filename); // if (play_files_from_start) // core->open(filename/*, 0*/);//每次从头开始播放文件 // else // core->open(filename); /* else { // Stream name = filename; //emit this->playListFinishedWithError(filename); }*/ } } //20170725 void Playlist::playNext() { // emit this->sig_playing_title(""); // qDebug("Playlist::playNext pl[current_item]->name()=%s", pl[current_item]->name()); if (pref->play_order == Preferences::RandomPlay) {//随机播放 int chosen_item = chooseRandomItem(); if (chosen_item == -1) { clearPlayedTag(); chosen_item = chooseRandomItem(); if (chosen_item == -1) chosen_item = 0; } playItem(chosen_item); } else if (pref->play_order == Preferences::ListLoopPlay) {//列表循环 bool finished_list = (current_item+1 >= pl.count()); if (finished_list) { clearPlayedTag(); } if (finished_list) { playItem(0); } else { playItem(current_item+1); } } else {//顺序播放 bool finished_list = (current_item+1 >= pl.count()); if (finished_list) { clearPlayedTag(); } if (finished_list) { // emit this->finish_list(); emit this->showMessage(tr("Reached the end of the playlist")); } else { playItem(current_item + 1); } } } void Playlist::playPrev() { if (current_item > 0) { playItem(current_item - 1); } else { if (pl.count() > 1) { playItem(pl.count() - 1); } } } void Playlist::resumePlay() { if (pl.count() > 0) { if (current_item < 0) current_item = 0; // current_item = 0;//20170713 playItem(current_item); } } void Playlist::getMediaInfo() { QString filename = core->mdat.filename; double duration = core->mdat.duration; // QString artist = core->mdat.clip_artist; //kobe:有的rmvb视频的clip_name存在乱码 QString name; //QString name = core->mdat.clip_name; //if (name.isEmpty()) name = core->mdat.stream_title; if (name.isEmpty()) { QFileInfo fi(filename); name = fi.fileName();//20170713 // if (fi.exists()) { // // Local file // name = fi.fileName(); // } else { // // Stream // name = filename; // } } // if (!artist.isEmpty()) name = artist + " - " + name; for (int n = 0; n < pl.count(); n++) { if (pl[n]->filename() == filename) { current_item = n;//kobe 20170712 // Found item if (pl[n]->duration() < 1) { if (!name.isEmpty()) { pl[n]->setName(name.toUtf8().data());//edit by kobe } pl[n]->setDuration(duration); } else // Edited name (sets duration to 1) if (pl[n]->duration() == 1) { pl[n]->setDuration(duration); } } } updateView(); } //0707 void Playlist::popupDialogtoSelectFiles() { //打开一个或多个文件时,此时只是将选择的文件加入播放列表,并不会自动去播放选择的文件 Extensions e; QStringList files = MyFileDialog::getOpenFileNames( this, tr("Select one or more files to open"), lastDir(), tr("Multimedia") + e.multimedia().forFilter() + ";;" + tr("All files") +" (*.*)" ); if (files.count()!=0) addFiles(files); } void Playlist::addFiles(QStringList files, AutoGetInfo auto_get_info) { bool get_info = (auto_get_info == GetInfo); get_info = true; // MediaData data; setCursor(Qt::WaitCursor); QString initial_file; if (pl.count() == 1) { initial_file = pl[0]->filename()/*.toUtf8().data()*/;//0526 qDebug() << "pl[0]->filename()=" << pl[0]->filename(); } int new_current_item = -1; for (int n = 0; n < files.count(); n++) { QString name = ""; double duration = 0; //kobe 0606 如果选择多个文件,此时读取信息会耗时很长,导致界面卡顿,此处暂时不获取视频信息,在双击播放后再在函数updateView中更新视频的时长 // if ( (get_info) && (QFile::exists(files[n])) ) { // data = InfoProvider::getInfo(files[n]); // name = data.displayName(); // duration = data.duration; // } // qDebug() << "USE_INFOPROVIDER name=" << name << " duration=" << duration << " current_item=" << current_item; if (!initial_file.isEmpty() && files[n] == initial_file) { PlayListItem *first_item = pl.takeFirst();//pl.takeFirst(); name = first_item->name(); duration = first_item->duration(); new_current_item = n; } this->addOneItem(files[n], name, duration); if (QFile::exists(files[n])) { playlist_load_latest_dir = QFileInfo(files[n]).absolutePath(); } } unsetCursor(); // if (new_current_item != -1) setListCurrentItem(new_current_item); // else setListCurrentItem(pl.count() - 1);//0526 kobe updateView(); } void Playlist::addFile(QString file, AutoGetInfo auto_get_info) { //打开一个文件时 addFiles( QStringList() << file, auto_get_info ); } void Playlist::addDirectory() { QString s = MyFileDialog::getExistingDirectory( this, tr("Choose a directory"), lastDir() ); if (!s.isEmpty()) { addDirectory(s); playlist_load_latest_dir = s; } } void Playlist::addOneDirectory(QString dir) { QStringList filelist; Extensions e; QRegExp rx_ext(e.multimedia().forRegExp()); rx_ext.setCaseSensitivity(Qt::CaseInsensitive); QStringList dir_list = QDir(dir).entryList(); QString filename; QStringList::Iterator it = dir_list.begin(); while( it != dir_list.end() ) { filename = dir; if (filename.right(1)!="/") filename += "/"; filename += (*it); QFileInfo fi(filename); if (!fi.isDir()) { if (rx_ext.indexIn(fi.suffix()) > -1) { filelist << filename; } } ++it; } addFiles(filelist); } void Playlist::addDirectory(QString dir) { addOneDirectory(dir); // if (recursive_add_directory) {//递归 // QFileInfoList dir_list = QDir(dir).entryInfoList(QStringList() << "*", QDir::AllDirs | QDir::NoDotAndDotDot); // for (int n=0; n < dir_list.count(); n++) { // if (dir_list[n].isDir()) { // qDebug("Playlist::addDirectory: adding directory: %s", dir_list[n].filePath().toUtf8().data()); // addDirectory(dir_list[n].filePath()); // } // } // } } void Playlist::removeTheSelected() { int current = listView->currentRow(); if ( (current >= pl.count()) || (current < 0) ) { qDebug("Playlist::playItem: out of range when remove"); return; } QString filename = pl[current]->filename(); if (!filename.isEmpty()) { MessageDialog msgDialog(0, tr("Confirm remove"), tr("You're about to remove the file '%1' from the playlist.").arg(filename) + "
"+ tr("Are you sure you want to proceed?"), QMessageBox::Yes | QMessageBox::No); if (msgDialog.exec() != -1) { if (msgDialog.standardButton(msgDialog.clickedButton()) == QMessageBox::Yes) { removeSelected(filename); } } // removeSelected(filename); } } void Playlist::onPlayListItemDeleteBtnClicked(QString filename) { if (!filename.isEmpty()) { MessageDialog msgDialog(0, tr("Confirm remove"), tr("You're about to remove the file '%1' from the playlist.").arg(filename) + "
"+ tr("Are you sure you want to proceed?"), QMessageBox::Yes | QMessageBox::No); if (msgDialog.exec() != -1) { if (msgDialog.standardButton(msgDialog.clickedButton()) == QMessageBox::Yes) { removeSelected(filename); } } } } // Remove selected item void Playlist::removeSelected(QString filename) { int first_selected = -1; int number_previous_item = 0; for (int i = 0; i < listView->count(); ++i) { QListWidgetItem *item = listView->item(i); PlayListItem *playlistItem = qobject_cast(listView->itemWidget(item)); if (playlistItem->data() == filename) { pl[i]->setMarkForDeletion(true); number_previous_item++; if (first_selected == -1) first_selected = i; // break; listView->removeItemWidget(item); delete listView->takeItem(listView->row(item)); Q_ASSERT(listView->count() > 0); listView->updateScrollbar(); listView->setCurrentItem(listView->item(0)); break; } } QList::Iterator it = pl.begin(), itend = pl.end(); for(;it !=itend;it++) { if ( (*it)->markedForDeletion() ) { qDebug("remove '%s'", (*it)->filename().toUtf8().data()); it = pl.erase(it); // it--; setModified(true); break; } } emit this->update_playlist_count(pl.count()); if (pl.count() > 0) { noVideoFrame->hide(); listView->show(); this->playNext();//Fixed bug: #4915 } else { noVideoFrame->show(); listView->hide(); } if (first_selected < current_item) { current_item -= number_previous_item; } if (isEmpty()) setModified(false); updateView(); if (first_selected >= listView->count()) first_selected = listView->count() - 1; if ( ( first_selected > -1) && ( first_selected < listView->count() ) ) { // listView->clearSelection(); listView->setCurrentRow(first_selected); } } void Playlist::removeAll() { clear(); } void Playlist::clearPlayedTag() { for (int n = 0; n < pl.count(); n++) { pl[n]->setPlayed(false); } updateView(); } int Playlist::chooseRandomItem() { QList fi; //List of not played items (free items) for (int n = 0; n < pl.count(); n++) { if (!pl[n]->played()) fi.append(n); } // qDebug("Playlist::chooseRandomItem: free items: %d", fi.count() ); if (fi.count() == 0) return -1; // none free for (int i = 0; i < fi.count(); i++) { qDebug("Playlist::chooseRandomItem: * item: %d", fi[i]); } int selected = (int) ((double) fi.count() * rand()/(RAND_MAX+1.0)); // qDebug("Playlist::chooseRandomItem: selected item: %d (%d)", selected, fi[selected]); return fi[selected]; } void Playlist::swapItems(int item1, int item2 ) { } void Playlist::upItem() { // qDebug("Playlist::upItem"); int current = listView->currentRow(); qDebug(" currentRow: %d", current ); moveItemUp(current); } void Playlist::downItem() { qDebug("Playlist::downItem"); int current = listView->currentRow(); qDebug(" currentRow: %d", current ); moveItemDown(current); } void Playlist::moveItemUp(int current){ } void Playlist::moveItemDown(int current ){ } void Playlist::editCurrentItem() { // int current = listView->currentRow(); // if (current > -1) editItem(current); } void Playlist::editItem(int item) { } void Playlist::deleteSelectedFileFromDisk() { qDebug("Playlist::deleteSelectedFileFromDisk"); int current = listView->currentRow(); if (current > -1) { // // If more that one row is selected, select only the current one // listView->clearSelection(); // listView->setCurrentCell(current, 0); QString filename = pl[current]->filename(); qDebug() << "Playlist::deleteSelectedFileFromDisk: current file:" << filename; //20170715 QFileInfo fi(filename); if (fi.exists() && fi.isFile() && fi.isWritable()) { // Ask the user for confirmation MessageDialog msgDialog(0, tr("Confirm deletion"), tr("You're about to DELETE the file '%1' from your drive.").arg(filename) + "
"+ tr("This action cannot be undone. Are you sure you want to proceed?"), QMessageBox::Yes | QMessageBox::No); if (msgDialog.exec() != -1) { if (msgDialog.standardButton(msgDialog.clickedButton()) == QMessageBox::Yes) { // Delete file bool success = QFile::remove(filename); if (success) { // Remove item from the playlist removeSelected(filename); } else { // QMessageBox::warning(this, tr("Deletion failed"), // tr("It wasn't possible to delete '%1'").arg(filename)); MessageDialog warnDialog(0, tr("Deletion failed"), tr("It wasn't possible to delete '%1'").arg(filename), QMessageBox::Ok); warnDialog.exec(); } } } } else { // qDebug("Playlist::deleteSelectedFileFromDisk: file doesn't exists, it's not a file or it's not writable"); MessageDialog infoDialog(0, tr("Error deleting the file"), tr("It's not possible to delete '%1' from the filesystem.").arg(filename), QMessageBox::Ok); infoDialog.exec(); } } } // Drag&drop void Playlist::dragEnterEvent( QDragEnterEvent *e ) { // qDebug("Playlist::dragEnterEvent"); if (e->mimeData()->hasUrls()) { e->acceptProposedAction(); } } void Playlist::dropEvent( QDropEvent *e ) { // qDebug("Playlist::dropEvent"); QStringList files; if (e->mimeData()->hasUrls()) { QList l = e->mimeData()->urls(); QString s; for (int n=0; n < l.count(); n++) { if (l[n].isValid()) { qDebug("Playlist::dropEvent: scheme: '%s'", l[n].scheme().toUtf8().data()); if (l[n].scheme() == "file") s = l[n].toLocalFile(); else s = l[n].toString(); /* qDebug(" * '%s'", l[n].toString().toUtf8().data()); qDebug(" * '%s'", l[n].toLocalFile().toUtf8().data()); */ qDebug("Playlist::dropEvent: file: '%s'", s.toUtf8().data()); files.append(s); } } } files.sort(); QStringList only_files; for (int n = 0; n < files.count(); n++) { if ( QFileInfo( files[n] ).isDir() ) { addDirectory( files[n] ); } else { only_files.append( files[n] ); } } addFiles( only_files ); } void Playlist::hideEvent( QHideEvent * ) { emit visibilityChanged(false); } void Playlist::showEvent( QShowEvent * ) { emit visibilityChanged(true); } void Playlist::closeEvent( QCloseEvent * e ) { saveSettings(); e->accept(); } void Playlist::playerFailed(QProcess::ProcessError e) { qDebug("Playlist::playerFailed"); emit this->sig_playing_title(""); // if (ignore_player_errors) { // if (e != QProcess::FailedToStart) { // playNext(); // } // } } void Playlist::playerFinishedWithError(int e) { emit this->sig_playing_title(""); // qDebug("@@@@@@@@@@@@@@@@@@@Playlist::playerFinishedWithError: %d", e); // if (ignore_player_errors) { // playNext(); // } } void Playlist::maybeSaveSettings() { if (isModified()) saveSettings(); } void Playlist::saveSettings() { QSettings * set = settings; //Save current list set->beginGroup( "playlist_contents"); set->setValue( "playlist_load_latest_dir", playlist_load_latest_dir ); set->setValue("count", (int)pl.count()); for ( int n=0; n < pl.count(); n++ ) { set->setValue(QString("item_%1_filename").arg(n), pl[n]->filename()); set->setValue(QString("item_%1_duration").arg(n), pl[n]->duration()); set->setValue(QString("item_%1_name").arg(n), pl[n]->name()); } set->setValue("current_item", current_item ); set->setValue("play_order", (int) pref->play_order);//20170725 set->endGroup(); } void Playlist::loadSettings() { QSettings * set = settings; //Load latest list set->beginGroup( "playlist_contents"); playlist_load_latest_dir = set->value( "laylist_load_latest_dir", playlist_load_latest_dir ).toString();//latest_dir 0526 pref->play_order = (Preferences::PlayOrder) set->value("play_order", (int) pref->play_order).toInt();//20170725 int count = set->value("count", 0).toInt(); QString filename, name; double duration; for (int n=0; n < count; n++ ) { filename = set->value(QString("item_%1_filename").arg(n), "").toString()/*.toUtf8().data()*/; duration = set->value(QString("item_%1_duration").arg(n), -1).toDouble(); name = set->value( QString("item_%1_name").arg(n), "" ).toString()/*.toUtf8().data()*/; // qDebug() << "===============kobe test filename:" << filename << " name=" << name << " duration=" << duration;//.toUtf8().data(); this->addOneItem(filename, name, duration);//kobe add playlist contents } int index = set->value("current_item", -1).toInt(); setListCurrentItem(index); emit this->update_playlist_count(pl.count()); if (pl.count() > 0) { noVideoFrame->hide(); listView->show(); } else { noVideoFrame->show(); listView->hide(); } updateView(); set->endGroup(); } QString Playlist::lastDir() { QString last_dir = playlist_load_latest_dir; if (last_dir.isEmpty()) last_dir = pref->latest_dir; return last_dir; } void Playlist::paintEvent(QPaintEvent *event) { Q_UNUSED(event); QStyleOption opt; opt.init(this); QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); // QPainter p(this); // p.setCompositionMode(QPainter::CompositionMode_Clear); // p.fillRect(rect(), Qt::SolidPattern);//p.fillRect(0, 0, this->width(), this->height(), Qt::SolidPattern); } //#include "moc_playlist.cpp" kylin-video/src/merge/prefshortcut.cpp0000664000175000017500000000517013233751662017067 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 "prefshortcut.h" #include "../smplayer/images.h" #include "../smplayer/config.h" PrefShortCut::PrefShortCut(QWidget * parent, Qt::WindowFlags f) : PrefWidget(parent, f ) { setupUi(this); retranslateStrings(); } PrefShortCut::~PrefShortCut() { } QString PrefShortCut::sectionName() { return tr("ShortCut"); } QPixmap PrefShortCut::sectionIcon() { return Images::icon("input_devices", 22); } void PrefShortCut::retranslateStrings() { retranslateUi(this); actioneditor_desc->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); actioneditor_desc->setText( tr("Here you can change any key shortcut. To do it double click or " "start typing over a shortcut cell.") ); createHelp(); } void PrefShortCut::setData(Preferences * pref) { } void PrefShortCut::getData(Preferences * pref) { requires_restart = false; } void PrefShortCut::createHelp() { clearHelp(); addSectionTitle(tr("Shortcut Key")); setWhatsThis(actions_editor, tr("Shortcut editor"), tr("This table allows you to change the key shortcuts of most " "available actions. Double click or press enter on a item, or " "press the Change shortcut button to enter in the " "Modify shortcut dialog. There are two ways to change a " "shortcut: if the Capture button is on then just " "press the new key or combination of keys that you want to " "assign for the action (unfortunately this doesn't work for all " "keys). If the Capture button is off " "then you could enter the full name of the key.") ); } //#include "moc_prefshortcut.cpp" kylin-video/src/merge/prefaudio.ui0000664000175000017500000001750613214706400016143 0ustar fengfeng PrefAudio 0 0 470 371 10 20 451 111 Volume 4 4 4 4 Global volume 6 0 0 0 0 Use software volume control Qt::Horizontal 20 20 false Max. Amplification: false softvol_max_spin false 10 10000 Volume normalization by default 10 140 451 59 Synchronization 4 4 4 4 Audio/video auto synchronization Qt::Horizontal QSizePolicy::Expanding 40 31 false Factor: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter false autosync_spin false 0 1000 100 10 210 451 29 Output driver: false ao_combo 0 0 false Qt::Horizontal 81 20 10 250 451 29 6 0 0 0 0 Channels by default: channels_combo Qt::Horizontal 40 20 kylin-video/src/merge/prefshortcut.ui0000664000175000017500000000425413214706400016711 0ustar fengfeng PrefShortCut 0 0 470 360 9 6 451 51 6 0 0 0 0 0 0 Here you can change any key shortcut. To do it double click or press enter over a shortcut cell. Qt::AlignVCenter true 5 59 460 301 0 0 ActionsEditor QWidget
../smplayer/actionseditor.h
kylin-video/src/merge/filepropertiesdialog.cpp0000664000175000017500000004702113233751662020554 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 "filepropertiesdialog.h" #include #include #include #include #include #include "../smplayer/images.h" #include "../smplayer/infofile.h" #include "../smplayer/playerid.h" #include #include #include #include #include "../kylin/titlebutton.h" FilePropertiesDialog::FilePropertiesDialog( QWidget* parent, Qt::WindowFlags f ) : QDialog(parent, f) { setupUi(this); this->setFixedSize(650, 509); this->setStyleSheet("QDialog{border: 1px solid #121212;border-radius:1px;background-color:#1f1f1f;}"); this->setAttribute(Qt::WA_DeleteOnClose); this->setWindowFlags(Qt::FramelessWindowHint); this->setAutoFillBackground(true); info_edit->setStyleSheet("QTextEdit {border: 1px solid #000000;color: #999999;background: #0f0f0f;font-family:方正黑体_GBK;font-size: 12px;}"); info_edit->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {width: 12px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:vertical {width: 12px;min-height: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:vertical:hover {background: #3e3e3e;}QScrollBar::handle:vertical:pressed {background: #272727;}QScrollBar::sub-line:vertical {height: 6px;background: transparent;subcontrol-position: top;}QScrollBar::add-line:vertical {height: 6px;background: transparent;subcontrol-position: bottom;}QScrollBar::sub-line:vertical:hover {background: #292929;}QScrollBar::add-line:vertical:hover {background: #292929;}QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;}"); this->setMouseTracking(true); installEventFilter(this); title_widget->setAutoFillBackground(true); title_widget->setStyleSheet("QWidget{border:none;background-color:#2e2e2e;}"); // QPalette palette; // palette.setColor(QPalette::Background, QColor("#2e2e2e")); // title_widget->setPalette(palette); demuxer_listbox->setStyleSheet("QListWidget{color: #999999;font-size: 12px;border: 0px solid rgba(255, 0, 0, 0.7);background-color: #171717;outline:none;}QListWidget::item{color: #999999;height: 30px;}QListWidget::item:hover{background: #242424;}QListWidget::item:selected:!active {color: #999999;background-color: #171717;}QListWidget::item:selected:active {color: white;background-color: #0f0f0f;}"); vc_listbox->setStyleSheet("QListWidget{color: #999999;font-size: 12px;border: 0px solid rgba(255, 0, 0, 0.7);background-color: #171717;outline:none;}QListWidget::item{color: #999999;height: 30px;}QListWidget::item:hover{background: #242424;}QListWidget::item:selected:!active {color: #999999;background-color: #171717;}QListWidget::item:selected:active {color: white;background-color: #0f0f0f;}"); ac_listbox->setStyleSheet("QListWidget{color: #999999;font-size: 12px;border: 0px solid rgba(255, 0, 0, 0.7);background-color: #171717;outline:none;}QListWidget::item{color: #999999;height: 30px;}QListWidget::item:hover{background: #242424;}QListWidget::item:selected:!active {color: #999999;background-color: #171717;}QListWidget::item:selected:active {color: white;background-color: #0f0f0f;}"); demuxer_listbox->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {width: 12px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:vertical {width: 12px;min-height: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:vertical:hover {background: #3e3e3e;}QScrollBar::handle:vertical:pressed {background: #272727;}QScrollBar::sub-line:vertical {height: 6px;background: transparent;subcontrol-position: top;}QScrollBar::add-line:vertical {height: 6px;background: transparent;subcontrol-position: bottom;}QScrollBar::sub-line:vertical:hover {background: #292929;}QScrollBar::add-line:vertical:hover {background: #292929;}QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;}"); demuxer_listbox->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal {height: 8px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:horizontal {height: 8px;min-width: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:horizontal:hover {background: #3e3e3e;}QScrollBar::handle:horizontal:pressed {background: #272727;}QScrollBar::sub-line:horizontal {width: 6px;background: transparent;subcontrol-position: left;}QScrollBar::add-line:horizontal {width: 6px;background: transparent;subcontrol-position: right;}QScrollBar::sub-line:horizontal:hover {background: #292929;}QScrollBar::add-line:horizontal:hover {background: #292929;}QScrollBar::add-page:horizontal,QScrollBar::sub-page:horizontal {background: transparent;}"); vc_listbox->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {width: 12px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:vertical {width: 12px;min-height: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:vertical:hover {background: #3e3e3e;}QScrollBar::handle:vertical:pressed {background: #272727;}QScrollBar::sub-line:vertical {height: 6px;background: transparent;subcontrol-position: top;}QScrollBar::add-line:vertical {height: 6px;background: transparent;subcontrol-position: bottom;}QScrollBar::sub-line:vertical:hover {background: #292929;}QScrollBar::add-line:vertical:hover {background: #292929;}QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;}"); vc_listbox->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal {height: 8px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:horizontal {height: 8px;min-width: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:horizontal:hover {background: #3e3e3e;}QScrollBar::handle:horizontal:pressed {background: #272727;}QScrollBar::sub-line:horizontal {width: 6px;background: transparent;subcontrol-position: left;}QScrollBar::add-line:horizontal {width: 6px;background: transparent;subcontrol-position: right;}QScrollBar::sub-line:horizontal:hover {background: #292929;}QScrollBar::add-line:horizontal:hover {background: #292929;}QScrollBar::add-page:horizontal,QScrollBar::sub-page:horizontal {background: transparent;}"); ac_listbox->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {width: 12px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:vertical {width: 12px;min-height: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:vertical:hover {background: #3e3e3e;}QScrollBar::handle:vertical:pressed {background: #272727;}QScrollBar::sub-line:vertical {height: 6px;background: transparent;subcontrol-position: top;}QScrollBar::add-line:vertical {height: 6px;background: transparent;subcontrol-position: bottom;}QScrollBar::sub-line:vertical:hover {background: #292929;}QScrollBar::add-line:vertical:hover {background: #292929;}QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;}"); ac_listbox->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal {height: 8px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:horizontal {height: 8px;min-width: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:horizontal:hover {background: #3e3e3e;}QScrollBar::handle:horizontal:pressed {background: #272727;}QScrollBar::sub-line:horizontal {width: 6px;background: transparent;subcontrol-position: left;}QScrollBar::add-line:horizontal {width: 6px;background: transparent;subcontrol-position: right;}QScrollBar::sub-line:horizontal:hover {background: #292929;}QScrollBar::add-line:horizontal:hover {background: #292929;}QScrollBar::add-page:horizontal,QScrollBar::sub-page:horizontal {background: transparent;}"); connect(okButton, SIGNAL(clicked()), this, SLOT(accept())); connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject())); connect(applyButton, SIGNAL(clicked()), this, SLOT(apply())); okButton->setFixedSize(91, 25); cancelButton->setFixedSize(91, 25); applyButton->setFixedSize(91, 25); resetDemuxerButton->setFixedSize(91, 25); resetACButton->setFixedSize(91, 25); resetVCButton->setFixedSize(91, 25); okButton->setFocusPolicy(Qt::NoFocus); cancelButton->setFocusPolicy(Qt::NoFocus); applyButton->setFocusPolicy(Qt::NoFocus); resetDemuxerButton->setFocusPolicy(Qt::NoFocus); resetACButton->setFocusPolicy(Qt::NoFocus); resetVCButton->setFocusPolicy(Qt::NoFocus); okButton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); cancelButton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #000000;color:#999999;}QPushButton:hover{background-color:#1f1f1f;border:1px solid #0f0f0f;color:#ffffff;} QPushButton:pressed{background-color:#0d0d0d;border:1px solid #000000;color:#ffffff;}"); applyButton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); resetDemuxerButton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); resetACButton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); resetVCButton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); title_label->setStyleSheet("QLabel{background:transparent;font-family:方正黑体_GBK;font-size:20px;color:#999999;}"); demuxer_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); video_codec_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); audio_codec_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 5, 0, 0); layout->setSpacing(0); TitleButton *btn = new TitleButton(0, false, tr("Information")); btn->setActived(true); connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); layout->addWidget(btn); m_buttonList << btn; btn = new TitleButton(1, false, tr("Demuxer")); connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); layout->addWidget(btn); m_buttonList << btn; btn = new TitleButton(2, false, tr("Video codec")); connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); layout->addWidget(btn); m_buttonList << btn; btn = new TitleButton(3, false, tr("Audio codec")); connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); layout->addWidget(btn); m_buttonList << btn; layout->addStretch(); sections->setLayout(layout); pages->setCurrentWidget(info_page); codecs_set = false; retranslateStrings(); } FilePropertiesDialog::~FilePropertiesDialog() { for(int i=0; isetText(info.getInfo(media_data)); } void FilePropertiesDialog::setCurrentID(int id) { foreach (TitleButton *button, m_buttonList) { if (button->id() == id) { button->setActived(true); } else { button->setActived(false); } } } void FilePropertiesDialog::onButtonClicked(int id) { setCurrentID(id); if (id == 0) { pages->setCurrentWidget(info_page); } else if (id == 1) { pages->setCurrentWidget(demuxer_page); } else if (id == 2) { pages->setCurrentWidget(vc_page); } else if (id == 3) { pages->setCurrentWidget(ac_page); } } void FilePropertiesDialog::retranslateStrings() { retranslateUi(this); // setWindowIcon( Images::icon("logo") ); this->setWindowIcon(QIcon(":/res/kylin-video.png")); icon_label->setPixmap(QPixmap(":/res/info.png")); showInfo(); okButton->setText( tr("OK") ); cancelButton->setText( tr("Cancel") ); applyButton->setText( tr("Apply") ); } void FilePropertiesDialog::accept() { qDebug("FilePropertiesDialog::accept"); hide(); setResult( QDialog::Accepted ); emit applied(); } void FilePropertiesDialog::apply() { qDebug("FilePropertiesDialog::apply"); setResult( QDialog::Accepted ); emit applied(); } void FilePropertiesDialog::reject() { hide(); setResult( QDialog::Rejected ); setResult( QDialog::Accepted ); } void FilePropertiesDialog::setCodecs(InfoList vc, InfoList ac, InfoList demuxer) { vclist = vc; aclist = ac; demuxerlist = demuxer; qSort(vclist); qSort(aclist); qSort(demuxerlist); vc_listbox->clear(); ac_listbox->clear(); demuxer_listbox->clear(); InfoList::iterator it; for ( it = vclist.begin(); it != vclist.end(); ++it ) { vc_listbox->addItem( (*it).name() +" - "+ (*it).desc() ); } for ( it = aclist.begin(); it != aclist.end(); ++it ) { ac_listbox->addItem( (*it).name() +" - "+ (*it).desc() ); } for ( it = demuxerlist.begin(); it != demuxerlist.end(); ++it ) { demuxer_listbox->addItem( (*it).name() +" - "+ (*it).desc() ); } codecs_set = true; } void FilePropertiesDialog::setDemuxer(QString demuxer, QString original_demuxer) { // qDebug("FilePropertiesDialog::setDemuxer"); if (!original_demuxer.isEmpty()) orig_demuxer = original_demuxer; int pos = find(demuxer, demuxerlist ); if (pos != -1) demuxer_listbox->setCurrentRow(pos); // qDebug(" * demuxer: '%s', pos: %d", demuxer.toUtf8().data(), pos ); } QString FilePropertiesDialog::demuxer() { int pos = demuxer_listbox->currentRow(); if ( pos < 0 ) return ""; else return demuxerlist[pos].name(); } void FilePropertiesDialog::setVideoCodec(QString vc, QString original_vc) { qDebug("FilePropertiesDialog::setVideoCodec"); if (!original_vc.isEmpty()) orig_vc = original_vc; int pos = find(vc, vclist ); if (pos != -1) vc_listbox->setCurrentRow(pos); qDebug(" * vc: '%s', pos: %d", vc.toUtf8().data(), pos ); } QString FilePropertiesDialog::videoCodec() { int pos = vc_listbox->currentRow(); if ( pos < 0 ) return ""; else return vclist[pos].name(); } void FilePropertiesDialog::setAudioCodec(QString ac, QString original_ac) { qDebug("FilePropertiesDialog::setAudioCodec"); if (!original_ac.isEmpty()) orig_ac = original_ac; int pos = find(ac, aclist ); if (pos != -1) ac_listbox->setCurrentRow(pos); qDebug(" * ac: '%s', pos: %d", ac.toUtf8().data(), pos ); } QString FilePropertiesDialog::audioCodec() { int pos = ac_listbox->currentRow(); if ( pos < 0 ) return ""; else return aclist[pos].name(); } void FilePropertiesDialog::on_resetDemuxerButton_clicked() { setDemuxer( orig_demuxer ); } void FilePropertiesDialog::on_resetACButton_clicked() { setAudioCodec( orig_ac ); } void FilePropertiesDialog::on_resetVCButton_clicked() { setVideoCodec( orig_vc ); } int FilePropertiesDialog::find(QString s, InfoList &list) { int n=0; InfoList::iterator it; for ( it = list.begin(); it != list.end(); ++it ) { //qDebug(" * item: '%s', s: '%s'", (*it).name().toUtf8().data(), s.toUtf8().data()); if ((*it).name() == s) return n; n++; } return -1; } // Language change stuff void FilePropertiesDialog::changeEvent(QEvent *e) { if (e->type() == QEvent::LanguageChange) { retranslateStrings(); } else { QDialog::changeEvent(e); } } void FilePropertiesDialog::moveDialog(QPoint diff) { #if QT_VERSION >= 0x050000 // Move the window with some delay. // Seems to work better with Qt 5 static QPoint d; static int count = 0; d += diff; count++; if (count > 3) { QPoint new_pos = pos() + d; if (new_pos.y() < 0) new_pos.setY(0); if (new_pos.x() < 0) new_pos.setX(0); move(new_pos); count = 0; d = QPoint(0,0); } #else move(pos() + diff); #endif } bool FilePropertiesDialog::eventFilter( QObject * object, QEvent * event ) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { drag_state = NOT_FDRAGGING; return false; } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_FDRAGGING; return false; } drag_state = START_FDRAGGING; start_drag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (drag_state != FDRAGGING || mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_FDRAGGING; return false; } // Stop dragging and eat event drag_state = NOT_FDRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (drag_state == NOT_FDRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { drag_state = NOT_FDRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - start_drag; if (drag_state == START_FDRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; drag_state = FDRAGGING; } this->moveDialog(diff); start_drag = pos; event->accept(); return true; } //#include "moc_filepropertiesdialog.cpp" kylin-video/src/merge/errordialog.h0000664000175000017500000000305313233751662016313 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 */ #ifndef _ERRORDIALOG_H_ #define _ERRORDIALOG_H_ #include "ui_errordialog.h" enum EDragState {NOT_EDRAGGING, START_EDRAGGING, EDRAGGING}; class ErrorDialog : public QDialog, public Ui::ErrorDialog { Q_OBJECT public: ErrorDialog( QWidget* parent = 0, Qt::WindowFlags f = 0 ); ~ErrorDialog(); virtual bool eventFilter(QObject *, QEvent *); void moveDialog(QPoint diff); public slots: void setText(QString error); void setLog(QString log_text); void setTitleText(QString error); void hideDetailBtn(); protected slots: void toggleLog(bool); private: EDragState drag_state; QPoint start_drag; }; #endif kylin-video/src/merge/prefsubtitles.ui0000664000175000017500000001253113214706400017051 0ustar fengfeng PrefSubtitles 0 0 470 360 10 20 448 91 Autoload 9 9 9 9 6 Qt::Horizontal QSizePolicy::Expanding 131 21 Autoload subtitles files (*.srt, *.sub...): false font_autoload_combo Same name as movie All subs containing movie name All subs in directory 10 120 448 104 Encoding 6 0 0 0 0 Default subtitle encoding: false font_encoding_combo 0 0 false Qt::Horizontal QSizePolicy::Expanding 161 31 0 Try to autodetect for this language: false 0 0 Qt::Horizontal 40 20 kylin-video/src/merge/prefscreenshot.ui0000664000175000017500000000577613214706400017225 0ustar fengfeng PrefScreenShot 0 0 470 360 10 20 448 128 Screenshots Enable screenshots false Folder: false screenshot_edit false false Template: screenshot_template_edit false false Format: screenshot_format_combo false FileChooser QLineEdit
../smplayer/filechooser.h
kylin-video/src/merge/prefperformance.cpp0000664000175000017500000002576313233751662017527 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 "prefperformance.h" #include "../smplayer/images.h" #include "../smplayer/global.h" #include "../smplayer/preferences.h" #include using namespace Global; PrefPerformance::PrefPerformance(QWidget * parent, Qt::WindowFlags f) : PrefWidget(parent, f ) { setupUi(this); hwdec_combo->addItem(tr("None"), "no"); hwdec_combo->addItem(tr("Auto"), "auto"); hwdec_combo->addItem("vdpau", "vdpau"); hwdec_combo->addItem("vaapi", "vaapi"); hwdec_combo->addItem("vaapi-copy", "vaapi-copy"); retranslateStrings(); } PrefPerformance::~PrefPerformance() { } void PrefPerformance::setCurrentPage(int index) { } QString PrefPerformance::sectionName() { return tr("Performance"); } QPixmap PrefPerformance::sectionIcon() { return Images::icon("pref_performance", 22); } void PrefPerformance::retranslateStrings() { retranslateUi(this); groupBox_cache->setStyleSheet("QGroupBox{border:none;margin-top:20px;font-size:14px;}QGroupBox:title{subcontrol-origin: margin;subcontrol-position: top left;padding: 0px 1px;color: #999999;font-family: 方正黑体_GBK;font-weight:bold;}"); groupBox_decode->setStyleSheet("QGroupBox{border:none;margin-top:20px;font-size:14px;}QGroupBox:title{subcontrol-origin: margin;subcontrol-position: top left;padding: 0px 1px;color: #999999;font-family: 方正黑体_GBK;font-weight:bold;}"); cache_streams_spin->setStyleSheet("QSpinBox {height: 24px;min-width: 40px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QSpinBox:hover {height: 24px;min-width: 40px;background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QSpinBox:enabled {color: #999999;}QSpinBox:enabled:hover, QSpinBox:enabled:focus {color: #999999;}QSpinBox:!enabled {color: #383838;background: transparent;}QSpinBox::up-button {border: none;width: 17px;height: 12px;image: url(:/res/spin_top_arrow_normal.png);}QSpinBox::up-button:hover {image: url(:/res/spin_top_arrow_hover.png);}QSpinBox::up-button:pressed {image: url(:/res/spin_top_arrow_press.png);}QSpinBox::up-button:!enabled {background: transparent;}QSpinBox::up-button:enabled:hover {background: rgb(255, 255, 255, 30);}QSpinBox::down-button {border: none;width: 17px;height: 12px;image: url(:/res/spin_bottom_arrow_normal.png);}QSpinBox::down-button:hover {image: url(:/res/spin_bottom_arrow_hover.png);}QSpinBox::down-button:pressed {image: url(:/res/spin_bottom_arrow_press.png);}QSpinBox::down-button:!enabled {background: transparent;}QSpinBox::down-button:hover{background: #0f0f0f;}"); cache_files_spin->setStyleSheet("QSpinBox {height: 24px;min-width: 40px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QSpinBox:hover {height: 24px;min-width: 40px;background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QSpinBox:enabled {color: #999999;}QSpinBox:enabled:hover, QSpinBox:enabled:focus {color: #999999;}QSpinBox:!enabled {color: #383838;background: transparent;}QSpinBox::up-button {border: none;width: 17px;height: 12px;image: url(:/res/spin_top_arrow_normal.png);}QSpinBox::up-button:hover {image: url(:/res/spin_top_arrow_hover.png);}QSpinBox::up-button:pressed {image: url(:/res/spin_top_arrow_press.png);}QSpinBox::up-button:!enabled {background: transparent;}QSpinBox::up-button:enabled:hover {background: rgb(255, 255, 255, 30);}QSpinBox::down-button {border: none;width: 17px;height: 12px;image: url(:/res/spin_bottom_arrow_normal.png);}QSpinBox::down-button:hover {image: url(:/res/spin_bottom_arrow_hover.png);}QSpinBox::down-button:pressed {image: url(:/res/spin_bottom_arrow_press.png);}QSpinBox::down-button:!enabled {background: transparent;}QSpinBox::down-button:hover{background: #0f0f0f;}"); threads_spin->setStyleSheet("QSpinBox {height: 24px;min-width: 40px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QSpinBox:hover {height: 24px;min-width: 40px;background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QSpinBox:enabled {color: #999999;}QSpinBox:enabled:hover, QSpinBox:enabled:focus {color: #999999;}QSpinBox:!enabled {color: #383838;background: transparent;}QSpinBox::up-button {border: none;width: 17px;height: 12px;image: url(:/res/spin_top_arrow_normal.png);}QSpinBox::up-button:hover {image: url(:/res/spin_top_arrow_hover.png);}QSpinBox::up-button:pressed {image: url(:/res/spin_top_arrow_press.png);}QSpinBox::up-button:!enabled {background: transparent;}QSpinBox::up-button:enabled:hover {background: rgb(255, 255, 255, 30);}QSpinBox::down-button {border: none;width: 17px;height: 12px;image: url(:/res/spin_bottom_arrow_normal.png);}QSpinBox::down-button:hover {image: url(:/res/spin_bottom_arrow_hover.png);}QSpinBox::down-button:pressed {image: url(:/res/spin_bottom_arrow_press.png);}QSpinBox::down-button:!enabled {background: transparent;}QSpinBox::down-button:hover{background: #0f0f0f;}"); hwdec_combo->setStyleSheet("QComboBox{width:150px;height:24px;border:1px solid #000000;background:#0f0f0f;font-size:12px;font-family:方正黑体_GBK;background-position:center left;padding-left:5px;color:#999999;selection-color:#ffffff;selection-background-color:#1f1f1f;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox::drop-down {width:17px;border:none;background:transparent;}QComboBox::drop-down:hover {background:transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView{border:1px solid #0a9ff5;background:#262626;outline:none;}"); // hwdec_combo->setStyleSheet("QComboBox{width:150px;height:24px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:enabled {background:#0f0f0f;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox:enabled:hover, QComboBox:enabled:focus {color: #1f1f1f;}QComboBox::drop-down {width: 17px;border: none;background: transparent;}QComboBox::drop-down:hover {background: transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView {border: 1px solid #0a9ff5;background: #1f1f1f;outline: none;}"); cache_local_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); cache_streams_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); kb_local_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); kb_streams_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); thread_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); hd_decode_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); createHelp(); } void PrefPerformance::setData(Preferences * pref) { setCacheForFiles( pref->cache_for_files ); setCacheForStreams( pref->cache_for_streams ); setThreads(pref->threads); setHwdec(pref->hwdec); } void PrefPerformance::getData(Preferences * pref) { requires_restart = false; TEST_AND_SET(pref->cache_for_files, cacheForFiles()); TEST_AND_SET(pref->cache_for_streams, cacheForStreams()); TEST_AND_SET(pref->threads, threads()); TEST_AND_SET(pref->hwdec, hwdec()); } void PrefPerformance::setCacheForFiles(int n) { cache_files_spin->setValue(n); } int PrefPerformance::cacheForFiles() { return cache_files_spin->value(); } void PrefPerformance::setCacheForStreams(int n) { cache_streams_spin->setValue(n); } int PrefPerformance::cacheForStreams() { return cache_streams_spin->value(); } void PrefPerformance::setThreads(int v) { threads_spin->setValue(v); } int PrefPerformance::threads() { return threads_spin->value(); } void PrefPerformance::setHwdec(const QString & v) { int idx = hwdec_combo->findData(v); if (idx < 0) idx = 0; hwdec_combo->setCurrentIndex(idx); } QString PrefPerformance::hwdec() { int idx = hwdec_combo->currentIndex(); return hwdec_combo->itemData(idx).toString(); } void PrefPerformance::createHelp() { clearHelp(); addSectionTitle(tr("Performance")); setWhatsThis(threads_spin, tr("Threads for decoding"), tr("Sets the number of threads to use for decoding. Only for " "MPEG-1/2 and H.264") ); setWhatsThis(hwdec_combo, tr("Hardware decoding"), tr("Sets the hardware video decoding API. " "If hardware decoding is not possible, software decoding will be used instead.") + " " + tr("Available options:") + "
    " "
  • " + tr("None: only software decoding will be used.") + "
  • " "
  • " + tr("Auto: it tries to automatically enable hardware decoding using the first available method.") + "
  • " #ifdef Q_OS_LINUX "
  • " + tr("vdpau: for the vdpau and opengl video outputs.") + "
  • " "
  • " + tr("vaapi: for the opengl and vaapi video outputs. For Intel GPUs only.") + "
  • " "
  • " + tr("vaapi-copy: it copies video back into system RAM. For Intel GPUs only.") + "
  • " #endif "
" + tr("This option only works with mpv.")); addSectionTitle(tr("Cache")); setWhatsThis(cache_files_spin, tr("Cache for files"), tr("This option specifies how much memory (in kBytes) to use when " "precaching a file.") ); setWhatsThis(cache_streams_spin, tr("Cache for streams"), tr("This option specifies how much memory (in kBytes) to use when " "precaching a URL.") ); } //#include "moc_prefperformance.cpp" kylin-video/src/merge/audiodelaydialog.ui0000664000175000017500000000460313214706400017457 0ustar fengfeng AudioDelayDialog 0 0 380 170 380 170 380 170 Audio delay 160 130 91 25 OK 260 130 91 25 Cancel 344 0 36 36 95 10 191 20 Audio delay Qt::AlignCenter 30 50 341 20 Audio delay (in milliseconds): 30 80 320 27 -3600000 3600000 kylin-video/src/merge/lineedit_with_icon.h0000664000175000017500000000245113233751662017643 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 */ #ifndef LINEEDIT_WITH_ICON_H #define LINEEDIT_WITH_ICON_H #include class QToolButton; class LineEditWithIcon : public QLineEdit { Q_OBJECT public: LineEditWithIcon(QWidget *parent = 0); void setIcon(const QPixmap & pixmap); protected: void resizeEvent(QResizeEvent *); virtual void setupButton(); protected: QToolButton *button; }; #endif kylin-video/src/merge/preferencesdialog.h0000664000175000017500000000603413233751662017465 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 */ #ifndef _PREFERENCESDIALOG_H_ #define _PREFERENCESDIALOG_H_ #include "ui_preferencesdialog.h" enum PDragState {NOT_PDRAGGING, START_PDRAGGING, PDRAGGING}; class QTextBrowser; class QPushButton; class PrefWidget; class PrefGeneral; class PrefVideo; class PrefAudio; class PrefPerformance; class PrefSubtitles; class PrefScreenShot; class PrefShortCut; //class PrefInterface; //class PrefAdvanced; //class PrefPlaylist; //class PrefTV; //class PrefUpdates; //class PrefNetwork; //class PrefAssociations; class Preferences; class TitleButton; class PreferencesDialog : public QDialog, public Ui::PreferencesDialog { Q_OBJECT public: enum Section { General=0, Drives=1, Performance=2, Subtitles=3, Gui=4, Mouse=5, Advanced=6, Associations=7 }; PreferencesDialog(QString arch_type = "", QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~PreferencesDialog(); PrefShortCut *mod_shortcut_page() { return page_shortcut; } void addSection(PrefWidget *w); // Pass data to the standard dialogs void setData(Preferences * pref); // Apply changes void getData(Preferences * pref); // Return true if the mplayer process should be restarted. bool requiresRestart(); virtual bool eventFilter(QObject *, QEvent *); void moveDialog(QPoint diff); public slots: void showSection(Section s); virtual void accept(); // Reimplemented to send a signal virtual void reject(); signals: void applied(); void generalclicked(int id); void performanceclicked(int id); void subtitlesclicked(int id); protected: virtual void retranslateStrings(); virtual void changeEvent ( QEvent * event ) ; protected slots: void apply(); public slots: void onButtonClicked(int id); void setCurrentID(int id); void switchCurrentIDPage(int id); private: QList m_buttonList; protected: PrefGeneral * page_general; PrefVideo * page_video; PrefAudio * page_audio; PrefPerformance * page_performance; PrefSubtitles * page_subtitles; PrefScreenShot * page_screenshot; PrefShortCut *page_shortcut; private: PDragState drag_state; QPoint start_drag; }; #endif kylin-video/src/merge/audiodelaydialog.h0000664000175000017500000000307713233751662017310 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 */ #ifndef _AUDIODELAYDIALOG_H_ #define _AUDIODELAYDIALOG_H_ #include "ui_audiodelaydialog.h" #include #include enum AADragState {NOT_AADRAGGING, START_AADRAGGING, AADRAGGING}; class AudioDelayDialog : public QDialog, public Ui::AudioDelayDialog { Q_OBJECT public: AudioDelayDialog( QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~AudioDelayDialog(); void setDefaultValue(int audio_delay); int getCurrentValue(); void initConnect(); virtual bool eventFilter(QObject *, QEvent *); void moveDialog(QPoint diff); public slots: private: AADragState drag_state; QPoint start_drag; }; #endif kylin-video/src/merge/prefgeneral.h0000664000175000017500000000367113233751662016302 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 */ #ifndef _PREFGENERAL_H_ #define _PREFGENERAL_H_ #include "ui_prefgeneral.h" #include "../smplayer/prefwidget.h" #include "../smplayer/inforeader.h" #include "../smplayer/deviceinfo.h" #include "../smplayer/preferences.h" class PrefGeneral : public PrefWidget, public Ui::PrefGeneral { Q_OBJECT public: PrefGeneral( QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~PrefGeneral(); // Pass data to the dialog void setData(Preferences * pref); // Apply changes void getData(Preferences * pref); bool fileSettingsMethodChanged() { return filesettings_method_changed; }; public slots: void selectRadioButton(); protected: virtual void createHelp(); // Tab General void setMplayerPath(QString path); QString mplayerPath(); void setPauseWhenHidden(bool b); bool pauseWhenHidden(); void setPreviewWhenPlaying(bool b); bool previewWhenPlaying(); signals: void ready_to_update_driver(); protected: virtual void retranslateStrings(); private: bool filesettings_method_changed; }; #endif kylin-video/src/merge/prefsubtitles.cpp0000664000175000017500000002517013233751662017234 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 "prefsubtitles.h" #include "../smplayer/images.h" #include "../smplayer/preferences.h" #include "paths.h" #include "../smplayer/filedialog.h" #include "../smplayer/languages.h" #include #include PrefSubtitles::PrefSubtitles(QWidget * parent, Qt::WindowFlags f) : PrefWidget(parent, f ) { setupUi(this); retranslateStrings(); } PrefSubtitles::~PrefSubtitles() { } void PrefSubtitles::setCurrentPage(int index) { qDebug() << "PrefSubtitles::setCurrentPage index=" << index; } QString PrefSubtitles::sectionName() { return tr("Subtitles"); } QPixmap PrefSubtitles::sectionIcon() { return Images::icon("pref_subtitles", 22); } void PrefSubtitles::retranslateStrings() { int font_autoload_item = font_autoload_combo->currentIndex(); retranslateUi(this); groupBox_autoload->setStyleSheet("QGroupBox{border:none;margin-top:20px;font-size:14px;}QGroupBox:title{subcontrol-origin: margin;subcontrol-position: top left;padding: 0px 1px;color: #999999;font-family: 方正黑体_GBK;font-weight:bold;}"); groupBox_encoding->setStyleSheet("QGroupBox{border:none;margin-top:20px;font-size:14px;}QGroupBox:title{subcontrol-origin: margin;subcontrol-position: top left;padding: 0px 1px;color: #999999;font-family: 方正黑体_GBK;font-weight:bold;}"); font_autoload_combo->setStyleSheet("QComboBox{width:150px;height:24px;border:1px solid #000000;background:#0f0f0f;font-size:12px;font-family:方正黑体_GBK;background-position:center left;padding-left:5px;color:#999999;selection-color:#ffffff;selection-background-color:#1f1f1f;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox::drop-down {width:17px;border:none;background:transparent;}QComboBox::drop-down:hover {background:transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView{border:1px solid #0a9ff5;background:#262626;outline:none;}"); font_encoding_combo->setStyleSheet("QComboBox{width:150px;height:24px;border:1px solid #000000;background:#0f0f0f;font-size:12px;font-family:方正黑体_GBK;background-position:center left;padding-left:5px;color:#999999;selection-color:#ffffff;selection-background-color:#1f1f1f;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox::drop-down {width:17px;border:none;background:transparent;}QComboBox::drop-down:hover {background:transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView{border:1px solid #0a9ff5;background:#262626;outline:none;}"); enca_lang_combo->setStyleSheet("QComboBox{width:150px;height:24px;border:1px solid #000000;background:#0f0f0f;font-size:12px;font-family:方正黑体_GBK;background-position:center left;padding-left:5px;color:#999999;selection-color:#ffffff;selection-background-color:#1f1f1f;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox::drop-down {width:17px;border:none;background:transparent;}QComboBox::drop-down:hover {background:transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView{border:1px solid #0a9ff5;background:#262626;outline:none;}"); // font_autoload_combo->setStyleSheet("QComboBox{width:150px;height:24px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:enabled {background:#0f0f0f;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox:enabled:hover, QComboBox:enabled:focus {color: #1f1f1f;}QComboBox::drop-down {width: 17px;border: none;background: transparent;}QComboBox::drop-down:hover {background: transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView {border: 1px solid #0a9ff5;background: #1f1f1f;outline: none;}"); // font_encoding_combo->setStyleSheet("QComboBox{width:150px;height:24px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:enabled {background:#0f0f0f;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox:enabled:hover, QComboBox:enabled:focus {color: #1f1f1f;}QComboBox::drop-down {width: 17px;border: none;background: transparent;}QComboBox::drop-down:hover {background: transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView {border: 1px solid #0a9ff5;background: #1f1f1f;outline: none;}"); // enca_lang_combo->setStyleSheet("QComboBox{width:150px;height:24px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:enabled {background:#0f0f0f;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox:enabled:hover, QComboBox:enabled:focus {color: #1f1f1f;}QComboBox::drop-down {width: 17px;border: none;background: transparent;}QComboBox::drop-down:hover {background: transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView {border: 1px solid #0a9ff5;background: #1f1f1f;outline: none;}"); autoload_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); encoding_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); use_enca_check->setFocusPolicy(Qt::NoFocus); font_autoload_combo->setCurrentIndex(font_autoload_item); connect(use_enca_check, SIGNAL(toggled(bool)), enca_lang_combo, SLOT(setEnabled(bool))); // Encodings combo QString current_encoding = fontEncoding(); QString current_enca_lang = encaLang(); font_encoding_combo->clear(); enca_lang_combo->clear(); QMap l = Languages::encodings(); QMapIterator i(l); while (i.hasNext()) { i.next(); font_encoding_combo->addItem( i.value() + " (" + i.key() + ")", i.key() ); } l = Languages::enca(); i = l; while (i.hasNext()) { i.next(); enca_lang_combo->addItem( i.value() + " (" + i.key() + ")", i.key() ); } font_encoding_combo->model()->sort(0); enca_lang_combo->model()->sort(0); setFontEncoding(current_encoding); setEncaLang(current_enca_lang); createHelp(); } void PrefSubtitles::setData(Preferences * pref) { setFontEncoding( pref->subcp ); setUseEnca( pref->use_enca ); setEncaLang( pref->enca_lang ); } void PrefSubtitles::getData(Preferences * pref) { requires_restart = false; TEST_AND_SET(pref->subcp, fontEncoding()); TEST_AND_SET(pref->use_enca, useEnca()); TEST_AND_SET(pref->enca_lang, encaLang()); } void PrefSubtitles::setFontEncoding(QString s) { int i = font_encoding_combo->findData(s); font_encoding_combo->setCurrentIndex(i); } QString PrefSubtitles::fontEncoding() { int index = font_encoding_combo->currentIndex(); return font_encoding_combo->itemData(index).toString(); } void PrefSubtitles::setEncaLang(QString s) { int i = enca_lang_combo->findData(s); enca_lang_combo->setCurrentIndex(i); } QString PrefSubtitles::encaLang() { int index = enca_lang_combo->currentIndex(); return enca_lang_combo->itemData(index).toString(); } void PrefSubtitles::setUseEnca(bool b) { use_enca_check->setChecked(b); } bool PrefSubtitles::useEnca() { return use_enca_check->isChecked(); } void PrefSubtitles::createHelp() { clearHelp(); addSectionTitle(tr("Subtitles")); setWhatsThis(font_autoload_combo, tr("Autoload"), tr("Select the subtitle autoload method.") ); setWhatsThis(font_encoding_combo, tr("Default subtitle encoding"), tr("Select the encoding which will be used for subtitle files " "by default.") ); setWhatsThis(use_enca_check, tr("Try to autodetect for this language"), tr("When this option is on, the encoding of the subtitles will be " "tried to be autodetected for the given language. " "It will fall back to the default encoding if the autodetection " "fails. This option requires a MPlayer compiled with ENCA " "support.") ); setWhatsThis(enca_lang_combo, tr("Subtitle language"), tr("Select the language for which you want the encoding to be guessed " "automatically.") ); addSectionTitle(tr("Font")); } //#include "moc_prefsubtitles.cpp" kylin-video/src/merge/preferencesdialog.cpp0000664000175000017500000002761513233751662020030 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 "preferencesdialog.h" #include #include #include #include "prefgeneral.h" #include "prefvideo.h" #include "prefaudio.h" #include "prefperformance.h" #include "prefsubtitles.h" #include "prefscreenshot.h" #include "prefshortcut.h" #include "../kylin/titlebutton.h" #include "../smplayer/preferences.h" #include #include #include PreferencesDialog::PreferencesDialog(QString arch_type, QWidget * parent, Qt::WindowFlags f) : QDialog(parent, f ) , drag_state(NOT_PDRAGGING) , start_drag(QPoint(0,0)) { setupUi(this); this->setFixedSize(675, 425); this->setStyleSheet("QDialog{border: 1px solid #121212;border-radius:1px;background-color:#1f1f1f;}"); this->setWindowIcon(QIcon(":/res/kylin-video.png")); this->setAttribute(Qt::WA_DeleteOnClose); this->setWindowFlags(Qt::FramelessWindowHint); this->setAutoFillBackground(true); this->setMouseTracking(true); installEventFilter(this); title_widget->setAutoFillBackground(true); title_widget->setStyleSheet("QWidget{border:none;background-color:#2e2e2e;}"); connect(okButton, SIGNAL(clicked()), this, SLOT(accept())); connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject())); connect(applyButton, SIGNAL(clicked()), this, SLOT(apply())); okButton->setFixedSize(91, 25); cancelButton->setFixedSize(91, 25); applyButton->setFixedSize(91, 25); okButton->setFocusPolicy(Qt::NoFocus); cancelButton->setFocusPolicy(Qt::NoFocus); applyButton->setFocusPolicy(Qt::NoFocus); okButton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); cancelButton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #000000;color:#999999;}QPushButton:hover{background-color:#1f1f1f;border:1px solid #0f0f0f;color:#ffffff;} QPushButton:pressed{background-color:#0d0d0d;border:1px solid #000000;color:#ffffff;}"); applyButton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); title_label->setStyleSheet("QLabel{background:transparent;font-family: 方正黑体_GBK;font-size:20px;color:#999999;}"); QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 5, 0, 0); layout->setSpacing(0); page_general = new PrefGeneral; addSection(page_general); pages->setCurrentWidget(page_general); TitleButton *btn = new TitleButton(0, false, tr("General")); connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); layout->addWidget(btn); m_buttonList << btn; btn->setActived(true); page_video = new PrefVideo(arch_type); addSection(page_video); btn = new TitleButton(1, false, tr("Video")); connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); layout->addWidget(btn); m_buttonList << btn; page_audio = new PrefAudio; addSection(page_audio); btn = new TitleButton(2, false, tr("Audio")); connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); layout->addWidget(btn); m_buttonList << btn; page_performance = new PrefPerformance; addSection( page_performance ); btn = new TitleButton(3, false, tr("Performance")); connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); layout->addWidget(btn); m_buttonList << btn; page_subtitles = new PrefSubtitles; addSection(page_subtitles); btn = new TitleButton(4, false, tr("Subtitles")); connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); layout->addWidget(btn); m_buttonList << btn; page_screenshot = new PrefScreenShot; addSection(page_screenshot); btn = new TitleButton(5, false, tr("ScreenShot")); connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); layout->addWidget(btn); m_buttonList << btn; page_shortcut = new PrefShortCut; addSection(page_shortcut); btn = new TitleButton(6, false, tr("Shortcut Key")); connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); layout->addWidget(btn); m_buttonList << btn; layout->addStretch(); sections->setLayout(layout); connect(page_general, SIGNAL(ready_to_update_driver()), page_video, SLOT(update_driver_combobox())); connect(page_general, SIGNAL(ready_to_update_driver()), page_audio, SLOT(update_driver_combobox())); retranslateStrings(); } PreferencesDialog::~PreferencesDialog() { for(int i=0; iid() == id) { button->setActived(true); } else { button->setActived(false); } } } void PreferencesDialog::onButtonClicked(int id) { setCurrentID(id); if (id == 0) { pages->setCurrentWidget(page_general); } else if (id == 1) { pages->setCurrentWidget(page_video); } else if (id == 2) { pages->setCurrentWidget(page_audio); } else if (id == 3) { pages->setCurrentWidget(page_performance); } else if (id == 4) { pages->setCurrentWidget(page_subtitles); } else if (id == 5) { pages->setCurrentWidget(page_screenshot); } else if (id == 6) { pages->setCurrentWidget(page_shortcut); } } void PreferencesDialog::showSection(Section s) { qDebug("PreferencesDialog::showSection: %d", s); } void PreferencesDialog::retranslateStrings() { retranslateUi(this); icon_label->setPixmap(QPixmap(":/res/settings.png")); okButton->setText(tr("OK")); cancelButton->setText(tr("Cancel")); applyButton->setText(tr("Apply")); } void PreferencesDialog::accept() { hide(); setResult( QDialog::Accepted ); emit applied(); } void PreferencesDialog::apply() { setResult( QDialog::Accepted ); emit applied(); } void PreferencesDialog::reject() { hide(); setResult( QDialog::Rejected ); setResult( QDialog::Accepted ); } void PreferencesDialog::addSection(PrefWidget *w) { pages->addWidget(w); } void PreferencesDialog::setData(Preferences * pref) { page_general->setData(pref); page_video->setData(pref); page_audio->setData(pref); page_performance->setData(pref); page_subtitles->setData(pref); page_screenshot->setData(pref); page_shortcut->setData(pref); } void PreferencesDialog::getData(Preferences * pref) { page_general->getData(pref); page_video->getData(pref); page_audio->getData(pref); page_performance->getData(pref); page_subtitles->getData(pref); page_screenshot->getData(pref); page_shortcut->getData(pref); } bool PreferencesDialog::requiresRestart() { bool need_restart = page_general->requiresRestart(); if (!need_restart) need_restart = page_video->requiresRestart(); if (!need_restart) need_restart = page_audio->requiresRestart(); if (!need_restart) need_restart = page_performance->requiresRestart(); if (!need_restart) need_restart = page_subtitles->requiresRestart(); if (!need_restart) need_restart = page_screenshot->requiresRestart(); if (!need_restart) need_restart = page_shortcut->requiresRestart(); return need_restart; } // Language change stuff void PreferencesDialog::changeEvent(QEvent *e) { if (e->type() == QEvent::LanguageChange) { retranslateStrings(); } else { QDialog::changeEvent(e); } } void PreferencesDialog::moveDialog(QPoint diff) { #if QT_VERSION >= 0x050000 // Move the window with some delay. // Seems to work better with Qt 5 static QPoint d; static int count = 0; d += diff; count++; if (count > 3) { // qDebug() << "> 3PreferencesDialog::moveWindowDiff:" << d; QPoint new_pos = pos() + d; if (new_pos.y() < 0) new_pos.setY(0); if (new_pos.x() < 0) new_pos.setX(0); // qDebug() << "PreferencesDialog::moveWindowDiff: new_pos:" << new_pos; move(new_pos); count = 0; d = QPoint(0,0); } #else move(pos() + diff); #endif } bool PreferencesDialog::eventFilter( QObject * object, QEvent * event ) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { drag_state = NOT_PDRAGGING; return false; } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_PDRAGGING; return false; } drag_state = START_PDRAGGING; start_drag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (drag_state != PDRAGGING || mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_PDRAGGING; return false; } // Stop dragging and eat event drag_state = NOT_PDRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (drag_state == NOT_PDRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { drag_state = NOT_PDRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - start_drag; if (drag_state == START_PDRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; drag_state = PDRAGGING; } this->moveDialog(diff); start_drag = pos; event->accept(); return true; } //#include "moc_preferencesdialog.cpp" kylin-video/src/merge/prefaudio.h0000664000175000017500000000454213233751662015764 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 */ #ifndef _PREFAUDIO_H_ #define _PREFAUDIO_H_ #include "ui_prefaudio.h" #include "../smplayer/prefwidget.h" #include "../smplayer/inforeader.h" #include "../smplayer/deviceinfo.h" #include "../smplayer/preferences.h" class PrefAudio : public PrefWidget, public Ui::PrefAudio { Q_OBJECT public: PrefAudio( QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~PrefAudio(); // Pass data to the dialog void setData(Preferences * pref); // Apply changes void getData(Preferences * pref); bool fileSettingsMethodChanged() { return filesettings_method_changed; }; protected: virtual void createHelp(); void setAO( QString ao_driver ); QString AO(); void setGlobalVolume(bool b); bool globalVolume(); void setAutoSyncFactor(int factor); int autoSyncFactor(); void setAutoSyncActivated(bool b); bool autoSyncActivated(); void setMc(double value); double mc(); void setMcActivated(bool b); bool mcActivated(); void setSoftVol(bool b); bool softVol(); void setInitialVolNorm(bool b); bool initialVolNorm(); void setAmplification(int n); int amplification(); void setAudioChannels(int ID); int audioChannels(); protected slots: void ao_combo_changed(int); public slots: void update_driver_combobox(); protected: virtual void retranslateStrings(); void updateDriverCombos(); InfoList ao_list; DeviceList alsa_devices; DeviceList xv_adaptors; private: bool filesettings_method_changed; }; #endif kylin-video/src/merge/prefvideo.cpp0000664000175000017500000002433513233751662016326 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 "prefvideo.h" #include "../smplayer/preferences.h" #include "../smplayer/filedialog.h" #include "../smplayer/images.h" #include "../smplayer/mediasettings.h" #include "paths.h" #include "../smplayer/playerid.h" #include #include "../smplayer/deviceinfo.h" PrefVideo::PrefVideo(QString arch_type, QWidget * parent, Qt::WindowFlags f) : PrefWidget(parent, f ), arch(arch_type) { setupUi(this); // Read driver info from InfoReader: InfoReader * i = InfoReader::obj(); i->getInfo(); vo_list = i->voList(); alsa_devices = DeviceInfo::alsaDevices(); xv_adaptors = DeviceInfo::xvAdaptors(); connect(vo_combo, SIGNAL(currentIndexChanged(int)), this, SLOT(vo_combo_changed(int))); retranslateStrings(); } PrefVideo::~PrefVideo() { } void PrefVideo::retranslateStrings() { retranslateUi(this); postprocessing_check->setFocusPolicy(Qt::NoFocus); eq2_check->setFocusPolicy(Qt::NoFocus); double_buffer_check->setFocusPolicy(Qt::NoFocus); direct_rendering_check->setFocusPolicy(Qt::NoFocus); use_slices_check->setFocusPolicy(Qt::NoFocus); vo_combo->setStyleSheet("QComboBox{width:150px;height:24px;border:1px solid #000000;background:#0f0f0f;font-size:12px;font-family:方正黑体_GBK;background-position:center left;padding-left:5px;color:#999999;selection-color:#ffffff;selection-background-color:#1f1f1f;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox::drop-down {width:17px;border:none;background:transparent;}QComboBox::drop-down:hover {background:transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView{border:1px solid #0a9ff5;background:#262626;outline:none;}"); // vo_combo->setStyleSheet("QComboBox{width:150px;height:24px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:enabled {background:#0f0f0f;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox:enabled:hover, QComboBox:enabled:focus {color: #1f1f1f;}QComboBox::drop-down {width: 17px;border: none;background: transparent;}QComboBox::drop-down:hover {background: transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView {border: 1px solid #0a9ff5;background: #1f1f1f;outline: none;}"); vo_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); updateDriverCombos(); createHelp(); } void PrefVideo::setData(Preferences *pref) { QString vo = pref->vo; if (vo.isEmpty()) { //kobe pref->vo = "xv"; vo = "xv"; } setVO( vo ); setEq2( pref->use_soft_video_eq ); setInitialPostprocessing(pref->initial_postprocessing); setDirectRendering(pref->use_direct_rendering); setDoubleBuffer(pref->use_double_buffer); setUseSlices(pref->use_slices); } void PrefVideo::getData(Preferences * pref) { requires_restart = false; filesettings_method_changed = false; TEST_AND_SET(pref->vo, VO()); TEST_AND_SET(pref->use_soft_video_eq, eq2()); pref->initial_postprocessing = initialPostprocessing(); TEST_AND_SET(pref->use_direct_rendering, directRendering()); TEST_AND_SET(pref->use_double_buffer, doubleBuffer()); TEST_AND_SET(pref->use_slices, useSlices()); } void PrefVideo::update_driver_combobox() { InfoReader * i = InfoReader::obj(); i->getInfo(); // Update the drivers list at the same time vo_list = i->voList(); updateDriverCombos(); } void PrefVideo::updateDriverCombos() { QString current_vo = VO(); vo_combo->clear(); vo_combo->addItem(tr("Default"), "player_default"); QString vo; for ( int n = 0; n < vo_list.count(); n++ ) { vo = vo_list[n].name(); if (vo == "x11") { vo_combo->addItem("x11 (" + tr("slow") + ")", vo); } //当播放引擎为mplayer时如果选择sdl,视频显示尺寸可能异常,当播放引擎为mpv时如果选择sdl,视频窗口将分离。 else if (vo == "xv" || vo == "gl_nosw" /* || vo == "sdl"*/) { vo_combo->addItem(vo, vo); } else if (vo == "vdpau") {//kobe for arm 硬件解码基于飞腾上的只能基于vdpau接口来实现 if (arch == "aarch64") { vo_combo->addItem(vo, vo); } } /*else if (vo == "gl") {//kobe:此类驱动在arm64上会导致机器卡死 Bug:3152 // vo_combo->addItem( vo, vo);//kobe // vo_combo->addItem( "gl (" + tr("fast") + ")", "gl:yuv=2:force-pbo");//kobe // vo_combo->addItem( "gl (" + tr("fast - ATI cards") + ")", "gl:yuv=2:force-pbo:ati-hack");//kobe // vo_combo->addItem( "gl (yuv)", "gl:yuv=3");//kobe } else if (vo == "gl2") { vo_combo->addItem( vo, vo); vo_combo->addItem( "gl2 (yuv)", "gl2:yuv=3"); } else if (vo == "gl_tiled") { vo_combo->addItem( vo, vo); vo_combo->addItem( "gl_tiled (yuv)", "gl_tiled:yuv=3"); } else if (vo == "null" || vo == "png" || vo == "jpeg" || vo == "gif89a" || vo == "tga" || vo == "pnm" || vo == "md5sum" ) { ; // Nothing to do } else if (vo == "fbdev" || vo == "aa" || vo == "directfb" || vo == "mpegpes") {//kobe:此类驱动在arm64上会导致机器卡死 Bug:3152 ; // Nothing to do } else if (vo == "vdpau") { ; // kobe: Nothing to do } else vo_combo->addItem( vo, vo );*/ } // vo_combo->addItem( tr("User defined..."), "user_defined" );//kobe:去掉自定义驱动选项 setVO(current_vo); } void PrefVideo::setVO( QString vo_driver ) { int idx = vo_combo->findData( vo_driver ); if (idx != -1) { vo_combo->setCurrentIndex(idx); } else { //kobe idx = vo_combo->findData("xv"); vo_combo->setCurrentIndex(idx); // vo_combo->setCurrentIndex(vo_combo->findData("user_defined")); // vo_user_defined_edit->setText(vo_driver); } vo_combo_changed(vo_combo->currentIndex()); } QString PrefVideo::VO() { QString vo = vo_combo->itemData(vo_combo->currentIndex()).toString(); // if (vo == "user_defined") { // vo = vo_user_defined_edit->text(); // /* // if (vo.isEmpty()) { // vo = vo_combo->itemData(0).toString(); // qDebug("PrefGeneral::VO: user defined vo is empty, using %s", vo.toUtf8().constData()); // } // */ // } return vo; } void PrefVideo::setEq2(bool b) { eq2_check->setChecked(b); } bool PrefVideo::eq2() { return eq2_check->isChecked(); } void PrefVideo::setInitialPostprocessing(bool b) { postprocessing_check->setChecked(b); } bool PrefVideo::initialPostprocessing() { return postprocessing_check->isChecked(); } void PrefVideo::setDirectRendering(bool b) { direct_rendering_check->setChecked(b); } bool PrefVideo::directRendering() { return direct_rendering_check->isChecked(); } void PrefVideo::setDoubleBuffer(bool b) { double_buffer_check->setChecked(b); } bool PrefVideo::doubleBuffer() { return double_buffer_check->isChecked(); } void PrefVideo::setUseSlices(bool b) { use_slices_check->setChecked(b); } bool PrefVideo::useSlices() { return use_slices_check->isChecked(); } void PrefVideo::vo_combo_changed(int idx) { // qDebug("PrefGeneral::vo_combo_changed: %d", idx); // bool visible = (vo_combo->itemData(idx).toString() == "user_defined"); // vo_user_defined_edit->setVisible(visible); // vo_user_defined_edit->setFocus(); } void PrefVideo::createHelp() { clearHelp(); setWhatsThis(vo_combo, tr("Video output driver"), tr("Select the video output driver. %1 provides the best performance.") .arg("xv") ); setWhatsThis(postprocessing_check, tr("Enable postprocessing by default"), tr("Postprocessing will be used by default on new opened files.") ); setWhatsThis(eq2_check, tr("Software video equalizer"), tr("You can check this option if video equalizer is not supported by " "your graphic card or the selected video output driver.
" "Note: this option can be incompatible with some video " "output drivers.") ); setWhatsThis(direct_rendering_check, tr("Direct rendering"), tr("If checked, turns on direct rendering (not supported by all " "codecs and video outputs)
" "Warning: May cause OSD/SUB corruption!") ); setWhatsThis(double_buffer_check, tr("Double buffering"), tr("Double buffering fixes flicker by storing two frames in memory, " "and displaying one while decoding another. If disabled it can " "affect OSD negatively, but often removes OSD flickering.") ); setWhatsThis(use_slices_check, tr("Draw video using slices"), tr("Enable/disable drawing video by 16-pixel height slices/bands. " "If disabled, the whole frame is drawn in a single run. " "May be faster or slower, depending on video card and available " "cache. It has effect only with libmpeg2 and libavcodec codecs.") ); } //#include "moc_prefvideo.cpp" kylin-video/src/merge/prefaudio.cpp0000664000175000017500000004010413233751662016311 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 "prefaudio.h" #include "../smplayer/preferences.h" #include "../smplayer/filedialog.h" #include "../smplayer/images.h" #include "../smplayer/mediasettings.h" #include "../smplayer/paths.h" #include "../smplayer/playerid.h" #include #include "../smplayer/deviceinfo.h" PrefAudio::PrefAudio(QWidget * parent, Qt::WindowFlags f) : PrefWidget(parent, f ) { setupUi(this); // Read driver info from InfoReader: InfoReader * i = InfoReader::obj(); i->getInfo(); ao_list = i->aoList(); alsa_devices = DeviceInfo::alsaDevices(); xv_adaptors = DeviceInfo::xvAdaptors(); // Channels combo channels_combo->addItem( "2", MediaSettings::ChStereo ); channels_combo->addItem( "4", MediaSettings::ChSurround ); channels_combo->addItem( "6", MediaSettings::ChFull51 ); channels_combo->addItem( "7", MediaSettings::ChFull61 ); channels_combo->addItem( "8", MediaSettings::ChFull71 ); connect(ao_combo, SIGNAL(currentIndexChanged(int)), this, SLOT(ao_combo_changed(int))); retranslateStrings(); } PrefAudio::~PrefAudio() { } void PrefAudio::retranslateStrings() { retranslateUi(this); global_volume_check->setFocusPolicy(Qt::NoFocus); softvol_check->setFocusPolicy(Qt::NoFocus); volnorm_check->setFocusPolicy(Qt::NoFocus); autosync_check->setFocusPolicy(Qt::NoFocus); groupBox_volume->setStyleSheet("QGroupBox{border:none;margin-top:20px;font-size:14px;}QGroupBox:title{subcontrol-origin: margin;subcontrol-position: top left;padding: 0px 1px;color: #999999;font-family: 方正黑体_GBK;font-weight:bold;}"); groupBox_sync->setStyleSheet("QGroupBox{border:none;margin-top:20px;font-size:14px;}QGroupBox:title{subcontrol-origin: margin;subcontrol-position: top left;padding: 0px 1px;color: #999999;font-family: 方正黑体_GBK;font-weight:bold;}"); ao_combo->setStyleSheet("QComboBox{width:150px;height:24px;border:1px solid #000000;background:#0f0f0f;font-size:12px;font-family:方正黑体_GBK;background-position:center left;padding-left:5px;color:#999999;selection-color:#ffffff;selection-background-color:#1f1f1f;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox::drop-down {width:17px;border:none;background:transparent;}QComboBox::drop-down:hover {background:transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView{border:1px solid #0a9ff5;background:#262626;outline:none;}"); channels_combo->setStyleSheet("QComboBox{width:150px;height:24px;border:1px solid #000000;background:#0f0f0f;font-size:12px;font-family:方正黑体_GBK;background-position:center left;padding-left:5px;color:#999999;selection-color:#ffffff;selection-background-color:#1f1f1f;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox::drop-down {width:17px;border:none;background:transparent;}QComboBox::drop-down:hover {background:transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView{border:1px solid #0a9ff5;background:#262626;outline:none;}"); // ao_combo->setStyleSheet("QComboBox{width:150px;height:24px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:enabled {background:#0f0f0f;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox:enabled:hover, QComboBox:enabled:focus {color: #1f1f1f;}QComboBox::drop-down {width: 17px;border: none;background: transparent;}QComboBox::drop-down:hover {background: transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView {border: 1px solid #0a9ff5;background: #1f1f1f;outline: none;}"); // channels_combo->setStyleSheet("QComboBox{width:150px;height:24px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:enabled {background:#0f0f0f;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox:enabled:hover, QComboBox:enabled:focus {color: #1f1f1f;}QComboBox::drop-down {width: 17px;border: none;background: transparent;}QComboBox::drop-down:hover {background: transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView {border: 1px solid #0a9ff5;background: #1f1f1f;outline: none;}"); softvol_max_spin->setStyleSheet("QSpinBox {height: 24px;min-width: 40px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QSpinBox:hover {height: 24px;min-width: 40px;background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QSpinBox:enabled {color: #999999;}QSpinBox:enabled:hover, QSpinBox:enabled:focus {color: #999999;}QSpinBox:!enabled {color: #383838;background: transparent;}QSpinBox::up-button {border: none;width: 17px;height: 12px;image: url(:/res/spin_top_arrow_normal.png);}QSpinBox::up-button:hover {image: url(:/res/spin_top_arrow_hover.png);}QSpinBox::up-button:pressed {image: url(:/res/spin_top_arrow_press.png);}QSpinBox::up-button:!enabled {background: transparent;}QSpinBox::up-button:enabled:hover {background: rgb(255, 255, 255, 30);}QSpinBox::down-button {border: none;width: 17px;height: 12px;image: url(:/res/spin_bottom_arrow_normal.png);}QSpinBox::down-button:hover {image: url(:/res/spin_bottom_arrow_hover.png);}QSpinBox::down-button:pressed {image: url(:/res/spin_bottom_arrow_press.png);}QSpinBox::down-button:!enabled {background: transparent;}QSpinBox::down-button:hover{background: #0f0f0f;}"); autosync_spin->setStyleSheet("QSpinBox {height: 24px;min-width: 40px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QSpinBox:hover {height: 24px;min-width: 40px;background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QSpinBox:enabled {color: #999999;}QSpinBox:enabled:hover, QSpinBox:enabled:focus {color: #999999;}QSpinBox:!enabled {color: #383838;background: transparent;}QSpinBox::up-button {border: none;width: 17px;height: 12px;image: url(:/res/spin_top_arrow_normal.png);}QSpinBox::up-button:hover {image: url(:/res/spin_top_arrow_hover.png);}QSpinBox::up-button:pressed {image: url(:/res/spin_top_arrow_press.png);}QSpinBox::up-button:!enabled {background: transparent;}QSpinBox::up-button:enabled:hover {background: rgb(255, 255, 255, 30);}QSpinBox::down-button {border: none;width: 17px;height: 12px;image: url(:/res/spin_bottom_arrow_normal.png);}QSpinBox::down-button:hover {image: url(:/res/spin_bottom_arrow_hover.png);}QSpinBox::down-button:pressed {image: url(:/res/spin_bottom_arrow_press.png);}QSpinBox::down-button:!enabled {background: transparent;}QSpinBox::down-button:hover{background: #0f0f0f;}"); amplification_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); factor_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); ao_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); connect(softvol_check, SIGNAL(toggled(bool)), softvol_max_spin, SLOT(setEnabled(bool))); connect(autosync_check, SIGNAL(toggled(bool)), autosync_spin, SLOT(setEnabled(bool))); connect(softvol_check, SIGNAL(toggled(bool)), amplification_label, SLOT(setEnabled(bool))); connect(autosync_check, SIGNAL(toggled(bool)), factor_label, SLOT(setEnabled(bool))); channels_combo->setItemText(0, tr("2 (Stereo)") ); channels_combo->setItemText(1, tr("4 (4.0 Surround)") ); channels_combo->setItemText(2, tr("6 (5.1 Surround)") ); channels_combo->setItemText(3, tr("7 (6.1 Surround)") ); channels_combo->setItemText(4, tr("8 (7.1 Surround)") ); updateDriverCombos(); createHelp(); } void PrefAudio::setData(Preferences *pref) { QString ao = pref->ao; setAO(ao); setGlobalVolume(pref->global_volume); setSoftVol(pref->use_soft_vol); setInitialVolNorm(pref->initial_volnorm); setAmplification(pref->softvol_max); setAudioChannels(pref->initial_audio_channels); setAutoSyncActivated(pref->autosync); setAutoSyncFactor(pref->autosync_factor); } void PrefAudio::getData(Preferences * pref) { requires_restart = false; filesettings_method_changed = false; TEST_AND_SET(pref->use_soft_vol, softVol()); pref->global_volume = globalVolume(); pref->initial_volnorm = initialVolNorm(); TEST_AND_SET(pref->softvol_max, amplification()); pref->initial_audio_channels = audioChannels(); TEST_AND_SET(pref->autosync, autoSyncActivated()); TEST_AND_SET(pref->autosync_factor, autoSyncFactor()); } void PrefAudio::update_driver_combobox() { InfoReader * i = InfoReader::obj(); i->getInfo(); // Update the drivers list at the same time ao_list = i->aoList(); updateDriverCombos(); } void PrefAudio::updateDriverCombos() { QString current_ao = AO(); ao_combo->clear(); ao_combo->addItem(tr("Default"), "player_default"); QString ao; for ( int n = 0; n < ao_list.count(); n++) { ao = ao_list[n].name(); if (ao == "oss" || ao == "alsa" || ao == "pulse") { ao_combo->addItem( ao, ao ); } if ((ao == "alsa") && (!alsa_devices.isEmpty())) { for (int n=0; n < alsa_devices.count(); n++) { ao_combo->addItem( "alsa (" + alsa_devices[n].ID().toString() + " - " + alsa_devices[n].desc() + ")", "alsa:device=hw=" + alsa_devices[n].ID().toString() ); } } } setAO(current_ao); } void PrefAudio::setAO( QString ao_driver ) { int idx = ao_combo->findData( ao_driver ); if (idx != -1) { ao_combo->setCurrentIndex(idx); } else { //kobe idx = ao_combo->findData("pulse"); ao_combo->setCurrentIndex(idx); // ao_combo->setCurrentIndex(ao_combo->findData("user_defined")); // ao_user_defined_edit->setText(ao_driver); } ao_combo_changed(ao_combo->currentIndex()); } QString PrefAudio::AO() { QString ao = ao_combo->itemData(ao_combo->currentIndex()).toString(); // if (ao == "user_defined") { // ao = ao_user_defined_edit->text(); // /* // if (ao.isEmpty()) { // ao = ao_combo->itemData(0).toString(); // qDebug("PrefGeneral::AO: user defined ao is empty, using %s", ao.toUtf8().constData()); // } // */ // } return ao; } void PrefAudio::setSoftVol(bool b) { softvol_check->setChecked(b); } void PrefAudio::setGlobalVolume(bool b) { global_volume_check->setChecked(b); } bool PrefAudio::globalVolume() { return global_volume_check->isChecked(); } bool PrefAudio::softVol() { return softvol_check->isChecked(); } void PrefAudio::setAutoSyncFactor(int factor) { autosync_spin->setValue(factor); } int PrefAudio::autoSyncFactor() { return autosync_spin->value(); } void PrefAudio::setAutoSyncActivated(bool b) { autosync_check->setChecked(b); } bool PrefAudio::autoSyncActivated() { return autosync_check->isChecked(); } void PrefAudio::setInitialVolNorm(bool b) { volnorm_check->setChecked(b); } bool PrefAudio::initialVolNorm() { return volnorm_check->isChecked(); } void PrefAudio::setAmplification(int n) { softvol_max_spin->setValue(n); } int PrefAudio::amplification() { return softvol_max_spin->value(); } void PrefAudio::setAudioChannels(int ID) { int pos = channels_combo->findData(ID); if (pos != -1) { channels_combo->setCurrentIndex(pos); } else { qWarning("PrefGeneral::setAudioChannels: ID: %d not found in combo", ID); } } int PrefAudio::audioChannels() { if (channels_combo->currentIndex() != -1) { return channels_combo->itemData( channels_combo->currentIndex() ).toInt(); } else { qWarning("PrefGeneral::audioChannels: no item selected"); return 0; } } void PrefAudio::ao_combo_changed(int idx) { // qDebug("PrefGeneral::ao_combo_changed: %d", idx); // bool visible = (ao_combo->itemData(idx).toString() == "user_defined"); // ao_user_defined_edit->setVisible(visible); // ao_user_defined_edit->setFocus(); } void PrefAudio::createHelp() { clearHelp(); setWhatsThis(ao_combo, tr("Audio output driver"), tr("Select the audio output driver.") + " " + tr("%1 is the recommended one. Try to avoid %2 and %3, they are slow " "and can have an impact on performance.") .arg("alsa") .arg("esd") .arg("arts") ); setWhatsThis(channels_combo, tr("Channels by default"), tr("Requests the number of playback channels. MPlayer " "asks the decoder to decode the audio into as many channels as " "specified. Then it is up to the decoder to fulfill the " "requirement. This is usually only important when playing " "videos with AC3 audio (like DVDs). In that case liba52 does " "the decoding by default and correctly downmixes the audio " "into the requested number of channels. " "Note: This option is honored by codecs (AC3 only), " "filters (surround) and audio output drivers (OSS at least).") ); setWhatsThis(global_volume_check, tr("Global volume"), tr("If this option is checked, the same volume will be used for " "all files you play. If the option is not checked each " "file uses its own volume.") + "
" + tr("This option also applies for the mute control.") ); setWhatsThis(softvol_check, tr("Software volume control"), tr("Check this option to use the software mixer, instead of " "using the sound card mixer.") ); setWhatsThis(softvol_max_spin, tr("Max. Amplification"), tr("Sets the maximum amplification level in percent (default: 110). " "A value of 200 will allow you to adjust the volume up to a " "maximum of double the current level. With values below 100 the " "initial volume (which is 100%) will be above the maximum, which " "e.g. the OSD cannot display correctly.") ); setWhatsThis(volnorm_check, tr("Volume normalization by default"), tr("Maximizes the volume without distorting the sound.") ); setWhatsThis(autosync_check, tr("Audio/video auto synchronization"), tr("Gradually adjusts the A/V sync based on audio delay " "measurements.") ); } //#include "moc_prefaudio.cpp" kylin-video/src/merge/prefshortcut.h0000664000175000017500000000337213233751662016536 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 */ #ifndef _PREFSHORTCUT_H_ #define _PREFSHORTCUT_H_ #include "ui_prefshortcut.h" #include "../smplayer/preferences.h" #include "../smplayer/prefwidget.h" #include class Preferences; //class QLabel; //class ActionsEditor; class PrefShortCut : public PrefWidget, public Ui::PrefShortCut { Q_OBJECT public: PrefShortCut( QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~PrefShortCut(); virtual QString sectionName(); virtual QPixmap sectionIcon(); // Pass data to the dialog void setData(Preferences * pref); // Apply changes void getData(Preferences * pref); // ActionsEditor *actions_editor = nullptr; protected: virtual void createHelp(); protected: virtual void retranslateStrings(); //private: // QLabel *keyboard_icon = nullptr; // QLabel *actioneditor_desc = nullptr; }; #endif kylin-video/src/merge/inputurl.cpp0000664000175000017500000001560413233751662016224 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 "inputurl.h" #include "../smplayer/images.h" #include "../smplayer/mylineedit.h" #include #include #include #include //http://rbv01.ku6.com/WrTcR6Yik9QIW4XIcxYvDw.mp4 InputURL::InputURL( QWidget* parent, Qt::WindowFlags f ) : QDialog(parent, f) , drag_state(NOT_IDRAGGING) , start_drag(QPoint(0,0)) { setupUi(this); this->setWindowFlags(Qt::FramelessWindowHint); this->setFixedSize(500, 170); this->setStyleSheet("QDialog{border: 1px solid #121212;border-radius:1px;background-color:#1f1f1f;}"); this->setWindowIcon(QIcon(":/res/kylin-video.png"));//setWindowIcon( Images::icon("logo", 64) ); this->setAutoFillBackground(true); this->setMouseTracking(true); installEventFilter(this); // setMinimumSize( QSize(500,140) ); // setMaximumSize( QSize(600,170) ); //layout()->setSizeConstraint(QLayout::SetFixedSize); title_label->setStyleSheet("QLabel{background:transparent;font-size:14px;color:#999999;font-family:方正黑体_GBK;}");//font-weight:bold; label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}");//font-weight:bold; // url_icon->setPixmap( Images::icon("url_big", 48) ); url_edit->setFocus(); url_edit->setFixedHeight(27); url_edit->setStyleSheet("QComboBox{width:150px;height:27px;border:1px solid #000000;background:#0f0f0f;font-size:12px;font-family:方正黑体_GBK;background-position:center left;padding-left:5px;color:#999999;selection-color:#ffffff;selection-background-color:#1f1f1f;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox::drop-down {width:17px;border:none;background:transparent;}QComboBox::drop-down:hover {background:transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView{border:1px solid #0a9ff5;background:#262626;outline:none;}"); MyLineEdit *edit = new MyLineEdit(this); edit->setFixedHeight(25); url_edit->setLineEdit(edit); closeBtn->setFocusPolicy(Qt::NoFocus); closeBtn->setStyleSheet("QPushButton{background-image:url(':/res/close_normal.png');border:0px;}QPushButton:hover{background:url(':/res/close_hover.png');}QPushButton:pressed{background:url(':/res/close_press.png');}"); okBtn->setFixedSize(91, 25); okBtn->setText(tr("OK")); okBtn->setFocusPolicy(Qt::NoFocus); okBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); cancelBtn->setFixedSize(91, 25); cancelBtn->setText(tr("Cancel")); cancelBtn->setFocusPolicy(Qt::NoFocus); cancelBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #000000;color:#999999;}QPushButton:hover{background-color:#1f1f1f;border:1px solid #0f0f0f;color:#ffffff;} QPushButton:pressed{background-color:#0d0d0d;border:1px solid #000000;color:#ffffff;}"); this->initConnect(); } InputURL::~InputURL() { } void InputURL::initConnect() { connect(okBtn, SIGNAL(clicked()), this, SLOT(accept())); connect(cancelBtn, SIGNAL(clicked()), this, SLOT(close())); connect(closeBtn, SIGNAL(clicked()), this, SLOT(close())); } void InputURL::setURL(QString url) { url_edit->addItem(url); } QString InputURL::url() { return url_edit->currentText().trimmed(); } void InputURL::moveDialog(QPoint diff) { #if QT_VERSION >= 0x050000 // Move the window with some delay. // Seems to work better with Qt 5 static QPoint d; static int count = 0; d += diff; count++; if (count > 3) { QPoint new_pos = pos() + d; if (new_pos.y() < 0) new_pos.setY(0); if (new_pos.x() < 0) new_pos.setX(0); move(new_pos); count = 0; d = QPoint(0,0); } #else move(pos() + diff); #endif } bool InputURL::eventFilter( QObject * object, QEvent * event ) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { drag_state = NOT_IDRAGGING; return false; } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_IDRAGGING; return false; } drag_state = START_IDRAGGING; start_drag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (drag_state != IDRAGGING || mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_IDRAGGING; return false; } // Stop dragging and eat event drag_state = NOT_IDRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (drag_state == NOT_IDRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { drag_state = NOT_IDRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - start_drag; if (drag_state == START_IDRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; drag_state = IDRAGGING; } this->moveDialog(diff); start_drag = pos; event->accept(); return true; } //#include "moc_inputurl.cpp" kylin-video/src/merge/basegui.cpp0000664000175000017500000031602713233751662015764 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 "basegui.h" #include "../smplayer/filedialog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../smplayer/mplayerwindow.h" #include "../smplayer/desktopinfo.h" #include "../smplayer/helper.h" #include "../smplayer/paths.h" #include "../smplayer/colorutils.h" #include "../smplayer/global.h" #include "../smplayer/translator.h" #include "../smplayer/images.h" #include "../smplayer/preferences.h" #include "playlist.h" #include "filepropertiesdialog.h" #include "../smplayer/recents.h" #include "../smplayer/urlhistory.h" #include "errordialog.h" #include "../smplayer/timedialog.h" #include "../kylin/titlewidget.h" #include "../kylin/bottomwidget.h" #include "../kylin/playmask.h" #include "../kylin/aboutdialog.h" #include "../kylin/esctip.h" #include "../kylin/tipwidget.h" #include "audiodelaydialog.h" #include "../kylin/messagedialog.h" #include #include "../smplayer/mplayerversion.h" #include "../smplayer/config.h" #include "../smplayer/actionseditor.h" #include "preferencesdialog.h" #include "prefshortcut.h" #include "../smplayer/myaction.h" #include "../smplayer/myactiongroup.h" #include "../smplayer/extensions.h" #include "../smplayer/version.h" #include "../smplayer/videopreview.h" //#include "../kylin/shortcutswidget.h" #include "../kylin/helpdialog.h" #include "inputurl.h" using namespace Global; inline bool inRectCheck(QPoint point, QRect rect) { bool x = rect.x() <= point.x() && point.x() <= rect.x() + rect.width(); bool y = rect.y() <= point.y() && point.y() <= rect.y() + rect.height(); return x && y; } BaseGui::BaseGui(QString arch_type, QWidget* parent, Qt::WindowFlags flags) : QMainWindow( parent, flags ) #if QT_VERSION >= 0x050000 , was_minimized(false) #endif { this->setWindowTitle(tr("Kylin Video")); this->setMouseTracking(true); this->setAutoFillBackground(true); QWidget::setWindowFlags(Qt::Window | Qt::FramelessWindowHint); this->setMinimumSize(WINDOW_MIN_WIDTH, WINDOW_MIN_HEIGHT); this->resize(900, 600); this->setWindowIcon(QIcon(":/res/kylin-video.png")); arch = arch_type; ignore_show_hide_events = false; arg_close_on_finish = -1; arg_start_in_fullscreen = -1; isFinished = false;//kobe isPlaying = false; this->resizeFlag = false; fullscreen = false; core = 0; popup = 0; main_popup = 0; pref_dialog = 0; file_dialog = 0; aboutDlg = 0; helpDlg = 0; video_preview = 0; // shortcuts_widget = 0; tray = 0; play_mask = 0; mplayerwindow = 0; playlistWidget = 0; panel = 0; resizeCorner = 0; m_topToolbar = 0; m_bottomToolbar = 0; escWidget = 0; tipWidget = 0; contentLayout = 0; //遮罩 // shortcuts_widget = ShortcutsWidget::Instance(); // shortcuts_widget->set_parent_widget(this); createPanel(); setCentralWidget(panel);//kobe for QMainWindow 中心窗口部件,panel加载的是视频显示区域 createMplayerWindow(); createCore(); createPlaylist(); connect(mplayerwindow, SIGNAL(wheelUp()), core, SLOT(wheelUp())); connect(mplayerwindow, SIGNAL(wheelDown()), core, SLOT(wheelDown())); createActionsAndMenus(); createTrayActions(); addTrayActions(); createHiddenActions(); setAcceptDrops(true); panel->setFocus(); //top m_topToolbar = new TitleWidget(this); m_topToolbar->setFixedHeight(TOP_TOOLBAR_HEIGHT); this->setMenuWidget(m_topToolbar); connect(playlistWidget, SIGNAL(sig_playing_title(QString)), m_topToolbar, SLOT(set_title_name(QString))); connect(this, SIGNAL(clear_playing_title()), m_topToolbar, SLOT(clear_title_name())); connect(m_topToolbar, SIGNAL(sig_menu()), this, SLOT(slot_menu())); connect(m_topToolbar, SIGNAL(sig_min()), this, SLOT(slot_min())); connect(m_topToolbar, SIGNAL(sig_close()), this, SLOT(slot_close())); connect(m_topToolbar, SIGNAL(sig_max()), this, SLOT(slot_max())); connect(m_topToolbar, SIGNAL(mouseMovedDiff(QPoint)), this, SLOT(moveWindowDiff(QPoint)), Qt::QueuedConnection );//kobe 0524 //bottom m_bottomToolbar = new BottomWidget(this); m_bottomToolbar->setFixedHeight(BOTTOM_TOOLBAR_HEIGHT); connect(m_bottomToolbar, SIGNAL(sig_resize_corner()), this, SLOT(slot_resize_corner())); connect(m_bottomToolbar, SIGNAL(volumeChanged(int)), core, SLOT(setVolume(int))); connect(core, SIGNAL(volumeChanged(int)), m_bottomToolbar, SIGNAL(valueChanged(int))); connect(m_bottomToolbar, SIGNAL(toggleFullScreen()), this, SLOT(slot_set_fullscreen()));//0621 connect(m_bottomToolbar, SIGNAL(togglePlaylist()), this, SLOT(slot_playlist())); connect(this, SIGNAL(timeChanged(QString, QString)),m_bottomToolbar, SLOT(displayTime(QString, QString))); connect(m_bottomToolbar, SIGNAL(signal_stop()), core, SLOT(stop())); connect(m_bottomToolbar, SIGNAL(signal_prev()), playlistWidget, SLOT(playPrev())); connect(m_bottomToolbar, SIGNAL(signal_play_pause_status()), core, SLOT(play_or_pause())); connect(m_bottomToolbar, SIGNAL(signal_next()), playlistWidget, SLOT(playNext())); connect(m_bottomToolbar, SIGNAL(signal_open_file()), this, SLOT(openFile())); connect(m_bottomToolbar, SIGNAL(signal_mute(/*bool*/)), this, SLOT(slot_mute(/*bool*/))); connect(this, SIGNAL(sigActionsEnabled(bool)), m_bottomToolbar, SLOT(setActionsEnabled(bool))); connect(this, SIGNAL(setPlayOrPauseEnabled(bool)), m_bottomToolbar, SLOT(setPlayOrPauseEnabled(bool))); connect(this, SIGNAL(setStopEnabled(bool)), m_bottomToolbar, SLOT(setStopEnabled(bool))); connect(this, SIGNAL(change_playlist_btn_status(bool)), m_bottomToolbar, SLOT(slot_playlist_btn_status(bool))); //progress connect(m_bottomToolbar, SIGNAL(posChanged(int)), core, SLOT(goToPosition(int))); connect(core, SIGNAL(positionChanged(int)), m_bottomToolbar, SLOT(setPos(int))); connect(m_bottomToolbar, SIGNAL(draggingPos(int)), this, SLOT(displayGotoTime(int))); connect(m_bottomToolbar, SIGNAL(delayedDraggingPos(int)), this, SLOT(goToPosOnDragging(int))); connect(m_bottomToolbar, SIGNAL(wheelUp()), core, SLOT(wheelUp())); connect(m_bottomToolbar, SIGNAL(wheelDown()), core, SLOT(wheelDown())); connect(m_bottomToolbar, SIGNAL(mouseMovedDiff(QPoint)), this, SLOT(moveWindowDiff(QPoint)), Qt::QueuedConnection );//kobe 0524 connect(core, SIGNAL(newDuration(double)), m_bottomToolbar, SLOT(setDuration(double))); connect(m_bottomToolbar, SIGNAL(sig_show_or_hide_esc(bool)), this, SLOT(showOrHideEscWidget(bool))); connect(playlistWidget, SIGNAL(update_playlist_count(int)), m_bottomToolbar, SLOT(update_playlist_count_label(int))); connect(m_bottomToolbar, SIGNAL(need_to_save_pre_image(int)), this, SLOT(ready_save_pre_image(int))); connect(this, SIGNAL(send_save_preview_image_name(int,QString)), m_bottomToolbar, SIGNAL(send_save_preview_image_name(int,QString))); resizeCorner = new QPushButton(m_bottomToolbar); resizeCorner->setFocusPolicy(Qt::NoFocus); resizeCorner->setStyleSheet("QPushButton{background-image:url(':/res/dragbar_normal.png');border:0px;}QPushButton:hover{background-image:url(':/res/dragbar_normal.png')}QPushButton:pressed{background-image:url(':/res/dragbar_normal.png')}"); resizeCorner->setFixedSize(15, 15); resizeCorner->move(m_bottomToolbar->width()-15, m_bottomToolbar->height()-15); resizeCorner->installEventFilter(this); mainwindow_pos = pos(); tipWidget = new TipWidget("Hello, Kylin!", this); tipWidget->setFixedHeight(30); tipWidget->move(10, TOP_TOOLBAR_HEIGHT); tipWidget->hide(); contentLayout = new QStackedLayout(panel); contentLayout->setContentsMargins(0, 0, 0, 0); contentLayout->setMargin(0); contentLayout->setSpacing(0); contentLayout->addWidget(m_topToolbar); contentLayout->addWidget(mplayerwindow); contentLayout->addWidget(m_bottomToolbar); m_topToolbar->show(); mplayerwindow->show(); m_bottomToolbar->show(); m_bottomToolbar->setFocus(); this->setActionsEnabled(false); if (playlistWidget->count() > 0) { emit this->setPlayOrPauseEnabled(true); m_bottomToolbar->update_playlist_count_label(playlistWidget->count()); } else { m_bottomToolbar->update_playlist_count_label(0); } int windowWidth = QApplication::desktop()->screenGeometry(0).width(); int windowHeight = QApplication::desktop()->screenGeometry(0).height(); this->move((windowWidth - this->width()) / 2,(windowHeight - this->height()) / 2); this->reset_mute_button(); escWidget = new EscTip(this); escWidget->setFixedSize(440, 64); escWidget->move((windowWidth - escWidget->width()) / 2,(windowHeight - escWidget->height()) / 2); escWidget->hide(); play_mask = new PlayMask(mplayerwindow); mplayerwindow->setCornerWidget(play_mask); play_mask->hide(); connect(play_mask, SIGNAL(signal_play_continue()), core, SLOT(play_or_pause())); tip_timer = new QTimer(this); connect(tip_timer, SIGNAL(timeout()), this, SLOT(hideTipWidget())); tip_timer->setInterval(2000); initializeGui(); } //0829 /*void BaseGui::onShowControls() { if (turned_on) { if (!m_topToolbar->isVisible()) { m_topToolbar->showSpreadAnimated(); } if (!m_bottomToolbar->getCtrlWidgetVisible()) { m_bottomToolbar->showSpreadAnimated(); } } } bool BaseGui::mouseInControlsArea() { QPoint mousePos = QCursor::pos();//getCursorPos bool mouseInTitleBar = inRectCheck(QPoint(mousePos.x() - this->x(), mousePos.y() - this->y()), QRect(0, 0, this->width(), m_topToolbar->height())); bool mouseInControlBar = inRectCheck(QPoint(mousePos.x() - this->x(), mousePos.y() - this->y()), QRect(0, this->height() - m_bottomToolbar->height(), this->width(), m_bottomToolbar->height())); return mouseInTitleBar || mouseInControlBar; } void BaseGui::checkUnderMouse() { // if (!underMouse()) { if (m_topToolbar->isVisible()) { m_topToolbar->showGatherAnimated(); } if (m_bottomToolbar->getCtrlWidgetVisible()) { this->showOrHideEscWidget(false); m_bottomToolbar->showGatherAnimated(); } // } } void BaseGui::activate_timer() { turned_on = true; if (mouse_timer->isActive()) mouse_timer->stop(); mouse_timer->start(); } //void BaseGui::deactivate_timer() { // turned_on = false; // if (mouse_timer->isActive()) // mouse_timer->stop(); // m_topToolbar->showSpreadAnimated(); // m_bottomToolbar->showSpreadAnimated(); //} void BaseGui::showAlways() { turned_on = false; if (mouse_timer->isActive()) mouse_timer->stop(); m_topToolbar->showAlways(); m_bottomToolbar->showAlways(); }*/ /*void BaseGui::enterEvent(QEvent *event) { this->mouseIn = true; // if (turned_on) { // if (!m_topToolbar->isVisible()) { // qDebug() << "------------BaseGui::enterEvent------------111"; // m_topToolbar->showWidget(); // } // if (!m_bottomToolbar->getCtrlWidgetVisible()) { // qDebug() << "------------BaseGui::enterEvent------------222"; // m_bottomToolbar->showWidget(); // } // } QWidget::enterEvent(event); } void BaseGui::leaveEvent(QEvent *event) { this->mouseIn = false; qDebug() << "------------BaseGui::leaveEvent------------"; QWidget::leaveEvent(event); }*/ void BaseGui::setTransparent(bool transparent) { if (transparent) { setAttribute(Qt::WA_TranslucentBackground); setWindowFlags(windowFlags() | Qt::FramelessWindowHint|Qt::X11BypassWindowManagerHint); set_widget_opacity(0.5); } else { setAttribute(Qt::WA_TranslucentBackground,false); setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint); } } void BaseGui::set_widget_opacity(const float &opacity) { QGraphicsOpacityEffect* opacityEffect = new QGraphicsOpacityEffect; this->setGraphicsEffect(opacityEffect); opacityEffect->setOpacity(opacity); } //void BaseGui::showShortcuts() //{ // shortcuts_widget->setPrefData(pref); // shortcuts_widget->show(); // shortcuts_widget->restart_timer(); //} void BaseGui::keyPressEvent(QKeyEvent *event) { // if (event->key() == Qt::Key_Up) { // } // if (event->key() == Qt::Key_Down) { // } if (event->key() == Qt::Key_Space) { this->leftClickFunction(); } if (event->key() == Qt::Key_Escape) { if (this->fullscreen) { toggleFullscreen(false); } } // if (event->key() == Qt::Key_Question) { // this->showShortcuts(); // } QMainWindow::keyPressEvent(event); } void BaseGui::slot_mute(/*bool b*/) { bool muted = core->getMute(); core->mute(!muted); if (muted && core->getVolumn() <= 0) {//0620 core->setVolume(50, true); } updateWidgets(); } void BaseGui::reset_mute_button() { bool muted = core->getMute(); m_bottomToolbar->onMutedChanged(muted, core->getVolumn());//0519 } void BaseGui::slot_max() { // if (!this->isMaximized()) { // this->showMaximized(); // m_topToolbar->show_max_or_normal_button(false); // } /*if(maxOrNormal){ setWindowState( Qt::WindowMaximized); }else { setWindowState( Qt::WindowNoState); } maxOrNormal = !maxOrNormal;*/ if (!this->isMaximized()) { m_topToolbar->update_max_status(true); this->showMaximized(); } else { m_topToolbar->update_max_status(false); this->showNormal(); } /*if (this->isMaximized()) { // if (window()->isMaximized()) // window()->showNormal(); m_topToolbar->update_max_status(false); this->showNormal(); } else { m_topToolbar->update_max_status(true); this->showMaximized(); } update();*/ } void BaseGui::slot_min() { /*if( windowState() != Qt::WindowMinimized ){ setWindowState( Qt::WindowMinimized ); }*/ this->showMinimized(); } void BaseGui::slot_menu() { QPoint p = rect().topRight(); p.setX(p.x() - 38*4); p.setY(p.y() + 36); main_popup->exec(this->mapToGlobal(p)); // main_popup->move(QCursor::pos()); // main_popup->show(); } void BaseGui::slot_close() { // qApp->quit(); this->quit(); } void BaseGui::initializeGui() { changeStayOnTop(pref->stay_on_top); changePlayOrder(pref->play_order); updateRecents(); updateWidgets(); // Call loadActions() outside initialization of the class. // Otherwise DefaultGui (and other subclasses) doesn't exist, and // its actions are not loaded QTimer::singleShot(20, this, SLOT(loadActions())); } #ifdef SINGLE_INSTANCE void BaseGui::handleMessageFromOtherInstances(const QString& message) { // qDebug("BaseGui::handleMessageFromOtherInstances: '%s'", message.toUtf8().constData()); int pos = message.indexOf(' '); if (pos > -1) { QString command = message.left(pos); QString arg = message.mid(pos+1); // qDebug("command: '%s'", command.toUtf8().constData()); // qDebug("arg: '%s'", arg.toUtf8().constData()); if (command == "open_file") { emit openFileRequested(); open(arg); } else if (command == "open_files") { QStringList file_list = arg.split(" <> "); emit openFileRequested(); openFiles(file_list); } else if (command == "add_to_playlist") { // QStringList file_list = arg.split(" <> "); /* if (core->state() == Core::Stopped) { emit openFileRequested(); } */ // playlist->addFiles(file_list); } else if (command == "media_title") { QStringList list = arg.split(" <> "); core->addForcedTitle(list[0], list[1]); } else if (command == "action") { processFunction(arg); } else if (command == "load_sub") { setInitialSubtitle(arg); if (core->state() != Core::Stopped) { core->loadSub(arg); } } } } #endif BaseGui::~BaseGui() { this->clearMplayerLog();//add by kobe if (core) { delete core; // delete before mplayerwindow, otherwise, segfault... core = 0; } if (play_mask) { delete play_mask; play_mask = 0; } if (escWidget) { delete escWidget; escWidget = 0; } if (tipWidget) { delete tipWidget; tipWidget = 0; } if (mplayerwindow) { delete mplayerwindow; mplayerwindow = 0; } if (playlistWidget) { delete playlistWidget; playlistWidget = 0; } if (video_preview) { delete video_preview; video_preview = 0; } // if (shortcuts_widget) { // delete shortcuts_widget; // shortcuts_widget = 0; // } if (pref_dialog) { delete pref_dialog; pref_dialog = 0; } if (file_dialog) { delete file_dialog; file_dialog = 0; } if (aboutDlg) { delete aboutDlg; aboutDlg = 0; } if (helpDlg) { delete helpDlg; helpDlg = 0; } if (tray) { delete tray; tray = 0; } if (popup) { delete popup; popup = 0; } if (main_popup) { delete main_popup; main_popup = 0; } if (resizeCorner) { delete resizeCorner; resizeCorner = 0; } if (m_topToolbar) { delete m_topToolbar; m_topToolbar = 0; } if (m_bottomToolbar) { delete m_bottomToolbar; m_bottomToolbar = 0; } if (contentLayout) { delete contentLayout; contentLayout = 0; } if (panel) { delete panel; panel = 0; } if (tip_timer != NULL) { disconnect(tip_timer,SIGNAL(timeout()),this,SLOT(hideTipWidget())); if(tip_timer->isActive()) { tip_timer->stop(); } delete tip_timer; tip_timer = NULL; } } void BaseGui::createActionsAndMenus() { openMenu = new QMenu(this); openMenu->menuAction()->setText(tr("Open")); openMenu->setIcon(Images::icon("open_file_normal")); // Menu File openFileAct = new MyAction(QKeySequence("Ctrl+F"), this, "open_file"); connect(openFileAct, SIGNAL(triggered()), this, SLOT(openFile())); openFileAct->change(QPixmap(":/res/open_file_normal.png"), tr("Open &File...")); openDirectoryAct = new MyAction( this, "open_directory"); connect(openDirectoryAct, SIGNAL(triggered()), this, SLOT(openDirectory())); openDirectoryAct->change(/*QPixmap(":/res/openfolder.png"), */tr("Directory...")); openURLAct = new MyAction(QKeySequence("Ctrl+U"), this, "open_url" ); connect(openURLAct, SIGNAL(triggered()), this, SLOT(openURL()) ); openURLAct->change(tr("&URL...")); openMenu->addAction(openFileAct); openMenu->addAction(openDirectoryAct); openMenu->addAction(openURLAct); clearRecentsAct = new MyAction(this, "clear_recents"); connect(clearRecentsAct, SIGNAL(triggered()), this, SLOT(clearRecentsList())); clearRecentsAct->change(QPixmap(":/res/delete_normal.png"), tr("&Clear")); recentfiles_menu = new QMenu(this); recentfiles_menu->addSeparator(); recentfiles_menu->addAction(clearRecentsAct); recentfiles_menu->menuAction()->setText(tr("Recent files")); // recentfiles_menu->menuAction()->setIcon(QPixmap(":/res/delete.png")); playMenu = new QMenu(this); playMenu->menuAction()->setText(tr("Play control")); control_menu = new QMenu(this); control_menu->menuAction()->setText(tr("Forward and rewind"));//快进快退 // control_menu->menuAction()->setIcon(QPixmap(":/res/speed.png")); control_menu->menuAction()->setObjectName("control_menu"); rewind1Act = new MyAction( Qt::Key_Left, this, "rewind1"); rewind1Act->addShortcut(QKeySequence("Shift+Ctrl+B")); // MCE remote key connect(rewind1Act, SIGNAL(triggered()), core, SLOT(srewind())); rewind2Act = new MyAction( Qt::Key_Down, this, "rewind2"); connect(rewind2Act, SIGNAL(triggered()), core, SLOT(rewind())); rewind3Act = new MyAction( Qt::Key_PageDown, this, "rewind3"); connect(rewind3Act, SIGNAL(triggered()), core, SLOT(fastrewind())); forward1Act = new MyAction( Qt::Key_Right, this, "forward1"); forward1Act->addShortcut(QKeySequence("Shift+Ctrl+F")); // MCE remote key connect(forward1Act, SIGNAL(triggered()), core, SLOT(sforward())); forward2Act = new MyAction( Qt::Key_Up, this, "forward2"); connect(forward2Act, SIGNAL(triggered()), core, SLOT(forward())); forward3Act = new MyAction( Qt::Key_PageUp, this, "forward3" ); connect(forward3Act, SIGNAL(triggered()), core, SLOT(fastforward())); gotoAct = new MyAction( QKeySequence("Ctrl+J"), this, "jump_to"); connect(gotoAct, SIGNAL(triggered()), this, SLOT(showGotoDialog())); // gotoAct->change( Images::icon("jumpto"), tr("&Jump to...")); gotoAct->change(tr("&Jump to...")); control_menu->addAction(rewind1Act); control_menu->addAction(forward1Act); control_menu->addSeparator(); control_menu->addAction(rewind2Act); control_menu->addAction(forward2Act); control_menu->addSeparator(); control_menu->addAction(rewind3Act); control_menu->addAction(forward3Act); playMenu->addMenu(control_menu); // Speed submenu speed_menu = new QMenu(this); speed_menu->menuAction()->setText(tr("Play Speed")); // speed_menu->menuAction()->setIcon(QPixmap(":/res/speed.png")); speed_menu->menuAction()->setObjectName("speed_menu"); normalSpeedAct = new MyAction(Qt::Key_Backspace, this, "normal_speed"); connect(normalSpeedAct, SIGNAL(triggered()), core, SLOT(normalSpeed())); halveSpeedAct = new MyAction(Qt::Key_BraceLeft, this, "halve_speed"); connect(halveSpeedAct, SIGNAL(triggered()), core, SLOT(halveSpeed())); doubleSpeedAct = new MyAction(Qt::Key_BraceRight, this, "double_speed"); connect(doubleSpeedAct, SIGNAL(triggered()), core, SLOT(doubleSpeed())); decSpeed10Act = new MyAction(Qt::Key_BracketLeft, this, "dec_speed"); connect(decSpeed10Act, SIGNAL(triggered()), core, SLOT(decSpeed10())); incSpeed10Act = new MyAction(Qt::Key_BracketRight, this, "inc_speed"); connect(incSpeed10Act, SIGNAL(triggered()), core, SLOT(incSpeed10())); decSpeed4Act = new MyAction(this, "dec_speed_4"); connect(decSpeed4Act, SIGNAL(triggered()), core, SLOT(decSpeed4())); incSpeed4Act = new MyAction(this, "inc_speed_4"); connect(incSpeed4Act, SIGNAL(triggered()), core, SLOT(incSpeed4())); decSpeed1Act = new MyAction(this, "dec_speed_1"); connect(decSpeed1Act, SIGNAL(triggered()), core, SLOT(decSpeed1())); incSpeed1Act = new MyAction(this, "inc_speed_1"); connect(incSpeed1Act, SIGNAL(triggered()), core, SLOT(incSpeed1())); normalSpeedAct->change( tr("Normal speed")); halveSpeedAct->change(tr("Half speed") ); doubleSpeedAct->change(tr("Double speed")); decSpeed10Act->change(tr("Speed -10%")); incSpeed10Act->change(tr("Speed +10%")); decSpeed4Act->change(tr("Speed -4%")); incSpeed4Act->change(tr("Speed +4%")); decSpeed1Act->change(tr("Speed -1%")); incSpeed1Act->change(tr("Speed +1%")); speed_menu->addAction(normalSpeedAct);//正常速度 1 speed_menu->addSeparator(); speed_menu->addAction(halveSpeedAct);//半速 0.5 speed_menu->addAction(doubleSpeedAct);//双倍速度 2 speed_menu->addSeparator(); speed_menu->addAction(decSpeed10Act);//速度-10% speed_menu->addAction(incSpeed10Act);//速度+10% speed_menu->addSeparator(); speed_menu->addAction(decSpeed4Act);//速度-4% speed_menu->addAction(incSpeed4Act);//速度+4% speed_menu->addSeparator(); speed_menu->addAction(decSpeed1Act);//速度-1% speed_menu->addAction(incSpeed1Act);//速度+1% playMenu->addMenu(speed_menu); playMenu->addSeparator(); playMenu->addAction(gotoAct); playMenu->addSeparator(); playPrevAct = new MyAction(Qt::Key_Less, this, "play_prev"); playPrevAct->addShortcut(Qt::Key_MediaPrevious); // MCE remote key connect(playPrevAct, SIGNAL(triggered()), playlistWidget, SLOT(playPrev())); playNextAct = new MyAction(Qt::Key_Greater, this, "play_next"); playNextAct->addShortcut(Qt::Key_MediaNext); // MCE remote key connect(playNextAct, SIGNAL(triggered()), playlistWidget, SLOT(playNext())); playNextAct->change(tr("Next") ); playPrevAct->change(tr("Previous")); playNextAct->setIcon(QPixmap(":/res/next_normal.png")); playPrevAct->setIcon(QPixmap(":/res/previous_normal.png")); playMenu->addAction(playPrevAct); playMenu->addAction(playNextAct); // Video aspect aspectGroup = new MyActionGroup(this); aspectDetectAct = new MyActionGroupItem(this, aspectGroup, "aspect_detect", MediaSettings::AspectAuto); aspect11Act = new MyActionGroupItem(this, aspectGroup, "aspect_1:1", MediaSettings::Aspect11 ); aspect54Act = new MyActionGroupItem(this, aspectGroup, "aspect_5:4", MediaSettings::Aspect54 ); aspect43Act = new MyActionGroupItem(this, aspectGroup, "aspect_4:3", MediaSettings::Aspect43); aspect118Act = new MyActionGroupItem(this, aspectGroup, "aspect_11:8", MediaSettings::Aspect118 ); aspect1410Act = new MyActionGroupItem(this, aspectGroup, "aspect_14:10", MediaSettings::Aspect1410 ); aspect32Act = new MyActionGroupItem(this, aspectGroup, "aspect_3:2", MediaSettings::Aspect32); aspect149Act = new MyActionGroupItem(this, aspectGroup, "aspect_14:9", MediaSettings::Aspect149 ); aspect1610Act = new MyActionGroupItem(this, aspectGroup, "aspect_16:10", MediaSettings::Aspect1610 ); aspect169Act = new MyActionGroupItem(this, aspectGroup, "aspect_16:9", MediaSettings::Aspect169 ); aspect235Act = new MyActionGroupItem(this, aspectGroup, "aspect_2.35:1", MediaSettings::Aspect235 ); { QAction * sep = new QAction(aspectGroup); sep->setSeparator(true); } aspectNoneAct = new MyActionGroupItem(this, aspectGroup, "aspect_none", MediaSettings::AspectNone); connect(aspectGroup, SIGNAL(activated(int)), core, SLOT(changeAspectRatio(int))); aspectDetectAct->change(tr("&Auto")); aspect11Act->change("1&:1"); aspect32Act->change("&3:2"); aspect43Act->change("&4:3"); aspect118Act->change("11:&8"); aspect54Act->change("&5:4"); aspect149Act->change("&14:9"); aspect1410Act->change("1&4:10"); aspect169Act->change("16:&9"); aspect1610Act->change("1&6:10"); aspect235Act->change("&2.35:1"); aspectNoneAct->change(tr("&Disabled")); // Aspect submenu aspect_menu = new QMenu(this); aspect_menu->menuAction()->setObjectName("aspect_menu"); aspect_menu->addActions(aspectGroup->actions()); aspect_menu->menuAction()->setText(tr("Aspect ratio"));//宽高比 画面比例 // Rotate rotateGroup = new MyActionGroup(this); rotateNoneAct = new MyActionGroupItem(this, rotateGroup, "rotate_none", MediaSettings::NoRotate); rotateClockwiseFlipAct = new MyActionGroupItem(this, rotateGroup, "rotate_clockwise_flip", MediaSettings::Clockwise_flip); rotateClockwiseAct = new MyActionGroupItem(this, rotateGroup, "rotate_clockwise", MediaSettings::Clockwise); rotateCounterclockwiseAct = new MyActionGroupItem(this, rotateGroup, "rotate_counterclockwise", MediaSettings::Counterclockwise); rotateCounterclockwiseFlipAct = new MyActionGroupItem(this, rotateGroup, "rotate_counterclockwise_flip", MediaSettings::Counterclockwise_flip); connect(rotateGroup, SIGNAL(activated(int)), core, SLOT(changeRotate(int))); rotateNoneAct->change(tr("&Off")); rotateClockwiseFlipAct->change(tr("&Rotate by 90 degrees clockwise and flip")); rotateClockwiseAct->change(tr("Rotate by 90 degrees &clockwise")); rotateCounterclockwiseAct->change(tr("Rotate by 90 degrees counterclock&wise")); rotateCounterclockwiseFlipAct->change(tr("Rotate by 90 degrees counterclockwise and &flip")); flipAct = new MyAction(this, "flip"); flipAct->setCheckable(true); connect(flipAct, SIGNAL(toggled(bool)), core, SLOT(toggleFlip(bool))); flipAct->change(tr("Fli&p image")); mirrorAct = new MyAction(this, "mirror"); mirrorAct->setCheckable(true); connect(mirrorAct, SIGNAL(toggled(bool)), core, SLOT(toggleMirror(bool))); mirrorAct->change(tr("Mirr&or image")); // Rotate menu rotate_flip_menu = new QMenu(this); rotate_flip_menu->menuAction()->setText(tr("Frame rotation"));//画面旋转 // Rotate submenu rotate_menu = new QMenu(this); rotate_menu->menuAction()->setObjectName("rotate_menu"); rotate_menu->addActions(rotateGroup->actions()); rotate_menu->menuAction()->setText(tr("&Rotate") ); rotate_flip_menu->addMenu(rotate_menu); rotate_flip_menu->addAction(flipAct); rotate_flip_menu->addAction(mirrorAct); // shortcutsAct = new MyAction(QKeySequence("Shift+?"), this, "Shortcuts");//快捷键 Qt::Key_Question //// shortcutsAct->addShortcut(QKeySequence("Shift+Ctrl+?")); // connect(shortcutsAct, SIGNAL(triggered()), this, SLOT(showShortcuts())); // shortcutsAct->change(tr("Shortcuts")); // Single screenshot screenshotAct = new MyAction(Qt::Key_S, this, "screenshot");//屏幕截图 connect(screenshotAct, SIGNAL(triggered()), core, SLOT(screenshot())); screenshotAct->change(Images::icon("screenshot_normal"), tr("&Screenshot")); // On Top onTopActionGroup = new MyActionGroup(this); onTopAlwaysAct = new MyActionGroupItem(this,onTopActionGroup,"on_top_always",Preferences::AlwaysOnTop); onTopNeverAct = new MyActionGroupItem(this,onTopActionGroup,"on_top_never",Preferences::NeverOnTop); onTopWhilePlayingAct = new MyActionGroupItem(this,onTopActionGroup,"on_top_playing",Preferences::WhilePlayingOnTop); onTopAlwaysAct->change(tr("&Always")); onTopNeverAct->change(tr("&Never")); onTopWhilePlayingAct->change(tr("While &playing")); connect(onTopActionGroup, SIGNAL(activated(int)), this, SLOT(changeStayOnTop(int))); // Ontop submenu ontop_menu = new QMenu(this); ontop_menu->menuAction()->setObjectName("ontop_menu"); ontop_menu->addActions(onTopActionGroup->actions()); ontop_menu->menuAction()->setText(tr("S&tay on top")); // ontop_menu->menuAction()->setIcon(Images::icon("ontop")); //play order playOrderActionGroup = new MyActionGroup(this); orderPlaysAct = new MyActionGroupItem(this,playOrderActionGroup,"order_play",Preferences::OrderPlay); randomPlayAct = new MyActionGroupItem(this,playOrderActionGroup,"random_play",Preferences::RandomPlay); listLoopPlayAct = new MyActionGroupItem(this,playOrderActionGroup,"list_loop_play",Preferences::ListLoopPlay); orderPlaysAct->change(tr("Order play")); randomPlayAct->change(tr("Random play")); listLoopPlayAct->change(tr("List loop play")); connect(playOrderActionGroup, SIGNAL(activated(int)), this, SLOT(changePlayOrder(int))); play_order_menu = new QMenu(this); play_order_menu->menuAction()->setObjectName("play_order_menu"); play_order_menu->addActions(playOrderActionGroup->actions()); play_order_menu->menuAction()->setText(tr("Play order")); // play_order_menu->menuAction()->setIcon(Images::icon("list_cycle_normal")); // Audio channels channelsGroup = new MyActionGroup(this); channelsStereoAct = new MyActionGroupItem(this, channelsGroup, "channels_stereo", MediaSettings::ChStereo); channelsSurroundAct = new MyActionGroupItem(this, channelsGroup, "channels_surround", MediaSettings::ChSurround); channelsFull51Act = new MyActionGroupItem(this, channelsGroup, "channels_ful51", MediaSettings::ChFull51); channelsFull61Act = new MyActionGroupItem(this, channelsGroup, "channels_ful61", MediaSettings::ChFull61); channelsFull71Act = new MyActionGroupItem(this, channelsGroup, "channels_ful71", MediaSettings::ChFull71); connect(channelsGroup, SIGNAL(activated(int)), core, SLOT(setAudioChannels(int))); channelsStereoAct->change(tr("&Stereo")); channelsSurroundAct->change(tr("&4.0 Surround")); channelsFull51Act->change(tr("&5.1 Surround")); channelsFull61Act->change(tr("&6.1 Surround")); channelsFull71Act->change(tr("&7.1 Surround")); // Audio channels submenu audiochannels_menu = new QMenu(this); audiochannels_menu->menuAction()->setObjectName("audiochannels_menu"); audiochannels_menu->addActions(channelsGroup->actions()); audiochannels_menu->menuAction()->setText(tr("&Channels")); audioMenu = new QMenu(this); audioMenu->menuAction()->setText(tr("Audio")); // audioMenuAct->setIcon(Images::icon("audio_menu")); muteAct = new MyAction(Qt::Key_M, this, "mute" );//kobe:音频菜单里面的静音 muteAct->addShortcut(Qt::Key_VolumeMute); // MCE remote key muteAct->setCheckable(true); connect(muteAct, SIGNAL(toggled(bool)), core, SLOT(mute(bool))); QIcon icset(Images::icon("volume_low_normal")); icset.addPixmap(Images::icon("volume_mute_normal"), QIcon::Normal, QIcon::On); muteAct->change(icset, tr("&Mute")); decVolumeAct = new MyAction(Qt::Key_9, this, "dec_volume"); connect(decVolumeAct, SIGNAL(triggered()), core, SLOT(decVolume())); decVolumeAct->change(tr("Volume -")); incVolumeAct = new MyAction(Qt::Key_0, this, "inc_volume"); connect(incVolumeAct, SIGNAL(triggered()), core, SLOT(incVolume())); incVolumeAct->change(tr("Volume +") ); decAudioDelayAct = new MyAction(Qt::Key_Minus, this, "dec_audio_delay"); connect( decAudioDelayAct, SIGNAL(triggered()), core, SLOT(decAudioDelay())); decAudioDelayAct->change(tr("Delay -")); incAudioDelayAct = new MyAction(Qt::Key_Plus, this, "inc_audio_delay"); connect(incAudioDelayAct, SIGNAL(triggered()), core, SLOT(incAudioDelay())); incAudioDelayAct->change( tr("Delay +")); audioDelayAct = new MyAction(Qt::Key_Y, this, "audio_delay"); connect(audioDelayAct, SIGNAL(triggered()), this, SLOT(showAudioDelayDialog())); audioDelayAct->change(tr("Set dela&y...")); // Stereo mode stereoGroup = new MyActionGroup(this); stereoAct = new MyActionGroupItem(this, stereoGroup, "stereo", MediaSettings::Stereo); leftChannelAct = new MyActionGroupItem(this, stereoGroup, "left_channel", MediaSettings::Left); rightChannelAct = new MyActionGroupItem(this, stereoGroup, "right_channel", MediaSettings::Right); monoAct = new MyActionGroupItem(this, stereoGroup, "mono", MediaSettings::Mono); reverseAct = new MyActionGroupItem(this, stereoGroup, "reverse_channels", MediaSettings::Reverse); connect(stereoGroup, SIGNAL(activated(int)), core, SLOT(setStereoMode(int))); stereoAct->change(tr("&Stereo")); leftChannelAct->change(tr("&Left channel")); rightChannelAct->change(tr("&Right channel")); monoAct->change(tr("&Mono")); reverseAct->change(tr("Re&verse")); // Stereo mode submenu stereomode_menu = new QMenu(this); stereomode_menu->menuAction()->setObjectName("stereomode_menu"); stereomode_menu->addActions(stereoGroup->actions()); stereomode_menu->menuAction()->setText(tr("&Stereo mode")); // stereomode_menu->menuAction()->setIcon(Images::icon("stereo_mode")); audioMenu->addAction(muteAct); audioMenu->addSeparator(); audioMenu->addMenu(audiochannels_menu); audioMenu->addMenu(stereomode_menu); audioMenu->addSeparator(); audioMenu->addAction(decVolumeAct); audioMenu->addAction(incVolumeAct); audioMenu->addSeparator(); audioMenu->addAction(decAudioDelayAct); audioMenu->addAction(incAudioDelayAct); audioMenu->addSeparator(); audioMenu->addAction(audioDelayAct); subtitlesMenu = new QMenu(this); subtitlesMenu->menuAction()->setText( tr("Subtitles") ); // subtitlesMenuAct->setIcon(Images::icon("subtitles_menu")); loadSubsAct = new MyAction(this, "load_subs" ); connect(loadSubsAct, SIGNAL(triggered()), this, SLOT(loadSub())); loadSubsAct->change(tr("Load...")); subVisibilityAct = new MyAction(Qt::Key_V, this, "subtitle_visibility"); subVisibilityAct->setCheckable(true); connect(subVisibilityAct, SIGNAL(toggled(bool)), core, SLOT(changeSubVisibility(bool))); subVisibilityAct->change(tr("Subtitle &visibility")); subtitlesMenu->addAction(loadSubsAct); subtitlesMenu->addAction(subVisibilityAct); showPreferencesAct = new MyAction(QKeySequence("Ctrl+P"), this, "show_preferences"); connect(showPreferencesAct, SIGNAL(triggered()), this, SLOT(showPreferencesDialog())); showPreferencesAct->change(QPixmap(":/res/prefs.png"), tr("Preferences"));//首选项 showPropertiesAct = new MyAction(QKeySequence("Ctrl+I"), this, "show_file_properties"); connect(showPropertiesAct, SIGNAL(triggered()), this, SLOT(showFilePropertiesDialog())); showPropertiesAct->change(QPixmap(":/res/info.png"), tr("View &info and properties..."));//查看信息和属性 helpAct = new MyAction(QKeySequence("Ctrl+H"), this, "show_help" ); connect(helpAct, SIGNAL(triggered()), this, SLOT(showHelpDialog())); helpAct->change(QPixmap(":/res/help_normal.png"), tr("Help")); aboutAct = new MyAction(QKeySequence("Ctrl+A"), this, "about_kylin_video"); connect(aboutAct, SIGNAL(triggered()), this, SLOT(showAboutDialog())); aboutAct->change(Images::icon("about_normal"), tr("About &Kylin Video")); quitAct = new MyAction(QKeySequence("Ctrl+Q"), this, "quit"); quitAct->change(Images::icon("quit_normal"), tr("Quit")); connect(quitAct, SIGNAL(triggered()), this, SLOT(slot_close())); this->setJumpTexts(); // POPUP MENU if (!popup) popup = new QMenu(this); else popup->clear(); popup->addMenu(openMenu); popup->addMenu(recentfiles_menu); popup->addMenu(ontop_menu); popup->addMenu(playMenu); popup->addMenu(play_order_menu); popup->addMenu(aspect_menu); popup->addMenu(rotate_flip_menu); popup->addMenu(audioMenu); popup->addMenu(subtitlesMenu); // popup->addAction(shortcutsAct); popup->addAction(screenshotAct); popup->addAction(showPreferencesAct); popup->addAction(showPropertiesAct); popup->addAction(aboutAct); if (!main_popup) main_popup = new QMenu(this); else main_popup->clear(); main_popup->addAction(openFileAct); main_popup->addAction(screenshotAct); main_popup->addAction(showPreferencesAct); main_popup->addAction(helpAct); main_popup->addAction(aboutAct); main_popup->addSeparator(); main_popup->addAction(quitAct); } void BaseGui::createTrayActions() { tray = new QSystemTrayIcon(Images::icon("logo", 22), this); tray->setToolTip("Kylin Video"); tray->show(); connect(tray, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason))); tray->setIcon(Images::icon("logo", 22)); tray_menu = new QMenu(this); action_show = new MyAction(this, "open_window"); action_show->change(Images::icon("open_window_normal"), tr("Open Homepage")); action_openshotsdir = new MyAction(this, "open_shots_dir"); action_openshotsdir->change(Images::icon("open_screen"), tr("Open screenshots folder")); connect(action_show, SIGNAL(triggered()), this, SLOT(showAll())); connect(action_openshotsdir, SIGNAL(triggered()), this, SLOT(open_screenshot_directory())); tray_menu->setFixedWidth(250); tray->setContextMenu(tray_menu); } void BaseGui::addTrayActions() { //添加菜单项 tray_menu->addAction(action_show); tray_menu->addAction(action_openshotsdir); tray_menu->addSeparator(); tray_menu->addAction(aboutAct); tray_menu->addAction(helpAct); tray_menu->addSeparator(); tray_menu->addAction(showPreferencesAct); tray_menu->addAction(quitAct); } void BaseGui::createHiddenActions() { playlist_action = new MyAction(QKeySequence("F3"), this, "playlist_open_close"); playlist_action->change(tr("PlayList")); connect(playlist_action, SIGNAL(triggered()), this, SLOT(slot_playlist())); play_pause_aciton = new MyAction(QKeySequence(Qt::Key_Space), this, "play_pause"); play_pause_aciton->change(tr("Play/Pause")); connect(playlist_action, SIGNAL(triggered()), core, SLOT(play_or_pause())); stopAct = new MyAction(Qt::Key_MediaStop, this, "stop"); stopAct->change(tr("Stop")); connect(stopAct, SIGNAL(triggered()), core, SLOT(stop())); fullscreenAct = new MyAction(QKeySequence("Ctrl+Return"), this, "fullscreen"); fullscreenAct->change(tr("Fullscreen")); connect(fullscreenAct, SIGNAL(triggered()), this, SLOT(slot_set_fullscreen())); } void BaseGui::setActionsEnabled(bool b) { // qDebug() << "BaseGui::setActionsEnabled " << b; emit this->sigActionsEnabled(b); rewind1Act->setEnabled(b); rewind2Act->setEnabled(b); rewind3Act->setEnabled(b); forward1Act->setEnabled(b); forward2Act->setEnabled(b); forward3Act->setEnabled(b); gotoAct->setEnabled(b); // Menu Speed normalSpeedAct->setEnabled(b); halveSpeedAct->setEnabled(b); doubleSpeedAct->setEnabled(b); decSpeed10Act->setEnabled(b); incSpeed10Act->setEnabled(b); decSpeed4Act->setEnabled(b); incSpeed4Act->setEnabled(b); decSpeed1Act->setEnabled(b); incSpeed1Act->setEnabled(b); screenshotAct->setEnabled(b); showPropertiesAct->setEnabled(b); // Menu Audio muteAct->setEnabled(b); decVolumeAct->setEnabled(b); incVolumeAct->setEnabled(b); decAudioDelayAct->setEnabled(b); incAudioDelayAct->setEnabled(b); audioDelayAct->setEnabled(b); flipAct->setEnabled(b); mirrorAct->setEnabled(b); // Menu Subtitles loadSubsAct->setEnabled(b); aspectGroup->setActionsEnabled(b); rotateGroup->setActionsEnabled(b); channelsGroup->setActionsEnabled(b); stereoGroup->setActionsEnabled(b); } void BaseGui::start_top_and_bottom_timer() { // this->activate();//0830 m_topToolbar->activate(); m_bottomToolbar->activate(); } void BaseGui::enableActionsOnPlaying() { this->setActionsEnabled(true); isPlaying = true; // QTimer::singleShot(100, this, SLOT(start_top_and_bottom_timer())); start_top_and_bottom_timer(); // this->activate_timer(); // Screenshot option bool screenshots_enabled = ((pref->use_screenshot) && (!pref->screenshot_directory.isEmpty()) && (QFileInfo(pref->screenshot_directory).isDir())); screenshotAct->setEnabled(screenshots_enabled); // Disable audio actions if there's not audio track if ((core->mdat.audios.numItems()==0) && (core->mset.external_audio.isEmpty())) { muteAct->setEnabled(false); decVolumeAct->setEnabled(false); incVolumeAct->setEnabled(false); decAudioDelayAct->setEnabled(false); incAudioDelayAct->setEnabled(false); audioDelayAct->setEnabled(false); channelsGroup->setActionsEnabled(false); stereoGroup->setActionsEnabled(false); } // Disable video actions if it's an audio file if (core->mdat.novideo) { screenshotAct->setEnabled(false); flipAct->setEnabled(false); mirrorAct->setEnabled(false); aspectGroup->setActionsEnabled(false); rotateGroup->setActionsEnabled(false); } if (pref->hwdec.startsWith("vdpau") && pref->mplayer_bin.contains("mpv")) {//kobe 20170706 screenshotAct->setEnabled(false); } // Disable video filters if using vdpau if ((pref->vdpau.disable_video_filters) && (pref->vo.startsWith("vdpau"))) { screenshotAct->setEnabled(false); flipAct->setEnabled(false); mirrorAct->setEnabled(false); rotateGroup->setActionsEnabled(false); displayMessage(tr("Video filters are disabled when using vdpau")); } } void BaseGui::disableActionsOnStop() { // qDebug("BaseGui::disableActionsOnStop"); this->setActionsEnabled(false);//kobe:此处会让一些按钮处于禁用状态 emit this->setPlayOrPauseEnabled(true); // this->showAlways();//0830 m_topToolbar->showAlways(); m_bottomToolbar->showAlways(); isPlaying = false; m_topToolbar->enable_turned_on();//0519 isFinished = true;//kobe // turned_on = true;//0829 } void BaseGui::togglePlayAction(Core::State state) { if (state == Core::Playing) {//Stopped = 0, Playing = 1, Paused = 2 m_bottomToolbar->onMusicPlayed(); play_mask->hide();//0620 } else if (state == Core::Stopped) {//0621 m_bottomToolbar->onMusicPause(); play_mask->hide();//0620 } else { m_bottomToolbar->onMusicPause(); if (mplayerwindow) { mplayerwindow->hideLogo(); } play_mask->show();//0620 } } void BaseGui::setJumpTexts() { rewind1Act->change( tr("-%1").arg(Helper::timeForJumps(pref->seeking1)) ); rewind2Act->change( tr("-%1").arg(Helper::timeForJumps(pref->seeking2)) ); rewind3Act->change( tr("-%1").arg(Helper::timeForJumps(pref->seeking3)) ); forward1Act->change( tr("+%1").arg(Helper::timeForJumps(pref->seeking1)) ); forward2Act->change( tr("+%1").arg(Helper::timeForJumps(pref->seeking2)) ); forward3Act->change( tr("+%1").arg(Helper::timeForJumps(pref->seeking3)) ); } void BaseGui::createCore() { core = new Core(mplayerwindow, this); connect(core, SIGNAL(widgetsNeedUpdate()), this, SLOT(updateWidgets())); connect(core, SIGNAL(showFrame(int)), this, SIGNAL(frameChanged(int))); connect(core, SIGNAL(ABMarkersChanged(int,int)), this, SIGNAL(ABMarkersChanged(int,int))); connect(core, SIGNAL(showTime(double, bool)), this, SLOT(gotCurrentTime(double, bool))); connect(core, SIGNAL(needResize(int, int)), this, SLOT(resizeWindow(int,int))); connect(core, SIGNAL(showMessage(QString)), this, SLOT(displayMessage(QString))); connect(core, SIGNAL(stateChanged(Core::State)), this, SLOT(displayState(Core::State))); connect(core, SIGNAL(stateChanged(Core::State)), this, SLOT(checkStayOnTop(Core::State)), Qt::QueuedConnection); connect(core, SIGNAL(mediaStartPlay()), this, SLOT(enterFullscreenOnPlay()), Qt::QueuedConnection); connect(core, SIGNAL(mediaStoppedByUser()), this, SLOT(exitFullscreenOnStop())); connect(core, SIGNAL(mediaStoppedByUser()), mplayerwindow, SLOT(showLogo())); connect(core, SIGNAL(show_logo_signal(bool)), mplayerwindow, SLOT(setLogoVisible(bool))); connect(core, SIGNAL(mediaLoaded()), this, SLOT(enableActionsOnPlaying())); connect(core, SIGNAL(noFileToPlay()), this, SLOT(gotNoFileToPlay())); connect(core, SIGNAL(audioTracksChanged()), this, SLOT(enableActionsOnPlaying())); connect(core, SIGNAL(mediaFinished()), this, SLOT(disableActionsOnStop())); connect(core, SIGNAL(mediaStoppedByUser()), this, SLOT(disableActionsOnStop())); connect(core, SIGNAL(stateChanged(Core::State)), this, SLOT(togglePlayAction(Core::State))); //kobe connect的第五个参数Qt::QueuedConnection表示槽函数由接受信号的线程所执行,如果不加表示槽函数由发出信号的次线程执行。当传递信号的参数类型不是QT的元类型时要用qRegisterMetaType先注册 connect(core, SIGNAL(mediaStartPlay()), this, SLOT(newMediaLoaded()), Qt::QueuedConnection); connect(core, SIGNAL(mediaInfoChanged()), this, SLOT(updateMediaInfo())); connect(core, SIGNAL(failedToParseMplayerVersion(QString)), this, SLOT(askForMplayerVersion(QString))); connect(core, SIGNAL(mplayerFailed(QProcess::ProcessError)), this, SLOT(showErrorFromMplayer(QProcess::ProcessError))); connect(core, SIGNAL(mplayerFinishedWithError(int)), this, SLOT(showExitCodeFromMplayer(int))); //kobe:没有视频的时候进行相关隐藏设置 Hide mplayer window connect(core, SIGNAL(noVideo()), mplayerwindow, SLOT(showLogo())); // Log mplayer output connect(core, SIGNAL(aboutToStartPlaying()), this, SLOT(clearMplayerLog())); connect(core, SIGNAL(logLineAvailable(QString)), this, SLOT(recordMplayerLog(QString))); // connect(core, SIGNAL(mediaLoaded()), this, SLOT(autosaveMplayerLog())); connect(core, SIGNAL(receivedForbidden()), this, SLOT(gotForbidden())); } void BaseGui::createMplayerWindow() { //20170720 mplayerwindow = new MplayerWindow(this); mplayerwindow->setObjectName("mplayerwindow"); mplayerwindow->installEventFilter(this); mplayerwindow->setColorKey("121212");//121212 mplayerwindow->setColorKey("20202"); 0x020202 // pref->color_key kobe:视频显示区域背景色设置为黑色 0d87ca mplayerwindow->setContentsMargins(0, 0, 0, 0); /* mplayerwindow = new MplayerWindow(panel); mplayerwindow->setObjectName("mplayerwindow"); mplayerwindow->setColorKey("121212");//mplayerwindow->setColorKey("20202"); 0x020202 // pref->color_key kobe:视频显示区域背景色设置为黑色 QVBoxLayout * layout = new QVBoxLayout; layout->setSpacing(0); layout->setMargin(0); layout->addWidget(mplayerwindow); panel->setLayout(layout);*/ // mplayerwindow mouse events connect(mplayerwindow, SIGNAL(doubleClicked()), this, SLOT(doubleClickFunction())); connect(mplayerwindow, SIGNAL(leftClicked()), this, SLOT(leftClickFunction())); connect(mplayerwindow, SIGNAL(rightClicked()), this, SLOT(rightClickFunction())); connect(mplayerwindow, SIGNAL(middleClicked()), this, SLOT(middleClickFunction())); connect(mplayerwindow, SIGNAL(xbutton1Clicked()), this, SLOT(xbutton1ClickFunction())); connect(mplayerwindow, SIGNAL(xbutton2Clicked()), this, SLOT(xbutton2ClickFunction())); connect(mplayerwindow, SIGNAL(mouseMovedDiff(QPoint)), this, SLOT(moveWindowDiff(QPoint)), Qt::QueuedConnection); // connect(mplayerwindow->videoLayer(), SIGNAL(sigShowControls()), this, SLOT(onShowControls()));//0830 mplayerwindow->activateMouseDragTracking(true/*pref->move_when_dragging*/); // connect(mplayerwindow, SIGNAL(resize_mainwindow(int,int)), this, SLOT(slot_resize_mainwindow(int,int)));//add by kobe. remove on 20170720 replace by resizeEvent } void BaseGui::createPlaylist() { playlistWidget = new Playlist(core, this, 0); playlistWidget->setFixedSize(220, this->height() - TOP_TOOLBAR_HEIGHT - BOTTOM_TOOLBAR_HEIGHT); playlistWidget->setViewHeight(); playlistWidget->move(this->width()-220, TOP_TOOLBAR_HEIGHT); playlistWidget->hide(); connect(playlistWidget, SIGNAL(playlistEnded()), this, SLOT(playlistHasFinished())); connect(playlistWidget, SIGNAL(playlistEnded()), mplayerwindow, SLOT(showLogo())); connect(playlistWidget, SIGNAL(closePlaylist()), this, SLOT(slot_playlist())); connect(playlistWidget, SIGNAL(playListFinishedWithError(QString)), this, SLOT(showErrorFromPlayList(QString))); connect(playlistWidget, SIGNAL(showMessage(QString)), this, SLOT(displayMessage(QString))); // connect(playlistWidget, SIGNAL(finish_list()), } void BaseGui::createPanel() { panel = new QWidget(this); panel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); panel->setMinimumSize(QSize(1,1)); panel->setFocusPolicy(Qt::StrongFocus); } void BaseGui::createPreferencesDialog() { QApplication::setOverrideCursor(Qt::WaitCursor); pref_dialog = new PreferencesDialog(arch/*, this*/); pref_dialog->setModal(false); connect(pref_dialog, SIGNAL(applied()), this, SLOT(applyNewPreferences())); QApplication::restoreOverrideCursor(); } void BaseGui::createFilePropertiesDialog() { QApplication::setOverrideCursor(Qt::WaitCursor); file_dialog = new FilePropertiesDialog(/*this*/); file_dialog->setModal(false); connect( file_dialog, SIGNAL(applied()), this, SLOT(applyFileProperties()) ); QApplication::restoreOverrideCursor(); } void BaseGui::createAboutDialog() { QApplication::setOverrideCursor(Qt::WaitCursor); aboutDlg = new AboutDialog(); aboutDlg->setModal(false); QApplication::restoreOverrideCursor(); } void BaseGui::createHelpDialog() { QApplication::setOverrideCursor(Qt::WaitCursor); helpDlg = new HelpDialog(); helpDlg->setModal(false); QApplication::restoreOverrideCursor(); } void BaseGui::slot_playlist() { setPlaylistVisible(!playlistWidget->isVisible()); } void BaseGui::slideEdgeWidget(QWidget *right, QRect start, QRect end, int delay, bool hide) { right->show(); QPropertyAnimation *animation = new QPropertyAnimation(right, "geometry"); animation->setEasingCurve(QEasingCurve::InCurve); animation->setDuration(delay); animation->setStartValue(start); animation->setEndValue(end); animation->start(); connect(animation, SIGNAL(finished()), animation, SLOT(deleteLater())); if (hide) { connect(animation, SIGNAL(finished()), right, SLOT(hide())); } } void BaseGui::disableControl(int delay) { QTimer::singleShot(delay, this, SLOT(disableSomeComponent())); } void BaseGui::disableSomeComponent() { playlistWidget->setEnabled(true); } void BaseGui::setPlaylistProperty() { playlistWidget->setProperty("moving", false); } void BaseGui::setPlaylistVisible(bool visible) { playlistWidget->setProperty("moving", true); int titleBarHeight = TOP_TOOLBAR_HEIGHT; double factor = 0.6; QRect start(this->width(), titleBarHeight, playlistWidget->width(), playlistWidget->height()); QRect end(this->width() - playlistWidget->width(), titleBarHeight, playlistWidget->width(), playlistWidget->height()); if (!visible) { this->slideEdgeWidget(playlistWidget, end, start, ANIMATIONDELAY * factor, true); emit this->change_playlist_btn_status(false); } else { playlistWidget->setFocus(); this->slideEdgeWidget(playlistWidget, start, end, ANIMATIONDELAY * factor); emit this->change_playlist_btn_status(true); } disableControl(ANIMATIONDELAY * factor); m_topToolbar->raise(); QTimer::singleShot(ANIMATIONDELAY * factor * 1, this, SLOT(setPlaylistProperty())); } void BaseGui::slot_resize_corner() { resizeCorner->move(m_bottomToolbar->width()- 16, m_bottomToolbar->height() - 16);//0519 } void BaseGui::slot_set_fullscreen() { if (this->fullscreen) { toggleFullscreen(false); } else { toggleFullscreen(true); } } void BaseGui::showPreferencesDialog() { exitFullscreenIfNeeded(); if (!pref_dialog) { createPreferencesDialog(); } pref_dialog->setData(pref); //从最新的配置文件读取快捷键并进行设置 pref_dialog->mod_shortcut_page()->actions_editor->clear(); pref_dialog->mod_shortcut_page()->actions_editor->addCurrentActions(this); pref_dialog->move((width() - pref_dialog->width()) / 2 + mapToGlobal(QPoint(0, 0)).x(), (window()->height() - pref_dialog->height()) / 2 + mapToGlobal(QPoint(0, 0)).y()); pref_dialog->show(); } // The user has pressed OK in preferences dialog void BaseGui::applyNewPreferences() { PlayerID::Player old_player_type = PlayerID::player(pref->mplayer_bin); pref_dialog->getData(pref); m_bottomToolbar->setPreviewData(pref->preview_when_playing); mplayerwindow->activateMouseDragTracking(true/*pref->move_when_dragging*/); setJumpTexts(); // Update texts in menus updateWidgets(); // Update the screenshot action // Restart the video if needed if (pref_dialog->requiresRestart()) core->restart(); // Update actions pref_dialog->mod_shortcut_page()->actions_editor->applyChanges(); saveActions(); pref->save(); if (old_player_type != PlayerID::player(pref->mplayer_bin)) { // qDebug("BaseGui::applyNewPreferences: player changed!"); // Hack, simulate a change of GUI to restart the interface // FIXME: try to create a new Core::proc in the future core->stop(); if (pref_dialog && pref_dialog->isVisible()) {//add by kobe to hide the pref_dialog pref_dialog->accept(); } emit guiChanged(); } } void BaseGui::showFilePropertiesDialog() { // qDebug("BaseGui::showFilePropertiesDialog"); exitFullscreenIfNeeded(); if (!file_dialog) { createFilePropertiesDialog(); } setDataToFileProperties(); file_dialog->show(); } void BaseGui::setDataToFileProperties() { InfoReader *i = InfoReader::obj(); i->getInfo(); file_dialog->setCodecs( i->vcList(), i->acList(), i->demuxerList() ); // Save a copy of the original values if (core->mset.original_demuxer.isEmpty()) core->mset.original_demuxer = core->mdat.demuxer; if (core->mset.original_video_codec.isEmpty()) core->mset.original_video_codec = core->mdat.video_codec; if (core->mset.original_audio_codec.isEmpty()) core->mset.original_audio_codec = core->mdat.audio_codec; QString demuxer = core->mset.forced_demuxer; if (demuxer.isEmpty()) demuxer = core->mdat.demuxer; QString ac = core->mset.forced_audio_codec; if (ac.isEmpty()) ac = core->mdat.audio_codec; QString vc = core->mset.forced_video_codec; if (vc.isEmpty()) vc = core->mdat.video_codec; file_dialog->setDemuxer(demuxer, core->mset.original_demuxer); file_dialog->setAudioCodec(ac, core->mset.original_audio_codec); file_dialog->setVideoCodec(vc, core->mset.original_video_codec); file_dialog->setMediaData(core->mdat); } void BaseGui::applyFileProperties() { // qDebug("BaseGui::applyFileProperties"); bool need_restart = false; #undef TEST_AND_SET #define TEST_AND_SET( Pref, Dialog ) \ if ( Pref != Dialog ) { Pref = Dialog; need_restart = true; qDebug("BaseGui::applyFileProperties====================================111");} bool demuxer_changed = false; QString prev_demuxer = core->mset.forced_demuxer; if (prev_demuxer != core->mset.forced_demuxer) { // Demuxer changed demuxer_changed = true; core->mset.current_audio_id = MediaSettings::NoneSelected; core->mset.current_sub_id = MediaSettings::NoneSelected; } // Restart the video to apply if (need_restart) { if (demuxer_changed) { core->reload(); } else { core->restart(); } } } void BaseGui::updateMediaInfo() { // qDebug("BaseGui::updateMediaInfo"); tray->setToolTip( windowTitle() ); emit videoInfoChanged(core->mdat.video_width, core->mdat.video_height, core->mdat.video_fps.toDouble()); } void BaseGui::newMediaLoaded() { QString stream_title = core->mdat.stream_title; // qDebug("BaseGui::newMediaLoaded: mdat.stream_title: %s", stream_title.toUtf8().constData()); if (!stream_title.isEmpty()) { pref->history_recents->addItem( core->mdat.filename, stream_title ); //pref->history_recents->list(); } else { pref->history_recents->addItem( core->mdat.filename ); } updateRecents(); QFileInfo fi(core->mdat.filename); if (fi.exists()) { QString name = fi.fileName(); m_topToolbar->set_title_name(name); } // Automatically add files to playlist if ((core->mdat.type == TYPE_FILE) /*&& (pref->auto_add_to_playlist)*/) { //qDebug("BaseGui::newMediaLoaded: playlist count: %d", playlist->count()); QStringList files_to_add; if (playlistWidget->count() == 1) { files_to_add = Helper::filesForPlaylist(core->mdat.filename, pref->media_to_add_to_playlist); } if (!files_to_add.empty()) playlistWidget->addFiles(files_to_add); } } void BaseGui::gotNoFileToPlay() { playlistWidget->resumePlay();//当前播放的文件不存在时,去播放下一个 } void BaseGui::clearMplayerLog() { mplayer_log.clear(); } void BaseGui::recordMplayerLog(QString line) { if (pref->log_mplayer) { if ( (line.indexOf("A:")==-1) && (line.indexOf("V:")==-1) ) { line.append("\n"); mplayer_log.append(line); } } } void BaseGui::updateRecents() { // qDebug("BaseGui::updateRecents"); recentfiles_menu->clear(); int cur_items = 0; if (pref->history_recents == NULL) { return; } if (pref->history_recents->count() > 0) { for (int n=0; n < pref->history_recents->count(); n++) { QString i = QString::number( n+1 ); QString fullname = pref->history_recents->item(n); QString filename = fullname; QFileInfo fi(fullname); //if (fi.exists()) filename = fi.fileName(); // Can be slow // Let's see if it looks like a file (no dvd://1 or something) if (fullname.indexOf(QRegExp("^.*://.*")) == -1) filename = fi.fileName(); if (filename.size() > 85) { filename = filename.left(80) + "..."; } QString show_name = filename; QString title = pref->history_recents->title(n); if (!title.isEmpty()) show_name = title; // qDebug() << "kobe recents=" << QString("%1. " + show_name ).arg( i.insert( i.size()-1, '&' ), 3, ' ' ); QAction * a = recentfiles_menu->addAction( QString("%1. " + show_name ).arg( i.insert( i.size()-1, '&' ), 3, ' ' )); a->setStatusTip(fullname); a->setData(n); connect(a, SIGNAL(triggered()), this, SLOT(openRecent())); cur_items++; } } else { QAction * a = recentfiles_menu->addAction( tr("") ); a->setEnabled(false); } recentfiles_menu->menuAction()->setVisible( cur_items > 0 ); if (cur_items > 0) { recentfiles_menu->addSeparator(); recentfiles_menu->addAction( clearRecentsAct ); } } void BaseGui::clearRecentsList() { MessageDialog msgDialog(0, tr("Confirm deletion - Kylin Video"), tr("Delete the list of recent files?")); if (msgDialog.exec() != -1) { if (msgDialog.standardButton(msgDialog.clickedButton()) == QMessageBox::Ok) { // Delete items in menu pref->history_recents->clear(); updateRecents(); } } } void BaseGui::updateWidgets() { m_bottomToolbar->setPreviewData(pref->preview_when_playing); muteAct->setChecked((pref->global_volume ? pref->mute : core->mset.mute));//kobe 0606 bool muted = core->getMute(); m_bottomToolbar->onMutedChanged(muted, core->getVolumn());//0519 if (core->getVolumn() <= 0) { reset_mute_button(); } channelsGroup->setChecked(core->mset.audio_use_channels); // // Aspect ratio aspectGroup->setChecked(core->mset.aspect_ratio_id); // Rotate rotateGroup->setChecked(core->mset.rotate); // Flip flipAct->setChecked(core->mset.flip); // Mirror mirrorAct->setChecked(core->mset.mirror); // Audio menu stereoGroup->setChecked(core->mset.stereo_mode); // Subtitle visibility subVisibilityAct->setChecked(pref->sub_visibility); // Stay on top onTopActionGroup->setChecked((int)pref->stay_on_top); } void BaseGui::openRecent() { QAction *a = qobject_cast (sender()); if (a) { int item = a->data().toInt(); // qDebug("BaseGui::openRecent: %d", item); QString file = pref->history_recents->item(item); QFileInfo fi(file); if (fi.exists()) { playlistWidget->addFile(file, Playlist::NoGetInfo);//20170712 open(file); } else { this->showErrorFromPlayList(file); } } } void BaseGui::open(QString file) { // qDebug("BaseGui::open: '%s'", file.toUtf8().data()); // If file is a playlist, open that playlist QString extension = QFileInfo(file).suffix().toLower(); if ( ((extension=="m3u") || (extension=="m3u8")) && (QFile::exists(file)) ) { // playlist->load_m3u(file); } else if (extension=="pls") { // playlist->load_pls(file); } else if (QFileInfo(file).isDir()) { openDirectory(file); } else { // Let the core to open it, autodetecting the file type core->open(file/*, 0*/);//每次从头开始播放文件 } if (QFile::exists(file)) pref->latest_dir = QFileInfo(file).absolutePath(); } void BaseGui::openFiles(QStringList files) { // qDebug("BaseGui::openFiles"); if (files.empty()) return; if (files.count()==1) { playlistWidget->addFile(files[0], Playlist::NoGetInfo);//20170712 open(files[0]); } else { playlistWidget->addFiles(files); open(files[0]); } } void BaseGui::openFile() { exitFullscreenIfNeeded(); Extensions e; QString s = MyFileDialog::getOpenFileName( this, tr("Choose a file"), pref->latest_dir, tr("Multimedia") + e.allPlayable().forFilter()+";;" + tr("Video") + e.video().forFilter()+";;" + tr("Audio") + e.audio().forFilter()+";;" + tr("Playlists") + e.playlist().forFilter()+";;" + tr("All files") +" (*.*)" ); if ( !s.isEmpty() ) { openFile(s); } } void BaseGui::openFile(QString file) { // qDebug("BaseGui::openFile: '%s'", file.toUtf8().data()); if ( !file.isEmpty() ) { // If file is a playlist, open that playlist QString extension = QFileInfo(file).suffix().toLower(); if ( (extension=="m3u") || (extension=="m3u8") ) { // playlist->load_m3u(file); } else if (extension=="pls") { // playlist->load_pls(file); } else if (extension=="iso") { core->open(file/*, 0*/);//每次从头开始播放文件 } else {//kobe:打开一个本地视频文件 core->openFile(file);//开始播放新打开的本地视频文件 playlistWidget->addFile(file, Playlist::NoGetInfo);//将新打开的本地视频文件加入到播放列表中 } if (QFile::exists(file)) pref->latest_dir = QFileInfo(file).absolutePath(); } } void BaseGui::openDirectory() { qDebug("BaseGui::openDirectory"); QString s = MyFileDialog::getExistingDirectory( this, tr("Choose a directory"), pref->latest_dir ); if (!s.isEmpty()) { openDirectory(s); } } void BaseGui::openDirectory(QString directory) { // qDebug("BaseGui::openDirectory: '%s'", directory.toUtf8().data()); if (Helper::directoryContainsDVD(directory)) { core->open(directory); } else { QFileInfo fi(directory); if ( (fi.exists()) && (fi.isDir()) ) { //playlistWidget->clear(); //playlistWidget->addDirectory(directory); playlistWidget->addDirectory(fi.absoluteFilePath()); playlistWidget->startPlay(); } else { qDebug("BaseGui::openDirectory: directory is not valid"); } } } void BaseGui::openURL() { exitFullscreenIfNeeded(); /* bool ok; QString s = QInputDialog::getText(this, tr("Kylin Video - Enter URL"), tr("URL:"), QLineEdit::Normal, pref->last_url, &ok ); if ( ok && !s.isEmpty() ) { //playlist->clear(); //playlistdock->hide(); openURL(s); } else { // user entered nothing or pressed Cancel } */ //kobe 20170627 // InputURL d(this); InputURL d;//kobe 20170627 // Get url from clipboard QString clipboard_text = QApplication::clipboard()->text(); if ((!clipboard_text.isEmpty()) && (clipboard_text.contains("://")) /*&& (QUrl(clipboard_text).isValid())*/) { d.setURL(clipboard_text); } for (int n=0; n < pref->history_urls->count(); n++) { d.setURL(pref->history_urls->url(n) ); } int w_x = this->frameGeometry().topLeft().x() + (this->width() / 2) - (400 / 2); int w_y = this->frameGeometry().topLeft().y() + (this->height() /2) - (170 / 2); d.move(w_x, w_y); if (d.exec() == QDialog::Accepted ) { QString url = d.url(); if (!url.isEmpty()) { pref->history_urls->addUrl(url); openURL(url); } } } void BaseGui::openURL(QString url) { if (!url.isEmpty()) { pref->history_urls->addUrl(url); core->openStream(url); // if (pref->auto_add_to_playlist) { // if (playlist->maybeSave()) { // core->openStream(url); // playlist->clear(); // playlist->addFile(url, Playlist::NoGetInfo); // } // } else { // core->openStream(url); // } } } void BaseGui::loadSub() { qDebug("BaseGui::loadSub"); exitFullscreenIfNeeded(); Extensions e; QString s = MyFileDialog::getOpenFileName( this, tr("Choose a file"), pref->latest_dir, tr("Subtitles") + e.subtitles().forFilter()+ ";;" + tr("All files") +" (*.*)" ); if (!s.isEmpty()) core->loadSub(s); } void BaseGui::setInitialSubtitle(const QString & subtitle_file) { qDebug("BaseGui::setInitialSubtitle: '%s'", subtitle_file.toUtf8().constData()); core->setInitialSubtitle(subtitle_file); } void BaseGui::loadAudioFile() { qDebug("BaseGui::loadAudioFile"); exitFullscreenIfNeeded(); Extensions e; QString s = MyFileDialog::getOpenFileName( this, tr("Choose a file"), pref->latest_dir, tr("Audio") + e.audio().forFilter()+";;" + tr("All files") +" (*.*)" ); if (!s.isEmpty()) core->loadAudioFile(s); } void BaseGui::setDataToAboutDialog() { aboutDlg->setVersions(); } void BaseGui::showAboutDialog() { if (!aboutDlg) { createAboutDialog(); } setDataToAboutDialog(); int w_x = this->frameGeometry().topLeft().x() + (this->width() / 2) - (438 / 2); int w_y = this->frameGeometry().topLeft().y() + (this->height() /2) - (320 / 2); aboutDlg->move(w_x, w_y); aboutDlg->show(); } void BaseGui::showHelpDialog() { if (!helpDlg) { createHelpDialog(); } helpDlg->setData(pref); helpDlg->move((width() - helpDlg->width()) / 2 + mapToGlobal(QPoint(0, 0)).x(), (window()->height() - helpDlg->height()) / 2 + mapToGlobal(QPoint(0, 0)).y()); helpDlg->show(); } void BaseGui::showGotoDialog() { TimeDialog d; d.setLabel(tr("&Jump to:")); d.setWindowTitle(tr("Kylin Video - Seek")); d.setMaximumTime((int) core->mdat.duration); d.setTime((int) core->mset.current_sec); int w_x = this->frameGeometry().topLeft().x() + (this->width() / 2) - (380 / 2); int w_y = this->frameGeometry().topLeft().y() + (this->height() /2) - (170 / 2); d.move(w_x, w_y); if (d.exec() == QDialog::Accepted) { core->goToSec(d.time()); } } void BaseGui::showAudioDelayDialog() { AudioDelayDialog dlg; dlg.setDefaultValue(core->mset.audio_delay); int w_x = this->frameGeometry().topLeft().x() + (this->width() / 2) - (380 / 2); int w_y = this->frameGeometry().topLeft().y() + (this->height() /2) - (170 / 2); dlg.move(w_x, w_y); if (dlg.exec() == QDialog::Accepted) { int delay = dlg.getCurrentValue(); core->setAudioDelay(delay); } } void BaseGui::showSubDelayDialog() { bool ok; #if QT_VERSION >= 0x050000 int delay = QInputDialog::getInt(this, tr("Kylin Video - Subtitle delay"), tr("Subtitle delay (in milliseconds):"), core->mset.sub_delay, -3600000, 3600000, 1, &ok); #else int delay = QInputDialog::getInteger(this, tr("Kylin Video - Subtitle delay"), tr("Subtitle delay (in milliseconds):"), core->mset.sub_delay, -3600000, 3600000, 1, &ok); #endif if (ok) { core->setSubDelay(delay); } } void BaseGui::setStayOnTop(bool b) { // qDebug("BaseGui::setStayOnTop: %d", b); if ( (b && (windowFlags() & Qt::WindowStaysOnTopHint)) || (!b && (!(windowFlags() & Qt::WindowStaysOnTopHint))) ) { // identical do nothing // qDebug("BaseGui::setStayOnTop: nothing to do"); return; } ignore_show_hide_events = true; bool visible = isVisible(); QPoint old_pos = pos(); if (b) { setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); } else { setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint); } move(old_pos); if (visible) { show(); } ignore_show_hide_events = false; } void BaseGui::changeStayOnTop(int stay_on_top) { switch (stay_on_top) { case Preferences::AlwaysOnTop : setStayOnTop(true); break; case Preferences::NeverOnTop : setStayOnTop(false); break; case Preferences::WhilePlayingOnTop : setStayOnTop((core->state() == Core::Playing)); break; } pref->stay_on_top = (Preferences::OnTop) stay_on_top; // updateWidgets(); // Stay on top onTopActionGroup->setChecked((int)pref->stay_on_top); } void BaseGui::checkStayOnTop(Core::State state) { // qDebug("BaseGui::checkStayOnTop"); if ((!pref->fullscreen) && (pref->stay_on_top == Preferences::WhilePlayingOnTop)) { setStayOnTop((state == Core::Playing)); } } void BaseGui::changePlayOrder(int play_order) { pref->play_order = (Preferences::PlayOrder) play_order; // updateWidgets(); playOrderActionGroup->setChecked((int)pref->play_order); } void BaseGui::exitFullscreen() { if (pref->fullscreen) { toggleFullscreen(false); } } void BaseGui::toggleFullscreen(bool b) { if (b==this->fullscreen) {//kobe:b==pref->fullscreen // Nothing to do qDebug("BaseGui::toggleFullscreen: nothing to do, returning"); return; } this->fullscreen = b; mplayerwindow->hideLogoForTemporary(); if (this->fullscreen) { m_topToolbar->showAlways(); m_bottomToolbar->showAlways(); // m_topToolbar->hide(); // m_bottomToolbar->hide(); // this->showAlways(); was_maximized = isMaximized(); showFullScreen(); this->mplayerwindow->resize(QMainWindow::size()); m_bottomToolbar->onFullScreen();//让全屏/取消全屏的按钮更换图片为取消全屏 this->resizeCorner->hide(); // if (core->state())//0811 // QTimer::singleShot(100, this, SLOT(start_top_and_bottom_timer())); QString state = core->stateToString().toUtf8().data(); // this->showAlways(); if (state == "Playing" || state == "Paused") {//全屏的时候如果不是正在播放或暂停,则显示标题栏和控制栏 // this->activate_timer(); start_top_and_bottom_timer(); } //kobe:全屏的时候让所有视频大小的设置菜单禁用 // Make all not checkable // sizeGroup->setActionsEnabled(false); // doubleSizeAct->setEnabled(false); } else { // this->showAlways(); m_topToolbar->showAlways(); m_bottomToolbar->showAlways(); showNormal(); if (was_maximized) showMaximized(); // It has to be called after showNormal() this->mplayerwindow->resize(QMainWindow::size()); m_bottomToolbar->onUnFullScreen();//让全屏/取消全屏的按钮更换图片为全屏//0519 this->resizeCorner->show();//0519 if (this->escWidget->isVisible()) this->escWidget->hide(); QString state = core->stateToString().toUtf8().data(); if (state == "Playing" || state == "Paused") {//kobe: Stopped Playing Paused // QTimer::singleShot(100, this, SLOT(start_top_and_bottom_timer())); // this->activate_timer(); start_top_and_bottom_timer(); } //kobe:退出全屏的时候如果视频仍然在播放,则让所有视频大小的设置菜单恢复使用 // Make all checkable // if (isFinished == false) { // sizeGroup->setActionsEnabled(true); // doubleSizeAct->setEnabled(true); // } } updateWidgets(); setFocus(); // Fixes bug #2493415 QTimer::singleShot(100, mplayerwindow, SLOT(update_logo_pos())); } void BaseGui::leftClickFunction() { if (playlistWidget->isVisible()) {//20170713 setPlaylistVisible(false); } //kobe QString state = core->stateToString().toUtf8().data(); if (state == "Playing" || state == "Paused") {//kobe: Stopped Playing Paused core->play_or_pause(); } // if (!pref->mouse_left_click_function.isEmpty()) { // processFunction(pref->mouse_left_click_function); // } } void BaseGui::rightClickFunction() { showPopupMenu();//kobe // if (!pref->mouse_right_click_function.isEmpty()) { // processFunction(pref->mouse_right_click_function); // } } void BaseGui::doubleClickFunction() { this->slot_set_fullscreen();//kobe // if (!pref->mouse_double_click_function.isEmpty()) { // processFunction(pref->mouse_double_click_function); // } } void BaseGui::middleClickFunction() { processFunction("mute");//kobe // if (!pref->mouse_middle_click_function.isEmpty()) { // processFunction(pref->mouse_middle_click_function); // } } void BaseGui::xbutton1ClickFunction() { qDebug("BaseGui::xbutton1ClickFunction"); // if (!pref->mouse_xbutton1_click_function.isEmpty()) { // processFunction(pref->mouse_xbutton1_click_function); // } } void BaseGui::xbutton2ClickFunction() { qDebug("BaseGui::xbutton2ClickFunction"); // if (!pref->mouse_xbutton2_click_function.isEmpty()) { // processFunction(pref->mouse_xbutton2_click_function); // } } void BaseGui::processFunction(QString function) { // qDebug("##########################BaseGui::processFunction: '%s'", function.toUtf8().data()); //parse args for checkable actions QRegExp func_rx("(.*) (true|false)"); bool value = false; bool checkableFunction = false; if(func_rx.indexIn(function) > -1){ function = func_rx.cap(1); value = (func_rx.cap(2) == "true"); checkableFunction = true; } //end if //kobe //smplayer源码是用QAction关联各个事件,比如全屏,创建全屏菜单项的时候设置了objectName为fullscreen, //然后如果双击屏幕,因为代码设置了mouse_double_click_function = "fullscreen",所以在调用processFunction时,传递的是fullscreen, //后续会在ActionsEditor::findAction中寻找是否有fullscreen,如果有,则调用绑定fullscreen的菜单项的槽函数。 QAction * action = ActionsEditor::findAction(this, function); if (!action) action = ActionsEditor::findAction(playlistWidget, function); if (action) { qDebug("BaseGui::processFunction: action found"); if (!action->isEnabled()) { qDebug("BaseGui::processFunction: action is disabled, doing nothing"); return; } if (action->isCheckable()){ if(checkableFunction) action->setChecked(value); else //action->toggle(); action->trigger(); }else{ action->trigger(); } } else { qDebug("BaseGui::processFunction: action not found"); } } void BaseGui::gotForbidden() { qDebug("BaseGui::gotForbidden"); static bool busy = false; if (busy) return; busy = true; QMessageBox::warning(this, tr("Error detected"), tr("Unfortunately this video can't be played.") +"
"+ tr("The server returned '%1'").arg("403: Forbidden")); busy = false; } void BaseGui::dragEnterEvent( QDragEnterEvent *e ) { // qDebug("BaseGui::dragEnterEvent"); if (e->mimeData()->hasUrls()) { e->acceptProposedAction(); } } void BaseGui::dropEvent( QDropEvent *e ) { // qDebug("BaseGui::dropEvent"); QStringList files; if (e->mimeData()->hasUrls()) { QList l = e->mimeData()->urls(); QString s; for (int n=0; n < l.count(); n++) { if (l[n].isValid()) { qDebug("BaseGui::dropEvent: scheme: '%s'", l[n].scheme().toUtf8().data()); if (l[n].scheme() == "file") s = l[n].toLocalFile(); else s = l[n].toString(); /* qDebug(" * '%s'", l[n].toString().toUtf8().data()); qDebug(" * '%s'", l[n].toLocalFile().toUtf8().data()); */ qDebug("BaseGui::dropEvent: file: '%s'", s.toUtf8().data()); files.append(s); } } } qDebug( "BaseGui::dropEvent: count: %d", files.count()); if (files.count() > 0) { #ifdef Q_OS_WIN files = Helper::resolveSymlinks(files); // Check for Windows shortcuts #endif files.sort(); if (files.count() == 1) { QFileInfo fi( files[0] ); Extensions e; QRegExp ext_sub(e.subtitles().forRegExp()); ext_sub.setCaseSensitivity(Qt::CaseInsensitive); if (ext_sub.indexIn(fi.suffix()) > -1) { qDebug( "BaseGui::dropEvent: loading sub: '%s'", files[0].toUtf8().data()); core->loadSub( files[0] ); } else if (fi.isDir()) { openDirectory( files[0] ); } else { //openFile( files[0] ); // if (pref->auto_add_to_playlist) { // if (playlistWidget->maybeSave()) { // playlistWidget->clear(); playlistWidget->addFile(files[0], Playlist::NoGetInfo);//20170712 open( files[0] ); // } // } else { // open( files[0] ); // } } } else { // More than one file qDebug("BaseGui::dropEvent: adding files to playlist"); // playlistWidget->clear(); playlistWidget->addFiles(files); //openFile( files[0] ); playlistWidget->startPlay(); } } } void BaseGui::showPopupMenu() { showPopupMenu(QCursor::pos()); } void BaseGui::showPopupMenu( QPoint p ) { // //qDebug("BaseGui::showPopupMenu: %d, %d", p.x(), p.y()); popup->move(p); popup->show(); } // Called when a video has started to play void BaseGui::enterFullscreenOnPlay() { // qDebug("BaseGui::enterFullscreenOnPlay: arg_start_in_fullscreen: %d, pref->start_in_fullscreen: %d", arg_start_in_fullscreen, pref->start_in_fullscreen); if (arg_start_in_fullscreen != 0) { if ( (arg_start_in_fullscreen == 1)/* || (pref->start_in_fullscreen) */) { if (!pref->fullscreen) { toggleFullscreen(true); } } } } // Called when the playlist has stopped void BaseGui::exitFullscreenOnStop() { // qDebug("BaseGui::exitFullscreenOnStop"); if (pref->fullscreen) { toggleFullscreen(false); } emit this->clear_playing_title(); } void BaseGui::playlistHasFinished() { // qDebug("BaseGui::playlistHasFinished"); core->stop(); exitFullscreenOnStop(); } void BaseGui::displayState(Core::State state) { // qDebug("BaseGui::displayState: %s", core->stateToString().toUtf8().data()); switch (state) {//0830 case Core::Playing://播放时开启自动隐藏标题栏和控制栏的定时器 start_top_and_bottom_timer(); // this->activate_timer(); break; case Core::Paused://暂停时显示标题栏和控制栏 // this->showAlways(); m_bottomToolbar->showAlways(); m_topToolbar->showAlways(); break; case Core::Stopped: // this->showAlways(); m_bottomToolbar->showAlways(); m_topToolbar->set_title_name(""); m_topToolbar->showAlways(); break; } } void BaseGui::displayMessage(QString message) { this->showTipWidget(message); } //kobe 0606 flag=true时表示充值时间显示label的值为初始值 void BaseGui::gotCurrentTime(double sec, bool flag) { //qDebug( "DefaultGui::displayTime: %f", sec); QString time; QString all_time; if (flag) { time = "00:00:00"; all_time = " / 00:00:00"; } else { static int last_second = 0; if (floor(sec)==last_second) return; // Update only once per second last_second = (int) floor(sec); // time = Helper::formatTime( (int) sec ) + " / " + // Helper::formatTime( (int) core->mdat.duration ); time = Helper::formatTime((int) sec); all_time = " / " + Helper::formatTime((int) core->mdat.duration); //qDebug( " duration: %f, current_sec: %f", core->mdat.duration, core->mset.current_sec); } emit timeChanged(time, all_time); } void BaseGui::loadConfig() { // qDebug("DefaultGui::loadConfig"); QSettings * set = settings; set->beginGroup("default_gui"); QPoint p = set->value("pos", pos()).toPoint(); // QSize s = set->value("size", size()).toSize(); move(p); setWindowState( (Qt::WindowStates) set->value("state", 0).toInt() ); if (!DesktopInfo::isInsideScreen(this)) { move(0,0); qWarning("DefaultGui::loadConfig: window is outside of the screen, moved to 0x0"); } set->endGroup(); updateWidgets(); } //add by kobe, remove on 20170720 replace by resizeEvent /*void BaseGui::slot_resize_mainwindow(int w, int h) { // qDebug("==============================aaaBaseGui::slot_resize_mainwindow: %d, %d", w, h); // qDebug("BaseGui::slot_resize_mainwindow: done: panel->size: %d, %d", // panel->size().width(), // panel->size().height() ); // qDebug("BaseGui::slot_resize_mainwindow: done: mplayerwindow->size: %d, %d", // mplayerwindow->size().width(), // mplayerwindow->size().height()); // if (pref->fullscreen) return; this->playlistWidget->setFixedSize(220, panel->size().height() - TOP_TOOLBAR_HEIGHT - BOTTOM_TOOLBAR_HEIGHT);//0531 if (this->playlistWidget->isVisible()) { this->playlistWidget->hide(); emit this->change_playlist_btn_status(false);//0619 } //test kobe // setPlaylistVisible(!playlistWidget->isVisible()); if (m_topToolbar) { m_topToolbar->raise(); // m_topToolbar->resize(width(), TOP_TOOLBAR_HEIGHT); m_topToolbar->resize(panel->size().width(), TOP_TOOLBAR_HEIGHT); // m_topToolbar->show_title_widget(); // m_topSeparatorLine->setVisible(true); } if (m_bottomToolbar) {//0519 // if (this->isFullScreen()) // return; m_bottomToolbar->raise(); m_bottomToolbar->resize(panel->size().width(), BOTTOM_TOOLBAR_HEIGHT); // qDebug() << "height()="<pos().y()="<pos().y(); m_bottomToolbar->move(0, height() - BOTTOM_TOOLBAR_HEIGHT); m_bottomToolbar->show_control_widget(); //kobe:设置一个临界值判断界面拉伸时底部工具栏是全显示模式还是只显示进度条模式,正常拉伸界面有效,但是点击最大化后再切换回正常尺寸显示会有异常,下方会显示不出来 // int h_interval = qAbs(height() - m_bottomToolbar->pos().y()); // if (h_interval < 30) { // m_bottomToolbar->move(0, height() - 6); // } // else { // m_bottomToolbar->move(0, height() - BOTTOM_TOOLBAR_HEIGHT); // } resizeCorner->move(m_bottomToolbar->width()- 16, m_bottomToolbar->height() - 16); } this->update(); // if (m_topSeparatorLine) {//0519 // m_topSeparatorLine->resize(window()->width(), 1); // m_topSeparatorLine->move(0, TOP_TOOLBAR_HEIGHT); // } // if (window()->isFullScreen()) {//0519 // m_topSeparatorLine->setVisible(false); // } else { // m_topSeparatorLine->setVisible(true); // } // if (m_btmSeparatorLine) {//0519 //// m_btmSeparatorLine->resize(window()->width(), 1); //// m_btmSeparatorLine->move(0, window()->height() - m_bottomToolbar->height() - 1); // m_btmSeparatorLine->resize(panel->size().width(), 1); // m_btmSeparatorLine->move(0, panel->size().height() - BOTTOM_TOOLBAR_HEIGHT - 1); // } }*/ void BaseGui::resizeWindow(int w, int h) { // qDebug("BaseGui::resizeWindow: %d, %d", w, h); // If fullscreen, don't resize! if (pref->fullscreen) return; if ( (pref->resize_method==Preferences::Never) && (panel->isVisible()) ) { return; } if (!panel->isVisible()) { panel->show(); } resizeMainWindow(w, h); } void BaseGui::resizeMainWindow(int w, int h) { // qDebug("BaseGui::resizeWindow: size to scale: %d, %d", w, h); QSize video_size(w,h); if (video_size == panel->size()) { qDebug("BaseGui::resizeWindow: the panel size is already the required size. Doing nothing."); return; } int diff_width = this->width() - panel->width(); int diff_height = this->height() - panel->height(); int new_width = w + diff_width; int new_height = h + diff_height; int minimum_width = minimumSizeHint().width(); if (new_width < minimum_width) { qDebug("BaseGui::resizeWindow: width is too small, setting width to %d", minimum_width); new_width = minimum_width; } // qDebug("BaseGui::resizeWindow: new_width: %d new_height: %d", new_width, new_height); resize(new_width, new_height); } void BaseGui::centerWindow() {//kobe:播放后界面调整至屏幕中央 if (/*pref->center_window && */!pref->fullscreen && isVisible()) { QRect r = QApplication::desktop()->screenGeometry(this); // r.setX(500); r.setY(150); // Test // qDebug() << "BaseGui::centerWindow: desktop rect:" << r; int x = r.x() + ((r.width() - width()) / 2); int y = r.y() + ((r.height() - height()) / 2); move(x, y); } } void BaseGui::displayGotoTime(int t) { int jump_time = (int)core->mdat.duration * t / SEEKBAR_RESOLUTION; QString s = tr("Jump to %1").arg( Helper::formatTime(jump_time) ); if (pref->fullscreen) { core->displayTextOnOSD( s ); } } void BaseGui::goToPosOnDragging(int t) { // #ifdef SEEKBAR_RESOLUTION // core->goToPosition(t); // #else // core->goToPos(t); // #endif } // Called when a new window (equalizer, preferences..) is opened. void BaseGui::exitFullscreenIfNeeded() { if (pref->fullscreen) { toggleFullscreen(false); } } void BaseGui::loadActions() { qDebug("BaseGui::loadActions"); ActionsEditor::loadFromConfig(this, settings); // actions_list = ActionsEditor::actionsNames(this); } void BaseGui::saveActions() { qDebug("BaseGui::saveActions"); ActionsEditor::saveToConfig(this, settings); } void BaseGui::moveWindowDiff(QPoint diff) { if (pref->fullscreen || isMaximized()) { return; } #if QT_VERSION >= 0x050000 // Move the window with some delay. // Seems to work better with Qt 5 static QPoint d; static int count = 0; d += diff; count++; if (count > 3) { QPoint new_pos = pos() + d; if (new_pos.y() < 0) new_pos.setY(0); if (new_pos.x() < 0) new_pos.setX(0); // qDebug() << "BaseGui::moveWindowDiff: new_pos:" << new_pos; move(new_pos); count = 0; d = QPoint(0,0); } #else move(pos() + diff); #endif } #if QT_VERSION < 0x050000 void BaseGui::showEvent( QShowEvent * ) { qDebug("BaseGui::showEvent"); if (ignore_show_hide_events) return; //qDebug("BaseGui::showEvent: pref->pause_when_hidden: %d", pref->pause_when_hidden); if ((pref->pause_when_hidden) && (core->state() == Core::Paused)) { qDebug("BaseGui::showEvent: unpausing"); core->pause(); // Unpauses } } void BaseGui::hideEvent( QHideEvent * ) { qDebug("BaseGui::hideEvent"); if (ignore_show_hide_events) return; //qDebug("BaseGui::hideEvent: pref->pause_when_hidden: %d", pref->pause_when_hidden); if ((pref->pause_when_hidden) && (core->state() == Core::Playing)) { qDebug("BaseGui::hideEvent: pausing"); core->pause(); } } #else // Qt 5 doesn't call showEvent / hideEvent when the window is minimized or unminimized bool BaseGui::event(QEvent * e) {//kobe 0522 QWidget::paintEngine: Should no longer be called // qDebug("BaseGui::event: %d", e->type()); bool result = QWidget::event(e); // if ((ignore_show_hide_events)/* || (!pref->pause_when_hidden)*/) return result; if ((ignore_show_hide_events) || (!pref->pause_when_hidden)) return result;//20170627 kobe if (e->type() == QEvent::WindowStateChange) { // qDebug("BaseGui::event: WindowStateChange"); if (isMinimized()) { was_minimized = true; if (core->state() == Core::Playing) { qDebug("BaseGui::event: pausing"); core->pause(); // this->showAlways(); // this->deactivate();//0829 // m_topToolbar->show(); // m_bottomToolbar->show(); m_topToolbar->deactivate(); m_bottomToolbar->deactivate(); } } } if ((e->type() == QEvent::ActivationChange) && (isActiveWindow())) { // qDebug("BaseGui::event: ActivationChange: %d", was_minimized); if ((!isMinimized()) && (was_minimized)) { was_minimized = false; if (core->state() == Core::Paused) { // qDebug("BaseGui::showEvent: unpausing"); core->pause(); // Unpauses //kobe:在函数displayState已经处理了 /*m_topToolbar->deactivate(); m_bottomToolbar->deactivate(); QString state = core->stateToString().toUtf8().data(); if (state == "Playing" || state == "Paused") {//kobe: Stopped Playing Paused // QTimer::singleShot(100, this, SLOT(start_top_and_bottom_timer())); start_top_and_bottom_timer(); }*/ } } } return result; } #endif void BaseGui::quit() { qDebug("BaseGui::quit"); closeWindow(); } void BaseGui::trayIconActivated(QSystemTrayIcon::ActivationReason reason) { qDebug("DefaultGui::trayIconActivated: %d", reason); switch(reason) { case QSystemTrayIcon::Trigger: toggleShowAll(); break; case QSystemTrayIcon::DoubleClick: toggleShowAll(); break; case QSystemTrayIcon::MiddleClick: core->pause(); break; default: break; } } void BaseGui::toggleShowAll() { // Ignore if tray is not visible if (tray->isVisible()) { showAll( !isVisible() ); } } void BaseGui::showAll() { if (!isVisible()) showAll(true); } void BaseGui::showAll(bool b) { if (!b) { trayicon_playlist_was_visible = playlistWidget->isVisible(); playlist_pos = playlistWidget->pos(); playlistWidget->hide(); mainwindow_pos = pos(); hide(); } else { // Show all move(mainwindow_pos); show(); if (trayicon_playlist_was_visible) { playlistWidget->move(playlist_pos); playlistWidget->show(); } } } void BaseGui::askForMplayerVersion(QString line) { qDebug("BaseGui::askForMplayerVersion: %s", line.toUtf8().data()); } void BaseGui::showErrorFromPlayList(QString errorStr) { ErrorDialog d; d.setWindowTitle(tr("%1 Error").arg(PLAYER_NAME)); d.setTitleText(tr("%1 Error").arg(PLAYER_NAME)); d.setText(tr("'%1' was not found!").arg(errorStr)); d.hideDetailBtn(); d.exec(); } void BaseGui::showExitCodeFromMplayer(int exit_code) { qDebug("BaseGui::showExitCodeFromMplayer: %d", exit_code); if (exit_code != 255 ) { ErrorDialog d;//kobe d.setWindowTitle(tr("%1 Error").arg(PLAYER_NAME)); d.setTitleText(tr("%1 Error").arg(PLAYER_NAME)); d.setText(tr("%1 has finished unexpectedly.").arg(PLAYER_NAME) + " " + tr("Exit code: %1").arg(exit_code)); d.setLog(mplayer_log); d.exec(); } this->clearMplayerLog();//add by kobe } void BaseGui::showErrorFromMplayer(QProcess::ProcessError e) { // qDebug("BaseGui::showErrorFromMplayer"); /*QProcess::FailedToStart 0 进程启动失败 QProcess::Crashed 1 进程成功启动后崩溃 QProcess::Timedout 2 最后一次调用waitFor...()函数超时.此时QProcess状态不变,并可以再次 调用waitFor()类型的函数 QProcess::WriteError 3 向进程写入时出错.如进程尚未启动,或者输入通道被关闭时 QProcess::ReadError 4 从进程中读取数据时出错.如进程尚未启动时 QProcess::UnknownError 5 未知错误.这也是error()函数返回的默认值。*/ if ((e == QProcess::FailedToStart) || (e == QProcess::Crashed)) { ErrorDialog d;//kobe 20170627 d.setWindowTitle(tr("%1 Error").arg(PLAYER_NAME)); d.setTitleText(tr("%1 Error").arg(PLAYER_NAME)); if (e == QProcess::FailedToStart) { d.setText(tr("%1 failed to start.").arg(PLAYER_NAME) + " " + tr("Please check the %1 path in preferences.").arg(PLAYER_NAME)); } else { d.setText(tr("%1 has crashed.").arg(PLAYER_NAME) + " " + tr("See the log for more info.")); } d.setLog(mplayer_log); d.exec(); } this->clearMplayerLog();//add by kobe // else if ((e == QProcess::ReadError) || (e == QProcess::WriteError)) {//add by kobe // ErrorDialog d;//kobe 20170627 // d.setWindowTitle(tr("%1 Error").arg(PLAYER_NAME)); // d.setTitleText(tr("%1 Error").arg(PLAYER_NAME)); // if (e == QProcess::ReadError) { // d.setText(tr("%1 failed to read.").arg(PLAYER_NAME) + " " + // tr("Please check the file %1 still exists.")); // } else { // d.setText(tr("%1 failed to write.").arg(PLAYER_NAME) + " " + // tr("Please check if the file still exists.")); // } // d.setLog(mplayer_log); // d.exec(); // } } void BaseGui::showTipWidget(const QString text) { if (this->tipWidget->isVisible()) this->tipWidget->hide(); if (tip_timer->isActive()) tip_timer->stop(); tip_timer->start(); // this->tipWidget->move(this->pos().x() + 30, this->pos().y() + TOP_TOOLBAR_HEIGHT); this->tipWidget->setText(text); this->tipWidget->show(); } void BaseGui::hideTipWidget() { this->tipWidget->hide(); } void BaseGui::showOrHideEscWidget(bool b) { if (escWidget) { if (b) { if (!escWidget->isVisible() && this->isFullScreen()) { this->escWidget->show(); } } else { if (escWidget->isVisible() && this->isFullScreen()) { this->escWidget->hide(); } } } } bool BaseGui::eventFilter(QObject *obj, QEvent *event) { // qDebug() << "BaseGui::eventFilter" << obj->objectName(); if (obj == this->resizeCorner) { if (!this->isMaximized()) { if (event->type() == QEvent::MouseButtonPress) { this->resizeFlag = true; } else if (event->type() == QEvent::MouseButtonRelease) { this->resizeFlag = false; } } } /*else if (obj == this->panel || obj == this->mplayerwindow || obj == this->m_bottomToolbar || obj == this->m_topToolbar) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) { return false; } QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) { return false; } if (mouseEvent->modifiers() != Qt::NoModifier) { return false; } if (event->type() == QEvent::MouseMove && turned_on) { if (!m_topToolbar->isVisible()) { m_topToolbar->showSpreadAnimated(); } if (!m_bottomToolbar->getCtrlWidgetVisible()) { m_bottomToolbar->showSpreadAnimated(); } } }*/ return qApp->eventFilter(obj, event); } void BaseGui::mousePressEvent(QMouseEvent *event) { switch(event->button()) { case Qt::LeftButton: // dragPosition = event->globalPos() - this->frameGeometry().topLeft(); break; default: QWidget::mousePressEvent(event); } } void BaseGui::mouseMoveEvent(QMouseEvent *event) { if (event->buttons() == Qt::LeftButton) { if (this->resizeFlag) {//resize int targetWidth = event->globalX() - this->frameGeometry().topLeft().x(); int targetHeight = event->globalY() - this->frameGeometry().topLeft().y(); if(targetWidth < WINDOW_MIN_WIDTH) { if(targetHeight < WINDOW_MIN_HEIGHT) resize(WINDOW_MIN_WIDTH, WINDOW_MIN_HEIGHT); else resize(WINDOW_MIN_WIDTH, targetHeight); } else { if(targetHeight < WINDOW_MIN_HEIGHT) { resize(targetWidth, WINDOW_MIN_HEIGHT); } else { resize(targetWidth, targetHeight); } } event->accept(); } //此处如果移动将会导致一些控件拖动时主界面乱动 /*else {//# drag move // if(dragPosition != QPoint(-1, -1)) { this->move((event->globalPos().x() - this->dragPosition.x()), (event->globalPos().y() - this->dragPosition.y())); event->accept(); // } }*/ } QWidget::mouseMoveEvent(event); } void BaseGui::ready_save_pre_image(int time) { // QString state = core->stateToString().toUtf8().data(); // if (state == "Playing" || state == "Paused") { // } if (core) { if (core->state() == Core::Playing || core->state() == Core::Paused) { if (video_preview == 0) { video_preview = new VideoPreview(pref->mplayer_bin, 0); } if (!core->mdat.filename.isEmpty()) { video_preview->setVideoFile(core->mdat.filename); } video_preview->setMplayerPath(pref->mplayer_bin); bool res = video_preview->createPreThumbnail(time); if (res) { emit this->send_save_preview_image_name(time, video_preview->getCurrentPicture()); } else { emit this->send_save_preview_image_name(time, ""); } } else { emit this->send_save_preview_image_name(time, ""); } } } //20170720 void BaseGui::resizeEvent(QResizeEvent *e) { QMainWindow::resizeEvent(e); QSize newSize = QMainWindow::size(); // qDebug() << "new Size=" << newSize; int titleBarHeight = this->m_topToolbar->height(); this->m_topToolbar->raise(); this->m_topToolbar->move(0, 0); this->m_topToolbar->resize(newSize.width(), titleBarHeight); // this->mplayerwindow->setFixedSize(newSize); this->mplayerwindow->resize(newSize); this->playlistWidget->setFixedSize(220, newSize.height() - BOTTOM_TOOLBAR_HEIGHT - titleBarHeight); this->playlistWidget->setViewHeight(); if (this->playlistWidget->isVisible()) { this->playlistWidget->hide(); emit this->change_playlist_btn_status(false); } this->m_bottomToolbar->raise(); this->m_bottomToolbar->resize(newSize.width(), BOTTOM_TOOLBAR_HEIGHT); this->m_bottomToolbar->move(0, newSize.height() - BOTTOM_TOOLBAR_HEIGHT); this->m_bottomToolbar->show_control_widget(); resizeCorner->move(this->m_bottomToolbar->width()- 16, this->m_bottomToolbar->height() - 16); } void BaseGui::closeEvent( QCloseEvent * e ) { this->closeWindow(); e->accept(); } void BaseGui::closeWindow() { if (core->state() != Core::Stopped) { core->stop(); } playlistWidget->close();//kobe //qApp->quit(); emit quitSolicited(); } void BaseGui::open_screenshot_directory() { bool open_enabled = ((!pref->screenshot_directory.isEmpty()) && (QFileInfo(pref->screenshot_directory).isDir())); if (open_enabled) { QDesktopServices::openUrl(QUrl(QString("file:%1").arg(pref->screenshot_directory), QUrl::TolerantMode)); } else { tray->showMessage(tr("Information"), tr("The screenshot folder does not exist!"), QSystemTrayIcon::Information, 2000);//QSystemTrayIcon::Warning } } //#include "moc_basegui.cpp" kylin-video/src/merge/prefgeneral.cpp0000664000175000017500000001104613233751662016630 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 "prefgeneral.h" #include "../smplayer/preferences.h" #include "../smplayer/filedialog.h" #include "../smplayer/images.h" #include "../smplayer/mediasettings.h" #include "../smplayer/paths.h" #include "../smplayer/playerid.h" #include #include "../smplayer/deviceinfo.h" PrefGeneral::PrefGeneral(QWidget * parent, Qt::WindowFlags f) : PrefWidget(parent, f ) { setupUi(this); retranslateStrings(); } PrefGeneral::~PrefGeneral() { } void PrefGeneral::selectRadioButton() { // QObject *obj = sender();//返回发出信号的对象,用QObject类型接收 // QRadioButton* pbtn = qobject_cast(obj); // QString obj_name = pbtn->objectName(); // if(obj_name == "mplayer_radio") { // qDebug() << "mplayer_radio clicked......"; // } // else if(obj_name == "mpv_radio") { // qDebug() << "mpv_radio clicked......"; // } } void PrefGeneral::retranslateStrings() { retranslateUi(this); label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); mplayer_radioButton->setObjectName("mplayer_radio"); mplayer_radioButton->setFocusPolicy(Qt::NoFocus); mpv_radioButton->setObjectName("mpv_radio"); mpv_radioButton->setFocusPolicy(Qt::NoFocus); pause_if_hidden_check->setFocusPolicy(Qt::NoFocus); preview_if_play_check->setFocusPolicy(Qt::NoFocus); createHelp(); } void PrefGeneral::setData(Preferences *pref) { setMplayerPath(pref->mplayer_bin); setPauseWhenHidden(pref->pause_when_hidden);//true setPreviewWhenPlaying(pref->preview_when_playing); } void PrefGeneral::getData(Preferences * pref) { requires_restart = false; filesettings_method_changed = false; if (pref->mplayer_bin != mplayerPath()) { requires_restart = true; pref->mplayer_bin = mplayerPath(); emit this->ready_to_update_driver(); qDebug("PrefGeneral::getData: mplayer binary has changed, getting version number"); } pref->pause_when_hidden = pauseWhenHidden(); pref->preview_when_playing = previewWhenPlaying(); } void PrefGeneral::setMplayerPath(QString path) { if (path == "/usr/bin/mpv") { mpv_radioButton->setChecked(true); } else { mplayer_radioButton->setChecked(true); } } QString PrefGeneral::mplayerPath() { if (mpv_radioButton->isChecked()) { return "/usr/bin/mpv"; } else { return "/usr/bin/mplayer"; } } void PrefGeneral::setPauseWhenHidden(bool b) { pause_if_hidden_check->setChecked(b); } bool PrefGeneral::pauseWhenHidden() { return pause_if_hidden_check->isChecked(); } void PrefGeneral::setPreviewWhenPlaying(bool b) { preview_if_play_check->setChecked(b); } bool PrefGeneral::previewWhenPlaying() { return preview_if_play_check->isChecked(); } void PrefGeneral::createHelp() { clearHelp(); setWhatsThis(pause_if_hidden_check, tr("Pause when minimized"), tr("If this option is enabled, the file will be paused when the " "main window is hidden. When the window is restored, playback " "will be resumed.")); setWhatsThis(preview_if_play_check, tr("Preview when the video is playing"), tr("If this option is enabled, the video preview will be displayed " "when the mouse is placed on the progress bar.")); setWhatsThis(mplayer_radioButton, tr("Select MPlayer as playback engine"), tr("If you change the playback engine to MPlayer, please restart Kylin Video.")); setWhatsThis(mpv_radioButton, tr("Select MPV as playback engine"), tr("If you change the playback engine to MPV, please restart Kylin Video.")); } //#include "moc_prefgeneral.cpp" kylin-video/src/merge/errordialog.ui0000664000175000017500000000756113214706400016476 0ustar fengfeng ErrorDialog 0 0 514 364 0 0 16777215 16777215 MPlayer Error 388 116 91 25 OK 479 0 36 36 162 10 191 20 MPlayer Error Qt::AlignCenter 11 38 60 58 icon Qt::AlignCenter 4 80 37 381 31 0 0 Oops, something wrong happened 81 63 400 41 0 0 400 0 Error true 10 94 494 20 Qt::Horizontal 23 116 91 25 Show log true 10 150 494 207 true kylin-video/src/merge/errordialog.cpp0000664000175000017500000001670713233751662016660 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 "errordialog.h" #include "../smplayer/images.h" #include #include #include #include #include ErrorDialog::ErrorDialog( QWidget* parent, Qt::WindowFlags f ) : QDialog(parent, f) , drag_state(NOT_EDRAGGING) , start_drag(QPoint(0,0)) { setupUi(this); this->setWindowFlags(Qt::FramelessWindowHint); this->setFixedSize(514, 160); this->setStyleSheet("QDialog{border: 1px solid #121212;border-radius:1px;background-color:#1f1f1f;}"); this->setWindowIcon(QIcon(":/res/kylin-video.png"));//setWindowIcon( Images::icon("logo", 64) ); this->setAutoFillBackground(true); this->setMouseTracking(true); installEventFilter(this); log->setStyleSheet("QTextEdit {border: 1px solid #000000;color: #999999;background: #0f0f0f;font-family:方正黑体_GBK;font-size: 12px;}"); log->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {width: 12px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:vertical {width: 12px;min-height: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:vertical:hover {background: #3e3e3e;}QScrollBar::handle:vertical:pressed {background: #272727;}QScrollBar::sub-line:vertical {height: 6px;background: transparent;subcontrol-position: top;}QScrollBar::add-line:vertical {height: 6px;background: transparent;subcontrol-position: bottom;}QScrollBar::sub-line:vertical:hover {background: #292929;}QScrollBar::add-line:vertical:hover {background: #292929;}QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;}"); icon->setScaledContents(true); icon->setText(""); icon->setPixmap(Images::icon("warn")); // intro_label->setText("

" + tr("Oops, something wrong happened") +"

"); intro_label->setStyleSheet("QLabel{background:transparent;font-size:20px;color:#999999;font-family:方正黑体_GBK;}");//font-weight:bold; title_label->setStyleSheet("QLabel{background:transparent;font-size:14px;color:#999999;font-family:方正黑体_GBK;}");//font-weight:bold; text_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}");//font-weight:bold; text_label->setText(""); toggleLog(false); connect(viewlog_button, SIGNAL(toggled(bool)), this, SLOT(toggleLog(bool))); closeBtn->setFocusPolicy(Qt::NoFocus); closeBtn->setStyleSheet("QPushButton{background-image:url(':/res/close_normal.png');border:0px;}QPushButton:hover{background:url(':/res/close_hover.png');}QPushButton:pressed{background:url(':/res/close_press.png');}"); viewlog_button->setFixedSize(91, 25); viewlog_button->setFocusPolicy(Qt::NoFocus); viewlog_button->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); okBtn->setFixedSize(91, 25); okBtn->setFocusPolicy(Qt::NoFocus); okBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); connect(closeBtn, SIGNAL(clicked()),this, SLOT(close())); connect(okBtn, SIGNAL(clicked()),this, SLOT(accept())); // layout()->setSizeConstraint(QLayout::SetFixedSize); } ErrorDialog::~ErrorDialog() { } void ErrorDialog::hideDetailBtn() { viewlog_button->hide(); } void ErrorDialog::setText(QString error) { text_label->setText(error); } void ErrorDialog::setTitleText(QString error) { title_label->setText(error); } void ErrorDialog::setLog(QString log_text) { log->setPlainText(""); log->append(log_text); // To move cursor to the end } void ErrorDialog::toggleLog(bool checked) { log->setVisible(checked); if (checked) { viewlog_button->setText(tr("Hide log")); this->setFixedSize(514, 364); } else { viewlog_button->setText(tr("Show log")); this->setFixedSize(514, 160); } } void ErrorDialog::moveDialog(QPoint diff) { #if QT_VERSION >= 0x050000 // Move the window with some delay. // Seems to work better with Qt 5 static QPoint d; static int count = 0; d += diff; count++; if (count > 3) { QPoint new_pos = pos() + d; if (new_pos.y() < 0) new_pos.setY(0); if (new_pos.x() < 0) new_pos.setX(0); move(new_pos); count = 0; d = QPoint(0,0); } #else move(pos() + diff); #endif } bool ErrorDialog::eventFilter( QObject * object, QEvent * event ) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { drag_state = NOT_EDRAGGING; return false; } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_EDRAGGING; return false; } drag_state = START_EDRAGGING; start_drag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (drag_state != EDRAGGING || mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_EDRAGGING; return false; } // Stop dragging and eat event drag_state = NOT_EDRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (drag_state == NOT_EDRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { drag_state = NOT_EDRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - start_drag; if (drag_state == START_EDRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; drag_state = EDRAGGING; } this->moveDialog(diff); start_drag = pos; event->accept(); return true; } //#include "moc_errordialog.cpp" kylin-video/src/merge/prefvideo.ui0000664000175000017500000000527413214706400016147 0ustar fengfeng PrefVideo 0 0 470 360 10 20 256 22 Enable postprocessing by default 10 132 448 22 Draw video using slices 10 76 448 22 Direct rendering 10 104 448 22 Double buffering 10 48 448 22 Use software video equalizer 113 170 85 27 0 0 false 10 170 97 27 Output driver: false vo_combo kylin-video/src/merge/inputurl.ui0000664000175000017500000000520713214706400016042 0ustar fengfeng InputURL 0 0 500 170 0 0 16777215 16777215 Enter URL 297 127 91 25 OK 397 127 91 25 Cancel 464 0 36 36 154 10 191 20 Enter URL Qt::AlignCenter 68 60 421 27 0 0 true QComboBox::AdjustToMinimumContentsLength 11 57 51 31 URL: url_edit kylin-video/src/merge/preferencesdialog.ui0000664000175000017500000000625413214706400017644 0ustar fengfeng PreferencesDialog 0 0 675 425 Kylin Video - Preferences 0 0 160 425 49 20 101 33 Preference Qt::AlignCenter 0 72 160 353 0 0 QFrame::StyledPanel QFrame::Raised 14 20 32 32 Qt::AlignCenter 181 20 470 360 0 0 -1 570 390 91 25 Cancel 369 390 91 25 Apply 470 390 91 25 OK kylin-video/src/merge/prefgeneral.ui0000664000175000017500000000357113214706400016454 0ustar fengfeng PrefGeneral 0 0 470 360 10 60 448 22 Pause when minimized 128 23 117 22 MPlayer 250 23 117 22 MPV 10 20 121 27 Playback engine: cache_files_spin 10 95 448 22 Preview when video is playing kylin-video/src/merge/prefvideo.h0000664000175000017500000000446513233751662015775 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 */ #ifndef _PREFVIDEO_H_ #define _PREFVIDEO_H_ #include "ui_prefvideo.h" #include "../smplayer/prefwidget.h" #include "../smplayer/inforeader.h" #include "../smplayer/deviceinfo.h" #include "../smplayer/preferences.h" class PrefVideo : public PrefWidget, public Ui::PrefVideo { Q_OBJECT public: PrefVideo(QString arch_type = "", QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~PrefVideo(); // Pass data to the dialog void setData(Preferences * pref); // Apply changes void getData(Preferences * pref); bool fileSettingsMethodChanged() { return filesettings_method_changed; }; protected: virtual void createHelp(); void setVO( QString vo_driver ); QString VO(); // Tab video and audio void setEq2(bool b); bool eq2(); void setInitialPostprocessing(bool b); bool initialPostprocessing(); void setDirectRendering(bool b); bool directRendering(); void setDoubleBuffer(bool b); bool doubleBuffer(); void setUseSlices(bool b); bool useSlices(); void setAmplification(int n); int amplification(); void setAudioChannels(int ID); int audioChannels(); protected slots: void vo_combo_changed(int); public slots: void update_driver_combobox(); protected: virtual void retranslateStrings(); void updateDriverCombos(); InfoList vo_list; DeviceList alsa_devices; DeviceList xv_adaptors; private: bool filesettings_method_changed; QString arch; }; #endif kylin-video/src/merge/prefsubtitles.h0000664000175000017500000000354313233751662016701 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 */ #ifndef _PREFSUBTITLES_H_ #define _PREFSUBTITLES_H_ #include "ui_prefsubtitles.h" #include "../smplayer/prefwidget.h" class Preferences; class Encodings; class PrefSubtitles : public PrefWidget, public Ui::PrefSubtitles { Q_OBJECT public: PrefSubtitles( QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~PrefSubtitles(); virtual QString sectionName(); virtual QPixmap sectionIcon(); // Pass data to the dialog void setData(Preferences * pref); // Apply changes void getData(Preferences * pref); public slots: void setCurrentPage(int index); protected: virtual void createHelp(); void setFontEncoding(QString s); QString fontEncoding(); void setUseEnca(bool v); bool useEnca(); void setEncaLang(QString s); QString encaLang(); void setFreetypeSupport(bool b); bool freetypeSupport(); protected: virtual void retranslateStrings(); private: Encodings * encodings; QString forced_ass_style; }; #endif kylin-video/src/merge/prefperformance.ui0000664000175000017500000001203213214706400017330 0ustar fengfeng PrefPerformance 0 0 470 360 10 20 453 100 Cache 6 0 0 0 0 Cache for local files: cache_files_spin 100000 KB Cache for streams: cache_streams_spin 100000 KB 10 130 453 100 Decode 6 0 0 0 0 Threads for decoding (MPEG-1/2 and H.264 only): 1 16 1 Qt::Horizontal 40 20 Hardware decoding Qt::Horizontal 40 20 kylin-video/src/merge/lineedit_with_icon.cpp0000664000175000017500000000557613233751662020211 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 "lineedit_with_icon.h" #include #include #include #include LineEditWithIcon::LineEditWithIcon(QWidget *parent) : QLineEdit(parent) { //height: 27px; this->setStyleSheet("QLineEdit {border:1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QLineEdit::hover{border: 1px solid #000000;background: #0a0a0a;font-family:方正黑体_GBK;font-size:12px;color:#ffffff;}QLineEdit:enabled {background: #0a0a0a;color:#999999;}QLineEdit:enabled:hover, QLineEdit:enabled:focus {background: #0a0a0a;color:#ffffff;}QLineEdit:!enabled {color: #383838;}"); button = new QToolButton(this); button->setObjectName("folderToolButton"); button->setCursor(Qt::ArrowCursor); setupButton(); button->setText(tr("Change")); } void LineEditWithIcon::setupButton() { } void LineEditWithIcon::setIcon(const QPixmap & pixmap) { // QPixmap p = pixmap; // //qDebug("height: %d, icon height: %d", height(), p.height()); // int max_height = 16; // if (max_height > height()) max_height = height() - 4; // if (pixmap.height() > max_height) p = pixmap.scaledToHeight(max_height, Qt::SmoothTransformation); // button->setIcon(p); // button->setStyleSheet("QToolButton { border: none; padding: 0px; }"); // int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); // //qDebug("frameWidth: %d", frameWidth); // setStyleSheet(QString("QLineEdit { padding-right: %1px; } ").arg(button->sizeHint().width() + frameWidth + 1)); // /* // QSize msz = minimumSizeHint(); // setMinimumSize(qMax(msz.width(), button->sizeHint().height() + frameWidth * 2 + 2), // qMax(msz.height(), button->sizeHint().height() + frameWidth * 2 + 2)); // */ } void LineEditWithIcon::resizeEvent(QResizeEvent *) { QSize sz = button->sizeHint(); button->setFixedHeight(this->height()); button->move(rect().right() - sz.width() + 1, 0); } //#include "moc_lineedit_with_icon.cpp" kylin-video/src/merge/filepropertiesdialog.ui0000664000175000017500000001550713214706400020400 0ustar fengfeng FilePropertiesDialog 0 0 650 509 Kylin Video - Preferences 0 0 160 509 14 20 32 32 Qt::AlignCenter 0 72 160 437 0 0 QFrame::StyledPanel QFrame::Raised 49 20 101 33 Properties Qt::AlignCenter 181 20 444 441 0 0 0 6 6 444 441 true 5 5 444 17 &Select the demuxer that will be used for this file: false demuxer_listbox 5 30 444 378 352 414 91 25 &Reset demuxer_listbox demuxer_label resetDemuxerButton 5 30 444 378 5 5 444 17 &Select the video codec: false vc_listbox 352 414 91 25 &Reset 5 30 444 378 5 5 444 17 &Select the audio codec: false ac_listbox 352 414 91 25 Reset 331 470 91 25 Apply 432 470 91 25 OK 532 470 91 25 Cancel kylin-video/src/merge/prefscreenshot.cpp0000664000175000017500000002123513233751662017371 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 "prefscreenshot.h" #include "../smplayer/preferences.h" #include "../smplayer/filedialog.h" #include "../smplayer/images.h" #include "../smplayer/mediasettings.h" #include "../smplayer/paths.h" #include "../smplayer/playerid.h" #include #include "../smplayer/deviceinfo.h" //#include //qt4 //#include //qt5 PrefScreenShot::PrefScreenShot(QWidget * parent, Qt::WindowFlags f) : PrefWidget(parent, f ) { setupUi(this); // mplayerbin_edit->setDialogType(FileChooser::GetFileName); screenshot_edit->setDialogType(FileChooser::GetDirectory); retranslateStrings(); } PrefScreenShot::~PrefScreenShot() { } void PrefScreenShot::retranslateStrings() { retranslateUi(this); use_screenshots_check->setFocusPolicy(Qt::NoFocus); groupBox->setStyleSheet("QGroupBox{border:none;margin-top:20px;font-size:14px;}QGroupBox:title{subcontrol-origin: margin;subcontrol-position: top left;padding: 0px 1px;color: #999999;font-family: 方正黑体_GBK;font-weight:bold;}"); screenshot_format_combo->setStyleSheet("QComboBox{width:150px;height:24px;border:1px solid #000000;background:#0f0f0f;font-size:12px;font-family:方正黑体_GBK;background-position:center left;padding-left:5px;color:#999999;selection-color:#ffffff;selection-background-color:#1f1f1f;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox::drop-down {width:17px;border:none;background:transparent;}QComboBox::drop-down:hover {background:transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView{border:1px solid #0a9ff5;background:#262626;outline:none;}"); // screenshot_format_combo->setStyle(new QWindowsStyle);//qt4 // screenshot_format_combo->setStyle(new QCommonStyle);//qt5 // screenshot_format_combo->setStyleSheet("QComboBox{width:150px;height:24px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:enabled {background:#0f0f0f;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox:enabled:hover, QComboBox:enabled:focus {color: #1f1f1f;}QComboBox::drop-down {width: 17px;border: none;background: transparent;}QComboBox::drop-down:hover {background: transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView {border: 1px solid #0a9ff5;background: #1f1f1f;outline: none;}"); screenshot_template_edit->setStyleSheet("QLineEdit {height: 25px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QLineEdit::hover{border: 1px solid #000000;background: #0a0a0a;font-family:方正黑体_GBK;font-size:12px;color:#ffffff;}QLineEdit:enabled {background: #0a0a0a;color:#999999;}QLineEdit:enabled:hover, QLineEdit:enabled:focus {background: #0a0a0a;color:#ffffff;}QLineEdit:!enabled {color: #383838;}"); screenshots_dir_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); screenshot_format_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); screenshot_template_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); connect(use_screenshots_check, SIGNAL(toggled(bool)), screenshots_dir_label, SLOT(setEnabled(bool))); connect(use_screenshots_check, SIGNAL(toggled(bool)), screenshot_edit, SLOT(setEnabled(bool))); connect(use_screenshots_check, SIGNAL(toggled(bool)), screenshot_template_edit, SLOT(setEnabled(bool))); connect(use_screenshots_check, SIGNAL(toggled(bool)), screenshot_format_label, SLOT(setEnabled(bool))); connect(use_screenshots_check, SIGNAL(toggled(bool)), screenshot_format_combo, SLOT(setEnabled(bool))); connect(use_screenshots_check, SIGNAL(toggled(bool)), screenshot_template_label, SLOT(setEnabled(bool))); screenshot_edit->setCaption(tr("Select a directory")); createHelp(); } void PrefScreenShot::setData(Preferences *pref) { setUseScreenshots(pref->use_screenshot); setScreenshotDir(pref->screenshot_directory); screenshot_format_combo->addItems(QStringList() << "png" << "ppm" << "pgm" << "pgmyuv" << "tga" << "jpg" << "jpeg"); screenshot_template_edit->setText(pref->screenshot_template); setScreenshotFormat(pref->screenshot_format); if (pref->mplayer_bin == "/usr/bin/mpv") { screenshot_template_label->show(); screenshot_template_edit->show(); screenshot_format_label->show(); screenshot_format_combo->show(); } else { screenshot_template_label->hide(); screenshot_template_edit->hide(); screenshot_format_label->hide(); screenshot_format_combo->hide(); } } void PrefScreenShot::getData(Preferences * pref) { requires_restart = false; filesettings_method_changed = false; TEST_AND_SET(pref->use_screenshot, useScreenshots()); TEST_AND_SET(pref->screenshot_directory, screenshotDir()); if (pref->mplayer_bin == "/usr/bin/mpv") { TEST_AND_SET(pref->screenshot_template, screenshot_template_edit->text()); TEST_AND_SET(pref->screenshot_format, screenshotFormat()); } } void PrefScreenShot::setUseScreenshots(bool b) { use_screenshots_check->setChecked(b); } bool PrefScreenShot::useScreenshots() { return use_screenshots_check->isChecked(); } void PrefScreenShot::setScreenshotDir( QString path ) { screenshot_edit->setText( path ); } QString PrefScreenShot::screenshotDir() { return screenshot_edit->text(); } void PrefScreenShot::setScreenshotFormat(const QString format) { int i = screenshot_format_combo->findText(format); if (i < 0) i = 0; screenshot_format_combo->setCurrentIndex(i); } QString PrefScreenShot::screenshotFormat() { return screenshot_format_combo->currentText(); } void PrefScreenShot::createHelp() { clearHelp(); setWhatsThis(use_screenshots_check, tr("Enable screenshots"), tr("You can use this option to enable or disable the possibility to " "take screenshots.") ); setWhatsThis(screenshot_edit, tr("Screenshots folder"), tr("Here you can specify a folder where the screenshots taken by " "Kylin Video will be stored. If the folder is not valid the " "screenshot feature will be disabled.") ); setWhatsThis(screenshot_template_edit, tr("Template for screenshots"), tr("This option specifies the filename template used to save screenshots.") + " " + tr("For example %1 would save the screenshot as 'moviename_0001.png'.").arg("%F_%04n") + "
" + tr("%1 specifies the filename of the video without the extension, " "%2 adds a 4 digit number padded with zeros.").arg("%F").arg("%04n") + " " + tr("For a full list of the template specifiers visit this link:") + " " "http://mpv.io/manual/stable/#options-screenshot-template" + "
" + tr("This option only works with mpv.") ); setWhatsThis(screenshot_format_combo, tr("Format for screenshots"), tr("This option allows one to choose the image file type used for saving screenshots.") + " " + tr("This option only works with mpv.") ); } //#include "moc_prefscreenshot.cpp" kylin-video/src/merge/filepropertiesdialog.h0000664000175000017500000000531613233751662020222 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 */ #ifndef _FILEPROPERTIESDIALOG_H_ #define _FILEPROPERTIESDIALOG_H_ #include "ui_filepropertiesdialog.h" #include "../smplayer/inforeader.h" #include "../smplayer/mediadata.h" #include "../smplayer/config.h" class QPushButton; class TitleButton; enum FDragState {NOT_FDRAGGING, START_FDRAGGING, FDRAGGING}; class FilePropertiesDialog : public QDialog, public Ui::FilePropertiesDialog { Q_OBJECT public: enum Section { Info=0, Demuxer=1, AC=2, VC=3, Options=4}; FilePropertiesDialog( QWidget* parent = 0, Qt::WindowFlags f = 0 ); ~FilePropertiesDialog(); void setMediaData(MediaData md); // Call it as soon as possible void setCodecs(InfoList vc, InfoList ac, InfoList demuxer); void setDemuxer(QString demuxer, QString original_demuxer=""); QString demuxer(); void setVideoCodec(QString vc, QString original_vc=""); QString videoCodec(); void setAudioCodec(QString ac, QString original_ac=""); QString audioCodec(); virtual bool eventFilter(QObject *, QEvent *); void moveDialog(QPoint diff); public slots: void accept(); // Reimplemented to send a signal virtual void reject(); void apply(); void onButtonClicked(int id); void setCurrentID(int id); signals: void applied(); protected slots: virtual void on_resetDemuxerButton_clicked(); virtual void on_resetACButton_clicked(); virtual void on_resetVCButton_clicked(); protected: bool hasCodecsList() { return codecs_set; }; int find(QString s, InfoList &list); void showInfo(); protected: virtual void retranslateStrings(); virtual void changeEvent ( QEvent * event ) ; private: bool codecs_set; InfoList vclist, aclist, demuxerlist; QString orig_demuxer, orig_ac, orig_vc; MediaData media_data; QList m_buttonList; FDragState drag_state; QPoint start_drag; }; #endif kylin-video/src/merge/audiodelaydialog.cpp0000664000175000017500000001624113233751662017640 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 "audiodelaydialog.h" #include "../smplayer/images.h" #include "../smplayer/version.h" #include "../smplayer/global.h" #include "../smplayer/paths.h" #include #include #include using namespace Global; AudioDelayDialog::AudioDelayDialog(QWidget * parent, Qt::WindowFlags f) : QDialog(parent, f) , drag_state(NOT_AADRAGGING) , start_drag(QPoint(0,0)) { setupUi(this); this->setWindowFlags(Qt::FramelessWindowHint); this->setFixedSize(380, 170); this->setStyleSheet("QDialog{border: 1px solid #121212;border-radius:1px;background-color:#1f1f1f;}"); this->setWindowIcon(QIcon(":/res/kylin-video.png"));//setWindowIcon( Images::icon("logo", 64) ); this->setAutoFillBackground(true); this->setMouseTracking(true); installEventFilter(this); title_label->setStyleSheet("QLabel{background:transparent;font-size:14px;color:#999999;font-family:方正黑体_GBK;}");//font-weight:bold; label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}");//font-weight:bold; spinBox->setStyleSheet("QSpinBox {height: 24px;min-width: 40px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QSpinBox:hover {height: 24px;min-width: 40px;background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QSpinBox:enabled {color: #999999;}QSpinBox:enabled:hover, QSpinBox:enabled:focus {color: #999999;}QSpinBox:!enabled {color: #383838;background: transparent;}QSpinBox::up-button {border: none;width: 17px;height: 12px;image: url(:/res/spin_top_arrow_normal.png);}QSpinBox::up-button:hover {image: url(:/res/spin_top_arrow_hover.png);}QSpinBox::up-button:pressed {image: url(:/res/spin_top_arrow_press.png);}QSpinBox::up-button:!enabled {background: transparent;}QSpinBox::up-button:enabled:hover {background: rgb(255, 255, 255, 30);}QSpinBox::down-button {border: none;width: 17px;height: 12px;image: url(:/res/spin_bottom_arrow_normal.png);}QSpinBox::down-button:hover {image: url(:/res/spin_bottom_arrow_hover.png);}QSpinBox::down-button:pressed {image: url(:/res/spin_bottom_arrow_press.png);}QSpinBox::down-button:!enabled {background: transparent;}QSpinBox::down-button:hover{background: #0f0f0f;}"); // baseWidget->setAutoFillBackground(true); // QPalette palette; // palette.setBrush(QPalette::Background, QBrush(QPixmap(":/res/about_bg.png"))); // baseWidget->setPalette(palette); closeBtn->setFocusPolicy(Qt::NoFocus); closeBtn->setStyleSheet("QPushButton{background-image:url(':/res/close_normal.png');border:0px;}QPushButton:hover{background:url(':/res/close_hover.png');}QPushButton:pressed{background:url(':/res/close_press.png');}"); okBtn->setFixedSize(91, 25); okBtn->setText(tr("OK")); okBtn->setFocusPolicy(Qt::NoFocus); okBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); cancelBtn->setFixedSize(91, 25); cancelBtn->setText(tr("Cancel")); cancelBtn->setFocusPolicy(Qt::NoFocus); cancelBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #000000;color:#999999;}QPushButton:hover{background-color:#1f1f1f;border:1px solid #0f0f0f;color:#ffffff;} QPushButton:pressed{background-color:#0d0d0d;border:1px solid #000000;color:#ffffff;}"); this->initConnect(); } AudioDelayDialog::~AudioDelayDialog() { } void AudioDelayDialog::setDefaultValue(int audio_delay) { spinBox->setValue(audio_delay); } int AudioDelayDialog::getCurrentValue() { return spinBox->value(); } void AudioDelayDialog::initConnect() { connect(okBtn, SIGNAL(clicked()), this, SLOT(accept())); connect(cancelBtn, SIGNAL(clicked()), this, SLOT(close())); connect(closeBtn, SIGNAL(clicked()), this, SLOT(close())); } void AudioDelayDialog::moveDialog(QPoint diff) { #if QT_VERSION >= 0x050000 // Move the window with some delay. // Seems to work better with Qt 5 static QPoint d; static int count = 0; d += diff; count++; if (count > 3) { QPoint new_pos = pos() + d; if (new_pos.y() < 0) new_pos.setY(0); if (new_pos.x() < 0) new_pos.setX(0); move(new_pos); count = 0; d = QPoint(0,0); } #else move(pos() + diff); #endif } bool AudioDelayDialog::eventFilter( QObject * object, QEvent * event ) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { drag_state = NOT_AADRAGGING; return false; } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_AADRAGGING; return false; } drag_state = START_AADRAGGING; start_drag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (drag_state != AADRAGGING || mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_AADRAGGING; return false; } // Stop dragging and eat event drag_state = NOT_AADRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (drag_state == NOT_AADRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { drag_state = NOT_AADRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - start_drag; if (drag_state == START_AADRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; drag_state = AADRAGGING; } this->moveDialog(diff); start_drag = pos; event->accept(); return true; } kylin-video/src/merge/inputurl.h0000664000175000017500000000271313233751662015666 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 */ #ifndef _INPUTURL_H_ #define _INPUTURL_H_ #include "ui_inputurl.h" #include class QPushButton; enum IDragState {NOT_IDRAGGING, START_IDRAGGING, IDRAGGING}; class InputURL : public QDialog, public Ui::InputURL { Q_OBJECT public: InputURL( QWidget* parent = 0, Qt::WindowFlags f = 0 ); ~InputURL(); void setURL(QString url); QString url(); void initConnect(); virtual bool eventFilter(QObject *, QEvent *); void moveDialog(QPoint diff); private: IDragState drag_state; QPoint start_drag; }; #endif kylin-video/src/merge/playlist.h0000664000175000017500000001202313233751662015640 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 */ #ifndef _PLAYLIST_H_ #define _PLAYLIST_H_ #include #include #include #include #include #include class MyAction; class Core; class QMenu; class QSettings; class QToolButton; class QTimer; class PlayListItem; class PlayListView; class QListWidgetItem; class QPushButton; class QLabel; class QHBoxLayout; class Playlist : public QFrame { Q_OBJECT public: enum AutoGetInfo { NoGetInfo = 0, GetInfo = 1, UserDefined = 2 }; Playlist( Core *c, QWidget * parent = 0, Qt::WindowFlags f = Qt::Window); ~Playlist(); void clear(); int count(); bool isEmpty(); bool isModified() { return modified; }; //0606 void setTransparent(bool transparent); void set_widget_opacity(const float &opacity=0.8); void setViewHeight(); protected: void paintEvent(QPaintEvent *event); public slots: void addOneItem(QString filename, QString name, double duration); // Start playing, from item 0 if shuffle is off, or from // a random item otherwise void startPlay(); void playItem(int n); virtual void playNext(); virtual void playPrev(); virtual void resumePlay(); virtual void removeTheSelected(); virtual void removeSelected(QString filename); virtual void removeAll(); virtual void onPlayListItemDeleteBtnClicked(QString filename); virtual void moveItemUp(int); virtual void moveItemDown(int); virtual void popupDialogtoSelectFiles(); virtual void addDirectory(); virtual void addFile(QString file, AutoGetInfo auto_get_info = UserDefined); virtual void addFiles(QStringList files, AutoGetInfo auto_get_info = UserDefined); // Adds a directory, no recursive virtual void addOneDirectory(QString dir); // Adds a directory, maybe with recursion (depends on user config) virtual void addDirectory(QString dir); // EDIT BY NEO --> // virtual void sortBy(int section); // <-- virtual void deleteSelectedFileFromDisk(); virtual void getMediaInfo(); void setModified(bool); void slot_listview_current_item_changed(QListWidgetItem * current, QListWidgetItem * previous); void slot_doubleclicked_resource(QString filename); void doubleclicked(QListWidgetItem *item); signals: void playlistEnded(); void visibilityChanged(bool visible); void sig_playing_title(QString title); void update_playlist_count(int count); void closePlaylist(); void playListFinishedWithError(QString errorStr); void showMessage(QString text); void finish_list(); protected: void updateView(); void setListCurrentItem(int current); void clearPlayedTag(); int chooseRandomItem(); void swapItems(int item1, int item2 ); // EDIT BY NEO --> // void sortBy(int section, bool revert, int count); // <-- QString lastDir(); protected slots: virtual void playCurrent(); virtual void itemDoubleClicked(int row); virtual void showPopupMenu(const QPoint & pos); virtual void upItem(); virtual void downItem(); virtual void editCurrentItem(); virtual void editItem(int item); virtual void saveSettings(); virtual void loadSettings(); virtual void maybeSaveSettings(); void playerFailed(QProcess::ProcessError); void playerFinishedWithError(int); protected: void createNoVideo(); void createTable(); void createToolbar(); protected: virtual void dragEnterEvent( QDragEnterEvent * ) ; virtual void dropEvent ( QDropEvent * ); virtual void hideEvent ( QHideEvent * ); virtual void showEvent ( QShowEvent * ); virtual void closeEvent( QCloseEvent * e ); protected: QList pl; int current_item; QString playlist_path; QString playlist_load_latest_dir; Core * core; QMenu * popup; QFrame *noVideoFrame; QLabel *novideo_icon; QLabel *novideo_text; QPushButton *add_Btn; PlayListView *listView; QLabel *titleLabel; QFrame *btAddFrame; QPushButton *btDel; QPushButton *btAdd; MyAction * playAct; MyAction * removeSelectedAct; MyAction * deleteSelectedFileFromDiskAct; private: bool modified; QTimer * save_timer; int row_spacing; bool automatically_play_next; QHBoxLayout *title_layout; }; #endif kylin-video/src/merge/prefscreenshot.h0000664000175000017500000000356113233751662017040 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 */ #ifndef _PREFSCREENSHOT_H_ #define _PREFSCREENSHOT_H_ #include "ui_prefscreenshot.h" #include "../smplayer/prefwidget.h" #include "../smplayer/inforeader.h" #include "../smplayer/deviceinfo.h" #include "../smplayer/preferences.h" class PrefScreenShot : public PrefWidget, public Ui::PrefScreenShot { Q_OBJECT public: PrefScreenShot( QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~PrefScreenShot(); // Pass data to the dialog void setData(Preferences * pref); // Apply changes void getData(Preferences * pref); bool fileSettingsMethodChanged() { return filesettings_method_changed; }; protected: virtual void createHelp(); void setUseScreenshots(bool b); bool useScreenshots(); void setScreenshotDir( QString path ); QString screenshotDir(); void setScreenshotFormat(const QString format); QString screenshotFormat(); protected: virtual void retranslateStrings(); private: bool filesettings_method_changed; }; #endif kylin-video/src/merge/prefperformance.h0000664000175000017500000000351413233751662017162 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 */ #ifndef _PREFPERFORMANCE_H_ #define _PREFPERFORMANCE_H_ #include "ui_prefperformance.h" #include "../smplayer/prefwidget.h" #include "../smplayer/preferences.h" #include "../smplayer/config.h" class PrefPerformance : public PrefWidget, public Ui::PrefPerformance { Q_OBJECT public: PrefPerformance( QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~PrefPerformance(); virtual QString sectionName(); virtual QPixmap sectionIcon(); // Pass data to the dialog void setData(Preferences * pref); // Apply changes void getData(Preferences * pref); public slots: void setCurrentPage(int index); protected: virtual void createHelp(); void setCacheForFiles(int n); int cacheForFiles(); void setCacheForStreams(int n); int cacheForStreams(); void setThreads(int v); int threads(); void setHwdec(const QString & v); QString hwdec(); protected: virtual void retranslateStrings(); }; #endif kylin-video/src/merge/basegui.h0000664000175000017500000003074713233751662015433 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. 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 */ #ifndef _BASEGUI_H_ #define _BASEGUI_H_ #include #include #include #include #include #include #include "../smplayer/mediadata.h" #include "../smplayer/mediasettings.h" #include "../smplayer/preferences.h" #include "../smplayer/core.h" #include "../smplayer/config.h" class QPushButton; class QWidget; class QMenu; class MplayerWindow; class QLabel; class FilePropertiesDialog; class AboutDialog; class HelpDialog; class Playlist; class EscTip; class TipWidget; class MyAction; class MyActionGroup; class PreferencesDialog; class TitleWidget; class BottomWidget; class PlayMask; class VideoPreview; //class ShortcutsWidget; class BaseGui : public QMainWindow { Q_OBJECT public: BaseGui(QString arch_type = "", QWidget* parent = 0, Qt::WindowFlags flags = 0); ~BaseGui(); /* Return true if the window shouldn't show on startup */ virtual bool startHidden() { return false; }; void setTransparent(bool transparent); void set_widget_opacity(const float &opacity=0.8); Core * getCore() { return core; }; Playlist * getPlaylist() { return playlistWidget; }; void setPlaylisshowPlaylisttVisible(bool visible); void setPlaylistVisible(bool visible); void slideEdgeWidget(QWidget *right, QRect start, QRect end, int delay, bool hide = false); void disableControl(int delay = 350); bool mouseInControlsArea(); public slots: void slot_mute(/*bool b*/); void reset_mute_button(); void start_top_and_bottom_timer(); virtual void open(QString file); // Generic open, autodetect type. virtual void openFile(); virtual void openFile(QString file); virtual void openFiles(QStringList files); virtual void openDirectory(); virtual void openDirectory(QString directory); virtual void openURL(); virtual void openURL(QString url); virtual void showAboutDialog(); virtual void showHelpDialog(); virtual void loadSub(); virtual void loadAudioFile(); // Load external audio file void setInitialSubtitle(const QString & subtitle_file); virtual void showPreferencesDialog(); virtual void showFilePropertiesDialog(); virtual void showGotoDialog(); virtual void showSubDelayDialog(); virtual void showAudioDelayDialog(); virtual void exitFullscreen(); virtual void toggleFullscreen(bool); void setStayOnTop(bool b); virtual void changeStayOnTop(int); virtual void checkStayOnTop(Core::State); void changePlayOrder(int play_order); void setForceCloseOnFinish(int n) { arg_close_on_finish = n; }; int forceCloseOnFinish() { return arg_close_on_finish; }; void setForceStartInFullscreen(int n) { arg_start_in_fullscreen = n; }; int forceStartInFullscreen() { return arg_start_in_fullscreen; }; void slot_min(); void slot_max(); void slot_close(); void slot_menu(); void disableSomeComponent(); void setPlaylistProperty(); void slot_playlist(); void slot_resize_corner(); void slot_set_fullscreen(); void showTipWidget(const QString text); void hideTipWidget(); void showOrHideEscWidget(bool b); void open_screenshot_directory(); void ready_save_pre_image(int time); // void showShortcuts(); protected slots: virtual void closeWindow(); virtual void trayIconActivated(QSystemTrayIcon::ActivationReason); virtual void toggleShowAll(); virtual void showAll(bool b); virtual void showAll(); virtual void quit(); virtual void setJumpTexts(); virtual void openRecent(); virtual void enterFullscreenOnPlay(); virtual void exitFullscreenOnStop(); virtual void exitFullscreenIfNeeded(); virtual void playlistHasFinished(); virtual void displayState(Core::State state); virtual void displayMessage(QString message); virtual void gotCurrentTime(double, bool); virtual void updateWidgets(); virtual void newMediaLoaded(); virtual void updateMediaInfo(); void gotNoFileToPlay(); void gotForbidden(); virtual void enableActionsOnPlaying(); virtual void disableActionsOnStop(); virtual void togglePlayAction(Core::State); void resizeMainWindow(int w, int h); void resizeWindow(int w, int h); void centerWindow(); virtual void displayGotoTime(int); //! You can call this slot to jump to the specified percentage in the video, while dragging the slider. virtual void goToPosOnDragging(int); virtual void showPopupMenu(); virtual void showPopupMenu( QPoint p ); virtual void leftClickFunction(); virtual void rightClickFunction(); virtual void doubleClickFunction(); virtual void middleClickFunction(); virtual void xbutton1ClickFunction(); virtual void xbutton2ClickFunction(); virtual void processFunction(QString function); virtual void dragEnterEvent( QDragEnterEvent * ) ; virtual void dropEvent ( QDropEvent * ); virtual void applyNewPreferences(); virtual void applyFileProperties(); virtual void clearRecentsList(); virtual void moveWindowDiff(QPoint diff); virtual void loadActions(); virtual void saveActions(); // Single instance stuff #ifdef SINGLE_INSTANCE void handleMessageFromOtherInstances(const QString& message); #endif //! Called when core can't parse the mplayer version and there's no //! version supplied by the user void askForMplayerVersion(QString); void showExitCodeFromMplayer(int exit_code); void showErrorFromMplayer(QProcess::ProcessError); void showErrorFromPlayList(QString errorStr); // //! Clears the mplayer log void clearMplayerLog(); // //! Saves the line from the mplayer output void recordMplayerLog(QString line); signals: void sigActionsEnabled(bool); void setPlayOrPauseEnabled(bool); void setStopEnabled(bool); void frameChanged(int); void ABMarkersChanged(int secs_a, int secs_b); void videoInfoChanged(int width, int height, double fps); void timeChanged(QString time_ready_to_print, QString all_time); void clear_playing_title(); //! Sent when the user wants to close the main window void quitSolicited(); //! Sent when another instance requested to play a file void openFileRequested(); void change_playlist_btn_status(bool);//0619 void guiChanged();//kobe 20170710 void send_save_preview_image_name(int time, QString filepath); protected: #if QT_VERSION < 0x050000 virtual void hideEvent( QHideEvent * ); virtual void showEvent( QShowEvent * ); #else virtual bool event(QEvent * e); bool was_minimized; #endif void closeEvent(QCloseEvent *event); void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); virtual bool eventFilter(QObject *obj, QEvent *event) override; virtual void resizeEvent(QResizeEvent *e) override;//20170720 void createCore(); void createMplayerWindow(); void createPlaylist(); void createPanel(); void createPreferencesDialog(); void createFilePropertiesDialog(); void setDataToFileProperties(); void createAboutDialog(); void createHelpDialog(); void setDataToAboutDialog(); void initializeGui(); void createActionsAndMenus(); void createTrayActions(); void addTrayActions(); void createHiddenActions(); void setActionsEnabled(bool); void updateRecents(); void loadConfig(); virtual void keyPressEvent(QKeyEvent *event); protected: QStackedLayout *contentLayout; QWidget * panel; TitleWidget *m_topToolbar; BottomWidget *m_bottomToolbar; // Menu File QMenu *openMenu;//打开 MyAction *openFileAct;//打开文件 MyAction *openDirectoryAct;//打开文件夹 MyAction *openURLAct;//打开URL MyAction *clearRecentsAct;//清空最近的文件 QMenu *recentfiles_menu;//打开最近的文件 QMenu *playMenu;//播放控制 QMenu * control_menu; MyAction * rewind1Act; MyAction * rewind2Act; MyAction * rewind3Act; MyAction * forward1Act; MyAction * forward2Act; MyAction * forward3Act; QMenu * speed_menu; MyAction * gotoAct; // Menu Speed MyAction * normalSpeedAct; MyAction * halveSpeedAct; MyAction * doubleSpeedAct; MyAction * decSpeed10Act; MyAction * incSpeed10Act; MyAction * decSpeed4Act; MyAction * incSpeed4Act; MyAction * decSpeed1Act; MyAction * incSpeed1Act; MyAction * playPrevAct; MyAction * playNextAct; QMenu * aspect_menu; // Aspect Action Group MyActionGroup * aspectGroup; MyAction * aspectDetectAct; MyAction * aspectNoneAct; MyAction * aspect11Act; // 1:1 MyAction * aspect32Act; // 3:2 MyAction * aspect43Act; // 4:3 MyAction * aspect118Act; // 11:8 MyAction * aspect54Act; // 5:4 MyAction * aspect149Act; // 14:9 MyAction * aspect1410Act; // 14:10 MyAction * aspect169Act; // 16:9 MyAction * aspect1610Act; // 16:10 MyAction * aspect235Act; // 2.35:1 // Rotate Group MyActionGroup * rotateGroup; MyAction * rotateNoneAct; MyAction * rotateClockwiseFlipAct; MyAction * rotateClockwiseAct; MyAction * rotateCounterclockwiseAct; MyAction * rotateCounterclockwiseFlipAct; MyAction * flipAct; MyAction * mirrorAct; // Rotate menu QMenu * rotate_flip_menu; QMenu * rotate_menu; // MyAction * shortcutsAct; MyAction * screenshotAct; QMenu * ontop_menu; // Menu StayOnTop MyActionGroup * onTopActionGroup; MyAction * onTopAlwaysAct; MyAction * onTopNeverAct; MyAction * onTopWhilePlayingAct; //play order QMenu * play_order_menu; MyActionGroup * playOrderActionGroup; MyAction * orderPlaysAct; MyAction * randomPlayAct; MyAction * listLoopPlayAct; QMenu *audioMenu;//声音 MyAction * muteAct; MyAction * decVolumeAct; MyAction * incVolumeAct; MyAction * decAudioDelayAct; MyAction * incAudioDelayAct; MyAction * audioDelayAct; // Ask for delay // Stereo Mode Action Group MyActionGroup * stereoGroup; MyAction * stereoAct; MyAction * leftChannelAct; MyAction * rightChannelAct; MyAction * monoAct; MyAction * reverseAct; QMenu * stereomode_menu; QMenu *subtitlesMenu;//字幕 MyAction * loadSubsAct; MyAction * subVisibilityAct; MyAction *showPreferencesAct;//设置 MyAction *showPropertiesAct;//信息和属性 MyAction *aboutAct; MyAction *helpAct; MyAction *quitAct; MyAction *openDirAct; QMenu *popup; QMenu *main_popup; QMenu * audiochannels_menu; MyActionGroup * channelsGroup; MyAction * channelsStereoAct; MyAction * channelsSurroundAct; MyAction * channelsFull51Act; MyAction * channelsFull61Act; MyAction * channelsFull71Act; //tray menu and actions QMenu *tray_menu; MyAction *action_show; MyAction *action_openshotsdir; //Hide actions MyAction *playlist_action; MyAction *play_pause_aciton; MyAction *stopAct; MyAction *fullscreenAct; PreferencesDialog *pref_dialog; FilePropertiesDialog *file_dialog; AboutDialog *aboutDlg; HelpDialog *helpDlg; Core * core; MplayerWindow *mplayerwindow; Playlist * playlistWidget; QString pending_actions_to_run; // Force settings from command line int arg_close_on_finish; // -1 = not set, 1 = true, 0 = false int arg_start_in_fullscreen; // -1 = not set, 1 = true, 0 = false private: bool was_maximized; QString mplayer_log; bool ignore_show_hide_events; bool isFinished; bool isPlaying; bool fullscreen; QPoint mainwindow_pos; QPoint playlist_pos; bool trayicon_playlist_was_visible; QPushButton *resizeCorner; bool resizeFlag; QSystemTrayIcon *tray; PlayMask *play_mask; EscTip *escWidget; TipWidget *tipWidget; QTimer *tip_timer; QString arch; VideoPreview *video_preview; // ShortcutsWidget *shortcuts_widget; }; #endif kylin-video/src/res.qrc0000664000175000017500000001253513214347337014036 0ustar fengfeng res/background.png res/delete_hover_press.png res/delete_normal.png res/logo.png res/playlist_delete_button.png res/trash_normal.png res/ok.png res/info.png res/prefs.png res/clear_left.png res/backoff_10_seconds_hover_press.png res/backoff_10_seconds_normal.png res/cancel_fullscreen_hover_press.png res/cancel_fullscreen_normal.png res/close_hover.png res/close_normal.png res/close_press.png res/dragbar_hover_press.png res/dragbar_normal.png res/forward_10_seconds_hover_press.png res/forward_10_seconds_normal.png res/fullscreen_hover_press.png res/fullscreen_normal.png res/list_cycle_hover_press.png res/list_cycle_normal.png res/max_hover.png res/max_normal.png res/max_press.png res/min_hover.png res/min_normal.png res/min_press.png res/next_hover_press.png res/next_normal.png res/option_hover.png res/option_normal.png res/option_press.png res/order_cycle_hover_press.png res/order_cycle_normal.png res/pause_hover_press.png res/pause_normal.png res/play_center_hover_press.png res/play_center_normal.png res/play_hover_press.png res/play_normal.png res/playlist_close_hover_press.png res/playlist_close_normal.png res/playlist_open_hover_press.png res/playlist_open_normal.png res/previous_hover_press.png res/previous_normal.png res/progress_pointer_hover.png res/progress_pointer_normal.png res/progress_pointer_press.png res/single_cycle_hover_press.png res/single_cycle_normal.png res/stop_hover_press.png res/stop_normal.png res/unmax_hover.png res/unmax_normal.png res/unmax_press.png res/volume_high_hover_press.png res/volume_high_normal.png res/volume_low_hover_press.png res/volume_low_normal.png res/volume_mid_hover_press.png res/volume_mid_normal.png res/volume_mute_hover_press.png res/volume_mute_normal.png res/open_file_normal.png res/open_file_hover_press.png res/no-video.png res/about_hover_press.png res/about_normal.png res/screenshot_hover_press.png res/screenshot_normal.png res/trash_hover_press.png res/video_hover_press.png res/video_normal.png res/open_window_hover_press.png res/open_window_normal.png res/quit_normal.png res/quit_hover_press.png res/about_bg.png res/menu_selected.png res/radiobutton_disable.png res/checkbox_disable.png res/spin_bottom_arrow_disable.png res/spin_bottom_arrow_hover.png res/spin_bottom_arrow_normal.png res/spin_bottom_arrow_press.png res/spin_top_arrow_disable.png res/spin_top_arrow_hover.png res/spin_top_arrow_normal.png res/spin_top_arrow_press.png res/combobox_arrow_disable.png res/combobox_arrow_hover.png res/combobox_arrow_normal.png res/combobox_arrow_press.png res/radiobutton_unchecked.png res/radiobutton_checked.png res/checkbox_unchecked.png res/checkbox_checked.png res/settings.png res/warn.png res/kylin-video.png res/open_screen.png res/open_screen_hover.png res/help.png res/help_hover_press.png res/help_normal.png res/close.png res/unmax.png res/option.png res/min.png res/max.png res/plus.png res/style.qss kylin-video/src/input.conf0000664000175000017500000000245713214347337014546 0ustar fengfeng## prevent mplayer from messing up our shortcuts RIGHT invalid_command LEFT invalid_command DOWN invalid_command UP invalid_command PGUP invalid_command PGDWN invalid_command - invalid_command + invalid_command ESC invalid_command ENTER invalid_command SPACE pausing_keep invalid_command HOME invalid_command END invalid_command > invalid_command < invalid_command INS invalid_command DEL invalid_command [ invalid_command ] invalid_command { invalid_command } invalid_command BS invalid_command TAB invalid_command . invalid_command # invalid_command @ invalid_command ! invalid_command 9 invalid_command / invalid_command 0 invalid_command * invalid_command 1 invalid_command 2 invalid_command 3 invalid_command 4 invalid_command 5 invalid_command 6 invalid_command 7 invalid_command 8 invalid_command a invalid_command b invalid_command c invalid_command d invalid_command e invalid_command F invalid_command f invalid_command g invalid_command h invalid_command i invalid_command j invalid_command k invalid_command l invalid_command m invalid_command n invalid_command o invalid_command p invalid_command q invalid_command r invalid_command s invalid_command t invalid_command T invalid_command u invalid_command v invalid_command w invalid_command x invalid_command y invalid_command z invalid_command S invalid_command kylin-video/src/smplayer/0000775000175000017500000000000013261113615014354 5ustar fengfengkylin-video/src/smplayer/myaction.h0000664000175000017500000000364513233751662016371 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _MYACTION_H_ #define _MYACTION_H_ #include #include #include #include class MyAction : public QAction { public: //! Creates a new MyAction with name \a name. If \a autoadd is true //! the action will be added to the parent MyAction ( QObject * parent, const char * name, bool autoadd = true ); //! Creates a new MyAction. If \a autoadd is true //! the action will be added to the parent MyAction ( QObject * parent, bool autoadd = true ); MyAction ( const QString & text, QKeySequence accel, QObject * parent, const char * name = "", bool autoadd = true ); MyAction ( QKeySequence accel, QObject * parent, const char * name = "", bool autoadd = true ); ~MyAction(); void addShortcut(QKeySequence key); //! Change the icon and text of the action. void change(const QIcon & icon, const QString & text ); //! Change the text of the action. void change(const QString & text); protected: //! Checks if the parent is a QWidget and adds the action to it. void addActionToParent(); }; #endif kylin-video/src/smplayer/urlhistory.cpp0000664000175000017500000000260613233751662017321 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "urlhistory.h" URLHistory::URLHistory() : Recents() { setMaxItems(50); } URLHistory::~URLHistory() { } void URLHistory::addUrl(QString url) { qDebug("Recents::addItem: '%s'", url.toUtf8().data()); // Delete duplicates QStringList::iterator iterator = l.begin(); while (iterator != l.end()) { QString s = (*iterator); if (s == url) iterator = l.erase(iterator); else iterator++; } // Add new item to list l.prepend(url); if (l.count() > max_items) l.removeLast(); } QString URLHistory::url(int n) { QString s = l[n]; return s; } kylin-video/src/smplayer/cleanconfig.cpp0000664000175000017500000000163213214706400017330 0ustar fengfeng#include "cleanconfig.h" #include #include void CleanConfig::clean(const QString & config_path) { qDebug("CleanConfig::clean"); QStringList files_to_delete; QString s = config_path + "/kylin_video_files.ini"; if (QFile::exists(s)) files_to_delete << s; s = config_path + "/player_info.ini"; if (QFile::exists(s)) files_to_delete << s; printf("Deleting files:\n"); for (int n = 0; n < files_to_delete.count(); n++) { printf("Delete: %s\n", files_to_delete[n].toUtf8().constData()); QFile::remove(files_to_delete[n]); } } QStringList CleanConfig::listDir(const QString &path) { QDir dir(path); QStringList file_list; foreach(QString file, dir.entryList(QDir::Files)) { file_list << QFileInfo(dir, file).absoluteFilePath(); } foreach(QString sub_dir, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { file_list << listDir(path +"/"+ sub_dir); } return file_list; } kylin-video/src/smplayer/version.h0000664000175000017500000000174013233751662016225 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef VERSION_H #define VERSION_H #include class Version { public: static QString printable(); static QString stable(); }; #endif kylin-video/src/smplayer/inforeadermpv.h0000664000175000017500000000363413233751662017405 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef INFOREADER_MPV_H #define INFOREADER_MPV_H #include "inforeader.h" #include #include #include class QProcess; class InfoReaderMPV : QObject { Q_OBJECT public: InfoReaderMPV( QString mplayer_bin, QObject * parent = 0); ~InfoReaderMPV(); void getInfo(); InfoList voList() { return vo_list; }; InfoList aoList() { return ao_list; }; InfoList demuxerList() { return demuxer_list; }; InfoList vcList() { return vc_list; }; InfoList acList() { return ac_list; }; QStringList vfList() { return vf_list; }; QStringList optionList() { return option_list; }; int mplayerSVN() { return mplayer_svn; }; QString mpvVersion() { return mpv_version; }; protected: QList run(QString options); InfoList getList(const QList &); QStringList getOptionsList(const QList &); void list(); protected: QString mplayerbin; InfoList vo_list; InfoList ao_list; InfoList demuxer_list; InfoList vc_list; InfoList ac_list; QStringList vf_list; QStringList option_list; int mplayer_svn; QString mpv_version; }; #endif kylin-video/src/smplayer/deviceinfo.cpp0000664000175000017500000000517313233751662017212 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "deviceinfo.h" #include #include DeviceList DeviceInfo::alsaDevices() { qDebug("DeviceInfo::alsaDevices"); DeviceList l; QRegExp rx_device("^card\\s([0-9]+).*\\[(.*)\\],\\sdevice\\s([0-9]+):"); QProcess p; p.setProcessChannelMode( QProcess::MergedChannels ); p.setEnvironment( QStringList() << "LC_ALL=C" ); p.start("aplay", QStringList() << "-l"); if (p.waitForFinished()) { QByteArray line; while (p.canReadLine()) { line = p.readLine(); // qDebug("DeviceInfo::alsaDevices: '%s'", line.constData()); if ( rx_device.indexIn(line) > -1 ) { QString id = rx_device.cap(1); id.append("."); id.append(rx_device.cap(3)); QString desc = rx_device.cap(2); // qDebug("DeviceInfo::alsaDevices: found device: '%s' '%s'", id.toUtf8().constData(), desc.toUtf8().constData()); l.append( DeviceData(id, desc) ); } } } else { qDebug("DeviceInfo::alsaDevices: could not start aplay, error %d", p.error()); } return l; } DeviceList DeviceInfo::xvAdaptors() { // qDebug("DeviceInfo::xvAdaptors"); DeviceList l; QRegExp rx_device("^.*Adaptor #([0-9]+): \"(.*)\""); QProcess p; p.setProcessChannelMode( QProcess::MergedChannels ); p.setEnvironment( QProcess::systemEnvironment() << "LC_ALL=C" ); p.start("xvinfo"); if (p.waitForFinished()) { QByteArray line; while (p.canReadLine()) { line = p.readLine(); // qDebug("DeviceInfo::xvAdaptors: '%s'", line.constData()); if ( rx_device.indexIn(line) > -1 ) { QString id = rx_device.cap(1); QString desc = rx_device.cap(2); // qDebug("DeviceInfo::xvAdaptors: found adaptor: '%s' '%s'", id.toUtf8().constData(), desc.toUtf8().constData()); l.append( DeviceData(id, desc) ); } } } else { qDebug("DeviceInfo::xvAdaptors: could not start xvinfo, error %d", p.error()); } return l; } kylin-video/src/smplayer/videopreview.cpp0000664000175000017500000002437413233751662017613 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "videopreview.h" #include "playerid.h" #include #include #include #include #include #include #include #include #include #include #include #define RENAME_PICTURES 0 #define N_OUTPUT_FRAMES 1 // MPlayer2 doesn't support png outdir /* #define VP_USE_PNG_OUTDIR */ VideoPreview::VideoPreview(QString mplayer_path, QObject * parent) : QObject(parent) { setMplayerPath(mplayer_path); prop.input_video.clear(); prop.initial_step = 0; prop.max_width = 800; prop.aspect_ratio = 0; prop.display_osd = true; prop.extract_format = JPEG;//PNG; output_dir = "kylin_video_preview"; full_output_dir = QDir::tempPath() +"/"+ output_dir; } VideoPreview::~VideoPreview() { cleanDir(full_output_dir, true); } void VideoPreview::setMplayerPath(QString mplayer_path) { mplayer_bin = mplayer_path; QFileInfo fi(mplayer_bin); if (fi.exists() && fi.isExecutable() && !fi.isDir()) { mplayer_bin = fi.absoluteFilePath(); } // qDebug("VideoPreview::setMplayerPath: mplayer_bin: '%s'", mplayer_bin.toUtf8().constData()); } QString VideoPreview::framePicture() { return QString("0000000%1.%2").arg(N_OUTPUT_FRAMES == 1 ? 1 : N_OUTPUT_FRAMES-1).arg(prop.extract_format == PNG ? "png" : "jpg"); } bool VideoPreview::createPreThumbnail(int time) { error_message.clear(); bool result = extractImages(time); if ((result == false) && (!error_message.isEmpty())) { // qDebug("The following error has occurred while creating the thumbnails:\n %s", error_message); qDebug() << "The following error has occurred while creating the thumbnails:" << error_message; } return result; } bool VideoPreview::extractImages(int time) { // qDebug() << "VideoPreview::extractImages time=" << time; VideoInfo i = getInfo(mplayer_bin, prop.input_video); int length = i.length; if (length == 0) { if (error_message.isEmpty()) error_message = QString(tr("The length of the video is 0")); return false; } // Create a temporary directory QDir d(QDir::tempPath()); if (!d.exists(output_dir)) { if (!d.mkpath(output_dir)) { qDebug("VideoPreview::extractImages: error: can't create '%s'", full_output_dir.toUtf8().constData()); error_message = QString(tr("The temporary directory (%1) can't be created").arg(full_output_dir)); return false; } } cleanDir(full_output_dir, false); prop.initial_step = time; int current_time = prop.initial_step; double aspect_ratio = i.aspect; if (prop.aspect_ratio != 0) aspect_ratio = prop.aspect_ratio; qApp->processEvents(); // qDebug() << "current_time=" << current_time << " and aspect_ratio=" << aspect_ratio;//current_time= 470 and aspect_ratio= 1.33333 if (!runPlayer(current_time, aspect_ratio)) return false; QString frame_picture = full_output_dir + "/" + framePicture(); if (!QFile::exists(frame_picture)) { error_message = QString(tr("The file %1 doesn't exist").arg(frame_picture)); // qDebug() << "error_message=" << error_message;//error_message= "文件 /tmp/kylin_video_preview/00000001.jpg 不存在" return false; } QString extension = (extractFormat()==PNG) ? "png" : "jpg"; QString output_file = output_dir + QString("/picture_%1.%2").arg(current_time, 8, 10, QLatin1Char('0')).arg(extension); // qDebug() << "1111111111 dir=" << output_dir + "/" + framePicture();//1111111111 dir= "kylin_video_preview/00000001.jpg" // qDebug() << "2222222222 dir=" << output_file;//2222222222 dir= "kylin_video_preview/picture_00006068.jpg" d.rename(output_dir + "/" + framePicture(), output_file); current_picture = QDir::tempPath() + "/" + output_file; return true; } /*参数解释:-ss 指定开始时间 -noframedrop 不跳过帧(即使解码速度跟不上) -nosound 没有声音输出(不对声音进行解码) -nolirc 禁用红外控制 -nojoystick 禁用控制棒 -vo 视频输出格式为jpeg -frames 从ss指定的时间开始截取多少帧 */ bool VideoPreview::runPlayer(int seek, double aspect_ratio) { QStringList args; if (PlayerID::player(mplayer_bin) == PlayerID::MPV) { // MPV args << "--no-config" << "--no-audio" << "--no-cache"; args << "--frames=" + QString::number(N_OUTPUT_FRAMES); args << "--framedrop=no" << "--start=" + QString::number(seek); if (aspect_ratio != 0) { args << "--video-aspect=" + QString::number(aspect_ratio); } QString format = (prop.extract_format == PNG) ? "png:png-compression=0" : "jpg"; args << QString("--vo=image=format=%1:outdir=\"%2\"").arg(format).arg(full_output_dir); } else { // MPlayer args << "-nosound" << "-nocache" << "-noframedrop"; if (prop.extract_format == PNG) { args << "-vo" << "png"; } else { args << "-vo" << "jpeg:outdir=\""+full_output_dir+"\""; } args << "-frames" << QString::number(N_OUTPUT_FRAMES) << "-ss" << QString::number(seek); if (aspect_ratio != 0) { args << "-aspect" << QString::number(aspect_ratio) << "-zoom"; } } args << prop.input_video; QString command = mplayer_bin + " "; for (int n = 0; n < args.count(); n++) command = command + args[n] + " "; // qDebug("VideoPreview::runMplayer: command: %s", command.toUtf8().constData());///usr/bin/mplayer -nosound -nocache -noframedrop -vo jpeg:outdir="/tmp/kylin_video_preview" -frames 1 -ss 77 -aspect 1.7778 -zoom /home/lixiang/resources/1080.wmv //VideoPreview::runMplayer: command: /usr/bin/mplayer -nosound -nocache -noframedrop -vo jpeg:outdir="/tmp/kylin_video_preview" -frames 1 -ss 470 -aspect 1.33333 -zoom /home/lixiang/resources/Katy Perry Roar.swf QProcess p; p.setWorkingDirectory(full_output_dir); p.start(mplayer_bin, args); if (!p.waitForFinished()) { qDebug() << "VideoPreview::runMplayer: error running process"; error_message = QString(tr("The mplayer process didn't run")); return false; } return true; } void VideoPreview::cleanDir(QString directory, bool removeDir) { QDir dir(directory); if (dir.exists()) { QStringList filter; if (prop.extract_format == PNG) { filter.append("*.png"); } else { filter.append("*.jpg"); } QDir d(directory); QStringList l = d.entryList( filter, QDir::Files, QDir::Unsorted); for (int n = 0; n < l.count(); n++) { // qDebug("VideoPreview::cleanDir: deleting '%s'", l[n].toUtf8().constData()); d.remove(l[n]); } // qDebug("VideoPreview::cleanDir: removing directory '%s'", directory.toUtf8().constData()); if (removeDir) d.rmpath(directory); } } VideoInfo VideoPreview::getInfo(const QString & mplayer_path, const QString & filename) { VideoInfo i; if (filename.isEmpty()) { error_message = QString(tr("No filename")); return i; } QFileInfo fi(filename); if (fi.exists()) { i.filename = fi.fileName(); i.size = fi.size(); } QRegExp rx("^ID_(.*)=(.*)"); QProcess p; p.setProcessChannelMode( QProcess::MergedChannels ); QStringList args; if (PlayerID::player(mplayer_path) == PlayerID::MPV) { args << "--term-playing-msg=" "ID_LENGTH=${=length}\n" "ID_VIDEO_WIDTH=${=width}\n" "ID_VIDEO_HEIGHT=${=height}\n" "ID_VIDEO_FPS=${=fps}\n" "ID_VIDEO_ASPECT=${=video-aspect}\n" "ID_VIDEO_BITRATE=${=video-bitrate}\n" "ID_AUDIO_BITRATE=${=audio-bitrate}\n" "ID_AUDIO_RATE=${=audio-samplerate}\n" "ID_VIDEO_FORMAT=${=video-format}"; args << "--vo=null" << "-ao=null" << "--frames=1" << "--no-quiet" << "--no-cache" << "--no-config"; args << filename; } else { // MPlayer args << "-vo" << "null" << "-ao" << "null" << "-frames" << "1" << "-identify" << "-nocache" << "-noquiet"; args << filename; } p.start(mplayer_path, args); if (p.waitForFinished()) { QByteArray line; while (p.canReadLine()) { line = p.readLine().trimmed(); // qDebug("VideoPreview::getInfo: '%s'", line.constData()); if (rx.indexIn(line) > -1) { QString tag = rx.cap(1); QString value = rx.cap(2); // qDebug("VideoPreview::getInfo: tag: '%s', value: '%s'", tag.toUtf8().constData(), value.toUtf8().constData()); if (tag == "LENGTH") i.length = (int) value.toDouble(); else if (tag == "VIDEO_WIDTH") i.width = value.toInt(); else if (tag == "VIDEO_HEIGHT") i.height = value.toInt(); else if (tag == "VIDEO_FPS") i.fps = value.toDouble(); else if (tag == "VIDEO_ASPECT") { i.aspect = value.toDouble(); if ((i.aspect == 0) && (i.width != 0) && (i.height != 0)) { i.aspect = (double) i.width / i.height; } } else if (tag == "VIDEO_BITRATE") i.video_bitrate = value.toInt(); else if (tag == "AUDIO_BITRATE") i.audio_bitrate = value.toInt(); else if (tag == "AUDIO_RATE") i.audio_rate = value.toInt(); else if (tag == "VIDEO_FORMAT") i.video_format = value; } } } else { qDebug("VideoPreview::getInfo: error: process didn't start"); error_message = QString(tr("The mplayer process didn't start while trying to get info about the video")); } // qDebug("VideoPreview::getInfo: filename: '%s'", i.filename.toUtf8().constData()); // qDebug("VideoPreview::getInfo: resolution: '%d x %d'", i.width, i.height); // qDebug("VideoPreview::getInfo: length: '%d'", i.length); // qDebug("VideoPreview::getInfo: size: '%d'", (int) i.size); return i; } //#include "moc_videopreview.cpp" kylin-video/src/smplayer/mylineedit.cpp0000664000175000017500000000271513233751662017241 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "mylineedit.h" #include #include #include "images.h" MyLineEdit::MyLineEdit(QWidget *parent) : LineEditWithIcon(parent) { this->setFixedHeight(25); setupButton(); button->hide(); button->setCursor(Qt::PointingHandCursor); connect(button, SIGNAL(clicked()), this, SLOT(clear())); connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateCloseButton(const QString&))); } void MyLineEdit::setupButton() { setIcon(Images::icon("clear_left")); } void MyLineEdit::updateCloseButton(const QString& text) { button->setVisible(!text.isEmpty()); } //#include "moc_mylineedit.cpp" kylin-video/src/smplayer/mpvoptions.cpp0000664000175000017500000006150613233751662017317 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 #include #include "inforeader.h" void MPVProcess::setMedia(const QString & media, bool is_playlist) { arg << "--term-playing-msg=" "MPV_VERSION=${=mpv-version:}\n" "INFO_VIDEO_WIDTH=${=width}\nINFO_VIDEO_HEIGHT=${=height}\n" "INFO_VIDEO_ASPECT=${=video-aspect}\n" // "INFO_VIDEO_DSIZE=${=dwidth}x${=dheight}\n" "INFO_VIDEO_FPS=${=fps}\n" // "INFO_VIDEO_BITRATE=${=video-bitrate}\n" "INFO_VIDEO_FORMAT=${=video-format}\n" "INFO_VIDEO_CODEC=${=video-codec}\n" // "INFO_AUDIO_BITRATE=${=audio-bitrate}\n" // "INFO_AUDIO_FORMAT=${=audio-format}\n" "INFO_AUDIO_FORMAT=${=audio-codec-name:${=audio-format}}\n" "INFO_AUDIO_CODEC=${=audio-codec}\n" // "INFO_AUDIO_RATE=${=audio-samplerate}\n" "INFO_AUDIO_RATE=${=audio-params/samplerate:${=audio-samplerate}}\n" // "INFO_AUDIO_NCH=${=audio-channels}\n" "INFO_AUDIO_NCH=${=audio-params/channel-count:${=audio-channels}}\n" // "INFO_LENGTH=${=length}\n" "INFO_LENGTH=${=duration:${=length}}\n" "INFO_DEMUXER=${=demuxer}\n" "INFO_TITLES=${=disc-titles}\n" "INFO_CHAPTERS=${=chapters}\n" "INFO_TRACKS_COUNT=${=track-list/count}\n" "METADATA_TITLE=${metadata/by-key/title:}\n" "METADATA_ARTIST=${metadata/by-key/artist:}\n" "METADATA_ALBUM=${metadata/by-key/album:}\n" "METADATA_GENRE=${metadata/by-key/genre:}\n" "METADATA_DATE=${metadata/by-key/date:}\n" "METADATA_TRACK=${metadata/by-key/track:}\n" "METADATA_COPYRIGHT=${metadata/by-key/copyright:}\n" "INFO_MEDIA_TITLE=${=media-title:}\n"; arg << "--term-status-msg=STATUS: ${=time-pos} / ${=duration:${=length:0}} P: ${=pause} B: ${=paused-for-cache} I: ${=core-idle}"; if (is_playlist) { arg << "--playlist=" + media; } else { arg << media; } } void MPVProcess::setFixedOptions() { arg << "--no-config"; arg << "--no-quiet"; arg << "--terminal"; arg << "--no-msg-color"; arg << "--input-file=/dev/stdin"; //arg << "--no-osc"; //arg << "--msg-level=vd=v"; } void MPVProcess::disableInput() { arg << "--no-input-default-bindings"; arg << "--input-x11-keyboard=no"; arg << "--no-input-cursor"; arg << "--cursor-autohide=no"; } bool MPVProcess::isOptionAvailable(const QString & option) { InfoReader * ir = InfoReader::obj(executable()); ir->getInfo(); //qDebug() << "MPVProcess::isOptionAvailable: option_list:" << ir->optionList(); return ir->optionList().contains(option); } void MPVProcess::addVFIfAvailable(const QString & vf, const QString & value) { InfoReader * ir = InfoReader::obj(executable()); ir->getInfo(); if (ir->vfList().contains(vf)) { QString s = "--vf-add=" + vf; if (!value.isEmpty()) s += "=" + value; arg << s; } else { QString f = vf +"="+ value; qDebug("MPVProcess::addVFIfAvailable: filter %s is not used because it's not available", f.toLatin1().constData()); } } void MPVProcess::messageFilterNotSupported(const QString & filter_name) { QString text = tr("the '%1' filter is not supported by mpv").arg(filter_name); writeToStdin(QString("show_text \"%1\" 3000").arg(text)); } void MPVProcess::setOption(const QString & option_name, const QVariant & value) { if (option_name == "cache") { int cache = value.toInt(); if (cache > 31) { arg << "--cache=" + value.toString(); } else { arg << "--cache=no"; } } else if (option_name == "ss") { arg << "--start=" + value.toString(); } else if (option_name == "endpos") { arg << "--length=" + value.toString(); } else if (option_name == "loop") { QString o = value.toString(); if (o == "0") o = "inf"; arg << "--loop=" + o; } else if (option_name == "ass") { arg << "--sub-ass"; } else if (option_name == "noass") { arg << "--no-sub-ass"; } else if (option_name == "sub-fuzziness") { QString v; switch (value.toInt()) { case 1: v = "fuzzy"; break; case 2: v = "all"; break; default: v = "exact"; } arg << "--sub-auto=" + v; } else if (option_name == "audiofile") { arg << "--audio-file=" + value.toString(); } else if (option_name == "delay") { arg << "--audio-delay=" + value.toString(); } else if (option_name == "subdelay") { arg << "--sub-delay=" + value.toString(); } else if (option_name == "sub") { arg << "--sub-file=" + value.toString(); } else if (option_name == "subpos") { arg << "--sub-pos=" + value.toString(); } else if (option_name == "font") { arg << "--osd-font=" + value.toString(); } else if (option_name == "subcp") { QString cp = value.toString(); if (!cp.startsWith("enca")) cp = "utf8:" + cp; arg << "--sub-codepage=" + cp; } else if (option_name == "osdlevel") { arg << "--osd-level=" + value.toString(); } else if (option_name == "sws") { arg << "--sws-scaler=lanczos"; } else if (option_name == "channels") { arg << "--audio-channels=" + value.toString(); } else if (option_name == "subfont-text-scale" || option_name == "ass-font-scale") { arg << "--sub-scale=" + value.toString(); } else if (option_name == "stop-xscreensaver") { bool stop_ss = value.toBool(); if (stop_ss) arg << "--stop-screensaver"; else arg << "--no-stop-screensaver"; } else if (option_name == "correct-pts") { bool b = value.toBool(); if (b) arg << "--correct-pts"; else arg << "--no-correct-pts"; } else if (option_name == "idx") { arg << "--index=default"; } else if (option_name == "softvol") { arg << "--softvol=yes"; } else if (option_name == "softvol-max") { int v = value.toInt(); if (v < 100) v = 100; arg << "--softvol-max=" + QString::number(v); } else if (option_name == "subfps") { arg << "--sub-fps=" + value.toString(); } else if (option_name == "forcedsubsonly") { arg << "--sub-forced-only"; } else if (option_name == "prefer-ipv4" || option_name == "prefer-ipv6" || option_name == "dr" || option_name == "double" || option_name == "adapter" || option_name == "edl" || option_name == "slices" || option_name == "colorkey" || option_name == "subcc" || option_name == "vobsub" || option_name == "zoom" || option_name == "flip-hebrew" || option_name == "autoq") { // Ignore } else if (option_name == "tsprog") { // Unsupported } else if (option_name == "dvdangle") { /* arg << "--dvd-angle=" + value.toString(); */ } else if (option_name == "screenshot_template") { arg << "--screenshot-template=" + value.toString(); } else if (option_name == "screenshot_format") { arg << "--screenshot-format=" + value.toString(); } else if (option_name == "threads") { arg << "--vd-lavc-threads=" + value.toString(); } else if (option_name == "skiploopfilter") { arg << "--vd-lavc-skiploopfilter=all"; } else if (option_name == "keepaspect" || option_name == "fs") { bool b = value.toBool(); if (b) arg << "--" + option_name; else arg << "--no-" + option_name; } else if (option_name == "ao") { QString o = value.toString(); if (o.startsWith("alsa:device=")) { QString device = o.mid(12); //qDebug() << "MPVProcess::setOption: alsa device:" << device; device = device.replace("=", ":").replace(".", ","); o = "alsa:device=[" + device + "]"; } arg << "--ao=" + o; } else if (option_name == "vc") { qDebug() << "MPVProcess::setOption: video codec ignored"; } else if (option_name == "ac") { qDebug() << "MPVProcess::setOption: audio codec ignored"; } else if (option_name == "afm") { QString s = value.toString(); if (s == "hwac3") arg << "--ad=spdif:ac3,spdif:dts"; } else if (option_name == "enable_streaming_sites_support") { if (isOptionAvailable("--ytdl")) { if (value.toBool()) arg << "--ytdl"; else arg << "--ytdl=no"; } } else if (option_name == "fontconfig") { if (isOptionAvailable("--use-text-osd")) { bool b = value.toBool(); if (b) arg << "--use-text-osd=yes"; else arg << "--use-text-osd=no"; } } else if (option_name == "verbose") { arg << "-v"; verbose = true; } else if (option_name == "mute") { arg << "--mute=yes"; } else if (option_name == "vf-add") { if (!value.isNull()) arg << "--vf-add=" + value.toString(); } else if (option_name == "af-add") { if (!value.isNull()) arg << "--af-add=" + value.toString(); } else if (option_name == "wid" || option_name == "vo" || option_name == "aid" || option_name == "vid" || option_name == "volume" || option_name == "ass-styles" || option_name == "ass-force-style" || option_name == "ass-line-spacing" || option_name == "embeddedfonts" || option_name == "osd-scale" || option_name == "speed" || option_name == "contrast" || option_name == "brightness" || option_name == "hue" || option_name == "saturation" || option_name == "gamma" || option_name == "monitorpixelaspect" || option_name == "monitoraspect" || option_name == "mc" || option_name == "framedrop" || option_name == "priority" || option_name == "hwdec" || option_name == "autosync" || option_name == "dvd-device" || option_name == "cdrom-device" || option_name == "demuxer" || option_name == "frames") { QString s = "--" + option_name; if (!value.isNull()) s += "=" + value.toString(); arg << s; } else { qDebug() << "MPVProcess::setOption: unknown option:" << option_name; } } void MPVProcess::addUserOption(const QString & option) { arg << option; if (option == "-v") { verbose = true; } } void MPVProcess::addVF(const QString & filter_name, const QVariant & value) { QString option = value.toString(); if ((filter_name == "harddup") || (filter_name == "hue")) { // ignore } else if (filter_name == "eq2") { arg << "--vf-add=eq"; } else if (filter_name == "blur") { addVFIfAvailable("lavfi", "[unsharp=la=-1.5:ca=-1.5]"); } else if (filter_name == "sharpen") { addVFIfAvailable("lavfi", "[unsharp=la=1.5:ca=1.5]"); } else if (filter_name == "noise") { addVFIfAvailable("lavfi", "[noise=alls=9:allf=t]"); } else if (filter_name == "deblock") { addVFIfAvailable("lavfi", "[pp=" + option +"]"); } else if (filter_name == "dering") { addVFIfAvailable("lavfi", "[pp=dr]"); } else if (filter_name == "phase") { addVFIfAvailable("lavfi", "[phase=" + option +"]"); } else if (filter_name == "postprocessing") { addVFIfAvailable("lavfi", "[pp]"); } else if (filter_name == "hqdn3d") { QString o; if (!option.isEmpty()) o = "=" + option; addVFIfAvailable("lavfi", "[hqdn3d" + o +"]"); } else if (filter_name == "yadif") { if (option == "1") { arg << "--vf-add=yadif=field"; } else { arg << "--vf-add=yadif"; } } else if (filter_name == "kerndeint") { addVFIfAvailable("lavfi", "[kerndeint=" + option +"]"); } else if (filter_name == "lb" || filter_name == "l5") { addVFIfAvailable("lavfi", "[pp=" + filter_name +"]"); } else if (filter_name == "subs_on_screenshots") { // Ignore } else if (filter_name == "screenshot") { if (!screenshot_dir.isEmpty() && isOptionAvailable("--screenshot-directory")) { arg << "--screenshot-directory=" + QDir::toNativeSeparators(screenshot_dir); } } else if (filter_name == "rotate") { if (option == "0") { arg << "--vf-add=rotate=270,flip"; } else if (option == "1") { arg << "--vf-add=rotate=90"; } else if (option == "2") { arg << "--vf-add=rotate=270"; } else if (option == "3") { arg << "--vf-add=rotate=90,flip"; } } else { if (filter_name == "pp") { QString s; if (option.isEmpty()) s = "[pp]"; else s = "[pp=" + option + "]"; addVFIfAvailable("lavfi", s); } else { QString s = filter_name; if (!option.isEmpty()) s += "=" + option; arg << "--vf-add=" + s; } } } void MPVProcess::addStereo3DFilter(const QString & in, const QString & out) { arg << "--vf-add=stereo3d=" + in + ":" + out; } void MPVProcess::addAF(const QString & filter_name, const QVariant & value) { QString option = value.toString(); if (filter_name == "volnorm") { QString s = "drc"; if (!option.isEmpty()) s += "=" + option; arg << "--af-add=" + s; } else if (filter_name == "channels") { if (option == "2:2:0:1:0:0") arg << "--af-add=channels=2:[0-1,0-0]"; else if (option == "2:2:1:0:1:1") arg << "--af-add=channels=2:[1-0,1-1]"; else if (option == "2:2:0:1:1:0") arg << "--af-add=channels=2:[0-1,1-0]"; } else if (filter_name == "pan") { if (option == "1:0.5:0.5") { arg << "--af-add=pan=1:[0.5,0.5]"; } } else if (filter_name == "equalizer") { previous_eq = option; arg << "--af-add=equalizer=" + option; } else if (filter_name == "extrastereo" || filter_name == "karaoke") { /* Not supported anymore */ /* Ignore */ } else { QString s = filter_name; if (!option.isEmpty()) s += "=" + option; arg << "--af-add=" + s; } } void MPVProcess::quit() { writeToStdin("quit 0"); } void MPVProcess::setVolume(int v) { qDebug() << "kobe set volumn" << v; writeToStdin("set volume " + QString::number(v)); } void MPVProcess::setOSD(int o) { writeToStdin("osd " + QString::number(o)); } void MPVProcess::setAudio(int ID) { writeToStdin("set aid " + QString::number(ID)); } void MPVProcess::setVideo(int ID) { writeToStdin("set vid " + QString::number(ID)); } void MPVProcess::setSubtitle(int /*type*/, int ID) { writeToStdin("set sid " + QString::number(ID)); } void MPVProcess::disableSubtitles() { writeToStdin("set sid no"); } void MPVProcess::setSecondarySubtitle(int ID) { writeToStdin("set secondary-sid " + QString::number(ID)); } void MPVProcess::disableSecondarySubtitles() { writeToStdin("set secondary-sid no"); } void MPVProcess::setSubtitlesVisibility(bool b) { writeToStdin(QString("set sub-visibility %1").arg(b ? "yes" : "no")); } void MPVProcess::seek(double secs, int mode, bool precise) { QString s = "seek " + QString::number(secs) + " "; switch (mode) { case 0 : s += "relative "; break; case 1 : s += "absolute-percent "; break; case 2 : s += "absolute "; break; } if (precise) s += "exact"; else s += "keyframes"; qDebug() << "*****************MPVProcess::seek="< #include #include InfoReaderMPV::InfoReaderMPV( QString mplayer_bin, QObject * parent ) : QObject(parent) , mplayer_svn(0) { mplayerbin = mplayer_bin; } InfoReaderMPV::~InfoReaderMPV() { } void InfoReaderMPV::getInfo() { vo_list.clear(); ao_list.clear(); demuxer_list.clear(); vc_list.clear(); ac_list.clear(); vf_list.clear(); mplayer_svn = -1; vo_list = getList(run("--vo help")); ao_list = getList(run("--ao help")); demuxer_list = getList(run("--demuxer help")); vc_list = getList(run("--vd help")); ac_list = getList(run("--ad help")); { InfoList list = getList(run("--vf help")); for (int n = 0; n < list.count(); n++) { vf_list.append(list[n].name()); } } QList lines = run("--version"); QString mpv_version_line; if (lines.count() >= 1) { mpv_version_line = lines[0]; mplayer_svn = MplayerVersion::mplayerVersion(mpv_version_line); mpv_version = MplayerVersion::mpvVersion(); } qDebug() << "InfoReaderMPV::getInfo: version_line" << mpv_version_line; qDebug() << "InfoReaderMPV::getInfo: mplayer_svn" << mplayer_svn; option_list = getOptionsList(run("--list-options")); //list(); } void InfoReaderMPV::list() { qDebug("InfoReaderMPV::list"); InfoList::iterator it; qDebug(" vo_list:"); for ( it = vo_list.begin(); it != vo_list.end(); ++it ) { qDebug( "driver: '%s', desc: '%s'", (*it).name().toUtf8().data(), (*it).desc().toUtf8().data()); } qDebug(" ao_list:"); for ( it = ao_list.begin(); it != ao_list.end(); ++it ) { qDebug( "driver: '%s', desc: '%s'", (*it).name().toUtf8().data(), (*it).desc().toUtf8().data()); } qDebug(" demuxer_list:"); for ( it = demuxer_list.begin(); it != demuxer_list.end(); ++it ) { qDebug( "demuxer: '%s', desc: '%s'", (*it).name().toUtf8().data(), (*it).desc().toUtf8().data()); } qDebug(" vc_list:"); for ( it = vc_list.begin(); it != vc_list.end(); ++it ) { qDebug( "codec: '%s', desc: '%s'", (*it).name().toUtf8().data(), (*it).desc().toUtf8().data()); } qDebug(" ac_list:"); for ( it = ac_list.begin(); it != ac_list.end(); ++it ) { qDebug( "codec: '%s', desc: '%s'", (*it).name().toUtf8().data(), (*it).desc().toUtf8().data()); } } QList InfoReaderMPV::run(QString options) { qDebug("InfoReaderMPV::run: '%s'", options.toUtf8().data()); QList r; QProcess proc(this); proc.setProcessChannelMode( QProcess::MergedChannels ); QStringList args = options.split(" "); proc.start(mplayerbin, args); if (!proc.waitForStarted()) { qWarning("InfoReaderMPV::run: process can't start!"); return r; } //Wait until finish if (!proc.waitForFinished()) { qWarning("InfoReaderMPV::run: process didn't finish. Killing it..."); proc.kill(); } QByteArray data = proc.readAll().replace("\r", ""); r = data.split('\n'); return r; } InfoList InfoReaderMPV::getList(const QList & lines) { InfoList l; foreach(QByteArray line, lines) { //qDebug() << "InfoReaderMPV::getList: line:" << line; line.replace("\n", ""); line = line.simplified(); if (line.startsWith("Available") || line.startsWith("demuxer:") || line.startsWith("Video decoders:") || line.startsWith("Audio decoders:")) { line = QByteArray(); } if (!line.isEmpty()) { int pos = line.indexOf(' '); if (pos > -1) { QString name = line.left(pos); if (name.endsWith(':')) name = name.left(name.count()-1); QString desc = line.mid(pos+1); desc = desc.replace(": ", "").replace("- ", ""); //qDebug() << "InfoReaderMPV::getList: name:" << name << "desc:" << desc; l.append(InfoData(name, desc)); } } } return l; } QStringList InfoReaderMPV::getOptionsList(const QList & lines) { QStringList l; foreach(QByteArray line, lines) { //qDebug() << "InfoReaderMPV::getOptionsList: line:" << line; line.replace("\n", ""); line = line.simplified(); if (line.startsWith("--")) { int pos = line.indexOf(' '); if (pos > -1) { QString option_name = line.left(pos); //qDebug() << "InfoReaderMPV::getOptionsList: option:" << option_name; l << option_name; } } } return l; } //#include "moc_inforeadermpv.cpp" kylin-video/src/smplayer/tracks.cpp0000664000175000017500000000435413233751662016366 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "tracks.h" #include Tracks::Tracks() { clear(); } Tracks::~Tracks() { } void Tracks::clear() { tm.clear(); } void Tracks::addLang(int ID, QString lang) { tm[ID].setLang(lang); tm[ID].setID(ID); } void Tracks::addName(int ID, QString name) { tm[ID].setName(name); tm[ID].setID(ID); } void Tracks::addID(int ID) { tm[ID].setID(ID); } int Tracks::numItems() { return tm.count(); } bool Tracks::existsItemAt(int n) { return ((n > 0) && (n < numItems())); } TrackData Tracks::itemAt(int n) { return tm.values()[n]; } TrackData Tracks::item(int ID) { return tm[ID]; } int Tracks::find(int ID) { for (int n=0; n < numItems(); n++) { if (itemAt(n).ID() == ID) return n; } return -1; } int Tracks::findLang(QString expr) { qDebug( "Tracks::findLang: '%s'", expr.toUtf8().data()); QRegExp rx( expr ); int res_id = -1; for (int n=0; n < numItems(); n++) { qDebug("Tracks::findLang: lang #%d '%s'", n, itemAt(n).lang().toUtf8().data()); if (rx.indexIn( itemAt(n).lang() ) > -1) { qDebug("Tracks::findLang: found preferred lang!"); res_id = itemAt(n).ID(); break; } } return res_id; } void Tracks::list() { QMapIterator i(tm); while (i.hasNext()) { i.next(); TrackData d = i.value(); qDebug("Tracks::list: item %d: ID: %d lang: '%s' name: '%s'", i.key(), d.ID(), d.lang().toUtf8().constData(), d.name().toUtf8().constData() ); } } kylin-video/src/smplayer/paths.h0000664000175000017500000000264513233751662015664 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _PATHS_H_ #define _PATHS_H_ #include class Paths { public: static void setAppPath(QString path); static QString appPath(); static QString translationPath(); static QString shortcutsPath(); static QString qtTranslationPath(); //! Forces to use a different path for the config files static void setConfigPath(QString path); //! Return the path where smplayer should save its config files static QString configPath(); //! Obsolete. Just returns configPath() static QString iniPath(); private: static QString app_path; static QString config_path; }; #endif kylin-video/src/smplayer/timedialog.ui0000664000175000017500000000503413214706400017031 0ustar fengfeng TimeDialog 0 0 380 170 380 170 380 170 Seek 160 130 91 25 OK 260 130 91 25 Cancel 344 0 36 36 95 10 191 20 Seek Qt::AlignCenter 60 64 91 29 0 0 Jump to: Qt::AlignCenter time_edit 165 65 141 27 kylin-video/src/smplayer/playerprocess.h0000664000175000017500000001605213233751662017435 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef PLAYERPROCESS_H #define PLAYERPROCESS_H #include "myprocess.h" #include "mediadata.h" #include "playerid.h" #include "config.h" #include #include class PlayerProcess : public MyProcess { Q_OBJECT public: enum ScreenshotType { Single = 0, Multiple = 1 }; PlayerProcess(QObject * parent = 0); PlayerID::Player player() { return player_id; } bool isMPlayer() { return (player_id == PlayerID::MPLAYER); } bool isMPV() { return (player_id == PlayerID::MPV); } virtual bool start() = 0; void writeToStdin(QString text); MediaData mediaData() { return md; }; // Command line options virtual void setMedia(const QString & media, bool is_playlist = false) = 0; virtual void setFixedOptions() = 0; virtual void disableInput() = 0; virtual void setOption(const QString & option_name, const QVariant & value = QVariant()) = 0; virtual void addUserOption(const QString & option) = 0; virtual void addVF(const QString & filter_name, const QVariant & value = QVariant()) = 0; virtual void addAF(const QString & filter_name, const QVariant & value = QVariant()) = 0; virtual void addStereo3DFilter(const QString & in, const QString & out) = 0; // virtual void setSubStyles(const AssStyles & styles, const QString & assStylesFile = QString::null) = 0; // Slave commands virtual void quit() = 0; virtual void setVolume(int v) = 0; virtual void setOSD(int o) = 0; virtual void setAudio(int ID) = 0; virtual void setVideo(int ID) = 0; virtual void setSubtitle(int type, int ID) = 0; virtual void disableSubtitles() = 0; virtual void setSecondarySubtitle(int ID) = 0; virtual void disableSecondarySubtitles() = 0; virtual void setSubtitlesVisibility(bool b) = 0; virtual void seek(double secs, int mode, bool precise) = 0; virtual void mute(bool b) = 0; virtual void setPause(bool b) = 0; virtual void frameStep() = 0; virtual void frameBackStep() = 0; virtual void showOSDText(const QString & text, int duration, int level) = 0; virtual void showFilenameOnOSD() = 0; virtual void showTimeOnOSD() = 0; virtual void setContrast(int value) = 0; virtual void setBrightness(int value) = 0; virtual void setHue(int value) = 0; virtual void setSaturation(int value) = 0; virtual void setGamma(int value) = 0; virtual void setChapter(int ID) = 0; virtual void setExternalSubtitleFile(const QString & filename) = 0; virtual void setSubPos(int pos) = 0; virtual void setSubScale(double value) = 0; virtual void setSubStep(int value) = 0; //#ifdef MPV_SUPPORT // virtual void seekSub(int value) = 0; //#endif virtual void setSubForcedOnly(bool b) = 0; virtual void setSpeed(double value) = 0; //#ifdef MPLAYER_SUPPORT virtual void enableKaraoke(bool b) = 0; virtual void enableExtrastereo(bool b) = 0; //#endif virtual void enableVolnorm(bool b, const QString & option) = 0; virtual void setAudioEqualizer(const QString & values) = 0; virtual void setAudioDelay(double delay) = 0; virtual void setSubDelay(double delay) = 0; virtual void setLoop(int v) = 0; virtual void takeScreenshot(ScreenshotType t, bool include_subtitles = false) = 0; //#ifdef CAPTURE_STREAM // virtual void switchCapturing() = 0; //#endif virtual void setTitle(int ID) = 0; virtual void changeVF(const QString & filter, bool enable, const QVariant & option = QVariant()) = 0; virtual void changeStereo3DFilter(bool enable, const QString & in, const QString & out) = 0; //#if DVDNAV_SUPPORT // virtual void discSetMousePos(int x, int y) = 0; // virtual void discButtonPressed(const QString & button_name) = 0; //#endif virtual void setAspect(double aspect) = 0; virtual void setFullscreen(bool b) = 0; //#if PROGRAM_SWITCH // virtual void setTSProgram(int ID) = 0; //#endif virtual void toggleDeinterlace() = 0; virtual void askForLength() = 0; virtual void setOSDScale(double value) = 0; virtual void setChannelsFile(const QString &) = 0; void setPausingPrefix(const QString & prefix) { pausing_prefix = prefix; // qDebug() << "kobe pausing_prefix=" << pausing_prefix; };//kobe void setScreenshotDirectory(const QString & dir) { screenshot_dir = dir; }; QString screenshotDirectory() { return screenshot_dir; }; //#ifdef CAPTURE_STREAM // virtual void setCaptureDirectory(const QString & dir); //#endif static PlayerProcess * createPlayerProcess(const QString & player_bin, QObject * parent = 0); // Signals signals: void processExited(); void lineAvailable(QString line); void receivedCurrentSec(double sec); void receivedCurrentFrame(int frame); void receivedPause(); void receivedWindowResolution(int,int); void receivedNoVideo(); void receivedVO(QString); void receivedAO(QString); void receivedEndOfFile(); void mplayerFullyLoaded(); void receivedStartingTime(double sec); void receivedCacheMessage(QString); void receivedCacheEmptyMessage(QString); void receivedCreatingIndex(QString); void receivedConnectingToMessage(QString); void receivedResolvingMessage(QString); void receivedBuffering(); void receivedPlaying(); void receivedScreenshot(QString); void receivedUpdatingFontCache(); void receivedScanningFont(QString); void receivedForbiddenText(); void receivedStreamTitle(QString); void receivedStreamTitleAndUrl(QString,QString); void failedToParseMplayerVersion(QString line_with_mplayer_version); #if NOTIFY_SUB_CHANGES //! Emitted if a new subtitle has been added or an old one changed void subtitleInfoChanged(const SubTracks &); //! Emitted when subtitle info has been received but there wasn't anything new void subtitleInfoReceivedAgain(const SubTracks &); #endif #if NOTIFY_AUDIO_CHANGES //! Emitted if a new audio track been added or an old one changed void audioInfoChanged(const Tracks &); #endif #if NOTIFY_VIDEO_CHANGES //! Emitted if a new video track been added or an old one changed void videoInfoChanged(const Tracks &); #endif //#if NOTIFY_CHAPTER_CHANGES // void chaptersChanged(const Chapters &); //#endif //#if DVDNAV_SUPPORT // void receivedDVDTitle(int); // void receivedDuration(double); // void receivedTitleIsMenu(); // void receivedTitleIsMovie(); //#endif void receivedVideoBitrate(int); void receivedAudioBitrate(int); protected: MediaData md; QString pausing_prefix; QString screenshot_dir; //#ifdef CAPTURE_STREAM // QString capture_filename; //#endif PlayerID::Player player_id; }; #endif kylin-video/src/smplayer/filedialog.cpp0000664000175000017500000000412013233751662017165 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "filedialog.h" #include QString MyFileDialog::getOpenFileName( QWidget * parent, const QString & caption, const QString & dir, const QString & filter, QString * selectedFilter, QFileDialog::Options options ) { return QFileDialog::getOpenFileName( parent, caption, dir, filter, selectedFilter, options ); } QString MyFileDialog::getExistingDirectory ( QWidget * parent, const QString & caption, const QString & dir, QFileDialog::Options options ) { return QFileDialog::getExistingDirectory( parent, caption, dir, options ); } QString MyFileDialog::getSaveFileName ( QWidget * parent, const QString & caption, const QString & dir, const QString & filter, QString * selectedFilter, QFileDialog::Options options ) { return QFileDialog::getSaveFileName( parent, caption, dir, filter, selectedFilter, options ); } QStringList MyFileDialog::getOpenFileNames ( QWidget * parent, const QString & caption, const QString & dir, const QString & filter, QString * selectedFilter, QFileDialog::Options options ) { return QFileDialog::getOpenFileNames( parent, caption, dir, filter, selectedFilter, options ); } kylin-video/src/smplayer/extensions.h0000664000175000017500000000310413233751662016733 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _EXTENSIONS_H_ #define _EXTENSIONS_H_ #include class ExtensionList : public QStringList { public: ExtensionList(); QString forFilter(); QStringList forDirFilter(); QString forRegExp(); }; class Extensions { public: Extensions(); ~Extensions(); ExtensionList video() { return _video; }; ExtensionList audio() { return _audio; }; ExtensionList playlist() { return _playlist; }; ExtensionList subtitles() { return _subtitles; }; ExtensionList multimedia() { return _multimedia; }; ExtensionList allPlayable() { return _all_playable; }; protected: ExtensionList _video, _audio, _playlist, _subtitles; ExtensionList _multimedia; //!< video and audio ExtensionList _all_playable; //!< video, audio and playlist }; #endif kylin-video/src/smplayer/mplayerwindow.h0000664000175000017500000001447213233751662017447 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef MPLAYERWINDOW_H #define MPLAYERWINDOW_H #include #include #include #include #include #include #include #include #include "config.h" class QWidget; class QLabel; class QKeyEvent; class QTimer; #define ZOOM_STEP 0.05 #define ZOOM_MIN 0.5 //#define DELAYED_RESIZE 0 // Number of pixels the window has to be dragged at least before dragging starts #define DRAG_THRESHOLD 4 enum TDragState {NOT_DRAGGING, START_DRAGGING, DRAGGING}; //! Screen is a widget that hides the mouse cursor after some seconds if not moved. class Screen : public QWidget { Q_OBJECT public: Screen(QWidget* parent = 0, Qt::WindowFlags f = 0); ~Screen(); void setAutoHideCursor(bool b); bool autoHideCursor() { return autohide_cursor; }; void setAutoHideInterval(int milliseconds) { autohide_interval = milliseconds; }; int autoHideInterval() { return autohide_interval; }; public slots: //! Should be called when a file has started. virtual void playingStarted(); //! Should be called when a file has stopped. virtual void playingStopped(); signals: void mouseMoved(QPoint); // void sigShowControls(); protected: virtual void mouseMoveEvent( QMouseEvent * e ); protected slots: virtual void checkMousePos(); private: QTimer * check_mouse_timer; QPoint mouse_last_position; bool autohide_cursor; int autohide_interval; }; //! MplayerLayer can be instructed to not delete the background. class MplayerLayer : public Screen { Q_OBJECT public: MplayerLayer(QWidget* parent = 0, Qt::WindowFlags f = 0); ~MplayerLayer(); //#if REPAINT_BACKGROUND_OPTION //! If b is true, the background of the widget will be repainted as usual. /*! Otherwise the background will not repainted when a video is playing. */ // void setRepaintBackground(bool b); // //! Return true if repainting the background is allowed. // bool repaintBackground() { return repaint_background; }; //#endif public slots: //! Should be called when a file has started. /*! It's needed to know if the background has to be cleared or not. */ virtual void playingStarted(); //! Should be called when a file has stopped. virtual void playingStopped(); //#if REPAINT_BACKGROUND_OPTION protected: virtual void paintEvent ( QPaintEvent * e );//0522 //#endif private: //#if REPAINT_BACKGROUND_OPTION // bool repaint_background; //#endif bool playing; }; class MplayerWindow : public Screen { Q_OBJECT public: MplayerWindow(QWidget* parent = 0, Qt::WindowFlags f = 0); ~MplayerWindow(); MplayerLayer * videoLayer() { return mplayerlayer; }; void setResolution( int w, int h); void setAspect( double asp); void setMonitorAspect(double asp); void updateVideoWindow(); //#if USE_COLORKEY void setColorKey(QColor c); //#endif void setOffsetX( int ); int offsetX(); void setOffsetY( int ); int offsetY(); void setZoom( double ); double zoom(); void allowVideoMovement(bool b) { allow_video_movement = b; }; bool isVideoMovementAllowed() { return allow_video_movement; }; // void delayLeftClick(bool b) { delay_left_click = b; }; // bool isLeftClickDelayed() { return delay_left_click; }; virtual QSize sizeHint () const; virtual QSize minimumSizeHint() const; virtual bool eventFilter(QObject *, QEvent *); //#if LOGO_ANIMATION // bool animatedLogo() { return animated_logo; } //#endif void setCornerWidget(QWidget * w); QWidget * cornerWidget() { return corner_widget; }; public slots: void setLogoVisible(bool b); void showLogo() { setLogoVisible(true);};//kobe:隐藏主界面和网络相关的按钮 void hideLogo() { setLogoVisible(false); }; void hideLogoForTemporary(); // void show_or_hide_logo(bool b); void update_logo_pos(); //#if LOGO_ANIMATION // void setAnimatedLogo(bool b) { animated_logo = b; }; //#endif void moveLeft(); void moveRight(); void moveUp(); void moveDown(); void incZoom(); void decZoom(); void activateMouseDragTracking(bool active) { mouse_drag_tracking = active; } //#if DELAYED_RESIZE //protected slots: // void resizeLater(); //#endif protected: virtual void retranslateStrings(); // virtual void changeEvent ( QEvent * event ) ; virtual void resizeEvent( QResizeEvent * e); virtual void mouseReleaseEvent( QMouseEvent * e); virtual void mouseDoubleClickEvent( QMouseEvent *event); virtual void wheelEvent( QWheelEvent * e ); void moveLayer( int offset_x, int offset_y ); virtual bool event(QEvent *event); signals: //void rightButtonReleased( QPoint p ); void doubleClicked(); void leftClicked(); void rightClicked(); void middleClicked(); void xbutton1Clicked(); // first X button void xbutton2Clicked(); // second X button void keyPressed(QKeyEvent * e); void wheelUp(); void wheelDown(); void mouseMovedDiff(QPoint); void resize_mainwindow(int w, int h);//add by kobe protected: int video_width, video_height; double aspect; double monitoraspect; MplayerLayer * mplayerlayer; QLabel * logo; bool stoped; // Zoom and moving int offset_x, offset_y; double zoom_factor; // Original pos and dimensions of the mplayerlayer // before zooming or moving int orig_x, orig_y; int orig_width, orig_height; bool allow_video_movement; //#if DELAYED_RESIZE // QTimer * resize_timer; //#endif // Delay left click event // bool delay_left_click; QTimer * left_click_timer; bool double_clicked; //#if LOGO_ANIMATION // bool animated_logo; //#endif QWidget * corner_widget; private: TDragState drag_state; QPoint start_drag; bool mouse_drag_tracking; }; #endif kylin-video/src/smplayer/helper.h0000664000175000017500000000422313233751662016016 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _HELPER_H_ #define _HELPER_H_ #include #include #include "preferences.h" class Helper { public: // Format a time (hh:mm:ss) static QString formatTime(int secs); static QString timeForJumps(int secs); // Give a name for config (group name) based on dvd id /* static QString dvdForPref(const QString & dvd_id, int title); */ static void msleep(int ms); //! Change filenames like "C:/Program Files/" to "C:\Program Files\" static QString changeSlashes(QString filename); static bool directoryContainsDVD(QString directory); //! Returns an int with the version number of Qt at run-time. //! If version is 4.3.2 it returns 40302. static int qtVersion(); //! Returns a string to be passed to mplayer with the audio equalizer //! values. // static QString equalizerListToString(AudioEqualizerList values); static QStringList filesForPlaylist(const QString & initial_file, Preferences::AutoAddToPlaylistFilter filter); #ifdef Q_OS_LINUX //! Tries to find the executable in the path. //! Returns the path if found or QString::null if not. static QString findExecutable(const QString & name); #endif private: static QStringList searchForConsecutiveFiles(const QString & initial_file); static QStringList filesInDirectory(const QString & initial_file, const QStringList & filter); }; #endif kylin-video/src/smplayer/shutdown.cpp0000664000175000017500000000576613233751662016762 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "shutdown.h" #include #ifdef Q_OS_LINUX #include #include #endif void Shutdown::shutdown() { #ifdef Q_OS_WIN QProcess::startDetached("shutdown -s -f -t 10"); #endif #ifdef Q_OS_LINUX bool works = false; QDBusMessage response; QDBusInterface gnomeSessionManager("org.gnome.SessionManager", "/org/gnome/SessionManager", "org.gnome.SessionManager", QDBusConnection::sessionBus()); response = gnomeSessionManager.call("RequestShutdown"); if (response.type() == QDBusMessage::ErrorMessage) { qDebug() << "Shutdown::shutdown: error:" << response.errorName() << ":" << response.errorMessage(); } else { works = true; } if (!works) { QDBusInterface kdeSessionManager("org.kde.ksmserver", "/KSMServer", "org.kde.KSMServerInterface", QDBusConnection::sessionBus()); response = kdeSessionManager.call("logout", 0, 2, 2); if (response.type() == QDBusMessage::ErrorMessage) { qDebug() << "Shutdown::shutdown: error:" << response.errorName() << ":" << response.errorMessage(); } else { works = true; } } if (!works) { QDBusInterface powermanagement("org.freedesktop.Hal", "/org/freedesktop/Hal/devices/computer", "org.freedesktop.Hal.Device.SystemPowerManagement", QDBusConnection::systemBus()); response = powermanagement.call("Shutdown"); if (response.type() == QDBusMessage::ErrorMessage) { qDebug() << "Shutdown::shutdown: error:" << response.errorName() << ":" << response.errorMessage(); } else { works = true; } } if (!works) { QDBusInterface powermanagement("org.freedesktop.ConsoleKit", "/org/freedesktop/ConsoleKit/Manager", "org.freedesktop.ConsoleKit.Manager", QDBusConnection::systemBus()); response = powermanagement.call("Stop"); if (response.type() == QDBusMessage::ErrorMessage) { qDebug() << "Shutdown::shutdown: error:" << response.errorName() << ":" << response.errorMessage(); } else { works = true; } } if (!works) { qDebug("Shutdown::shutdown: shutdown failed"); QProcess::startDetached("xmessage", QStringList() << "-buttons" << "Accept:0" << "-center" << "This is a message from SMPlayer\n" "The computer should shut down now.\n" "However shutdown failed."); } #endif } kylin-video/src/smplayer/infoprovider.h0000664000175000017500000000244013233751662017244 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ //! Reads info about a file (resolution, length...) #ifndef _INFOPROVIDER_H_ #define _INFOPROVIDER_H_ #include #include "mediadata.h" class InfoProvider { public: //! Gets info about the specified filename. static MediaData getInfo(QString mplayer_bin, QString filename); //! Gets info about the specified filename. The mplayer executable will be // obtained from the global preferences. static MediaData getInfo(QString filename); }; #endif kylin-video/src/smplayer/mediadata.cpp0000664000175000017500000000761613233751662017014 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "mediadata.h" #include #include MediaData::MediaData() { reset(); } MediaData::~MediaData() { } void MediaData::reset() { filename=""; dvd_id=""; type = TYPE_UNKNOWN; duration=0; novideo = false; video_width=0; video_height=0; video_aspect= (double) 4/3; //#if PROGRAM_SWITCH // programs.clear(); //#endif videos.clear(); audios.clear(); titles.clear(); subs.clear(); // chapters.clear(); n_chapters = 0; initialized=false; // Clip info; clip_name = ""; clip_artist = ""; clip_author = ""; clip_album = ""; clip_genre = ""; clip_date = ""; clip_track = ""; clip_copyright = ""; clip_comment = ""; clip_software = ""; stream_title = ""; stream_url = ""; // Other data demuxer=""; video_format=""; audio_format=""; video_bitrate=0; video_fps=""; audio_bitrate=0; audio_rate=0; audio_nch=0; video_codec=""; audio_codec=""; } QString MediaData::displayName(bool show_tag) { if (show_tag) { if (!stream_title.isEmpty()) return stream_title; // else // if (!clip_name.isEmpty()) return clip_name;//0526 } //kobe:有的rmvb视频的clip_name存在乱码 0526 QString name; if (name.isEmpty()) { QFileInfo fi(filename); if (fi.exists()) { // Local file name = fi.fileName(); } else { // Stream name = filename; } } return name; // QFileInfo fi(filename); // if (fi.exists()) // return fi.fileName(); // filename without path // else // return filename; } void MediaData::list() { // qDebug("MediaData::list"); // qDebug(" filename: '%s'", filename.toUtf8().data()); // qDebug(" duration: %f", duration); // qDebug(" video_width: %d", video_width); // qDebug(" video_height: %d", video_height); // qDebug(" video_aspect: %f", video_aspect); // qDebug(" type: %d", type); // qDebug(" novideo: %d", novideo); // qDebug(" dvd_id: '%s'", dvd_id.toUtf8().data()); // qDebug(" initialized: %d", initialized); // qDebug(" chapters: %d", n_chapters); // qDebug(" Subs:"); subs.list(); //#if PROGRAM_SWITCH // qDebug(" Programs:"); // programs.list(); //#endif // qDebug(" Videos:"); videos.list(); // qDebug(" Audios:"); audios.list(); // qDebug(" Titles:"); titles.list(); //qDebug(" chapters: %d", chapters); //qDebug(" angles: %d", angles); //kobe // qDebug(" demuxer: '%s'", demuxer.toUtf8().data() );//avi real // qDebug(" video_format: '%s'", video_format.toUtf8().data() );//XVID RV40 // qDebug(" audio_format: '%s'", audio_format.toUtf8().data() );//85 cook // qDebug(" video_bitrate: %d", video_bitrate );//1113640 0 // qDebug(" video_fps: '%s'", video_fps.toUtf8().data() );//25.000 23.000 // qDebug(" audio_bitrate: %d", audio_bitrate );//224000 64080 // qDebug(" audio_rate: %d", audio_rate );//44100 44100 // qDebug(" audio_nch: %d", audio_nch );//2 2 // qDebug(" video_codec: '%s'", video_codec.toUtf8().data() );//ffodivx ffrv40 // qDebug(" audio_codec: '%s'", audio_codec.toUtf8().data() );//mpg123 ffcook } kylin-video/src/smplayer/mplayerversion.cpp0000664000175000017500000002010113233751662020142 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "mplayerversion.h" #include "global.h" #include "preferences.h" #include using namespace Global; //QString MplayerVersion::mplayer2_version; QString MplayerVersion::mpv_version; //bool MplayerVersion::is_mplayer2 = false; bool MplayerVersion::is_mpv = false; int MplayerVersion::mplayerVersion(QString string) { //static QRegExp rx_mplayer_revision("^MPlayer (\\S+)-SVN-r(\\d+)-(.*)"); static QRegExp rx_mplayer_revision("^MPlayer (.*)[-\\.]r(\\d+)(.*)"); static QRegExp rx_mplayer_version("^MPlayer ([a-z0-9.]+)[-(.*)| (.*)]"); static QRegExp rx_mplayer_git("^MPlayer GIT(.*)", Qt::CaseInsensitive); static QRegExp rx_mplayer_version_final("1.0rc([0-9])"); static QRegExp rx_mplayer2_version("^MPlayer2 (.*) \\(C\\).*", Qt::CaseInsensitive); static QRegExp rx_mpv_version("^mpv (.*) \\(C\\).*", Qt::CaseInsensitive); static QRegExp rx_mplayer_version_ubuntu("^MPlayer (\\d):(\\d)\\.(\\d)~(.*)"); static QRegExp rx_mplayer_revision_ubuntu("^MPlayer svn r(\\d+) (.*)"); static QRegExp rx_mplayer_version_mandriva("^MPlayer ([a-z0-9\\.]+)-\\d+\\.([a-z0-9]+)\\.[\\d\\.]+[a-z]+[\\d\\.]+-(.*)"); int mplayer_svn = 0; // mplayer2_version = QString::null; // is_mplayer2 = false; is_mpv = false; // Hack to recognize mplayer 1.0rc1 from Ubuntu: if (rx_mplayer_version_ubuntu.indexIn(string) > -1) { int v1 = rx_mplayer_version_ubuntu.cap(2).toInt(); int v2 = rx_mplayer_version_ubuntu.cap(3).toInt(); QString rest = rx_mplayer_version_ubuntu.cap(4); //qDebug("%d - %d - %d", rx_mplayer_version_ubuntu.cap(1).toInt(), v1 , v2); string = QString("MPlayer %1.%2%3").arg(v1).arg(v2).arg(rest); qDebug("MplayerVersion::mplayerVersion: line converted to '%s'", string.toUtf8().data()); } else if (rx_mplayer_revision_ubuntu.indexIn(string) > -1) { int svn = rx_mplayer_revision_ubuntu.cap(1).toInt(); QString rest = rx_mplayer_revision_ubuntu.cap(2); string = QString("MPlayer SVN-r%1-%2").arg(svn).arg(rest); qDebug("MplayerVersion::mplayerVersion: line converted to '%s'", string.toUtf8().data()); } // Hack to recognize mplayer version from Mandriva: if (rx_mplayer_version_mandriva.indexIn(string) > -1) { QString v1 = rx_mplayer_version_mandriva.cap(1); QString v2 = rx_mplayer_version_mandriva.cap(2); QString rest = rx_mplayer_version_mandriva.cap(3); string = QString("MPlayer %1%2-%3").arg(v1).arg(v2).arg(rest); qDebug("MplayerVersion::mplayerVersion: line converted to '%s'", string.toUtf8().data()); } if (rx_mplayer_git.indexIn(string) > -1) { qDebug("MplayerVersion::mplayerVersion: MPlayer from git. Assuming >= 1.0rc3"); mplayer_svn = MPLAYER_1_0_RC3_SVN; } else if (rx_mplayer_revision.indexIn(string) > -1) { mplayer_svn = rx_mplayer_revision.cap(2).toInt(); qDebug("MplayerVersion::mplayerVersion: MPlayer SVN revision found: %d", mplayer_svn); } else if (rx_mplayer_version.indexIn(string) > -1) { QString version = rx_mplayer_version.cap(1); qDebug("MplayerVersion::mplayerVersion: MPlayer version found: %s", version.toUtf8().data()); mplayer_svn = 0; if (version == "1.2") mplayer_svn = MPLAYER_1_2; else if (version == "1.1") mplayer_svn = MPLAYER_1_1; else if (version == "1.0rc4") mplayer_svn = MPLAYER_1_0_RC4_SVN; else if (version == "1.0rc3") mplayer_svn = MPLAYER_1_0_RC3_SVN; else if (version == "1.0rc2") mplayer_svn = MPLAYER_1_0_RC2_SVN; else if (version == "1.0rc1") mplayer_svn = MPLAYER_1_0_RC1_SVN; else /* if(rx_mplayer_version_final.indexIn(version) > -1 && rx_mplayer_version_final.cap(1).toInt() > 3) mplayer_svn = MPLAYER_1_0_RC3_SVN; //version is > 1.0rc3, so treat as 1.0rc3 since support for later versions is not yet implemented else qWarning("MplayerVersion::mplayerVersion: unknown MPlayer version"); */ // Assume it's at least mplayer 1.2 mplayer_svn = MPLAYER_1_2; } // else // mplayer_svn = MPLAYER_1_2; // else // if (rx_mplayer2_version.indexIn(string) > -1) { // mplayer2_version = rx_mplayer2_version.cap(1); // qDebug("MplayerVersion::mplayerVersion: MPlayer2 version found: %s", mplayer2_version.toUtf8().data()); // is_mplayer2 = true; // mplayer_svn = MPLAYER_1_0_RC4_SVN; // simulates mplayer 1.0rc4 // } else if (rx_mpv_version.indexIn(string) > -1) { mpv_version = rx_mpv_version.cap(1); qDebug("MplayerVersion::mplayerVersion: mpv version found: %s", mpv_version.toUtf8().data()); is_mpv = true; // is_mplayer2 = true; mplayer_svn = MPLAYER_1_0_RC4_SVN; // simulates mplayer 1.0rc4 } else mplayer_svn = MPLAYER_1_2; if (pref) { pref->mplayer_detected_version = mplayer_svn; // pref->mplayer_is_mplayer2 = is_mplayer2; // pref->mplayer2_detected_version = mplayer2_version; } qDebug("MplayerVersion::mplayerVersion: mplayer_svn: %d", mplayer_svn); return mplayer_svn; } bool MplayerVersion::isMplayerAtLeast(int mplayer_svn, int svn_revision) { qDebug("MplayerVersion::isMplayerAtLeast: comparing %d with %d", svn_revision, mplayer_svn); if (mplayer_svn == -1) { qWarning("MplayerVersion::isMplayerAtLeast: no version found!"); } else if (mplayer_svn == 0) { qWarning("MplayerVersion::isMplayerAtLeast: version couldn't be parsed!"); } if (mplayer_svn <= 0) { qWarning("MplayerVersion::isMplayerAtLeast: assuming that the mplayer version is less than %d", svn_revision); return false; } return (mplayer_svn >= svn_revision); } bool MplayerVersion::isMplayerAtLeast(int svn_revision) { if (pref->mplayer_detected_version >= MPLAYER_1_0_RC1_SVN) { // SVN version seems valid if (pref->mplayer_user_supplied_version != -1) { qDebug("MplayerVersion::isMplayerAtLeast: using the parsed svn version from mplayer output"); qDebug("MplayerVersion::isMplayerAtLeast: and clearing the previously user supplied version"); pref->mplayer_user_supplied_version = -1; } return isMplayerAtLeast(pref->mplayer_detected_version, svn_revision); } else if (pref->mplayer_user_supplied_version != -1) { qDebug("MplayerVersion::isMplayerAtLeast: no parsed version, using user supplied version"); return isMplayerAtLeast(pref->mplayer_user_supplied_version, svn_revision); } else { qWarning("MplayerVersion::isMplayerAtLeast: there's no parsed version nor user supplied version!"); return isMplayerAtLeast(pref->mplayer_detected_version, svn_revision); } } QString MplayerVersion::toString(int svn_revision) { QString version; switch (svn_revision) { case MPLAYER_1_0_RC1_SVN: version = QString("1.0rc1"); break; case MPLAYER_1_0_RC2_SVN: version = QString("1.0rc2"); break; case MPLAYER_1_0_RC3_SVN: version = QString("1.0rc3"); break; case MPLAYER_1_0_RC4_SVN: version = QString("1.0rc4"); break; case MPLAYER_1_1: version = QString("1.1"); break; default : version = QString("SVN r%1").arg(svn_revision); } return version; } kylin-video/src/smplayer/actionseditor.h0000664000175000017500000000510113233751662017402 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ /* This is based on qq14-actioneditor-code.zip from Qt */ #ifndef _ACTIONSEDITOR_H_ #define _ACTIONSEDITOR_H_ #include #include #include class QTableWidget; class QTableWidgetItem; class QAction; class QSettings; class QPushButton; class ActionsEditor : public QWidget { Q_OBJECT public: ActionsEditor( QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~ActionsEditor(); // Clear the actionlist void clear(); // There are no actions yet? bool isEmpty(); void addCurrentActions(QWidget * widget); // Static functions static QAction * findAction(QObject *o, const QString & name); static QStringList actionsNames(QObject *o); static void saveToConfig(QObject *o, QSettings *set); static void loadFromConfig(QObject *o, QSettings *set); static QString shortcutsToString(QList shortcuts_list); static QList stringToShortcuts(QString shortcuts); public slots: void applyChanges(); // void saveActionsTable(); // bool saveActionsTable(const QString & filename); // void loadActionsTable(); // bool loadActionsTable(const QString & filename); void updateView(); protected: virtual void retranslateStrings(); virtual void changeEvent ( QEvent * event ) ; // Find in table, not in actionslist int findActionName(const QString & name); int findActionAccel(const QString & accel, int ignoreRow = -1); bool hasConflicts(); static bool containsShortcut(const QString & accel, const QString & shortcut); protected slots: void editShortcut(); private: QTableWidget *actionsTable; QList actionsList; // QList btnActionsList; // QPushButton *saveButton; // QPushButton *loadButton; QString latest_dir; // QPushButton *editButton; }; #endif kylin-video/src/smplayer/timedialog.h0000664000175000017500000000274613233751662016665 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _TIMEDIALOG_H_ #define _TIMEDIALOG_H_ #include "ui_timedialog.h" class QPushButton; enum TDDragState {NOT_TDDRAGGING, START_TDDRAGGING, TDDRAGGING}; class TimeDialog : public QDialog, public Ui::TimeDialog { Q_OBJECT public: TimeDialog( QWidget* parent = 0, Qt::WindowFlags f = 0 ); ~TimeDialog(); int time(); int maximumTime(); QString label(); void initConnect(); virtual bool eventFilter(QObject *, QEvent *); void moveDialog(QPoint diff); public slots: void setTime(int seconds); void setMaximumTime( int seconds ); void setLabel(const QString & label); private: TDDragState drag_state; QPoint start_drag; }; #endif kylin-video/src/smplayer/infoprovider.cpp0000664000175000017500000000365413233751662017607 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "infoprovider.h" #include "global.h" #include "preferences.h" #include "playerprocess.h" #include "playerid.h" #include MediaData InfoProvider::getInfo(QString mplayer_bin, QString filename) { qDebug("InfoProvider::getInfo: %s", filename.toUtf8().data()); QFileInfo fi(mplayer_bin); if (fi.exists() && fi.isExecutable() && !fi.isDir()) { mplayer_bin = fi.absoluteFilePath(); } PlayerProcess * proc = PlayerProcess::createPlayerProcess(mplayer_bin, 0); proc->setExecutable(mplayer_bin); proc->setFixedOptions(); proc->setOption("frames", "1"); proc->setOption("vo", "null"); proc->setOption("ao", "null"); proc->setMedia(filename); QString commandline = proc->arguments().join(" "); qDebug("InfoProvider::getInfo: command: '%s'", commandline.toUtf8().data()); proc->start(); if (!proc->waitForFinished()) { qWarning("InfoProvider::getInfo: process didn't finish. Killing it..."); proc->kill(); } MediaData md = proc->mediaData(); delete proc; return md; } MediaData InfoProvider::getInfo(QString filename) { return getInfo( Global::pref->mplayer_bin, filename ); } kylin-video/src/smplayer/recents.cpp0000664000175000017500000000416213233751662016537 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "recents.h" Recents::Recents() { l.clear(); max_items = 10; } Recents::~Recents() { } void Recents::clear() { l.clear(); } int Recents::count() { return l.count(); } void Recents::setMaxItems(int n_items) { max_items = n_items; fromStringList(l); } void Recents::addItem(QString s) { // qDebug("Recents::addItem: '%s'", s.toUtf8().data()); int pos = l.indexOf(s); if (pos != -1) l.removeAt(pos); l.prepend(s); if (l.count() > max_items) l.removeLast(); } void Recents::addItem(QString s, QString title) { s += "|title]=" + title; addItem(s); } QString Recents::item(int n) { QString res; QStringList s = l[n].split("|title]="); if (s.count() > 0) res = s[0]; return res; } QString Recents::title(int n) { QString res; QStringList s = l[n].split("|title]="); if (s.count() > 1) res = s[1]; return res; } void Recents::list() { qDebug("Recents::list"); for (int n=0; n < l.count(); n++) { qDebug(" * item %d: '%s'", n, l[n].toUtf8().constData() ); } } void Recents::fromStringList(QStringList list) { l.clear(); int max = list.count(); if (max_items < max) max = max_items; //qDebug("max_items: %d, count: %d max: %d", max_items, l.count(), max); for (int n = 0; n < max; n++) { l.append( list[n] ); } } QStringList Recents::toStringList() { return l; } kylin-video/src/smplayer/shortcutgetter.cpp0000664000175000017500000004775713233751662020203 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 Note: The ShortcutGetter class is taken from the source code of Edyuk (http://www.edyuk.org/), from file 3rdparty/qcumber/qshortcutdialog.cpp Copyright (C) 2006 FullMetalCoder License: GPL I modified it to support multiple shortcuts and some other few changes. */ /**************************************************************************** ** ** Copyright (C) 2006 FullMetalCoder ** ** This file is part of the Edyuk project (beta version) ** ** This file may be used under the terms of the GNU General Public License ** version 2 as published by the Free Software Foundation and appearing in the ** file GPL.txt included in the packaging of this file. ** ** Notes : Parts of the project are derivative work of Trolltech's QSA library ** or Trolltech's Qt4 framework but, unless notified, every single line of code ** is the work of the Edyuk team or a contributor. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ****************************************************************************/ #include "shortcutgetter.h" #include "images.h" #include #include #include #include #include #include #include #include #include #include #if 1 static QHash keyMap; static void initKeyMap() { if ( !keyMap.isEmpty() ) return; /* I'm a bit unsure about these one... */ keyMap[Qt::Key_Escape] = "Escape"; keyMap[Qt::Key_Return] = "Return"; keyMap[Qt::Key_Enter] = "Enter"; keyMap[Qt::Key_Insert] = "Ins"; keyMap[Qt::Key_Delete] = "Delete"; keyMap[Qt::Key_Home] = "Home"; keyMap[Qt::Key_End] = "End"; keyMap[Qt::Key_Left] = "Left"; keyMap[Qt::Key_Up] = "Up"; keyMap[Qt::Key_Right] = "Right"; keyMap[Qt::Key_Down] = "Down"; keyMap[Qt::Key_PageUp] = "PgUp"; keyMap[Qt::Key_PageDown] = "PgDown"; keyMap[Qt::Key_CapsLock] = "CapsLock"; keyMap[Qt::Key_NumLock] = "NumLock"; keyMap[Qt::Key_ScrollLock] = "ScrollLock"; /* These one are quite sure... */ keyMap[Qt::Key_F1] = "F1"; keyMap[Qt::Key_F2] = "F2"; keyMap[Qt::Key_F3] = "F3"; keyMap[Qt::Key_F4] = "F4"; keyMap[Qt::Key_F5] = "F5"; keyMap[Qt::Key_F6] = "F6"; keyMap[Qt::Key_F7] = "F7"; keyMap[Qt::Key_F8] = "F8"; keyMap[Qt::Key_F9] = "F9"; keyMap[Qt::Key_F10] = "F10"; keyMap[Qt::Key_F11] = "F11"; keyMap[Qt::Key_F12] = "F12"; keyMap[Qt::Key_F13] = "F13"; keyMap[Qt::Key_F14] = "F14"; keyMap[Qt::Key_F15] = "F15"; keyMap[Qt::Key_F16] = "F16"; keyMap[Qt::Key_F17] = "F17"; keyMap[Qt::Key_F18] = "F18"; keyMap[Qt::Key_F19] = "F19"; keyMap[Qt::Key_F20] = "F20"; keyMap[Qt::Key_F21] = "F21"; keyMap[Qt::Key_F22] = "F22"; keyMap[Qt::Key_F23] = "F23"; keyMap[Qt::Key_F24] = "F24"; keyMap[Qt::Key_F25] = "F25"; keyMap[Qt::Key_F26] = "F26"; keyMap[Qt::Key_F27] = "F27"; keyMap[Qt::Key_F28] = "F28"; keyMap[Qt::Key_F29] = "F29"; keyMap[Qt::Key_F30] = "F30"; keyMap[Qt::Key_F31] = "F31"; keyMap[Qt::Key_F32] = "F32"; keyMap[Qt::Key_F33] = "F33"; keyMap[Qt::Key_F34] = "F34"; keyMap[Qt::Key_F35] = "F35"; keyMap[Qt::Key_Exclam] = "!"; keyMap[Qt::Key_QuoteDbl] = "\""; keyMap[Qt::Key_NumberSign] = "-"; keyMap[Qt::Key_Dollar] = "$"; keyMap[Qt::Key_Percent] = "%"; keyMap[Qt::Key_Ampersand] = "&"; keyMap[Qt::Key_Apostrophe] = "\'"; keyMap[Qt::Key_ParenLeft] = "("; keyMap[Qt::Key_ParenRight] = ")"; keyMap[Qt::Key_Asterisk] = "*"; keyMap[Qt::Key_Plus] = "+"; keyMap[Qt::Key_Comma] = ","; keyMap[Qt::Key_Minus] = "-"; keyMap[Qt::Key_Period] = "Period"; keyMap[Qt::Key_Slash] = "/"; keyMap[Qt::Key_0] = "0"; keyMap[Qt::Key_1] = "1"; keyMap[Qt::Key_2] = "2"; keyMap[Qt::Key_3] = "3"; keyMap[Qt::Key_4] = "4"; keyMap[Qt::Key_5] = "5"; keyMap[Qt::Key_6] = "6"; keyMap[Qt::Key_7] = "7"; keyMap[Qt::Key_8] = "8"; keyMap[Qt::Key_9] = "9"; keyMap[Qt::Key_Colon] = ":"; keyMap[Qt::Key_Semicolon] = ";"; keyMap[Qt::Key_Less] = "<"; keyMap[Qt::Key_Equal] = "="; keyMap[Qt::Key_Greater] = ">"; keyMap[Qt::Key_Question] = "?"; keyMap[Qt::Key_At] = "@"; keyMap[Qt::Key_A] = "A"; keyMap[Qt::Key_B] = "B"; keyMap[Qt::Key_C] = "C"; keyMap[Qt::Key_D] = "D"; keyMap[Qt::Key_E] = "E"; keyMap[Qt::Key_F] = "F"; keyMap[Qt::Key_G] = "G"; keyMap[Qt::Key_H] = "H"; keyMap[Qt::Key_I] = "I"; keyMap[Qt::Key_J] = "J"; keyMap[Qt::Key_K] = "K"; keyMap[Qt::Key_L] = "L"; keyMap[Qt::Key_M] = "M"; keyMap[Qt::Key_N] = "N"; keyMap[Qt::Key_O] = "O"; keyMap[Qt::Key_P] = "P"; keyMap[Qt::Key_Q] = "Q"; keyMap[Qt::Key_R] = "R"; keyMap[Qt::Key_S] = "S"; keyMap[Qt::Key_T] = "T"; keyMap[Qt::Key_U] = "U"; keyMap[Qt::Key_V] = "V"; keyMap[Qt::Key_W] = "W"; keyMap[Qt::Key_X] = "X"; keyMap[Qt::Key_Y] = "Y"; keyMap[Qt::Key_Z] = "Z"; keyMap[Qt::Key_BracketLeft] = "["; keyMap[Qt::Key_Backslash] = "\\"; keyMap[Qt::Key_BracketRight] = "]"; keyMap[Qt::Key_Underscore] = "_"; keyMap[Qt::Key_BraceLeft] = "{"; keyMap[Qt::Key_Bar] = "|"; keyMap[Qt::Key_BraceRight] = "}"; keyMap[Qt::Key_AsciiTilde] = "~"; // Added by rvm: keyMap[Qt::Key_Space] = "Space"; keyMap[Qt::Key_Backspace] = "Backspace"; keyMap[Qt::Key_MediaPlay] = "Media Play"; keyMap[Qt::Key_MediaStop] = "Media Stop"; keyMap[Qt::Key_MediaPrevious] = "Media Previous"; keyMap[Qt::Key_MediaNext] = "Media Next"; keyMap[Qt::Key_MediaRecord] = "Media Record"; keyMap[Qt::Key_MediaLast] = "Media Last"; // doesn't work? keyMap[Qt::Key_VolumeUp] = "Volume Up"; keyMap[Qt::Key_VolumeDown] = "Volume Down"; keyMap[Qt::Key_VolumeMute] = "Volume Mute"; keyMap[Qt::Key_Back] = "Back"; keyMap[Qt::Key_Forward] = "Forward"; keyMap[Qt::Key_Stop] = "Stop"; } static QString keyToString(int k) { if ( k == Qt::Key_Shift || k == Qt::Key_Control || k == Qt::Key_Meta || k == Qt::Key_Alt || k == Qt::Key_AltGr ) return QString::null; initKeyMap(); qDebug() << "========keyToString========"; return keyMap[k]; } #else static QString keyToString(int k) { if ( k == Qt::Key_Shift || k == Qt::Key_Control || k == Qt::Key_Meta || k == Qt::Key_Alt || k == Qt::Key_AltGr ) return QString::null; return QKeySequence(k).toString(); } #endif static QStringList modToString(Qt::KeyboardModifiers k) { //qDebug("modToString: k: %x", (int) k); qDebug() << "========modToString========"; QStringList l; if ( k & Qt::ShiftModifier ) l << "Shift"; if ( k & Qt::ControlModifier ) l << "Ctrl"; if ( k & Qt::AltModifier ) l << "Alt"; if ( k & Qt::MetaModifier ) l << "Meta"; if ( k & Qt::GroupSwitchModifier ) ; if ( k & Qt::KeypadModifier ) ; return l; } ShortcutGetter::ShortcutGetter(/*bool isbtn, */QWidget *parent) : QDialog(parent) , drag_state(NOT_SCDRAGGING) , start_drag(QPoint(0,0)) { this->setWindowFlags(Qt::FramelessWindowHint); this->setFixedSize(438, 320); this->setStyleSheet("QDialog{border: 1px solid #121212;border-radius:1px;background-color:#1f1f1f;}"); this->setWindowIcon(QIcon(":/res/kylin-video.png"));//setWindowIcon( Images::icon("logo", 64) ); this->setAutoFillBackground(true); this->setMouseTracking(true); setWindowTitle(tr("Modify shortcut")); QVBoxLayout *vbox = new QVBoxLayout(this); vbox->setMargin(2); vbox->setSpacing(10); vbox->setContentsMargins(5,5,5,5); closeBtn = new QPushButton(this); closeBtn->setFixedSize(36, 36); closeBtn->setFocusPolicy(Qt::NoFocus); closeBtn->setStyleSheet("QPushButton{background-image:url(':/res/close_normal.png');border:0px;}QPushButton:hover{background:url(':/res/close_hover.png');}QPushButton:pressed{background:url(':/res/close_press.png');}"); vbox->addWidget(closeBtn, 0, Qt::AlignRight); // List and buttons added by rvm list = new QListWidget(this); list->setObjectName("ShortCutList"); connect(list, SIGNAL(currentRowChanged(int)), this, SLOT(rowChanged(int))); vbox->addWidget(list); QHBoxLayout *hbox = new QHBoxLayout; addItem = new QPushButton(/*Images::icon("plus"), "",*/ this); addItem->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); addItem->setFixedSize(40, 25); addItem->setFocusPolicy(Qt::NoFocus); addItem->setText("+"); addItem->setToolTip(tr("Add shortcut")); connect(addItem, SIGNAL(clicked()), this, SLOT(addItemClicked())); removeItem = new QPushButton(/*Images::icon("delete_normal"), "", */this); removeItem->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); removeItem->setFixedSize(40, 25); removeItem->setFocusPolicy(Qt::NoFocus); removeItem->setText("-"); removeItem->setToolTip(tr("Remove shortcut")); connect(removeItem, SIGNAL(clicked()), this, SLOT(removeItemClicked())); hbox->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding)); hbox->addWidget(addItem); hbox->addWidget(removeItem); vbox->addLayout(hbox); // if (isbtn) { // addItem->hide(); // removeItem->hide(); // } // else { // addItem->show(); // removeItem->show(); // } QLabel *l = new QLabel(this); l->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}"); l->setText(tr("Press the key combination you want to assign")); vbox->addWidget(l); leKey = new QLineEdit(this); leKey->setStyleSheet("QLineEdit {border:1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QLineEdit::hover{border: 1px solid #000000;background: #0a0a0a;font-family:方正黑体_GBK;font-size:12px;color:#ffffff;}QLineEdit:enabled {background: #0a0a0a;color:#999999;}QLineEdit:enabled:hover, QLineEdit:enabled:focus {background: #0a0a0a;color:#ffffff;}QLineEdit:!enabled {color: #383838;}"); // leKey->setStyleSheet("QLineEdit {height: 25px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QLineEdit::hover{border: 1px solid #000000;background: #0a0a0a;font-family:方正黑体_GBK;font-size:12px;color:#ffffff;}QLineEdit:enabled {background: #0a0a0a;color:#999999;}QLineEdit:enabled:hover, QLineEdit:enabled:focus {background: #0a0a0a;color:#ffffff;}QLineEdit:!enabled {color: #383838;}"); connect(leKey, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged(const QString &))); leKey->installEventFilter(this); vbox->addWidget(leKey); // Change by rvm: use a QDialogButtonBox instead of QPushButtons // and add a clear button setCaptureKeyboard(true); QDialogButtonBox * buttonbox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Reset ); QPushButton * clearbutton = buttonbox->button(QDialogButtonBox::Reset); clearbutton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); clearbutton->setFixedSize(91, 25); clearbutton->setText( tr("Clear") ); // clearbutton->setStyleSheet("QPushButton{font-size:12px;background:#ffffff;border:1px solid #0a9ff5;color:#000000;}QPushButton:hover{background-color:#ffffff;border:1px solid #3f96e4;color:#000000;} QPushButton:pressed{background-color:#ffffff;border:1px solid #3f96e4;color:#000000;}"); QPushButton * okbutton = buttonbox->button(QDialogButtonBox::Ok); okbutton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); okbutton->setFixedSize(91, 25); okbutton->setText( tr("OK") ); QPushButton * cancelbutton = buttonbox->button(QDialogButtonBox::Cancel); cancelbutton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #000000;color:#999999;}QPushButton:hover{background-color:#1f1f1f;border:1px solid #0f0f0f;color:#ffffff;} QPushButton:pressed{background-color:#0d0d0d;border:1px solid #000000;color:#ffffff;}"); cancelbutton->setFixedSize(91, 25); cancelbutton->setText(tr("Cancel")); QPushButton * captureButton = new QPushButton(tr("Capture"), this); captureButton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); captureButton->setFixedSize(91, 25); captureButton->setToolTip( tr("Capture keystrokes") ); captureButton->setCheckable( captureKeyboard() ); captureButton->setChecked( captureKeyboard() ); connect(captureButton, SIGNAL(toggled(bool)), this, SLOT(setCaptureKeyboard(bool))); connect(closeBtn, SIGNAL(clicked(bool)), this, SLOT(reject())); buttonbox->addButton(captureButton, QDialogButtonBox::ActionRole); connect( buttonbox, SIGNAL(accepted()), this, SLOT(accept()) ); connect( buttonbox, SIGNAL(rejected()), this, SLOT(reject()) ); connect( clearbutton, SIGNAL(clicked()), leKey, SLOT(clear()) ); vbox->addWidget(buttonbox); } void ShortcutGetter::setCaptureKeyboard(bool b) { capture = b; leKey->setReadOnly(b); leKey->setFocus(); } // Added by rvm void ShortcutGetter::rowChanged(int row) { QString s = list->item(row)->text(); leKey->setText(s); leKey->setFocus(); } // Added by rvm void ShortcutGetter::textChanged(const QString & text) { list->item(list->currentRow())->setText(text); } // Added by rvm void ShortcutGetter::addItemClicked() { qDebug("ShortcutGetter::addItemClicked"); list->addItem(""); list->setCurrentRow( list->count()-1 ); // Select last item } // Added by rvm void ShortcutGetter::removeItemClicked() { qDebug("ShortcutGetter::removeItemClicked"); if (list->count() > 1) { QListWidgetItem * i = list->takeItem( list->currentRow() ); if (i) delete i; } else { list->setCurrentRow(0); leKey->setText(""); } } QString ShortcutGetter::exec(const QString& s) { // Added by rvm QStringList shortcuts = s.split(", "); QString shortcut; foreach(shortcut, shortcuts) { list->addItem(shortcut.trimmed()); } list->setCurrentRow(0); bStop = false; if (QDialog::exec() == QDialog::Accepted) { // Added by rvm QStringList l; for (int n = 0; n < list->count(); n++) { QString shortcut = list->item(n)->text(); if (!shortcut.isEmpty()) { //qDebug("ShortcutGetter::exec: shortcut: '%s'", shortcut.toUtf8().constData()); l << shortcut; } } QString res = l.join(", "); if (res.isNull()) res = ""; return res; } return QString(); } bool ShortcutGetter::event(QEvent *e) { if (!capture) return QDialog::event(e); QString key; QStringList mods; QKeyEvent *k = static_cast(e); switch ( e->type() ) { case QEvent::KeyPress : if ( bStop ) { lKeys.clear(); bStop = false; } key = keyToString(k->key()); mods = modToString(k->modifiers()); //qDebug("event: key.count: %d, mods.count: %d", key.count(), mods.count()); if ( key.count() || mods.count() ) { if ( key.count() && !lKeys.contains(key) ) lKeys << key; foreach ( key, mods ) if ( !lKeys.contains(key) ) lKeys << key; } else { key = k->text(); if ( !lKeys.contains(key) ) lKeys << key; } setText(); break; case QEvent::KeyRelease : bStop = true; break; /* case QEvent::ShortcutOverride : leKey->setText("Shortcut override"); break; */ default: return QDialog::event(e); break; } return true; } bool ShortcutGetter::eventFilter(QObject *o, QEvent *e) { if (!capture) return QDialog::eventFilter(o, e); if ( e->type() == QEvent::KeyPress || e->type() ==QEvent::KeyRelease ) return event(e); else return QDialog::eventFilter(o, e); } void ShortcutGetter::setText() { QStringList seq; if ( lKeys.contains("Shift") ) seq << "Shift"; if ( lKeys.contains("Ctrl") ) seq << "Ctrl"; if ( lKeys.contains("Alt") ) seq << "Alt"; if ( lKeys.contains("Meta") ) seq << "Meta"; foreach ( QString s, lKeys ) { //qDebug("setText: s: '%s'", s.toUtf8().data()); if ( s != "Shift" && s != "Ctrl" && s != "Alt" && s != "Meta" ) seq << s; } leKey->setText(seq.join("+")); //leKey->selectAll(); } /*void ShortcutGetter::moveDialog(QPoint diff) { #if QT_VERSION >= 0x050000 // Move the window with some delay. // Seems to work better with Qt 5 static QPoint d; static int count = 0; d += diff; count++; if (count > 3) { QPoint new_pos = pos() + d; if (new_pos.y() < 0) new_pos.setY(0); if (new_pos.x() < 0) new_pos.setX(0); move(new_pos); count = 0; d = QPoint(0,0); } #else move(pos() + diff); #endif } bool ShortcutGetter::eventFilter( QObject * object, QEvent * event ) { // if (!capture) return QDialog::eventFilter(o, e); // if ( e->type() == QEvent::KeyPress || // e->type() ==QEvent::KeyRelease ) // return event(e); // else // return QDialog::eventFilter(o, e); QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { drag_state = NOT_SCDRAGGING; return false; } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_SCDRAGGING; return false; } drag_state = START_SCDRAGGING; start_drag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (drag_state != SCDRAGGING || mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_SCDRAGGING; return false; } // Stop dragging and eat event drag_state = NOT_SCDRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (drag_state == NOT_SCDRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { drag_state = NOT_SCDRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - start_drag; if (drag_state == START_SCDRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; drag_state = SCDRAGGING; } this->moveDialog(diff); start_drag = pos; event->accept(); return true; }*/ //#include "moc_shortcutgetter.cpp" kylin-video/src/smplayer/myactiongroup.h0000664000175000017500000000506713233751662017446 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _MYACTIONGROUP_H_ #define _MYACTIONGROUP_H_ #include #include #include "myaction.h" class MyActionGroup; //! This class makes easy to create actions for MyActionGroup class MyActionGroupItem : public MyAction { public: //! Creates a new item. /*! \a group is the group where the action will be added, \a data is the ID of the item. If \autoadd is true the action will be added to the parent (if it's a QWidget), so the shortcut could work. */ MyActionGroupItem( QObject * parent, MyActionGroup *group, const char * name, int data, bool autoadd = true ); //! Creates a new item. /*! \a text is the text that the item will have. */ MyActionGroupItem( QObject * parent, MyActionGroup *group, const QString & text, const char * name, int data, bool autoadd = true ); }; class QAction; //! MyActionGroup makes easier to create exclusive menus based on items //! with an integer data. class MyActionGroup : public QActionGroup { Q_OBJECT public: MyActionGroup ( QObject * parent ); //! Looks for the item which ID is \a ID and checks it void setChecked(int ID); //! Returns the ID of the item checked or -1 if none //! is checked int checked(); //! Remove all items. If \a remove is true the actions are also deleted. void clear(bool remove); //! Enable or disable all actions in the group void setActionsEnabled(bool); //! Adds all actions to the widget void addTo(QWidget *); //! Remove all actions from the widget void removeFrom(QWidget *); //! unchecks all items void uncheckAll(); signals: //! Emitted when an item has been checked void activated(int); protected slots: void itemTriggered(QAction *); }; #endif kylin-video/src/smplayer/urlhistory.h0000664000175000017500000000210613233751662016761 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _URLHISTORY_H_ #define _URLHISTORY_H_ #include "recents.h" class URLHistory : public Recents { public: URLHistory(); virtual ~URLHistory(); virtual void addUrl(QString url); //! Returns the URL virtual QString url(int n); }; #endif kylin-video/src/smplayer/global.cpp0000664000175000017500000000312213233751662016327 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "global.h" #include "preferences.h" #include #include "translator.h" #include "paths.h" #include #include #include QSettings * Global::settings = 0; Preferences * Global::pref = 0; Translator * Global::translator = 0; using namespace Global; void Global::global_init() { qDebug("global_init"); // Translator translator = new Translator(); // settings QString filename = Paths::iniPath() + "/kylin-video.ini"; settings = new QSettings(filename, QSettings::IniFormat ); settings->setIniCodec("UTF-8");//add by kobe // Preferences pref = new Preferences(); } void Global::global_end() { qDebug("global_end"); // delete delete pref; pref = 0; delete settings; delete translator; } kylin-video/src/smplayer/desktopinfo.cpp0000664000175000017500000000354213233751662017422 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "desktopinfo.h" #include #include QSize DesktopInfo::desktop_size(QWidget *w) { QDesktopWidget * dw = QApplication::desktop(); qDebug("DesktopInfo::desktop_size: primary screen: %d", dw->primaryScreen()); QSize s = dw->screen( dw->primaryScreen() )->size(); qDebug("DesktopInfo::desktop_size: size of primary screen: %d x %d", s.width(), s.height() ); //return dw->screen( dw->primaryScreen() )->size(); QRect r = dw->screenGeometry(w); qDebug("DesktopInfo::desktop_size: size of screen: %d x %d", r.width(), r.height() ); return QSize(r.width(), r.height() ); } double DesktopInfo::desktop_aspectRatio(QWidget *w) { QSize s = DesktopInfo::desktop_size(w); return (double) s.width() / s.height() ; } bool DesktopInfo::isInsideScreen(QWidget *w) { QDesktopWidget * dw = QApplication::desktop(); QRect r = dw->screenGeometry(w); qDebug("DesktopInfo::isInsideScreen: geometry of screen: x:%d y:%d w:%d h:%d", r.x(), r.y(), r.width(), r.height() ); return r.contains(w->pos()); } kylin-video/src/smplayer/kylinvideo.h0000664000175000017500000000365613233751662016725 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _KYLINVIDEO_H_ #define _KYLINVIDEO_H_ #include #include #include #include "merge/basegui.h" class KylinVideo : public QObject { Q_OBJECT public: enum ExitCode { ErrorArgument = -3, NoAction = -2, NoRunningInstance = -1, NoError = 0, NoExit = 1 }; KylinVideo(const QString &arch = QString::null, QObject * parent = 0); ~KylinVideo(); //! Process arguments. If ExitCode != NoExit the application must be exited. ExitCode processArgs(QStringList args); BaseGui * gui(); void start(); private slots: void changeGUI(); private: BaseGui * createGUI(QString arch_type); void deleteGUI(); void showInfo(); void deleteConfig(); static BaseGui * main_window; QStringList files_to_play; QString subtitle_file; QString media_title; //!< Force a title for the first file // Change position and size bool move_gui; QPoint gui_position; bool resize_gui; QSize gui_size; // Options to pass to gui int close_at_end; // -1 = not set, 1 = true, 0 false int start_in_fullscreen; // -1 = not set, 1 = true, 0 false QString arch_type; }; #endif kylin-video/src/smplayer/myslider.cpp0000664000175000017500000001355513214706400016717 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), Trolltech ASA (or its successors, if any) and the KDE Free Qt Foundation, which shall act as a proxy defined in Section 6 of version 3 of the license. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "myslider.h" #include #include #if CODE_FOR_CLICK == 0 #include #endif #if CODE_FOR_CLICK == 1 #include #include #endif MySlider::MySlider( QWidget * parent ) : QSlider(parent) { setOrientation( Qt::Horizontal ); } MySlider::~MySlider() { } #if CODE_FOR_CLICK == 1 // Function copied from qslider.cpp inline int MySlider::pick(const QPoint &pt) const { return orientation() == Qt::Horizontal ? pt.x() : pt.y(); } #if QT_VERSION < 0x040300 // Function copied from qslider.cpp and modified to make it compile void MySlider::initStyleOption(QStyleOptionSlider *option) const { if (!option) return; option->initFrom(this); option->subControls = QStyle::SC_None; option->activeSubControls = QStyle::SC_None; option->orientation = orientation(); option->maximum = maximum(); option->minimum = minimum(); option->tickPosition = (QSlider::TickPosition) tickPosition(); option->tickInterval = tickInterval(); option->upsideDown = (orientation() == Qt::Horizontal) ? (invertedAppearance() != (option->direction == Qt::RightToLeft)) : (!invertedAppearance()); option->direction = Qt::LeftToRight; // we use the upsideDown option instead option->sliderPosition = sliderPosition(); option->sliderValue = value(); option->singleStep = singleStep(); option->pageStep = pageStep(); if (orientation() == Qt::Horizontal) option->state |= QStyle::State_Horizontal; } #endif // Function copied from qslider.cpp and modified to make it compile int MySlider::pixelPosToRangeValue(int pos) const { QStyleOptionSlider opt; initStyleOption(&opt); QRect gr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, this); QRect sr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); int sliderMin, sliderMax, sliderLength; if (orientation() == Qt::Horizontal) { sliderLength = sr.width(); sliderMin = gr.x(); sliderMax = gr.right() - sliderLength + 1; } else { sliderLength = sr.height(); sliderMin = gr.y(); sliderMax = gr.bottom() - sliderLength + 1; } return QStyle::sliderValueFromPosition(minimum(), maximum(), pos - sliderMin, sliderMax - sliderMin, opt.upsideDown); } // Based on code from qslider.cpp void MySlider::mousePressEvent( QMouseEvent * e ) { if (e->button() == Qt::LeftButton) { QStyleOptionSlider opt; initStyleOption(&opt); const QRect sliderRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); const QPoint center = sliderRect.center() - sliderRect.topLeft(); // to take half of the slider off for the setSliderPosition call we use the center - topLeft if (!sliderRect.contains(e->pos())) { e->accept(); setSliderPosition(pixelPosToRangeValue(pick(e->pos() - center))); triggerAction(SliderMove); setRepeatAction(SliderNoAction); } else { QSlider::mousePressEvent(e); } } else { QSlider::mousePressEvent(e); } } #endif // CODE_FOR_CLICK == 1 #if CODE_FOR_CLICK == 2 void MySlider::mousePressEvent( QMouseEvent * e ) { // Swaps middle button click with left click if (e->button() == Qt::LeftButton) { QMouseEvent ev2(QEvent::MouseButtonRelease, e->pos(), e->globalPos(), Qt::MidButton, Qt::MidButton, e->modifiers()); QSlider::mousePressEvent(&ev2); } else if (e->button() == Qt::MidButton) { QMouseEvent ev2(QEvent::MouseButtonRelease, e->pos(), e->globalPos(), Qt::LeftButton, Qt::LeftButton, e->modifiers()); QSlider::mousePressEvent(&ev2); } else { QSlider::mousePressEvent(e); } } #endif // CODE_FOR_CLICK == 2 #if CODE_FOR_CLICK == 0 void MySlider::mousePressEvent( QMouseEvent * e ) { // FIXME: // The code doesn't work well with right to left layout, // so it's disabled. if (qApp->isRightToLeft()) { QSlider::mousePressEvent(e); return; } int range = maximum()-minimum(); int pos = (e->x() * range) / width(); //qDebug( "width: %d x: %d", width(), e->x()); //qDebug( "range: %d pos: %d value: %d", range, pos, value()); // Calculate how many positions takes the slider handle int metric = qApp->style()->pixelMetric( QStyle::PM_SliderLength ); double one_tick_pixels = (double) width() / range; int slider_handle_positions = (int) (metric / one_tick_pixels); /* qDebug("metric: %d", metric ); qDebug("one_tick_pixels :%f", one_tick_pixels); qDebug("width() :%d", width()); qDebug("slider_handle_positions: %d", slider_handle_positions); */ if (abs(pos - value()) > slider_handle_positions) { setValue(pos); emit sliderMoved( pos ); } else { QSlider::mousePressEvent(e); } } #endif //#include "moc_myslider.cpp" kylin-video/src/smplayer/prefwidget.cpp0000664000175000017500000000350013233751662017227 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "prefwidget.h" #include PrefWidget::PrefWidget(QWidget * parent, Qt::WindowFlags f ) : QWidget(parent, f) { requires_restart = false; help_message = ""; } PrefWidget::~PrefWidget() { } QString PrefWidget::sectionName() { return QString(); } QPixmap PrefWidget::sectionIcon() { return QPixmap(); } void PrefWidget::addSectionTitle(const QString & title) { help_message += "

"+title+"

"; } void PrefWidget::setWhatsThis( QWidget *w, const QString & title, const QString & text) { w->setWhatsThis(text); help_message += ""+title+"
"+text+"

"; w->setToolTip( ""+ text +"" ); } void PrefWidget::clearHelp() { help_message = "

" + sectionName() + "

"; } void PrefWidget::createHelp() { } // Language change stuff void PrefWidget::changeEvent(QEvent *e) { if (e->type() == QEvent::LanguageChange) { retranslateStrings(); } else { QWidget::changeEvent(e); } } void PrefWidget::retranslateStrings() { } kylin-video/src/smplayer/inforeader.h0000664000175000017500000000562313233751662016662 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef INFOREADER_H #define INFOREADER_H #include #include #include #include "config.h" class InfoData { public: InfoData() {}; InfoData( QString name, QString desc) { _name = name; _desc = desc; }; ~InfoData() {}; void setName(QString name) { _name = name; }; void setDesc(QString desc) { _desc = desc; }; QString name() const { return _name; }; QString desc() const { return _desc; }; bool operator<(const InfoData & other) const { return name() < other.name(); } bool operator==(const InfoData & other) const { return name() == other.name(); } private: QString _name, _desc; }; typedef QList InfoList; class InfoReader : QObject { Q_OBJECT public: InfoReader( QString mplayer_bin, QObject * parent = 0 ); ~InfoReader(); void setPlayerBin(const QString & bin); QString playerBin() { return mplayerbin; } void getInfo(); InfoList voList() { return vo_list; }; InfoList aoList() { return ao_list; }; InfoList demuxerList() { return demuxer_list; }; InfoList vcList() { return vc_list; }; InfoList acList() { return ac_list; }; QStringList vfList() { return vf_list; }; QStringList optionList() { return option_list; }; int mplayerSVN() { return mplayer_svn; }; QString mpvVersion() { return mpv_version; }; // QString mplayer2Version() { return mplayer2_version; }; // bool isMplayer2() { return is_mplayer2; }; bool isMPV() { return is_mpv; }; QString playerVersion(); //! Returns an InfoReader object. If it didn't exist before, one //! is created. static InfoReader * obj(const QString & mplayer_bin = QString::null); protected: QString mplayerbin; InfoList vo_list; InfoList ao_list; InfoList demuxer_list; InfoList vc_list; InfoList ac_list; QStringList vf_list; QStringList option_list; int mplayer_svn; QString mpv_version; // QString mplayer2_version; // bool is_mplayer2; bool is_mpv; private: static InfoReader * static_obj; static QStringList convertInfoListToList(InfoList l); static InfoList convertListToInfoList(QStringList l); }; #endif kylin-video/src/smplayer/mplayerprocess.h0000664000175000017500000001027513233751662017613 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _MPLAYERPROCESS_H_ #define _MPLAYERPROCESS_H_ #include #include "playerprocess.h" #include "mediadata.h" #include "config.h" class QStringList; class MplayerProcess : public PlayerProcess { Q_OBJECT public: MplayerProcess(QObject * parent = 0); ~MplayerProcess(); bool start(); // Command line options void setMedia(const QString & media, bool is_playlist = false); void setFixedOptions(); void disableInput(); void setOption(const QString & option_name, const QVariant & value = QVariant()); void addUserOption(const QString & option); void addVF(const QString & filter_name, const QVariant & value = QVariant()); void addAF(const QString & filter_name, const QVariant & value = QVariant()); void addStereo3DFilter(const QString & in, const QString & out); // void setSubStyles(const AssStyles & styles, const QString & assStylesFile = QString::null); // Slave commands void quit(); void setVolume(int v); void setOSD(int o); void setAudio(int ID); void setVideo(int ID); void setSubtitle(int type, int ID); void disableSubtitles(); void setSecondarySubtitle(int /*ID*/) {}; void disableSecondarySubtitles() {}; void setSubtitlesVisibility(bool b); void seek(double secs, int mode, bool precise); void mute(bool b); void setPause(bool b); void frameStep(); void frameBackStep(); void showOSDText(const QString & text, int duration, int level); void showFilenameOnOSD(); void showTimeOnOSD(); void setContrast(int value); void setBrightness(int value); void setHue(int value); void setSaturation(int value); void setGamma(int value); void setChapter(int ID); void setExternalSubtitleFile(const QString & filename); void setSubPos(int pos); void setSubScale(double value); void setSubStep(int value); //#ifdef MPV_SUPPORT // void seekSub(int value); //#endif void setSubForcedOnly(bool b); void setSpeed(double value); void enableKaraoke(bool b); void enableExtrastereo(bool b); void enableVolnorm(bool b, const QString & option); void setAudioEqualizer(const QString & values); void setAudioDelay(double delay); void setSubDelay(double delay); void setLoop(int v); void takeScreenshot(ScreenshotType t, bool include_subtitles = false); //#ifdef CAPTURE_STREAM // void switchCapturing(); //#endif void setTitle(int ID); void changeVF(const QString & filter, bool enable, const QVariant & option = QVariant()); void changeStereo3DFilter(bool enable, const QString & in, const QString & out); //#if DVDNAV_SUPPORT // void discSetMousePos(int x, int y); // void discButtonPressed(const QString & button_name); //#endif void setAspect(double aspect); void setFullscreen(bool b); //#if PROGRAM_SWITCH // void setTSProgram(int ID); //#endif void toggleDeinterlace(); void askForLength(); void setOSDScale(double value); void setChannelsFile(const QString &) {}; //#ifdef CAPTURE_STREAM // void setCaptureDirectory(const QString & dir); //#endif protected slots: void parseLine(QByteArray ba); void processFinished(int exitCode, QProcess::ExitStatus exitStatus); void gotError(QProcess::ProcessError); private: bool notified_mplayer_is_running; bool received_end_of_file; int last_sub_id; int mplayer_svn; #if NOTIFY_SUB_CHANGES SubTracks subs; bool subtitle_info_received; bool subtitle_info_changed; #endif #if NOTIFY_AUDIO_CHANGES Tracks audios; bool audio_info_changed; #endif int dvd_current_title; int br_current_title; }; #endif kylin-video/src/smplayer/tristatecombo.h0000664000175000017500000000253513233751662017422 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ /*! This class is to replace some QCheckBox with a combo with three possible values: true, false or autodetect */ #ifndef _TRISTATE_COMBO_H_ #define _TRISTATE_COMBO_H_ #include #include "preferences.h" class TristateCombo : public QComboBox { Q_OBJECT public: TristateCombo( QWidget * parent = 0 ); ~TristateCombo(); void setState( Preferences::OptionState v ); Preferences::OptionState state(); protected: virtual void retranslateStrings(); virtual void changeEvent( QEvent * event ); }; #endif kylin-video/src/smplayer/translator.cpp0000664000175000017500000000400013233751662017254 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "translator.h" #include "paths.h" #include #include #include #include Translator::Translator() { qApp->installTranslator( &app_trans ); qApp->installTranslator( &qt_trans ); } Translator::~Translator() { } bool Translator::loadCatalog(QTranslator & t, QString name, QString locale, QString dir) { QString s = name + "_" + locale; //.toLower(); bool r = t.load(s, dir); if (r) qDebug("Translator::loadCatalog: successfully loaded %s from %s", s.toUtf8().data(), dir.toUtf8().data()); else qDebug("Translator::loadCatalog: can't load %s from %s", s.toUtf8().data(), dir.toUtf8().data()); return r; } void Translator::load(/*QString locale*/) { QString locale = QLocale::system().name(); QString trans_path = Paths::translationPath(); QString qt_trans_path = Paths::qtTranslationPath(); // In linux try to load it first from app path (in case there's an updated // translation), if it fails it will try then from the Qt path. // if (! loadCatalog(qt_trans, "qt", locale, trans_path ) ) { loadCatalog(qt_trans, "qt", locale, qt_trans_path); // } loadCatalog(app_trans, "kylin-video", locale, trans_path); } kylin-video/src/smplayer/mplayerprocess.cpp0000664000175000017500000006523213233751662020151 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "mplayerprocess.h" #include #include #include #include "global.h" #include "preferences.h" #include "mplayerversion.h" #include "colorutils.h" #include using namespace Global; MplayerProcess::MplayerProcess(QObject * parent) : PlayerProcess(parent) , notified_mplayer_is_running(false) , received_end_of_file(false) , last_sub_id(-1) , mplayer_svn(-1) // Not found yet #if NOTIFY_SUB_CHANGES , subtitle_info_received(false) , subtitle_info_changed(false) #endif #if NOTIFY_AUDIO_CHANGES , audio_info_changed(false) #endif , dvd_current_title(-1) , br_current_title(-1) { player_id = PlayerID::MPLAYER; connect( this, SIGNAL(lineAvailable(QByteArray)), this, SLOT(parseLine(QByteArray)) ); connect( this, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished(int,QProcess::ExitStatus)) ); connect( this, SIGNAL(error(QProcess::ProcessError)), this, SLOT(gotError(QProcess::ProcessError)) ); } MplayerProcess::~MplayerProcess() { } bool MplayerProcess::start() { md.reset(); notified_mplayer_is_running = false; last_sub_id = -1; mplayer_svn = -1; // Not found yet received_end_of_file = false; #if NOTIFY_SUB_CHANGES subs.clear(); subtitle_info_received = false; subtitle_info_changed = false; #endif #if NOTIFY_AUDIO_CHANGES audios.clear(); audio_info_changed = false; #endif dvd_current_title = -1; br_current_title = -1; MyProcess::start(); return waitForStarted(); } static QRegExp rx_av("^[AV]: *([0-9,:.-]+)"); static QRegExp rx_frame("^[AV]:.* (\\d+)\\/.\\d+");// [0-9,.]+"); static QRegExp rx("^(.*)=(.*)"); #if !NOTIFY_AUDIO_CHANGES static QRegExp rx_audio_mat("^ID_AID_(\\d+)_(LANG|NAME)=(.*)"); #endif static QRegExp rx_video("^ID_VID_(\\d+)_(LANG|NAME)=(.*)"); static QRegExp rx_title("^ID_(DVD|BLURAY)_TITLE_(\\d+)_(LENGTH|CHAPTERS|ANGLES)=(.*)"); static QRegExp rx_chapters("^ID_CHAPTER_(\\d+)_(START|END|NAME)=(.+)"); static QRegExp rx_winresolution("^VO: \\[(.*)\\] (\\d+)x(\\d+) => (\\d+)x(\\d+)"); static QRegExp rx_ao("^AO: \\[(.*)\\]"); static QRegExp rx_paused("^ID_PAUSED"); #if !CHECK_VIDEO_CODEC_FOR_NO_VIDEO static QRegExp rx_novideo("^Video: no video"); #endif static QRegExp rx_cache("^Cache fill:.*"); static QRegExp rx_cache_empty("^Cache empty.*|^Cache not filling.*"); static QRegExp rx_create_index("^Generating Index:.*"); static QRegExp rx_play("^Starting playback..."); static QRegExp rx_connecting("^Connecting to .*"); static QRegExp rx_resolving("^Resolving .*"); static QRegExp rx_screenshot("^\\*\\*\\* screenshot '(.*)'"); static QRegExp rx_endoffile("^Exiting... \\(End of file\\)|^ID_EXIT=EOF"); static QRegExp rx_mkvchapters("\\[mkv\\] Chapter (\\d+) from"); static QRegExp rx_aspect2("^Movie-Aspect is ([0-9,.]+):1"); static QRegExp rx_fontcache("^\\[ass\\] Updating font cache|^\\[ass\\] Init"); static QRegExp rx_scanning_font("Scanning file"); static QRegExp rx_forbidden("Server returned 403: Forbidden"); //#if DVDNAV_SUPPORT //static QRegExp rx_dvdnav_switch_title("^DVDNAV, switched to title: (\\d+)"); //static QRegExp rx_dvdnav_length("^ANS_length=(.*)"); //static QRegExp rx_dvdnav_title_is_menu("^DVDNAV_TITLE_IS_MENU"); //static QRegExp rx_dvdnav_title_is_movie("^DVDNAV_TITLE_IS_MOVIE"); //#endif // VCD static QRegExp rx_vcd("^ID_VCD_TRACK_(\\d+)_MSF=(.*)"); // Audio CD static QRegExp rx_cdda("^ID_CDDA_TRACK_(\\d+)_MSF=(.*)"); //Subtitles static QRegExp rx_subtitle("^ID_(SUBTITLE|FILE_SUB|VOBSUB)_ID=(\\d+)"); static QRegExp rx_sid("^ID_(SID|VSID)_(\\d+)_(LANG|NAME)=(.*)"); static QRegExp rx_subtitle_file("^ID_FILE_SUB_FILENAME=(.*)"); // Audio #if NOTIFY_AUDIO_CHANGES static QRegExp rx_audio("^ID_AUDIO_ID=(\\d+)"); static QRegExp rx_audio_info("^ID_AID_(\\d+)_(LANG|NAME)=(.*)"); #endif //#if PROGRAM_SWITCH //static QRegExp rx_program("^PROGRAM_ID=(\\d+)"); //#endif //Clip info static QRegExp rx_clip_name("^ (name|title): (.*)", Qt::CaseInsensitive); static QRegExp rx_clip_artist("^ artist: (.*)", Qt::CaseInsensitive); static QRegExp rx_clip_author("^ author: (.*)", Qt::CaseInsensitive); static QRegExp rx_clip_album("^ album: (.*)", Qt::CaseInsensitive); static QRegExp rx_clip_genre("^ genre: (.*)", Qt::CaseInsensitive); static QRegExp rx_clip_date("^ (creation date|year): (.*)", Qt::CaseInsensitive); static QRegExp rx_clip_track("^ track: (.*)", Qt::CaseInsensitive); static QRegExp rx_clip_copyright("^ copyright: (.*)", Qt::CaseInsensitive); static QRegExp rx_clip_comment("^ comment: (.*)", Qt::CaseInsensitive); static QRegExp rx_clip_software("^ software: (.*)", Qt::CaseInsensitive); static QRegExp rx_stream_title("^.* StreamTitle='(.*)';"); static QRegExp rx_stream_title_and_url("^.* StreamTitle='(.*)';StreamUrl='(.*)';"); void MplayerProcess::parseLine(QByteArray ba) { // qDebug("MplayerProcess::parseLine: '%s'", ba.data() ); QString tag; QString value; //kobe 有些clip_name clip_author存在乱码,所以需要在此处处理一下 QTextCodec *str = QTextCodec::codecForName("GBK"); QString line = ColorUtils::stripColorsTags(str->toUnicode(ba)); // qDebug() << "AAAMplayerProcess::line:" << line; // Parse A: V: line //qDebug("%s", line.toUtf8().data()); if (rx_av.indexIn(line) > -1) { double sec = rx_av.cap(1).toDouble(); //qDebug("cap(1): '%s'", rx_av.cap(1).toUtf8().data() ); //qDebug("sec: %f", sec); #if NOTIFY_SUB_CHANGES if (notified_mplayer_is_running) { if (subtitle_info_changed) { // qDebug("MplayerProcess::parseLine: subtitle_info_changed"); subtitle_info_changed = false; subtitle_info_received = false; emit subtitleInfoChanged(subs); } if (subtitle_info_received) { // qDebug("MplayerProcess::parseLine: subtitle_info_received"); subtitle_info_received = false; emit subtitleInfoReceivedAgain(subs); } } #endif #if NOTIFY_AUDIO_CHANGES if (notified_mplayer_is_running) { if (audio_info_changed) { // qDebug("MplayerProcess::parseLine: audio_info_changed"); audio_info_changed = false; emit audioInfoChanged(audios); } } #endif if (!notified_mplayer_is_running) { // qDebug("MplayerProcess::parseLine: starting sec: %f", sec); if ( (md.n_chapters <= 0) && (dvd_current_title > 0) && (md.titles.find(dvd_current_title) != -1) ) { int idx = md.titles.find(dvd_current_title); md.n_chapters = md.titles.itemAt(idx).chapters(); // qDebug("MplayerProcess::parseLine: setting chapters to %d", md.n_chapters); } #if CHECK_VIDEO_CODEC_FOR_NO_VIDEO // Another way to find out if there's no video if (md.video_codec.isEmpty()) { md.novideo = true; emit receivedNoVideo(); } #endif emit receivedStartingTime(sec); emit mplayerFullyLoaded(); emit receivedCurrentFrame(0); // Ugly hack: set the frame counter to 0 notified_mplayer_is_running = true; } emit receivedCurrentSec( sec ); // Check for frame if (rx_frame.indexIn(line) > -1) { int frame = rx_frame.cap(1).toInt(); //qDebug(" frame: %d", frame); emit receivedCurrentFrame(frame); } } else { // Emulates mplayer version in Ubuntu: //if (line.startsWith("MPlayer 1.0rc1")) line = "MPlayer 2:1.0~rc1-0ubuntu13.1 (C) 2000-2006 MPlayer Team"; //if (line.startsWith("MPlayer2")) line = "mplayer2 d0305da (C) 2000-2012 MPlayer & mplayer2 teams"; //if (line.startsWith("MPlayer SVN")) line = "MPlayer svn r34540 (Ubuntu), built with gcc-4.6 (C) 2000-2012 MPlayer Team"; //if (line.startsWith("MPlayer SVN")) line = "MPlayer 1.2-4.8 (C) 2000-2015 MPlayer Team"; // Emulates unknown version //if (line.startsWith("MPlayer SVN")) line = "MPlayer lalksklsjjakksja"; emit lineAvailable(line); // qDebug("AAAA %s", line); // Parse other things // qDebug("========MplayerProcess::parseLine: '%s'", line.toUtf8().data() );//'*** screenshot '/home/lixiang/鍥剧墖/kylin_video_screenshots/shot0006.png' ***' //kobe Screenshot //MPV: //Debug: MPVProcess::parseLine: 'kobe test:Screenshot: '/home/lixiang/图片/smplayer_screenshots/cap_东成西就_00:00:03_01.jpg'' //Debug: MPVProcess::parseLine: 'kobe test:Screenshot: '/home/lixiang/图片/smplayer_screenshots/cap_东成西就_00:01:08_01.png'' //Mplayer //Debug: MplayerProcess::parseLine: screenshot: '/home/lixiang/图片/smplayer_screenshots/shot0001.png' //Debug: Core::displayScreenshotName: /home/lixiang/图片/smplayer_screenshots/shot0001.png if (rx_screenshot.indexIn(line) > -1) { QString shot = rx_screenshot.cap(1); // qDebug("MplayerProcess::parseLine: screenshot: '%s'", shot.toUtf8().data());//'/home/lixiang/鍥剧墖/kylin_video_screenshots/shot0006.png' emit receivedScreenshot(shot); } else // End of file if (rx_endoffile.indexIn(line) > -1) { // qDebug("MplayerProcess::parseLine: detected end of file"); if (!received_end_of_file) { // In case of playing VCDs or DVDs, maybe the first title // is not playable, so the GUI doesn't get the info about // available titles. So if we received the end of file // first let's pretend the file has started so the GUI can have // the data. if ( !notified_mplayer_is_running) { emit mplayerFullyLoaded(); } //emit receivedEndOfFile(); // Send signal once the process is finished, not now! received_end_of_file = true; } } else // Window resolution if (rx_winresolution.indexIn(line) > -1) { /* md.win_width = rx_winresolution.cap(4).toInt(); md.win_height = rx_winresolution.cap(5).toInt(); md.video_aspect = (double) md.win_width / md.win_height; */ int w = rx_winresolution.cap(4).toInt(); int h = rx_winresolution.cap(5).toInt(); emit receivedVO( rx_winresolution.cap(1) ); emit receivedWindowResolution( w, h ); //emit mplayerFullyLoaded(); } else #if !CHECK_VIDEO_CODEC_FOR_NO_VIDEO // No video if (rx_novideo.indexIn(line) > -1) { md.novideo = true; emit receivedNoVideo(); //emit mplayerFullyLoaded(); } else #endif // Pause if (rx_paused.indexIn(line) > -1) { emit receivedPause(); } // Stream title if (rx_stream_title_and_url.indexIn(line) > -1) { QString s = rx_stream_title_and_url.cap(1); QString url = rx_stream_title_and_url.cap(2); // qDebug("MplayerProcess::parseLine: stream_title: '%s'", s.toUtf8().data()); // qDebug("MplayerProcess::parseLine: stream_url: '%s'", url.toUtf8().data()); md.stream_title = s; md.stream_url = url; emit receivedStreamTitleAndUrl( s, url ); } else if (rx_stream_title.indexIn(line) > -1) { QString s = rx_stream_title.cap(1); // qDebug("MplayerProcess::parseLine: stream_title: '%s'", s.toUtf8().data()); md.stream_title = s; emit receivedStreamTitle( s ); } #if NOTIFY_SUB_CHANGES // Subtitles if ((rx_subtitle.indexIn(line) > -1) || (rx_sid.indexIn(line) > -1) || (rx_subtitle_file.indexIn(line) > -1)) { int r = subs.parse(line); //qDebug("MplayerProcess::parseLine: result of parse: %d", r); subtitle_info_received = true; if ((r == SubTracks::SubtitleAdded) || (r == SubTracks::SubtitleChanged)) subtitle_info_changed = true; } #endif #if NOTIFY_AUDIO_CHANGES // Audio if (rx_audio.indexIn(line) > -1) { int ID = rx_audio.cap(1).toInt(); // qDebug("MplayerProcess::parseLine: ID_AUDIO_ID: %d", ID); if (audios.find(ID) == -1) audio_info_changed = true; audios.addID( ID ); } if (rx_audio_info.indexIn(line) > -1) { int ID = rx_audio_info.cap(1).toInt(); QString lang = rx_audio_info.cap(3); QString t = rx_audio_info.cap(2); // qDebug("MplayerProcess::parseLine: Audio: ID: %d, Lang: '%s' Type: '%s'", // ID, lang.toUtf8().data(), t.toUtf8().data()); int idx = audios.find(ID); if (idx == -1) { // qDebug("MplayerProcess::parseLine: audio %d doesn't exist, adding it", ID); audio_info_changed = true; if ( t == "NAME" ) audios.addName(ID, lang); else audios.addLang(ID, lang); } else { // qDebug("MplayerProcess::parseLine: audio %d exists, modifing it", ID); if (t == "NAME") { //qDebug("MplayerProcess::parseLine: name of audio %d: %s", ID, audios.itemAt(idx).name().toUtf8().constData()); if (audios.itemAt(idx).name() != lang) { audio_info_changed = true; audios.addName(ID, lang); } } else { //qDebug("MplayerProcess::parseLine: language of audio %d: %s", ID, audios.itemAt(idx).lang().toUtf8().constData()); if (audios.itemAt(idx).lang() != lang) { audio_info_changed = true; audios.addLang(ID, lang); } } } } #endif //#if DVDNAV_SUPPORT // if (rx_dvdnav_switch_title.indexIn(line) > -1) { // int title = rx_dvdnav_switch_title.cap(1).toInt(); //// qDebug("MplayerProcess::parseLine: dvd title: %d", title); // emit receivedDVDTitle(title); // } // if (rx_dvdnav_length.indexIn(line) > -1) { // double length = rx_dvdnav_length.cap(1).toDouble(); //// qDebug("MplayerProcess::parseLine: length: %f", length); // if (length != md.duration) { // md.duration = length; // emit receivedDuration(length); // } // } // if (rx_dvdnav_title_is_menu.indexIn(line) > -1) { // emit receivedTitleIsMenu(); // } // if (rx_dvdnav_title_is_movie.indexIn(line) > -1) { // emit receivedTitleIsMovie(); // } //#endif if (rx_cache_empty.indexIn(line) > -1) { emit receivedCacheEmptyMessage(line); } // The following things are not sent when the file has started to play // (or if sent, smplayer will ignore anyway...) // So not process anymore, if video is playing to save some time if (notified_mplayer_is_running) { return; } if ( (mplayer_svn == -1) && ((line.startsWith("MPlayer ")) || (line.startsWith("MPlayer2 ", Qt::CaseInsensitive))) ) { mplayer_svn = MplayerVersion::mplayerVersion(line); qDebug("MplayerProcess::parseLine: MPlayer SVN: %d", mplayer_svn); if (mplayer_svn <= 0) { // qWarning("MplayerProcess::parseLine: couldn't parse mplayer version!"); emit failedToParseMplayerVersion(line); } } #if !NOTIFY_SUB_CHANGES // Subtitles if (rx_subtitle.indexIn(line) > -1) { md.subs.parse(line); } else if (rx_sid.indexIn(line) > -1) { md.subs.parse(line); } else if (rx_subtitle_file.indexIn(line) > -1) { md.subs.parse(line); } #endif // AO if (rx_ao.indexIn(line) > -1) { emit receivedAO( rx_ao.cap(1) ); } else #if !NOTIFY_AUDIO_CHANGES // Matroska audio if (rx_audio_mat.indexIn(line) > -1) { int ID = rx_audio_mat.cap(1).toInt(); QString lang = rx_audio_mat.cap(3); QString t = rx_audio_mat.cap(2); // qDebug("MplayerProcess::parseLine: Audio: ID: %d, Lang: '%s' Type: '%s'", // ID, lang.toUtf8().data(), t.toUtf8().data()); if ( t == "NAME" ) md.audios.addName(ID, lang); else md.audios.addLang(ID, lang); } else #endif //#if PROGRAM_SWITCH // // Program // if (rx_program.indexIn(line) > -1) { // int ID = rx_program.cap(1).toInt(); //// qDebug("MplayerProcess::parseLine: Program: ID: %d", ID); // md.programs.addID( ID ); // } // else //#endif // Video tracks if (rx_video.indexIn(line) > -1) { int ID = rx_video.cap(1).toInt(); QString lang = rx_video.cap(3); QString t = rx_video.cap(2); // qDebug("MplayerProcess::parseLine: Video: ID: %d, Lang: '%s' Type: '%s'", // ID, lang.toUtf8().data(), t.toUtf8().data()); if ( t == "NAME" ) md.videos.addName(ID, lang); else md.videos.addLang(ID, lang); } else // Matroshka chapters if (rx_mkvchapters.indexIn(line)!=-1) { int c = rx_mkvchapters.cap(1).toInt(); // qDebug("MplayerProcess::parseLine: mkv chapters: %d", c); if ((c+1) > md.n_chapters) { md.n_chapters = c+1; // qDebug("MplayerProcess::parseLine: chapters set to: %d", md.n_chapters); } } // else // // Chapter info // if (rx_chapters.indexIn(line) > -1) { // int const chap_ID = rx_chapters.cap(1).toInt(); // QString const chap_type = rx_chapters.cap(2); // QString const chap_value = rx_chapters.cap(3); // double const chap_value_d = chap_value.toDouble(); // if(!chap_type.compare("START")) // { // md.chapters.addStart(chap_ID, chap_value_d/1000); // qDebug("MplayerProcess::parseLine: Chapter (ID: %d) starts at: %g",chap_ID, chap_value_d/1000); // } // else if(!chap_type.compare("END")) // { // md.chapters.addEnd(chap_ID, chap_value_d/1000); // qDebug("MplayerProcess::parseLine: Chapter (ID: %d) ends at: %g",chap_ID, chap_value_d/1000); // } // else if(!chap_type.compare("NAME")) // { // md.chapters.addName(chap_ID, chap_value); // qDebug("MplayerProcess::parseLine: Chapter (ID: %d) name: %s",chap_ID, chap_value.toUtf8().data()); // } // } else // VCD titles if (rx_vcd.indexIn(line) > -1 ) { int ID = rx_vcd.cap(1).toInt(); QString length = rx_vcd.cap(2); //md.titles.addID( ID ); md.titles.addName( ID, length ); } else // Audio CD titles if (rx_cdda.indexIn(line) > -1 ) { int ID = rx_cdda.cap(1).toInt(); QString length = rx_cdda.cap(2); double duration = 0; QRegExp r("(\\d+):(\\d+):(\\d+)"); if ( r.indexIn(length) > -1 ) { duration = r.cap(1).toInt() * 60; duration += r.cap(2).toInt(); } md.titles.addID( ID ); /* QString name = QString::number(ID) + " (" + length + ")"; md.titles.addName( ID, name ); */ md.titles.addDuration( ID, duration ); } else // DVD/Bluray titles if (rx_title.indexIn(line) > -1) { int ID = rx_title.cap(2).toInt(); QString t = rx_title.cap(3); if (t=="LENGTH") { double length = rx_title.cap(4).toDouble(); // qDebug("MplayerProcess::parseLine: Title: ID: %d, Length: '%f'", ID, length); md.titles.addDuration(ID, length); } else if (t=="CHAPTERS") { int chapters = rx_title.cap(4).toInt(); // qDebug("MplayerProcess::parseLine: Title: ID: %d, Chapters: '%d'", ID, chapters); md.titles.addChapters(ID, chapters); } else if (t=="ANGLES") { int angles = rx_title.cap(4).toInt(); // qDebug("MplayerProcess::parseLine: Title: ID: %d, Angles: '%d'", ID, angles); md.titles.addAngles(ID, angles); } } else // Catch cache messages if (rx_cache.indexIn(line) > -1) { emit receivedCacheMessage(line); } else // Creating index if (rx_create_index.indexIn(line) > -1) { emit receivedCreatingIndex(line); } else // Catch connecting message if (rx_connecting.indexIn(line) > -1) { emit receivedConnectingToMessage(line); } else // Catch resolving message if (rx_resolving.indexIn(line) > -1) { emit receivedResolvingMessage(line); } else // Aspect ratio for old versions of mplayer if (rx_aspect2.indexIn(line) > -1) { md.video_aspect = rx_aspect2.cap(1).toDouble(); // qDebug("MplayerProcess::parseLine: md.video_aspect set to %f", md.video_aspect); } else // Clip info //QString::trimmed() is used for removing leading and trailing whitespaces //Some .mp3 files contain tags with starting and ending whitespaces //Unfortunately MPlayer gives us leading and trailing whitespaces, Winamp for example doesn't show them // Name if (rx_clip_name.indexIn(line) > -1) { // QTextCodec *tc = QTextCodec::codecForName("GBK"); // QString tmpQStr = tc->toUnicode(ba); // qDebug() << "AAAMplayerProcess::tmpQStr:" << tmpQStr; // qDebug() << "AAAMplayerProcess::parseLine:" << line; QString s = rx_clip_name.cap(2).trimmed(); // qDebug("AAA===================MplayerProcess::parseLine: clip_name: '%s'", s.toUtf8().data()); md.clip_name = s; } else // Artist if (rx_clip_artist.indexIn(line) > -1) { QString s = rx_clip_artist.cap(1).trimmed(); // qDebug("AAA===================MplayerProcess::parseLine: clip_artist: '%s'", s.toUtf8().data()); md.clip_artist = s; } else // Author if (rx_clip_author.indexIn(line) > -1) { QString s = rx_clip_author.cap(1).trimmed(); // qDebug("AAA===================MplayerProcess::parseLine: clip_author: '%s'", s.toUtf8().data()); md.clip_author = s; } else // Album if (rx_clip_album.indexIn(line) > -1) { QString s = rx_clip_album.cap(1).trimmed(); // qDebug("MplayerProcess::parseLine: clip_album: '%s'", s.toUtf8().data()); md.clip_album = s; } else // Genre if (rx_clip_genre.indexIn(line) > -1) { QString s = rx_clip_genre.cap(1).trimmed(); qDebug("MplayerProcess::parseLine: clip_genre: '%s'", s.toUtf8().data()); md.clip_genre = s; } else // Date if (rx_clip_date.indexIn(line) > -1) { QString s = rx_clip_date.cap(2).trimmed(); // qDebug("MplayerProcess::parseLine: clip_date: '%s'", s.toUtf8().data()); md.clip_date = s; } else // Track if (rx_clip_track.indexIn(line) > -1) { QString s = rx_clip_track.cap(1).trimmed(); // qDebug("MplayerProcess::parseLine: clip_track: '%s'", s.toUtf8().data()); md.clip_track = s; } else // Copyright if (rx_clip_copyright.indexIn(line) > -1) { QString s = rx_clip_copyright.cap(1).trimmed(); // qDebug("MplayerProcess::parseLine: clip_copyright: '%s'", s.toUtf8().data()); md.clip_copyright = s; } else // Comment if (rx_clip_comment.indexIn(line) > -1) { QString s = rx_clip_comment.cap(1).trimmed(); // qDebug("MplayerProcess::parseLine: clip_comment: '%s'", s.toUtf8().data()); md.clip_comment = s; } else // Software if (rx_clip_software.indexIn(line) > -1) { QString s = rx_clip_software.cap(1).trimmed(); // qDebug("MplayerProcess::parseLine: clip_software: '%s'", s.toUtf8().data()); md.clip_software = s; } else if (rx_fontcache.indexIn(line) > -1) { //qDebug("MplayerProcess::parseLine: updating font cache"); emit receivedUpdatingFontCache(); } else if (rx_scanning_font.indexIn(line) > -1) { emit receivedScanningFont(line); } else if (rx_forbidden.indexIn(line) > -1) { // qDebug("MplayerProcess::parseLine: 403 forbidden"); emit receivedForbiddenText(); } else // Catch starting message /* pos = rx_play.indexIn(line); if (pos > -1) { emit mplayerFullyLoaded(); } */ //Generic things if (rx.indexIn(line) > -1) { tag = rx.cap(1); value = rx.cap(2); //qDebug("MplayerProcess::parseLine: tag: %s, value: %s", tag.toUtf8().data(), value.toUtf8().data()); #if !NOTIFY_AUDIO_CHANGES // Generic audio if (tag == "ID_AUDIO_ID") { int ID = value.toInt(); // qDebug("MplayerProcess::parseLine: ID_AUDIO_ID: %d", ID); md.audios.addID( ID ); } else #endif // Video if (tag == "ID_VIDEO_ID") { int ID = value.toInt(); // qDebug("MplayerProcess::parseLine: ID_VIDEO_ID: %d", ID); md.videos.addID( ID ); } else if (tag == "ID_LENGTH") { md.duration = value.toDouble(); // qDebug("MplayerProcess::parseLine: md.duration set to %f", md.duration); // Use the bluray title length if duration is 0 if (md.duration == 0 && br_current_title != -1) { int i = md.titles.find(br_current_title); if (i != -1) { double duration = md.titles.itemAt(i).duration(); // qDebug("MplayerProcess::parseLine: using the br title length: %f", duration); md.duration = duration; } } } else if (tag == "ID_VIDEO_WIDTH") { md.video_width = value.toInt(); // qDebug("MplayerProcess::parseLine: md.video_width set to %d", md.video_width); } else if (tag == "ID_VIDEO_HEIGHT") { md.video_height = value.toInt(); // qDebug("MplayerProcess::parseLine: md.video_height set to %d", md.video_height); } else if (tag == "ID_VIDEO_ASPECT") { md.video_aspect = value.toDouble(); if ( md.video_aspect == 0.0 ) { // I hope width & height are already set. md.video_aspect = (double) md.video_width / md.video_height; } // qDebug("MplayerProcess::parseLine: md.video_aspect set to %f", md.video_aspect); } else if (tag == "ID_DVD_DISC_ID") { md.dvd_id = value; // qDebug("MplayerProcess::parseLine: md.dvd_id set to '%s'", md.dvd_id.toUtf8().data()); } else if (tag == "ID_DEMUXER") { md.demuxer = value; } else if (tag == "ID_VIDEO_FORMAT") { md.video_format = value; } else if (tag == "ID_AUDIO_FORMAT") { md.audio_format = value; } else if (tag == "ID_VIDEO_BITRATE") { md.video_bitrate = value.toInt(); } else if (tag == "ID_VIDEO_FPS") { // qDebug() << "0612$$$$$$$$$$$$$$$$$$$$$$$ video_fps=" << value; md.video_fps = value; } else if (tag == "ID_AUDIO_BITRATE") { md.audio_bitrate = value.toInt(); } else if (tag == "ID_AUDIO_RATE") { md.audio_rate = value.toInt(); } else if (tag == "ID_AUDIO_NCH") { md.audio_nch = value.toInt(); } else if (tag == "ID_VIDEO_CODEC") { md.video_codec = value; } else if (tag == "ID_AUDIO_CODEC") { md.audio_codec = value; } else if (tag == "ID_CHAPTERS") { md.n_chapters = value.toInt(); // #ifdef TOO_CHAPTERS_WORKAROUND if (md.n_chapters > 1000) { // qDebug("MplayerProcess::parseLine: warning too many chapters: %d", md.n_chapters); // qDebug(" chapters will be ignored"); md.n_chapters = 0; } // #endif } else if (tag == "ID_DVD_CURRENT_TITLE") { dvd_current_title = value.toInt(); } else if (tag == "ID_BLURAY_CURRENT_TITLE") { br_current_title = value.toInt(); } } } } // Called when the process is finished void MplayerProcess::processFinished(int exitCode, QProcess::ExitStatus exitStatus) { qDebug("MplayerProcess::processFinished: exitCode: %d, status: %d", exitCode, (int) exitStatus); // Send this signal before the endoffile one, otherwise // the playlist will start to play next file before all // objects are notified that the process has exited. emit processExited(); if (received_end_of_file) emit receivedEndOfFile(); } void MplayerProcess::gotError(QProcess::ProcessError error) { qDebug("MplayerProcess::gotError: %d", (int) error); } #include "mplayeroptions.cpp" //#include "moc_mplayerprocess.cpp" kylin-video/src/smplayer/shutdowndialog.ui0000664000175000017500000000523713214706400017753 0ustar fengfeng ShutdownDialog 0 0 472 162 Shutting down computer 100 0 icon Qt::AlignCenter 0 0 text true Qt::Horizontal Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox buttonBox accepted() ShutdownDialog accept() 250 189 250 105 buttonBox rejected() ShutdownDialog reject() 250 189 250 105 kylin-video/src/smplayer/helper.cpp0000664000175000017500000001662513233751662016362 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "helper.h" #include #include #include #include #include #include #include #include "config.h" #include "extensions.h" #if EXTERNAL_SLEEP #include #else #include #endif #if !EXTERNAL_SLEEP class Sleeper : public QThread { public: static void sleep(unsigned long secs) {QThread::sleep(secs);} static void msleep(unsigned long msecs) { //qDebug("sleeping..."); QThread::msleep(msecs); //qDebug("finished"); } static void usleep(unsigned long usecs) {QThread::usleep(usecs);} }; #endif /* QString Helper::dvdForPref(const QString & dvd_id, int title) { return QString("DVD_%1_%2").arg(dvd_id).arg(title); } */ QString Helper::formatTime(int secs) { bool negative = (secs < 0); secs = abs(secs); int t = secs; int hours = (int) t / 3600; t -= hours*3600; int minutes = (int) t / 60; t -= minutes*60; int seconds = t; //qDebug() << "Helper::formatTime:" << hours << ":" << minutes << ":" << seconds; return QString("%1%2:%3:%4").arg(negative ? "-" : "").arg(hours, 2, 10, QChar('0')).arg(minutes, 2, 10, QChar('0')).arg(seconds, 2, 10, QChar('0')); } QString Helper::timeForJumps(int secs) { int minutes = (int) secs / 60; int seconds = secs % 60; if (minutes==0) { return QObject::tr("%n second(s)", "", seconds); } else { if (seconds==0) return QObject::tr("%n minute(s)", "", minutes); else { QString m = QObject::tr("%n minute(s)", "", minutes); QString s = QObject::tr("%n second(s)", "", seconds); return QObject::tr("%1 and %2").arg(m).arg(s); } } } void Helper::msleep(int ms) { #if EXTERNAL_SLEEP //qDebug("Helper::msleep: %d (using usleep)", ms); usleep(ms*1000); #else //qDebug("Helper::msleep: %d (using QThread::msleep)", ms); Sleeper::msleep( ms ); #endif } QString Helper::changeSlashes(QString filename) { // Only change if file exists (it's a local file) if (QFileInfo(filename).exists()) return filename.replace('/', '\\'); else return filename; } bool Helper::directoryContainsDVD(QString directory) { //qDebug("Helper::directoryContainsDVD: '%s'", directory.latin1()); QDir dir(directory); QStringList l = dir.entryList(); bool valid = false; for (int n=0; n < l.count(); n++) { //qDebug(" * entry %d: '%s'", n, l[n].toUtf8().data()); if (l[n].toLower() == "video_ts") valid = true; } return valid; } int Helper::qtVersion() { QRegExp rx("(\\d+)\\.(\\d+)\\.(\\d+)"); QString v(qVersion()); int r = 0; if (rx.indexIn(v) > -1) { int n1 = rx.cap(1).toInt(); int n2 = rx.cap(2).toInt(); int n3 = rx.cap(3).toInt(); r = n1 * 1000 + n2 * 100 + n3; } qDebug("Helper::qtVersion: %d", r); return r; } QStringList Helper::searchForConsecutiveFiles(const QString & initial_file) { qDebug("Helper::searchForConsecutiveFiles: initial_file: '%s'", initial_file.toUtf8().constData()); QStringList files_to_add; QStringList matching_files; QFileInfo fi(initial_file); QString basename = fi.completeBaseName(); QString extension = fi.suffix(); QString path = fi.absolutePath(); QDir dir(path); dir.setFilter(QDir::Files); dir.setSorting(QDir::Name); QRegExp rx("(\\d+)"); int digits; int current_number; int pos = 0; QString next_name; bool next_found = false; qDebug("Helper::searchForConsecutiveFiles: trying to find consecutive files"); while ( ( pos = rx.indexIn(basename, pos) ) != -1 ) { qDebug("Helper::searchForConsecutiveFiles: captured: %s",rx.cap(1).toUtf8().constData()); digits = rx.cap(1).length(); current_number = rx.cap(1).toInt() + 1; next_name = basename.left(pos) + QString("%1").arg(current_number, digits, 10, QLatin1Char('0')); next_name.replace(QRegExp("([\\[\\]?*])"), "[\\1]"); next_name += "*." + extension; qDebug("Helper::searchForConsecutiveFiles: next name = %s",next_name.toUtf8().constData()); matching_files = dir.entryList((QStringList)next_name); if ( !matching_files.isEmpty() ) { next_found = true; break; } qDebug("Helper::searchForConsecutiveFiles: pos = %d",pos); pos += digits; } if (next_found) { qDebug("Helper::searchForConsecutiveFiles: adding consecutive files"); while ( !matching_files.isEmpty() ) { qDebug("Helper::searchForConsecutiveFiles: '%s' exists, added to the list", matching_files[0].toUtf8().constData()); files_to_add << path + "/" + matching_files[0]; current_number++; next_name = basename.left(pos) + QString("%1").arg(current_number, digits, 10, QLatin1Char('0')); next_name.replace(QRegExp("([\\[\\]?*])"), "[\\1]"); next_name += "*." + extension; matching_files = dir.entryList((QStringList)next_name); qDebug("Helper::searchForConsecutiveFiles: looking for '%s'", next_name.toUtf8().constData()); } } return files_to_add; } QStringList Helper::filesInDirectory(const QString & initial_file, const QStringList & filter) { qDebug("Helper::filesInDirectory: initial_file: %s", initial_file.toUtf8().constData()); //qDebug() << "Helper::filesInDirectory: filter:" << filter; QFileInfo fi(initial_file); QString current_file = fi.fileName(); QString path = fi.absolutePath(); QDir d(path); QStringList all_files = d.entryList(filter, QDir::Files); QStringList r; for (int n = 0; n < all_files.count(); n++) { //if (all_files[n] != current_file) { QString s = path +"/" + all_files[n]; r << s; //} } //qDebug() << "Helper::filesInDirectory: result:" << r; return r; } QStringList Helper::filesForPlaylist(const QString & initial_file, Preferences::AutoAddToPlaylistFilter filter) { QStringList res; if (filter == Preferences::ConsecutiveFiles) { res = searchForConsecutiveFiles(initial_file); } else { Extensions e; QStringList exts; switch (filter) { case Preferences::VideoFiles: exts = e.video().forDirFilter(); break; case Preferences::AudioFiles: exts = e.audio().forDirFilter(); break; case Preferences::MultimediaFiles: exts = e.multimedia().forDirFilter(); break; default: ; } if (!exts.isEmpty()) res = Helper::filesInDirectory(initial_file, exts); } return res; } #ifdef Q_OS_LINUX QString Helper::findExecutable(const QString & name) { QByteArray env = qgetenv("PATH"); QStringList search_paths = QString::fromLocal8Bit(env.constData()).split(':', QString::SkipEmptyParts); for (int n = 0; n < search_paths.count(); n++) { QString candidate = search_paths[n] + "/" + name; qDebug("Helper::findExecutable: candidate: %s", candidate.toUtf8().constData()); QFileInfo info(candidate); if (info.isFile() && info.isExecutable()) { qDebug("Helper::findExecutable: executable found: %s", candidate.toUtf8().constData()); return candidate; } } return QString::null; } #endif kylin-video/src/smplayer/myslider.h0000664000175000017500000000314113214706400016352 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), Trolltech ASA (or its successors, if any) and the KDE Free Qt Foundation, which shall act as a proxy defined in Section 6 of version 3 of the license. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef MYSLIDER_H #define MYSLIDER_H #include #include "config.h" #define CODE_FOR_CLICK 1 // 0 = old code, 1 = code copied from QSlider, 2 = button swap class QTimer; class MySlider : public QSlider { Q_OBJECT public: MySlider( QWidget * parent ); ~MySlider(); protected: void mousePressEvent ( QMouseEvent * event ); #if CODE_FOR_CLICK == 1 inline int pick(const QPoint &pt) const; int pixelPosToRangeValue(int pos) const; #if QT_VERSION < 0x040300 void initStyleOption(QStyleOptionSlider *option) const; #endif #endif }; #endif kylin-video/src/smplayer/preferences.h0000664000175000017500000001410513233751662017040 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _PREFERENCES_H_ #define _PREFERENCES_H_ /* Global settings */ #include #include #include #include "config.h" class Recents; class URLHistory; class Preferences { public: enum OSD { None = 0, Seek = 1, SeekTimer = 2, SeekTimerTotal = 3 }; enum OnTop { NeverOnTop = 0, AlwaysOnTop = 1, WhilePlayingOnTop = 2 }; enum PlayOrder { OrderPlay = 0, RandomPlay = 1, ListLoopPlay = 2 }; enum Resize { Never = 0, Always = 1, Afterload = 2 }; enum Priority { Realtime = 0, High = 1, AboveNormal = 2, Normal = 3, BelowNormal = 4, Idle = 5 }; enum WheelFunction { DoNothing = 1, Seeking = 2, Volume = 4, Zoom = 8, ChangeSpeed = 16 }; enum OptionState { Detect = -1, Disabled = 0, Enabled = 1 }; enum H264LoopFilter { LoopDisabled = 0, LoopEnabled = 1, LoopDisabledOnHD = 2 }; enum AutoAddToPlaylistFilter { NoFiles = 0, VideoFiles = 1, AudioFiles = 2, MultimediaFiles = 3, ConsecutiveFiles = 4 }; Q_DECLARE_FLAGS(WheelFunctions, WheelFunction); Preferences(); virtual ~Preferences(); virtual void reset(); void save(); void load(); void setupScreenshotFolder(); /* ******* General ******* */ QString mplayer_bin; QString vo; // video output QString ao; // audio output bool use_screenshot; QString screenshot_template; QString screenshot_format; QString screenshot_directory; // Video bool use_direct_rendering; bool use_double_buffer; bool use_soft_video_eq; bool use_slices; struct VDPAU_settings {//kobe 20170706 bool ffh264vdpau; bool ffmpeg12vdpau; bool ffwmv3vdpau; bool ffvc1vdpau; bool ffodivxvdpau; bool disable_video_filters; } vdpau; // Audio bool use_soft_vol; int softvol_max; // Global volume options bool global_volume; int volume; bool mute; bool autosync; int autosync_factor; int min_step; //) QString hwdec; //!< hardware video decoding (mpv only) int cache_for_files; int cache_for_streams; /* ********* Subtitles ********* */ QString subcp; // -subcp bool use_enca; QString enca_lang; bool sub_visibility; /* ******** Advanced ******** */ bool use_idx; //!< Use -idx bool use_lavf_demuxer; bool log_mplayer; bool verbose_log; // bool autosave_mplayer_log; // QString mplayer_log_saveto; bool log_smplayer; QString log_filter; bool save_smplayer_log; //! If true it will autoload edl files with the same name of the file //! to play bool use_edl_files; //! Preferred connection method: ipv4 or ipv6 bool prefer_ipv4; //! Windows only. If true, smplayer will pass short filenames to mplayer. //! To workaround a bug in mplayer. bool use_short_pathnames; //! If false, -brightness, -contrast and so on, won't be passed to //! mplayer. It seems that some graphic cards don't support those options. bool change_video_equalizer_on_startup; //! If true, smplayer will use the prefix pausing_keep_force to keep //! the pause on slave commands. This experimental prefix was added //! in mplayer svn r27665. bool use_pausing_keep_force; OptionState use_correct_pts; //!< Pass -correct-pts to mplayer QString actions_to_run; //!< List of actions to run every time a video loads. //! Show file tag in window title bool show_tag_in_window_title; int time_to_kill_mplayer; /* ********* GUI stuff ********* */ bool fullscreen; OnTop stay_on_top; PlayOrder play_order; int resize_method; //!< Mainwindow resize method int wheel_function; WheelFunctions wheel_function_cycle; bool wheel_function_seeking_reverse; // Configurable seeking int seeking1; // By default 10s int seeking2; // By default 1m int seeking3; // By default 10m int seeking4; // For mouse wheel, by default 30s // bool update_while_seeking; int time_slider_drag_delay; //!< Pause the current file when the main window is not visible bool pause_when_hidden; bool preview_when_playing; AutoAddToPlaylistFilter media_to_add_to_playlist; QString playlist_key; QString next_key; QString prev_key; /* *********** Directories *********** */ QString latest_dir; //!< Directory of the latest file loaded /* ************** Initial values ************** */ bool initial_postprocessing; //!< global postprocessing filter bool initial_volnorm; int initial_audio_channels; /* ************ MPlayer info ************ */ int mplayer_detected_version; //!< Latest version of mplayer parsed //! Version of mplayer supplied by the user which will be used if //! the version can't be parsed from mplayer output int mplayer_user_supplied_version; /* ******* History ******* */ Recents * history_recents; URLHistory * history_urls; }; Q_DECLARE_OPERATORS_FOR_FLAGS(Preferences::WheelFunctions) #endif kylin-video/src/smplayer/translator.h0000664000175000017500000000222013233751662016723 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _TRANSLATOR_H_ #define _TRANSLATOR_H_ #include #include class Translator { public: Translator(); ~Translator(); void load(); protected: static bool loadCatalog(QTranslator & t, QString name, QString locale, QString dir); QTranslator app_trans; QTranslator qt_trans; }; #endif kylin-video/src/smplayer/infofile.h0000664000175000017500000000245113233751662016333 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _INFOFILE_H_ #define _INFOFILE_H_ #include "mediadata.h" #include class InfoFile { public: InfoFile(); ~InfoFile(); QString getInfo(MediaData md); protected: QString title(QString text); QString openPar(QString text); QString closePar(); QString openItem(); QString closeItem(); QString addItem( QString tag, QString value ); int row; private: inline QString tr( const char * sourceText, const char * comment = 0, int n = -1 ); }; #endif kylin-video/src/smplayer/subtracks.cpp0000664000175000017500000001357413233751662017104 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "subtracks.h" #include "mediasettings.h" #include SubTracks::SubTracks() { index = 0; } SubTracks::~SubTracks() { } void SubTracks::clear() { subs.clear(); } void SubTracks::add( SubData::Type t, int ID ) { SubData d; d.setType(t); d.setID(ID); subs.append(d); } void SubTracks::list() { for (unsigned int n=0; n < subs.count(); n++) { qDebug("SubTracks::list: item %d: type: %d ID: %d lang: '%s' name: '%s' filename: '%s'", n, subs[n].type(), subs[n].ID(), subs[n].lang().toUtf8().data(), subs[n].name().toUtf8().data(), subs[n].filename().toUtf8().data() ); } } void SubTracks::listNames() { for (unsigned int n=0; n < subs.count(); n++) { qDebug("SubTracks::list: item %d: '%s'", n, subs[n].displayName().toUtf8().data() ); } } int SubTracks::numItems() { return subs.count(); } bool SubTracks::existsItemAt(int n) { return ((n > 0) && (n < numItems())); } int SubTracks::findLang(QString expr) { qDebug( "SubTracks::findLang: '%s'", expr.toUtf8().data()); QRegExp rx( expr ); int res_id = -1; for (int n=0; n < numItems(); n++) { qDebug("SubTracks::findLang: lang #%d '%s'", n, subs[n].lang().toUtf8().data()); if (rx.indexIn( subs[n].lang() ) > -1) { qDebug("SubTracks::findLang: found preferred lang!"); res_id = n; break; } } return res_id; } // Return first subtitle or the user preferred (if found) // or none if there's no subtitles int SubTracks::selectOne(QString preferred_lang, int default_sub) { int sub = MediaSettings::SubNone; if (numItems() > 0) { sub = 0; // First subtitle if (existsItemAt(default_sub)) { sub = default_sub; } // Check if one of the subtitles is the user preferred. if (!preferred_lang.isEmpty()) { int res = findLang( preferred_lang ); if (res != -1) sub = res; } } return sub; } int SubTracks::find( SubData::Type t, int ID ) { for (unsigned int n=0; n < subs.count(); n++) { if ( ( subs[n].type() == t ) && ( subs[n].ID() == ID ) ) { return n; } } qDebug("SubTracks::find: item type: %d, ID: %d doesn't exist", t, ID); return -1; } SubData SubTracks::findItem( SubData::Type t, int ID ) { SubData sub; int n = find(t,ID); if ( n != -1 ) return subs[n]; else return sub; } SubData SubTracks::itemAt( int n ) { if (n >= 0 && n < subs.count()) { return subs[n]; } else { qWarning("SubTracks::itemAt: %d out of range!", n); qWarning("SubTracks::itemAt: returning an empty sub to avoid a crash"); qWarning("SubTracks::itemAt: this shouldn't happen, report a bug if you see this"); SubData empty_sub; return empty_sub; } } bool SubTracks::changeLang( SubData::Type t, int ID, QString lang ) { int f = find(t,ID); if (f == -1) return false; subs[f].setLang(lang); return true; } bool SubTracks::changeName( SubData::Type t, int ID, QString name ) { int f = find(t,ID); if (f == -1) return false; subs[f].setName(name); return true; } bool SubTracks::changeFilename( SubData::Type t, int ID, QString filename ) { int f = find(t,ID); if (f == -1) return false; subs[f].setFilename(filename); return true; } SubTracks::ParseResult SubTracks::parse(QString text) { qDebug("SubTracks::parse: '%s'", text.toUtf8().data()); ParseResult result = SubtitleUnchanged; QRegExp rx_subtitle("^ID_(SUBTITLE|FILE_SUB|VOBSUB)_ID=(\\d+)"); QRegExp rx_sid("^ID_(SID|VSID)_(\\d+)_(LANG|NAME)=(.*)"); QRegExp rx_subtitle_file("^ID_FILE_SUB_FILENAME=(.*)"); if (rx_subtitle.indexIn(text) > -1) { int ID = rx_subtitle.cap(2).toInt(); QString type = rx_subtitle.cap(1); SubData::Type t; if (type == "FILE_SUB") t = SubData::File; else if (type == "VOBSUB") t = SubData::Vob; else t = SubData::Sub; if (find(t, ID) > -1) { qWarning("SubTracks::parse: subtitle type: %d, ID: %d already exists!", t, ID); } else { add(t,ID); result = SubtitleAdded; } } else if (rx_sid.indexIn(text) > -1) { int ID = rx_sid.cap(2).toInt(); QString value = rx_sid.cap(4); QString attr = rx_sid.cap(3); QString type = rx_sid.cap(1); SubData::Type t = SubData::Sub; if (type == "VSID") t = SubData::Vob; if (find(t, ID) == -1) { qWarning("SubTracks::parse: subtitle type: %d, ID: %d doesn't exist!", t, ID); } else { if (attr=="NAME") changeName(t,ID, value); else changeLang(t,ID, value); result = SubtitleChanged; } } else if (rx_subtitle_file.indexIn(text) > -1) { QString file = rx_subtitle_file.cap(1); if ( subs.count() > 0 ) { int last = subs.count() -1; if (subs[last].type() == SubData::File) { subs[last].setFilename( file ); result = SubtitleChanged; } } } return result; } /* void SubTracks::test() { process("ID_SUBTITLE_ID=0"); process("ID_SID_0_NAME=Arabic"); process("ID_SID_0_LANG=ara"); process("ID_SUBTITLE_ID=1"); process("ID_SID_1_NAME=Catalan"); process("ID_SID_1_LANG=cat"); process("ID_VOBSUB_ID=0"); process("ID_VSID_0_LANG=en"); process("ID_VOBSUB_ID=1"); process("ID_VSID_1_LANG=fr"); process("ID_FILE_SUB_ID=1"); process("ID_FILE_SUB_FILENAME=./lost313_es.sub"); list(); listNames(); } */ kylin-video/src/smplayer/myprocess.cpp0000664000175000017500000000741413233751662017123 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "myprocess.h" #include MyProcess::MyProcess(QObject * parent) : QProcess(parent) { clearArguments(); setProcessChannelMode( QProcess::MergedChannels ); connect(this, SIGNAL(readyReadStandardOutput()), this, SLOT(readStdOut())); connect(this, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(procFinished())); // Test splitArguments //QStringList l = MyProcess::splitArguments("-opt 1 hello \"56 67\" wssx -ios"); } void MyProcess::clearArguments() { program = ""; arg.clear(); } bool MyProcess::isRunning() { return (state() == QProcess::Running); } void MyProcess::addArgument(const QString & a) { if (program.isEmpty()) { program = a; } else { arg.append(a); } } QStringList MyProcess::arguments() { QStringList l = arg; l.prepend(program); return l; } void MyProcess::start() { remaining_output.clear(); QProcess::start(program, arg); } void MyProcess::readStdOut() { genericRead( readAllStandardOutput() ); } void MyProcess::readTmpFile() { genericRead( temp_file.readAll() ); } void MyProcess::genericRead(QByteArray buffer) { QByteArray ba = remaining_output + buffer; int start = 0; int from_pos = 0; int pos = canReadLine(ba, from_pos); //qDebug("MyProcess::read: pos: %d", pos); while ( pos > -1 ) { // Readline //QByteArray line = ba.left(pos); QByteArray line = ba.mid(start, pos-start); //ba = ba.mid(pos+1); from_pos = pos + 1; start = from_pos; emit lineAvailable(line); pos = canReadLine(ba, from_pos); } remaining_output = ba.mid(from_pos); } int MyProcess::canReadLine(const QByteArray & ba, int from) { int pos1 = ba.indexOf('\n', from); int pos2 = ba.indexOf('\r', from); //qDebug("MyProcess::canReadLine: pos2: %d", pos2); if ( (pos1 == -1) && (pos2 == -1) ) return -1; int pos = pos1; if ( (pos1 != -1) && (pos2 != -1) ) { /* if (pos2 == (pos1+1)) pos = pos2; // \r\n else */ if (pos1 < pos2) pos = pos1; else pos = pos2; } else { if (pos1 == -1) pos = pos2; else if (pos2 == -1) pos = pos1; } return pos; } /*! Do some clean up, and be sure that all output has been read. */ void MyProcess::procFinished() { qDebug("MyProcess::procFinished"); if ( bytesAvailable() > 0 ) readStdOut(); if ( temp_file.bytesAvailable() > 0 ) readTmpFile(); temp_file.close(); } QStringList MyProcess::splitArguments(const QString & args) { qDebug("MyProcess::splitArguments: '%s'", args.toUtf8().constData()); QStringList l; bool opened_quote = false; int init_pos = 0; for (int n = 0; n < args.length(); n++) { if ((args[n] == QChar(' ')) && (!opened_quote)) { l.append(args.mid(init_pos, n - init_pos)); init_pos = n+1; } else if (args[n] == QChar('\"')) opened_quote = !opened_quote; if (n == args.length()-1) { l.append(args.mid(init_pos, (n - init_pos)+1)); } } for (int n = 0; n < l.count(); n++) { qDebug("MyProcess::splitArguments: arg: %d '%s'", n, l[n].toUtf8().constData()); } return l; } //#include "moc_myprocess.cpp" kylin-video/src/smplayer/titletracks.h0000664000175000017500000000446113233751662017074 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _TITLETRACKS_H_ #define _TITLETRACKS_H_ #include #include "helper.h" /* Class to store info about DVD titles */ class TitleData { public: TitleData() { _name = ""; _duration = 0; _ID = -1; _chapters = 0; _angles = 0; }; ~TitleData() {}; void setName( const QString & n ) { _name = n; }; void setDuration( double d ) { _duration = d; }; void setChapters( int n ) { _chapters = n; }; void setAngles( int n ) { _angles = n; }; void setID( int id ) { _ID = id; }; QString name() const { return _name; }; double duration() const { return _duration; }; int chapters() const { return _chapters; }; int angles() const { return _angles; }; int ID() const { return _ID; }; QString displayName() const { QString dname = ""; if (!_name.isEmpty()) { dname = _name; } else dname = QString::number(_ID); if (_duration > 0) { dname += " ("+ Helper::formatTime( (int) _duration ) +")"; } return dname; }; protected: QString _name; double _duration; int _chapters; int _angles; int _ID; }; class TitleTracks { public: TitleTracks(); ~TitleTracks(); void clear(); void list(); void addName(int ID, QString name); void addDuration(int ID, double duration); void addChapters(int ID, int n); void addAngles(int ID, int n); void addID(int ID); int numItems(); bool existsItemAt(int n); TitleData itemAt(int n); TitleData item(int ID); int find(int ID); protected: typedef QMap TitleMap; TitleMap tm; }; #endif kylin-video/src/smplayer/playerprocess.cpp0000664000175000017500000000332013233751662017762 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "playerprocess.h" #include #include #include #include "mpvprocess.h" #include "mplayerprocess.h" PlayerProcess::PlayerProcess(QObject * parent) : MyProcess(parent) { #if NOTIFY_SUB_CHANGES qRegisterMetaType("SubTracks"); #endif #if NOTIFY_AUDIO_CHANGES qRegisterMetaType("Tracks"); #endif } void PlayerProcess::writeToStdin(QString text) { if (isRunning()) { write( text.toLocal8Bit() + "\n"); } else { qWarning("PlayerProcess::writeToStdin: process not running"); } } PlayerProcess * PlayerProcess::createPlayerProcess(const QString & player_bin, QObject * parent) { PlayerProcess * proc = 0; if (PlayerID::player(player_bin) == PlayerID::MPLAYER) {//kobe:go here proc = new MplayerProcess(parent); } else { proc = new MPVProcess(parent); } return proc; } //#include "moc_playerprocess.cpp" kylin-video/src/smplayer/cleanconfig.h0000664000175000017500000000035413214706400016775 0ustar fengfeng #ifndef CLEANCONFIG_H #define CLEANCONFIG_H #include #include class CleanConfig { public: static void clean(const QString &config_path); private: static QStringList listDir(const QString &path); }; #endif kylin-video/src/smplayer/mediasettings.cpp0000664000175000017500000004745213233751662017745 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "mediasettings.h" #include "preferences.h" #include "global.h" #include using namespace Global; MediaSettings::MediaSettings() { reset(); } MediaSettings::~MediaSettings() { } void MediaSettings::reset() { // qDebug("MediaSettings::reset"); current_sec = 0; //current_sub_id = SubNone; current_sub_id = NoneSelected; //#ifdef MPV_SUPPORT // current_secondary_sub_id = NoneSelected; //#endif //#if PROGRAM_SWITCH // current_program_id = NoneSelected; //#endif current_video_id = NoneSelected; current_audio_id = NoneSelected; current_title_id = NoneSelected; current_chapter_id = NoneSelected; current_angle_id = NoneSelected; aspect_ratio_id = AspectAuto; //fullscreen = false; volume = 40;//pref->initial_volume; mute = false; external_subtitles = ""; external_subtitles_fps = SFPS_None; external_audio = ""; sub_delay=0; audio_delay=0; sub_pos = 100;//pref->initial_sub_pos; // 100% by default sub_scale = 5;//pref->initial_sub_scale; sub_scale_ass = 1;//pref->initial_sub_scale_ass; closed_caption_channel = 0; // disabled brightness = 0;//pref->initial_brightness; contrast = 0;//pref->initial_contrast; gamma = 0;//pref->initial_gamma; hue = 0;//pref->initial_hue; saturation = 0;//pref->initial_saturation; // audio_equalizer = pref->initial_audio_equalizer; speed = 1.0; phase_filter = false; deblock_filter = false; dering_filter = false; gradfun_filter = false; noise_filter = false; postprocessing_filter = pref->initial_postprocessing; upscaling_filter = false; current_denoiser = NoDenoise; current_unsharp = 0; stereo3d_in = "none"; stereo3d_out = QString::null; current_deinterlacer = NoDeinterlace;//pref->initial_deinterlace; add_letterbox = false; //#ifdef MPLAYER_SUPPORT karaoke_filter = false; extrastereo_filter = false; //#endif volnorm_filter = pref->initial_volnorm; audio_use_channels = pref->initial_audio_channels; //ChDefault; // (0) stereo_mode = MediaSettings::Stereo;//pref->initial_stereo_mode; //Stereo; // (0) zoom_factor = 1.0;//pref->initial_zoom_factor; // 1.0; starting_time = -1; // Not set yet. rotate = NoRotate; flip = false; mirror = false; loop = false; A_marker = -1; B_marker = -1; //#ifdef BOOKMARKS // // Initialize bookmarks // bookmarks.clear(); // bookmarks.insert(0, ""); //#endif is264andHD = false; current_demuxer = "unknown"; forced_demuxer=""; if (pref->use_lavf_demuxer) forced_demuxer = "lavf"; forced_video_codec=""; forced_audio_codec=""; original_demuxer=""; original_video_codec=""; original_audio_codec=""; // mplayer_additional_options=""; // mplayer_additional_video_filters=""; // mplayer_additional_audio_filters=""; win_width=400; win_height=300; } double MediaSettings::win_aspect() { return (double) win_width / win_height; } double MediaSettings::aspectToNum(Aspect aspect) { double asp; switch (aspect) { case MediaSettings::AspectNone: asp = 0; break; case MediaSettings::Aspect43: asp = (double) 4 / 3; break; case MediaSettings::Aspect169: asp = (double) 16 / 9; break; case MediaSettings::Aspect149: asp = (double) 14 / 9; break; case MediaSettings::Aspect1610: asp = (double) 16 / 10; break; case MediaSettings::Aspect54: asp = (double) 5 / 4; break; case MediaSettings::Aspect235: asp = 2.35; break; case MediaSettings::Aspect11: asp = 1; break; case MediaSettings::Aspect32: asp = (double) 3 / 2; break; case MediaSettings::Aspect1410: asp = (double) 14 / 10; break; case MediaSettings::Aspect118: asp = (double) 11 / 8; break; case MediaSettings::AspectAuto: asp = win_aspect(); break; default: asp = win_aspect(); // qWarning("MediaSettings::aspectToNum: invalid aspect: %d", aspect); } return asp; } QString MediaSettings::aspectToString(Aspect aspect) { QString asp_name; switch (aspect) { case MediaSettings::AspectNone: asp_name = QObject::tr("disabled", "aspect_ratio"); break; case MediaSettings::Aspect43: asp_name = "4:3"; break; case MediaSettings::Aspect169: asp_name = "16:9"; break; case MediaSettings::Aspect149: asp_name = "14:9"; break; case MediaSettings::Aspect1610: asp_name = "16:10"; break; case MediaSettings::Aspect54: asp_name = "5:4"; break; case MediaSettings::Aspect235: asp_name = "2.35:1"; break; case MediaSettings::Aspect11: asp_name = "1:1"; break; case MediaSettings::Aspect32: asp_name = "3:2"; break; case MediaSettings::Aspect1410: asp_name = "14:10"; break; case MediaSettings::Aspect118: asp_name = "11:8"; break; case MediaSettings::AspectAuto: asp_name = QObject::tr("auto", "aspect_ratio"); break; default: asp_name = QObject::tr("unknown", "aspect_ratio"); } return asp_name; } void MediaSettings::list() { // qDebug("MediaSettings::list"); // qDebug(" current_sec: %f", current_sec); // qDebug(" current_sub_id: %d", current_sub_id); ////#ifdef MPV_SUPPORT //// qDebug(" current_secondary_sub_id: %d", current_secondary_sub_id); ////#endif //#if PROGRAM_SWITCH // qDebug(" current_program_id: %d", current_program_id); //#endif // qDebug(" current_video_id: %d", current_video_id); // qDebug(" current_audio_id: %d", current_audio_id); // qDebug(" current_title_id: %d", current_title_id); // qDebug(" current_chapter_id: %d", current_chapter_id); // qDebug(" current_angle_id: %d", current_angle_id); // qDebug(" aspect_ratio_id: %d", aspect_ratio_id); // //qDebug(" fullscreen: %d", fullscreen); // qDebug(" volume: %d", volume); // qDebug(" mute: %d", mute); // qDebug(" external_subtitles: '%s'", external_subtitles.toUtf8().data()); // qDebug(" external_subtitles_fps: '%d'", external_subtitles_fps); // qDebug(" external_audio: '%s'", external_audio.toUtf8().data()); // qDebug(" sub_delay: %d", sub_delay); // qDebug(" audio_delay: %d", sub_delay); // qDebug(" sub_pos: %d", sub_pos); // qDebug(" sub_scale: %f", sub_scale); // qDebug(" sub_scale_ass: %f", sub_scale_ass); // qDebug(" closed_caption_channel: %d", closed_caption_channel); // qDebug(" brightness: %d", brightness); // qDebug(" contrast: %d", contrast); // qDebug(" gamma: %d", gamma); // qDebug(" hue: %d", hue); // qDebug(" saturation: %d", saturation); // qDebug(" speed: %f", speed); // qDebug(" phase_filter: %d", phase_filter); // qDebug(" deblock_filter: %d", deblock_filter); // qDebug(" dering_filter: %d", dering_filter); // qDebug(" gradfun_filter: %d", gradfun_filter); // qDebug(" noise_filter: %d", noise_filter); // qDebug(" postprocessing_filter: %d", postprocessing_filter); // qDebug(" upscaling_filter: %d", upscaling_filter); // qDebug(" current_denoiser: %d", current_denoiser); // qDebug(" current_unsharp: %d", current_unsharp); // qDebug(" stereo3d_in: %s", stereo3d_in.toUtf8().constData()); // qDebug(" stereo3d_out: %s", stereo3d_out.toUtf8().constData()); // qDebug(" current_deinterlacer: %d", current_deinterlacer); // qDebug(" add_letterbox: %d", add_letterbox); //#ifdef MPLAYER_SUPPORT // qDebug(" karaoke_filter: %d", karaoke_filter); // qDebug(" extrastereo_filter: %d", extrastereo_filter); //#endif // qDebug(" volnorm_filter: %d", volnorm_filter); // qDebug(" audio_use_channels: %d", audio_use_channels); // qDebug(" stereo_mode: %d", stereo_mode); // qDebug(" zoom_factor: %f", zoom_factor); // qDebug(" rotate: %d", rotate); // qDebug(" flip: %d", flip); // qDebug(" mirror: %d", mirror); // qDebug(" loop: %d", loop); // qDebug(" A_marker: %d", A_marker); // qDebug(" B_marker: %d", B_marker); // qDebug(" current_demuxer: '%s'", current_demuxer.toUtf8().data()); // qDebug(" forced_demuxer: '%s'", forced_demuxer.toUtf8().data()); // qDebug(" forced_video_codec: '%s'", forced_video_codec.toUtf8().data()); // qDebug(" forced_audio_codec: '%s'", forced_video_codec.toUtf8().data()); // qDebug(" original_demuxer: '%s'", original_demuxer.toUtf8().data()); // qDebug(" original_video_codec: '%s'", original_video_codec.toUtf8().data()); // qDebug(" original_audio_codec: '%s'", original_video_codec.toUtf8().data()); // qDebug(" mplayer_additional_options: '%s'", mplayer_additional_options.toUtf8().data()); // qDebug(" mplayer_additional_video_filters: '%s'", mplayer_additional_video_filters.toUtf8().data()); // qDebug(" mplayer_additional_audio_filters: '%s'", mplayer_additional_audio_filters.toUtf8().data()); // qDebug(" win_width: %d", win_width); // qDebug(" win_height: %d", win_height); // qDebug(" win_aspect(): %f", win_aspect()); // qDebug(" starting_time: %f", starting_time); // qDebug(" is264andHD: %d", is264andHD); } //#ifndef NO_USE_INI_FILES void MediaSettings::save(QSettings * set, int player_id) { // qDebug("MediaSettings::save"); set->beginGroup("player_" + QString::number(player_id)); set->setValue( "current_demuxer", current_demuxer); set->setValue( "forced_demuxer", forced_demuxer); set->setValue( "forced_video_codec", forced_video_codec); set->setValue( "forced_audio_codec", forced_audio_codec); set->setValue( "original_demuxer", original_demuxer); set->setValue( "original_video_codec", original_video_codec); set->setValue( "original_audio_codec", original_audio_codec); // Save the tracks ID in a demuxer section QString demuxer_section = QString("demuxer_%1").arg(current_demuxer); if (!forced_demuxer.isEmpty()) { demuxer_section = QString("demuxer_%1").arg(forced_demuxer); } set->beginGroup(demuxer_section); set->setValue( "current_sub_id", current_sub_id ); // #ifdef MPV_SUPPORT // set->setValue( "current_secondary_sub_id", current_secondary_sub_id ); // #endif // #if PROGRAM_SWITCH // set->setValue( "current_program_id", current_program_id ); // #endif set->setValue( "current_video_id", current_video_id ); set->setValue( "current_audio_id", current_audio_id ); set->endGroup(); set->endGroup(); // player set->setValue( "current_sec", current_sec ); set->setValue( "current_title_id", current_title_id ); set->setValue( "current_chapter_id", current_chapter_id ); set->setValue( "current_angle_id", current_angle_id ); set->setValue( "aspect_ratio", aspect_ratio_id ); //set->setValue( "fullscreen", fullscreen ); set->setValue( "volume", volume ); set->setValue( "mute", mute ); set->setValue( "external_subtitles", external_subtitles ); set->setValue( "external_subtitles_fps", external_subtitles_fps ); set->setValue( "external_audio", external_audio ); set->setValue( "sub_delay", sub_delay); set->setValue( "audio_delay", audio_delay); set->setValue( "sub_pos", sub_pos); set->setValue( "sub_scale", sub_scale); set->setValue( "sub_scale_ass", sub_scale_ass); set->setValue( "closed_caption_channel", closed_caption_channel); set->setValue( "brightness", brightness); set->setValue( "contrast", contrast); set->setValue( "gamma", gamma); set->setValue( "hue", hue); set->setValue( "saturation", saturation); // set->setValue("audio_equalizer", audio_equalizer ); set->setValue( "speed", speed); set->setValue( "phase_filter", phase_filter); set->setValue( "deblock_filter", deblock_filter); set->setValue( "dering_filter", dering_filter); set->setValue( "gradfun_filter", gradfun_filter); set->setValue( "noise_filter", noise_filter); set->setValue( "postprocessing_filter", postprocessing_filter); set->setValue( "upscaling_filter", upscaling_filter); set->setValue( "current_denoiser", current_denoiser); set->setValue( "current_unsharp", current_unsharp); set->setValue( "stereo3d_in", stereo3d_in); set->setValue( "stereo3d_out", stereo3d_out); set->setValue( "current_deinterlacer", current_deinterlacer); set->setValue( "add_letterbox", add_letterbox ); //#ifdef MPLAYER_SUPPORT set->setValue( "karaoke_filter", karaoke_filter); set->setValue( "extrastereo_filter", extrastereo_filter); //#endif set->setValue( "volnorm_filter", volnorm_filter); set->setValue( "audio_use_channels", audio_use_channels); set->setValue( "stereo_mode", stereo_mode); set->setValue( "zoom_factor", zoom_factor); set->setValue( "rotate", rotate ); set->setValue( "flip", flip); set->setValue( "mirror", mirror); set->setValue( "loop", loop); set->setValue( "A_marker", A_marker); set->setValue( "B_marker", B_marker); //#ifdef BOOKMARKS // // Save bookmarks // bool save_bookmarks = true; // QMap::const_iterator i = bookmarks.constBegin(); // if (bookmarks.count() == 1 && i.key() == 0) save_bookmarks = false; // if (save_bookmarks) { // set->beginWriteArray("bookmarks"); // int count = 0; // while (i != bookmarks.constEnd()) { // set->setArrayIndex(count); // set->setValue("time", i.key()); // set->setValue("name", i.value()); // i++; // count++; // } // set->endArray(); // } //#endif // set->setValue( "mplayer_additional_options", mplayer_additional_options); // set->setValue( "mplayer_additional_video_filters", mplayer_additional_video_filters); // set->setValue( "mplayer_additional_audio_filters", mplayer_additional_audio_filters); set->setValue( "win_width", win_width ); set->setValue( "win_height", win_height ); set->setValue( "starting_time", starting_time ); set->setValue( "is264andHD", is264andHD ); } void MediaSettings::load(QSettings * set, int player_id) { // qDebug("MediaSettings::load"); set->beginGroup("player_" + QString::number(player_id)); current_demuxer = set->value( "current_demuxer", current_demuxer).toString(); forced_demuxer = set->value( "forced_demuxer", forced_demuxer).toString(); if (pref->use_lavf_demuxer) forced_demuxer = "lavf"; forced_video_codec = set->value( "forced_video_codec", forced_video_codec).toString(); forced_audio_codec = set->value( "forced_audio_codec", forced_audio_codec).toString(); original_demuxer = set->value( "original_demuxer", original_demuxer).toString(); original_video_codec = set->value( "original_video_codec", original_video_codec).toString(); original_audio_codec = set->value( "original_audio_codec", original_audio_codec).toString(); // Load the tracks ID from a demuxer section QString demuxer_section = QString("demuxer_%1").arg(current_demuxer); if (!forced_demuxer.isEmpty()) { demuxer_section = QString("demuxer_%1").arg(forced_demuxer); } // qDebug("MediaSettings::load: demuxer_section: %s", demuxer_section.toUtf8().constData()); set->beginGroup(demuxer_section); current_sub_id = set->value( "current_sub_id", NoneSelected ).toInt(); // #ifdef MPV_SUPPORT // current_secondary_sub_id = set->value( "current_secondary_sub_id", NoneSelected ).toInt(); // #endif // #if PROGRAM_SWITCH // current_program_id = set->value( "current_program_id", NoneSelected ).toInt(); // #endif current_video_id = set->value( "current_video_id", NoneSelected ).toInt(); current_audio_id = set->value( "current_audio_id", NoneSelected ).toInt(); set->endGroup(); set->endGroup(); // player current_sec = set->value( "current_sec", current_sec).toDouble(); current_title_id = set->value( "current_title_id", current_title_id ).toInt(); current_chapter_id = set->value( "current_chapter_id", current_chapter_id ).toInt(); current_angle_id = set->value( "current_angle_id", current_angle_id ).toInt(); aspect_ratio_id = set->value( "aspect_ratio", aspect_ratio_id ).toInt(); //fullscreen = set->value( "fullscreen", fullscreen ).toBool(); volume = set->value( "volume", volume ).toInt(); mute = set->value( "mute", mute ).toBool(); external_subtitles = set->value( "external_subtitles", external_subtitles ).toString(); external_subtitles_fps = set->value( "external_subtitles_fps", external_subtitles_fps ).toInt(); external_audio = set->value( "external_audio", external_audio ).toString(); sub_delay = set->value( "sub_delay", sub_delay).toInt(); audio_delay = set->value( "audio_delay", audio_delay).toInt(); sub_pos = set->value( "sub_pos", sub_pos).toInt(); sub_scale = set->value( "sub_scale", sub_scale).toDouble(); sub_scale_ass = set->value( "sub_scale_ass", sub_scale_ass).toDouble(); closed_caption_channel = set->value( "closed_caption_channel", closed_caption_channel).toInt(); brightness = set->value( "brightness", brightness).toInt(); contrast = set->value( "contrast", contrast).toInt(); gamma = set->value( "gamma", gamma).toInt(); hue = set->value( "hue", hue).toInt(); saturation = set->value( "saturation", saturation).toInt(); // audio_equalizer = set->value("audio_equalizer", audio_equalizer ).toList(); speed = set->value( "speed", speed ).toDouble(); phase_filter = set->value( "phase_filter", phase_filter ).toBool(); deblock_filter = set->value( "deblock_filter", deblock_filter).toBool(); dering_filter = set->value( "dering_filter", dering_filter).toBool(); gradfun_filter = set->value( "gradfun_filter", gradfun_filter).toBool(); noise_filter = set->value( "noise_filter", noise_filter).toBool(); postprocessing_filter = set->value( "postprocessing_filter", postprocessing_filter).toBool(); upscaling_filter = set->value( "upscaling_filter", upscaling_filter).toBool(); current_denoiser = set->value( "current_denoiser", current_denoiser).toInt(); current_unsharp = set->value( "current_unsharp", current_unsharp).toInt(); stereo3d_in = set->value( "stereo3d_in", stereo3d_in).toString(); stereo3d_out = set->value( "stereo3d_out", stereo3d_out).toString(); current_deinterlacer = set->value( "current_deinterlacer", current_deinterlacer ).toInt(); add_letterbox = set->value( "add_letterbox", add_letterbox ).toBool(); //#ifdef MPLAYER_SUPPORT karaoke_filter = set->value( "karaoke_filter", karaoke_filter).toBool(); extrastereo_filter = set->value( "extrastereo_filter", extrastereo_filter).toBool(); //#endif volnorm_filter = set->value( "volnorm_filter", volnorm_filter).toBool(); audio_use_channels = set->value( "audio_use_channels", audio_use_channels).toInt(); stereo_mode = set->value( "stereo_mode", stereo_mode).toInt(); zoom_factor = set->value( "zoom_factor", zoom_factor).toDouble(); rotate = set->value( "rotate", rotate).toInt(); flip = set->value( "flip", flip).toBool(); mirror = set->value( "mirror", mirror).toBool(); loop = set->value( "loop", loop).toBool(); A_marker = set->value( "A_marker", A_marker).toInt(); B_marker = set->value( "B_marker", B_marker).toInt(); //#ifdef BOOKMARKS // // Load bookmarks // int n_bookmarks = set->beginReadArray("bookmarks"); // if (n_bookmarks > 0) { // bookmarks.clear(); // for (int i = 0; i < n_bookmarks; ++i) { // set->setArrayIndex(i); // int time = set->value("time").toInt(); // QString name = set->value("name").toString(); // bookmarks.insert(time, name); // } // } // set->endArray(); //#endif // mplayer_additional_options = set->value( "mplayer_additional_options", mplayer_additional_options).toString(); // mplayer_additional_video_filters = set->value( "mplayer_additional_video_filters", mplayer_additional_video_filters).toString(); // mplayer_additional_audio_filters = set->value( "mplayer_additional_audio_filters", mplayer_additional_audio_filters).toString(); win_width = set->value( "win_width", win_width ).toInt(); win_height = set->value( "win_height", win_height ).toInt(); starting_time = set->value( "starting_time", starting_time ).toDouble(); is264andHD = set->value( "is264andHD", is264andHD ).toBool(); // ChDefault not used anymore if (audio_use_channels == ChDefault) audio_use_channels = ChStereo; } //#endif // NO_USE_INI_FILES kylin-video/src/smplayer/preferences.cpp0000664000175000017500000004337013233751662017401 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "preferences.h" #include "global.h" #include "paths.h" #include "mediasettings.h" #include "recents.h" #include "urlhistory.h" #include "helper.h" #include #include #include #include #include #include #if QT_VERSION >= 0x050000 #include #endif #if QT_VERSION >= 0x040400 #include #endif using namespace Global; Preferences::Preferences() { history_recents = new Recents; history_urls = new URLHistory; reset(); load(); } Preferences::~Preferences() { save(); delete history_recents; delete history_urls; } void Preferences::reset() { mplayer_bin = "mpv"; vo = ""; ao = ""; use_screenshot = true; screenshot_template = "cap_%F_%p_%02n"; screenshot_format = "jpg"; screenshot_directory=""; #if QT_VERSION < 0x040400 QString default_screenshot_path = Paths::configPath() + "/screenshots"; if (QFile::exists(default_screenshot_path)) { screenshot_directory = default_screenshot_path; } #endif use_direct_rendering = false; use_double_buffer = true; use_soft_video_eq = false; use_slices = false; vdpau.ffh264vdpau = true; vdpau.ffmpeg12vdpau = true; vdpau.ffwmv3vdpau = true; vdpau.ffvc1vdpau = true; vdpau.ffodivxvdpau = false; vdpau.disable_video_filters = true; use_soft_vol = true; softvol_max = 110; // 110 = default value in mplayer global_volume = true; volume = 50; mute = false; autosync = false; autosync_factor = 30;//调整音视频同步,帮助文件指出 置为30为最佳 min_step = 4; osd = None; osd_scale = 1; subfont_osd_scale = 3; osd_delay = 2200; //kobe:pref->file_settings_method 记住时间位置的配置设置在一个ini文件时为normal,在多个ini文件时为hash // file_settings_method = "hash"; // Possible values: normal & hash /* *********** Performance *********** */ HD_height = 720; threads = 4; hwdec = "no"; cache_for_files = 2048; cache_for_streams = 2048; /* ********* Subtitles ********* */ subcp = "UTF-8";//"ISO-8859-1"; use_enca = false; enca_lang = QString(QLocale::system().name()).section("_",0,0); sub_visibility = true; /* ******** Advanced ******** */ use_idx = false; use_lavf_demuxer = false; log_mplayer = true; verbose_log = false; // autosave_mplayer_log = false; // mplayer_log_saveto = ""; log_smplayer = true; log_filter = ".*"; save_smplayer_log = false; use_edl_files = true; prefer_ipv4 = true; use_short_pathnames = false; change_video_equalizer_on_startup = true; use_pausing_keep_force = true; use_correct_pts = Detect; actions_to_run = ""; show_tag_in_window_title = true; time_to_kill_mplayer = 1000; /* ********* GUI stuff ********* */ fullscreen = false; stay_on_top = NeverOnTop; play_order = OrderPlay; // resize_method = Afterload;//kobe: Never; resize_method = Never;//0620 kobe wheel_function = Seeking; wheel_function_cycle = Seeking | Volume | Zoom | ChangeSpeed; wheel_function_seeking_reverse = false; seeking1 = 10; seeking2 = 60; seeking3 = 10*60; seeking4 = 30; time_slider_drag_delay = 100; pause_when_hidden = true; preview_when_playing = true; media_to_add_to_playlist = NoFiles; playlist_key = "F3"; prev_key = "<, Media Previous"; next_key = ">, Media Next"; /* *********** Directories *********** */ latest_dir = QDir::homePath(); /* ************** Initial values ************** */ initial_postprocessing = false; initial_volnorm = false; initial_audio_channels = MediaSettings::ChDefault; /* ************ MPlayer info ************ */ mplayer_detected_version = -1; //None version parsed yet mplayer_user_supplied_version = -1; /* ******* History ******* */ history_recents->clear(); history_urls->clear(); } void Preferences::save() { qDebug("Preferences::save"); QSettings * set = settings; /* ******* General ******* */ set->beginGroup("General"); set->setValue("mplayer_bin", mplayer_bin); set->setValue("driver/vo", vo); set->setValue("driver/audio_output", ao); set->setValue("use_screenshot", use_screenshot); set->setValue("screenshot_template", screenshot_template); set->setValue("screenshot_format", screenshot_format); #if QT_VERSION >= 0x040400 set->setValue("screenshot_folder", screenshot_directory); #else set->setValue("screenshot_directory", screenshot_directory); #endif set->setValue("use_direct_rendering", use_direct_rendering); set->setValue("use_double_buffer", use_double_buffer); set->setValue("use_soft_video_eq", use_soft_video_eq); set->setValue("use_slices", use_slices ); set->setValue("use_soft_vol", use_soft_vol); set->setValue("softvol_max", softvol_max); set->setValue("global_volume", global_volume); set->setValue("volume", volume); set->setValue("mute", mute); set->setValue("autosync", autosync); set->setValue("autosync_factor", autosync_factor); set->setValue("min_step", min_step); set->endGroup(); // General /* *********** Performance *********** */ set->beginGroup( "performance"); set->setValue("HD_height", HD_height); set->setValue("threads", threads); set->setValue("hwdec", hwdec); set->setValue("cache_for_files", cache_for_files); set->setValue("cache_for_streams", cache_for_streams); set->endGroup(); // performance /* ********* Subtitles ********* */ set->beginGroup("subtitles"); set->setValue("subcp", subcp); set->setValue("use_enca", use_enca); set->setValue("enca_lang", enca_lang); set->setValue("sub_visibility", sub_visibility); set->endGroup(); // subtitles /* ******** Advanced ******** */ set->beginGroup( "advanced"); set->setValue("use_idx", use_idx); set->setValue("use_lavf_demuxer", use_lavf_demuxer); set->setValue("use_edl_files", use_edl_files); set->setValue("use_short_pathnames", use_short_pathnames); set->setValue("actions_to_run", actions_to_run); set->setValue("show_tag_in_window_title", show_tag_in_window_title); set->setValue("time_to_kill_mplayer", time_to_kill_mplayer); set->endGroup(); // advanced /* ********* GUI stuff ********* */ set->beginGroup("gui"); set->setValue("fullscreen", fullscreen); set->setValue("stay_on_top", (int) stay_on_top); set->setValue("mouse_wheel_function", wheel_function); set->setValue("wheel_function_cycle", (int) wheel_function_cycle); set->setValue("wheel_function_seeking_reverse", wheel_function_seeking_reverse); set->setValue("seeking1", seeking1); set->setValue("seeking2", seeking2); set->setValue("seeking3", seeking3); set->setValue("seeking4", seeking4); set->setValue("time_slider_drag_delay", time_slider_drag_delay); set->setValue("pause_when_hidden", pause_when_hidden); set->setValue("preview_when_playing", preview_when_playing); set->setValue("media_to_add_to_playlist", media_to_add_to_playlist); set->setValue("playlist_key", playlist_key); set->setValue("next_key", next_key); set->setValue("prev_key", prev_key); set->endGroup(); // gui /* ************** Initial values ************** */ set->beginGroup( "defaults"); set->setValue("latest_dir", latest_dir); set->setValue("initial_volnorm", initial_volnorm); set->setValue("initial_postprocessing", initial_postprocessing); set->setValue("initial_audio_channels", initial_audio_channels); set->endGroup(); // defaults /* ************ MPlayer info ************ */ set->beginGroup( "mplayer_info"); set->setValue("mplayer_detected_version", mplayer_detected_version); set->setValue("mplayer_user_supplied_version", mplayer_user_supplied_version); set->endGroup(); // mplayer_info /* ******* History ******* */ set->beginGroup("history"); set->setValue("recents", history_recents->toStringList()); set->setValue("recents/max_items", history_recents->maxItems()); set->setValue("urls", history_urls->toStringList()); set->setValue("urls/max_items", history_urls->maxItems()); set->endGroup(); // history set->sync(); } void Preferences::load() { qDebug("Preferences::load"); QSettings * set = settings; /* ******* General ******* */ set->beginGroup("General"); mplayer_bin = set->value("mplayer_bin", mplayer_bin).toString(); if (mplayer_bin.isEmpty()) mplayer_bin = "/usr/bin/mpv"; vo = set->value("driver/vo", vo).toString(); ao = set->value("driver/audio_output", ao).toString(); use_screenshot = set->value("use_screenshot", use_screenshot).toBool(); screenshot_template = set->value("screenshot_template", screenshot_template).toString(); if (screenshot_template.isEmpty()) screenshot_template = "cap_%F_%p_%02n"; screenshot_format = set->value("screenshot_format", screenshot_format).toString(); if (screenshot_format.isEmpty()) screenshot_format = "jpg"; #if QT_VERSION >= 0x040400 screenshot_directory = set->value("screenshot_folder", screenshot_directory).toString(); setupScreenshotFolder(); #else screenshot_directory = set->value("screenshot_directory", screenshot_directory).toString(); #endif use_direct_rendering = set->value("use_direct_rendering", use_direct_rendering).toBool(); use_double_buffer = set->value("use_double_buffer", use_double_buffer).toBool(); use_soft_video_eq = set->value("use_soft_video_eq", use_soft_video_eq).toBool(); use_slices = set->value("use_slices", use_slices ).toBool(); use_soft_vol = set->value("use_soft_vol", use_soft_vol).toBool(); softvol_max = set->value("softvol_max", softvol_max).toInt(); global_volume = set->value("global_volume", global_volume).toBool(); volume = set->value("volume", volume).toInt(); mute = set->value("mute", mute).toBool(); autosync = set->value("autosync", autosync).toBool(); autosync_factor = set->value("autosync_factor", autosync_factor).toInt(); min_step = set->value("min_step", min_step).toInt(); osd = set->value("osd", osd).toInt(); osd = 0;//kobe:选项->屏幕显示->仅字幕,该版本会屏蔽“屏幕显示”菜单,全部默认为仅字幕,即配置文件~/.config/smplayer/smplayer.ini的osd字段不管是多少,定制版播放器启动后都重新设置该值为0(仅字幕) osd_scale = set->value("osd_scale", osd_scale).toDouble(); subfont_osd_scale = set->value("subfont_osd_scale", subfont_osd_scale).toDouble(); osd_delay = set->value("osd_delay", osd_delay).toInt(); set->endGroup(); // General /* *********** Performance *********** */ set->beginGroup( "performance"); HD_height = set->value("HD_height", HD_height).toInt(); threads = set->value("threads", threads).toInt(); hwdec = set->value("hwdec", hwdec).toString(); cache_for_files = set->value("cache_for_files", cache_for_files).toInt(); cache_for_streams = set->value("cache_for_streams", cache_for_streams).toInt(); set->endGroup(); // performance /* ********* Subtitles ********* */ set->beginGroup("subtitles"); subcp = set->value("subcp", subcp).toString(); if (subcp.isEmpty()) subcp = "UTF-8";//ISO-8859-1";//kobe use_enca = set->value("use_enca", use_enca).toBool(); enca_lang = set->value("enca_lang", enca_lang).toString(); if (enca_lang.isEmpty()) enca_lang = "zh";//kobe sub_visibility = set->value("sub_visibility", sub_visibility).toBool(); set->endGroup(); // subtitles /* ******** Advanced ******** */ set->beginGroup( "advanced"); use_idx = set->value("use_idx", use_idx).toBool(); use_lavf_demuxer = set->value("use_lavf_demuxer", use_lavf_demuxer).toBool(); use_edl_files = set->value("use_edl_files", use_edl_files).toBool(); use_short_pathnames = set->value("use_short_pathnames", use_short_pathnames).toBool(); actions_to_run = set->value("actions_to_run", actions_to_run).toString(); show_tag_in_window_title = set->value("show_tag_in_window_title", show_tag_in_window_title).toBool(); time_to_kill_mplayer = set->value("time_to_kill_mplayer", time_to_kill_mplayer).toInt(); set->endGroup(); // advanced /* ********* GUI stuff ********* */ set->beginGroup("gui"); fullscreen = set->value("fullscreen", fullscreen).toBool(); stay_on_top = (Preferences::OnTop) set->value("stay_on_top", (int) stay_on_top).toInt(); wheel_function = set->value("mouse_wheel_function", wheel_function).toInt(); { int wheel_function_cycle_int = set->value("wheel_function_cycle", (int) wheel_function_cycle).toInt(); wheel_function_cycle = (WheelFunctions) wheel_function_cycle_int; } wheel_function_seeking_reverse = set->value("wheel_function_seeking_reverse", wheel_function_seeking_reverse).toBool(); seeking1 = set->value("seeking1", seeking1).toInt(); seeking2 = set->value("seeking2", seeking2).toInt(); seeking3 = set->value("seeking3", seeking3).toInt(); seeking4 = set->value("seeking4", seeking4).toInt(); time_slider_drag_delay = set->value("time_slider_drag_delay", time_slider_drag_delay).toInt(); pause_when_hidden = set->value("pause_when_hidden", pause_when_hidden).toBool(); preview_when_playing = set->value("preview_when_playing", preview_when_playing).toBool(); media_to_add_to_playlist = (AutoAddToPlaylistFilter) set->value("media_to_add_to_playlist", media_to_add_to_playlist).toInt(); playlist_key = set->value("playlist_key", playlist_key).toString(); next_key = set->value("next_key", next_key).toString(); prev_key = set->value("prev_key", prev_key).toString(); set->endGroup(); // gui /* ************** Initial values ************** */ set->beginGroup( "defaults"); latest_dir = set->value("latest_dir", latest_dir).toString(); initial_volnorm = set->value("initial_volnorm", initial_volnorm).toBool(); initial_postprocessing = set->value("initial_postprocessing", initial_postprocessing).toBool(); initial_audio_channels = set->value("initial_audio_channels", initial_audio_channels).toInt(); set->endGroup(); // defaults /* ************ MPlayer info ************ */ set->beginGroup( "mplayer_info"); mplayer_detected_version = set->value("mplayer_detected_version", mplayer_detected_version).toInt(); mplayer_user_supplied_version = set->value("mplayer_user_supplied_version", mplayer_user_supplied_version).toInt(); set->endGroup(); // mplayer_info /* ******* History ******* */ set->beginGroup("history"); history_recents->setMaxItems( set->value("recents/max_items", history_recents->maxItems()).toInt() ); history_recents->fromStringList( set->value("recents", history_recents->toStringList()).toStringList() ); history_urls->setMaxItems( set->value("urls/max_items", history_urls->maxItems()).toInt() ); history_urls->fromStringList( set->value("urls", history_urls->toStringList()).toStringList() ); set->endGroup(); // history if (!QFile::exists(mplayer_bin)) { QString app_path = Helper::findExecutable(mplayer_bin); //qDebug("Preferences::load: app_path: %s", app_path.toUtf8().constData()); if (!app_path.isEmpty()) { mplayer_bin = app_path; } else { // Executable not found, try to find an alternative if (mplayer_bin.startsWith("mplayer")) { app_path = Helper::findExecutable("mpv"); if (!app_path.isEmpty()) mplayer_bin = app_path; } else if (mplayer_bin.startsWith("mpv")) { app_path = Helper::findExecutable("mplayer"); if (!app_path.isEmpty()) mplayer_bin = app_path; } } } } void Preferences::setupScreenshotFolder() { #if QT_VERSION >= 0x040400 if (screenshot_directory.isEmpty()) { #if QT_VERSION >= 0x050000 QString pdir = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); if (pdir.isEmpty()) pdir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); if (pdir.isEmpty()) pdir = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); #else QString pdir = QDesktopServices::storageLocation(QDesktopServices::PicturesLocation); if (pdir.isEmpty()) pdir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation); if (pdir.isEmpty()) pdir = QDesktopServices::storageLocation(QDesktopServices::HomeLocation); #endif if (pdir.isEmpty()) pdir = "/tmp"; if (!QFile::exists(pdir)) { qWarning("Preferences::setupScreenshotFolder: folder '%s' does not exist. Using /tmp as fallback", pdir.toUtf8().constData()); pdir = "/tmp"; } QString default_screenshot_path = QDir::toNativeSeparators(pdir + "/kylin_video_screenshots"); if (!QFile::exists(default_screenshot_path)) { qDebug("Preferences::setupScreenshotFolder: creating '%s'", default_screenshot_path.toUtf8().constData()); if (!QDir().mkdir(default_screenshot_path)) { qWarning("Preferences::setupScreenshotFolder: failed to create '%s'", default_screenshot_path.toUtf8().constData()); } } if (QFile::exists(default_screenshot_path)) { screenshot_directory = default_screenshot_path; } qDebug() << "setup default_screenshot_path=" << default_screenshot_path; } else { screenshot_directory = QDir::toNativeSeparators(screenshot_directory); } #endif } kylin-video/src/smplayer/colorutils.h0000664000175000017500000000370513233751662016742 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _COLORUTILS_H_ #define _COLORUTILS_H_ #include class QWidget; class QColor; class ColorUtils { public: //! Returns a string suitable to be used for -ass-color static QString colorToRRGGBBAA(unsigned int color); static QString colorToRRGGBB(unsigned int color); //! Returns a string suitable to be used for -colorkey static QString colorToRGB(unsigned int color); static QString colorToAABBGGRR(unsigned int color); //! Changes the foreground color of the specified widget static void setForegroundColor(QWidget * w, const QColor & color); //! Changes the background color of the specified widget static void setBackgroundColor(QWidget * w, const QColor & color); /** ** \brief Strip colors and tags from MPlayer output lines ** ** Some MPlayer configurations (configured with --enable-color-console) ** use colored/tagged console output. This function removes those colors ** and tags. ** ** \param s The string to strip colors and tags from ** \return Returns a clean string (no colors, no tags) */ static QString stripColorsTags(QString s); }; #endif kylin-video/src/smplayer/inforeadermplayer.cpp0000664000175000017500000001721313233751662020605 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "inforeadermplayer.h" #include #include #include #include #include "colorutils.h" #include "global.h" #include "preferences.h" #include "mplayerversion.h" using namespace Global; #define NOME 0 #define VO 1 #define AO 2 #define DEMUXER 3 #define VC 4 #define AC 5 InfoReaderMplayer::InfoReaderMplayer( QString mplayer_bin, QObject * parent ) : QObject(parent) , proc(0) , mplayer_svn(0) // , is_mplayer2(false) { mplayerbin = mplayer_bin; proc = new QProcess(this); proc->setProcessChannelMode( QProcess::MergedChannels ); } InfoReaderMplayer::~InfoReaderMplayer() { } void InfoReaderMplayer::getInfo() { waiting_for_key = true; vo_list.clear(); ao_list.clear(); demuxer_list.clear(); mplayer_svn = -1; run("-identify -vo help -ao help -demuxer help -vc help -ac help"); //list(); } void InfoReaderMplayer::list() { qDebug("InfoReaderMplayer::list"); InfoList::iterator it; qDebug(" vo_list:"); for ( it = vo_list.begin(); it != vo_list.end(); ++it ) { qDebug( "driver: '%s', desc: '%s'", (*it).name().toUtf8().data(), (*it).desc().toUtf8().data()); } qDebug(" ao_list:"); for ( it = ao_list.begin(); it != ao_list.end(); ++it ) { qDebug( "driver: '%s', desc: '%s'", (*it).name().toUtf8().data(), (*it).desc().toUtf8().data()); } qDebug(" demuxer_list:"); for ( it = demuxer_list.begin(); it != demuxer_list.end(); ++it ) { qDebug( "demuxer: '%s', desc: '%s'", (*it).name().toUtf8().data(), (*it).desc().toUtf8().data()); } qDebug(" vc_list:"); for ( it = vc_list.begin(); it != vc_list.end(); ++it ) { qDebug( "codec: '%s', desc: '%s'", (*it).name().toUtf8().data(), (*it).desc().toUtf8().data()); } qDebug(" ac_list:"); for ( it = ac_list.begin(); it != ac_list.end(); ++it ) { qDebug( "codec: '%s', desc: '%s'", (*it).name().toUtf8().data(), (*it).desc().toUtf8().data()); } } static QRegExp rx_vo_key("^ID_VIDEO_OUTPUTS"); static QRegExp rx_ao_key("^ID_AUDIO_OUTPUTS"); static QRegExp rx_demuxer_key("^ID_DEMUXERS"); static QRegExp rx_ac_key("^ID_AUDIO_CODECS"); static QRegExp rx_vc_key("^ID_VIDEO_CODECS"); static QRegExp rx_driver("\\t(.*)\\t(.*)"); static QRegExp rx_demuxer("^\\s+([A-Z,a-z,0-9]+)\\s+(\\d+)\\s+(\\S.*)"); static QRegExp rx_demuxer2("^\\s+([A-Z,a-z,0-9]+)\\s+(\\S.*)"); static QRegExp rx_codec("^([A-Z,a-z,0-9]+)\\s+([A-Z,a-z,0-9]+)\\s+([A-Z,a-z,0-9]+)\\s+(\\S.*)"); void InfoReaderMplayer::readLine(QByteArray ba) { QString line = ColorUtils::stripColorsTags(QString::fromLocal8Bit(ba)); if (line.isEmpty()) return; //qDebug("InfoReaderMplayer::readLine: line: '%s'", line.toUtf8().data()); //qDebug("waiting_for_key: %d", waiting_for_key); if (!waiting_for_key) { if ((reading_type == VO) || (reading_type == AO)) { if ( rx_driver.indexIn(line) > -1 ) { QString name = rx_driver.cap(1); QString desc = rx_driver.cap(2); qDebug("InfoReaderMplayer::readLine: found driver: '%s' '%s'", name.toUtf8().data(), desc.toUtf8().data()); if (reading_type==VO) { vo_list.append( InfoData(name, desc) ); } else if (reading_type==AO) { ao_list.append( InfoData(name, desc) ); } } else { qWarning("InfoReaderMplayer::readLine: can't parse output driver from line '%s'", line.toUtf8().constData()); } } else if (reading_type == DEMUXER) { if ( rx_demuxer.indexIn(line) > -1 ) { QString name = rx_demuxer.cap(1); QString desc = rx_demuxer.cap(3); qDebug("InfoReaderMplayer::readLine: found demuxer: '%s' '%s'", name.toUtf8().data(), desc.toUtf8().data()); demuxer_list.append( InfoData(name, desc) ); } else if ( rx_demuxer2.indexIn(line) > -1 ) { QString name = rx_demuxer2.cap(1); QString desc = rx_demuxer2.cap(2); qDebug("InfoReaderMplayer::readLine: found demuxer: '%s' '%s'", name.toUtf8().data(), desc.toUtf8().data()); demuxer_list.append( InfoData(name, desc) ); } else { qWarning("InfoReaderMplayer::readLine: can't parse demuxer from line '%s'", line.toUtf8().constData()); } } else if ((reading_type == VC) || (reading_type == AC)) { if ( rx_codec.indexIn(line) > -1 ) { QString name = rx_codec.cap(1); QString desc = rx_codec.cap(4); qDebug("InfoReaderMplayer::readLine: found codec: '%s' '%s'", name.toUtf8().data(), desc.toUtf8().data()); if (reading_type==VC) { vc_list.append( InfoData(name, desc) ); } else if (reading_type==AC) { ac_list.append( InfoData(name, desc) ); } } else { qWarning("InfoReaderMplayer::readLine: can't parse codec from line '%s'", line.toUtf8().constData()); } } } if ( rx_vo_key.indexIn(line) > -1 ) { reading_type = VO; waiting_for_key = false; qDebug("InfoReaderMplayer::readLine: found key: vo"); } if ( rx_ao_key.indexIn(line) > -1 ) { reading_type = AO; waiting_for_key = false; qDebug("InfoReaderMplayer::readLine: found key: ao"); } if ( rx_demuxer_key.indexIn(line) > -1 ) { reading_type = DEMUXER; waiting_for_key = false; qDebug("InfoReaderMplayer::readLine: found key: demuxer"); } if ( rx_ac_key.indexIn(line) > -1 ) { reading_type = AC; waiting_for_key = false; qDebug("InfoReaderMplayer::readLine: found key: ac"); } if ( rx_vc_key.indexIn(line) > -1 ) { reading_type = VC; waiting_for_key = false; qDebug("InfoReaderMplayer::readLines: found key: vc"); } if (line.startsWith("MPlayer ") || line.startsWith("MPlayer2 ")) { mplayer_svn = MplayerVersion::mplayerVersion(line); // mplayer2_version = MplayerVersion::mplayer2Version(); // is_mplayer2 = MplayerVersion::isMplayer2(); } } bool InfoReaderMplayer::run(QString options) { qDebug("InfoReaderMplayer::run: '%s'", options.toUtf8().data()); if (proc->state() == QProcess::Running) { qWarning("InfoReaderMplayer::run: process already running"); return false; } QStringList args = options.split(" "); proc->start(mplayerbin, args); if (!proc->waitForStarted()) { qWarning("InfoReaderMplayer::run: process can't start!"); return false; } //Wait until finish if (!proc->waitForFinished()) { qWarning("InfoReaderMplayer::run: process didn't finish. Killing it..."); proc->kill(); } qDebug("================InfoReaderMplayer::run : terminating"); QByteArray ba; while (proc->canReadLine()) { ba = proc->readLine(); ba.replace("\n", ""); ba.replace("\r", ""); readLine( ba ); } return true; } //#include "moc_inforeadermplayer.cpp" kylin-video/src/smplayer/images.h0000664000175000017500000000261413233751662016006 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef IMAGES_H #define IMAGES_H #include #include #include class Images { public: static QPixmap icon(QString name, int size=-1); static QPixmap flippedIcon(QString name, int size=-1); //! Returns the filename of the icon static QString file(const QString & icon_name); static bool has_rcc; private: static QPixmap resize(QPixmap *p, int size=20); static QPixmap flip(QPixmap *p); static QString current_theme; static QString themes_path; static QString resourceFilename(); static QString last_resource_loaded; }; #endif kylin-video/src/smplayer/timeslider.h0000664000175000017500000000467213233751662016710 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef TIMESLIDER_H #define TIMESLIDER_H #include "myslider.h" #include "config.h" class TimeTip; class TimeSlider : public MySlider { Q_OBJECT // Q_PROPERTY(bool status READ isStatus WRITE setStatus)//kobe public: TimeSlider( QWidget * parent ); ~TimeSlider(); // void setStatus(bool e) { status = e; }//kobe // bool isStatus() const { return status; }//kobe void show_time_value(int time); void set_preview_flag(bool b); public slots: virtual void setPos(int); // Don't use setValue! virtual int pos(); virtual void setDuration(double t) { total_time = t; }; virtual double duration() { return total_time; }; void setDragDelay(int); int dragDelay(); void hideTip();//kobe signals: void posChanged(int); void draggingPos(int); // //! Emitted with a few ms of delay void delayedDraggingPos(int); void wheelUp(); void wheelDown(); void active_status(bool);//kobe void need_to_save_pre_image(int time);//kobe protected slots: void stopUpdate(); void resumeUpdate(); void mouseReleased(); void valueChanged_slot(int); void checkDragging(int); void sendDelayedPos(); void show_save_preview_image(int time, QString filepath); protected: virtual void wheelEvent(QWheelEvent * e); virtual bool event(QEvent *event); void enterEvent(QEvent *event);//kobe void leaveEvent(QEvent *event);//kobe bool eventFilter(QObject *obj, QEvent *event);//kobe private: bool dont_update; int position; double total_time; TimeTip *hintWidget; int last_pos_to_send; QTimer * timer; // bool status;//kobe QPoint cur_pos; bool preview; }; #endif kylin-video/src/smplayer/videopreview.h0000664000175000017500000000603013233751662017245 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _VIDEOPREVIEW_H_ #define _VIDEOPREVIEW_H_ #include #include #include class VideoInfo { public: VideoInfo() { filename.clear(); width = 0; height = 0; length = 0; size = 0; fps = 0; aspect = 0; video_bitrate = 0; audio_bitrate = 0; audio_rate = 0; video_format.clear(); }; ~VideoInfo() {}; QString filename; int width; int height; int length; qint64 size; double fps; double aspect; int video_bitrate; int audio_bitrate; int audio_rate; QString video_format; }; class VideoPreview : public QObject { Q_OBJECT public: enum ExtractFormat { JPEG = 1, PNG = 2 }; VideoPreview(QString mplayer_path, QObject *parent = 0); ~VideoPreview(); void setMplayerPath(QString mplayer_path); QString mplayerPath() { return mplayer_bin; }; void setVideoFile(QString file) { prop.input_video = file; }; QString videoFile() { return prop.input_video; }; void setInitialStep(int step) { prop.initial_step = step; }; int initialStep() { return prop.initial_step; }; void setMaxWidth(int w) { prop.max_width = w; }; int maxWidth() { return prop.max_width; }; void setDisplayOSD(bool b) { prop.display_osd = b; }; bool displayOSD() { return prop.display_osd; }; void setAspectRatio(double asp) { prop.aspect_ratio = asp; }; double aspectRatio() { return prop.aspect_ratio; }; void setExtractFormat( ExtractFormat format ) { prop.extract_format = format; }; ExtractFormat extractFormat() { return prop.extract_format; }; bool createPreThumbnail(int time); VideoInfo getInfo(const QString & mplayer_path, const QString & filename); QString errorMessage() { return error_message; }; QString getCurrentPicture() { return current_picture;}; protected: bool extractImages(int time); bool runPlayer(int seek, double aspect_ratio); void cleanDir(QString directory, bool removeDir=false); QString framePicture(); QString mplayer_bin; QString output_dir; QString full_output_dir; struct Properties { QString input_video; int initial_step, max_width; double aspect_ratio; bool display_osd; ExtractFormat extract_format; } prop; QString last_directory; QString error_message; QString current_picture; }; #endif kylin-video/src/smplayer/mplayeroptions.cpp0000664000175000017500000003436013233751662020164 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "subtracks.h" #include #include void MplayerProcess::setMedia(const QString & media, bool is_playlist) { if (is_playlist) arg << "-playlist"; arg << media; } void MplayerProcess::setFixedOptions() { /* "-slave" Mplayer运行在slave模式下,在关于slave模式,MPlayer为后台运行,不再截获键盘事件,MPlayer 从标准输入读取以新行 (\n) 分隔开的命令行 "-quiet" 使得控制台消息少输出; 特别地, 阻止状态行 (即 A: 0.7 V: 0.6 A-V: 0.068 ...)的显示。 "-intput" "file=/tmp/fifo" Mplayer 通过命名管道获取命令。 */ arg << "-noquiet" << "-slave" << "-identify";//kobe:必须使用noquiet而不是quiet,否则无法在parseLine函数中获取数据进行进行判断,比如判断当前播放是否成功等 // arg << "-quiet" << "-slave" << "-identify"; //-quiet 使得控制台消息少输出; 特别地, 阻止状态行 (即 A: 0.7 V: 0.6 A-V: 0.068 ...)的显示。 对慢机器或者不能正确处理回车符(即 \r)的旧机器特别有用 //-identify 是 −msglevel identify=4 的简写形式。使用便于解析的格式显示文件参数。 同时打印更为详细的关于字幕和音轨的语言与 ID 号的信息。 在某些情形下,使用 −msglevel identify=6 能得到更多的信息。 例如,对于一张 DVD 碟片,该选项能列出每个标题的章节和时长,以及一个碟片 ID 号。 将此选项与 −frames 0 一起使用能禁止所有输出。 封装脚本 TOOLS/midentify 禁止 MPlayer 的其它输出, 并且(很可能)shellescapes(脚本转义)了文件名。 } void MplayerProcess::disableInput() { arg << "-nomouseinput"; //#if !defined(Q_OS_WIN) && !defined(Q_OS_OS2) arg << "-input" << "nodefault-bindings:conf=/dev/null"; // arg << "-input" << "conf=/usr/share/kylin-video/input.conf"; // arg << "-input" << "nodefault-bindings:conf=/usr/share/kylin-video/input.conf"; //#endif } //#ifdef CAPTURE_STREAM //void MplayerProcess::setCaptureDirectory(const QString & dir) { // PlayerProcess::setCaptureDirectory(dir); // if (!capture_filename.isEmpty()) { // arg << "-capture" << "-dumpfile" << capture_filename; // } //} //#endif void MplayerProcess::setOption(const QString & option_name, const QVariant & value) { if (option_name == "cache") { int cache = value.toInt(); if (cache > 31) { arg << "-cache" << value.toString(); } else { arg << "-nocache"; } } else if (option_name == "stop-xscreensaver") { bool stop_ss = value.toBool(); if (stop_ss) arg << "-stop-xscreensaver"; else arg << "-nostop-xscreensaver"; } else if (option_name == "correct-pts") { bool b = value.toBool(); if (b) arg << "-correct-pts"; else arg << "-nocorrect-pts"; } else if (option_name == "framedrop") { QString o = value.toString(); if (o.contains("vo")) arg << "-framedrop"; if (o.contains("decoder")) arg << "-hardframedrop"; } else if (option_name == "osd-scale") { arg << "-subfont-osd-scale" << value.toString(); } else if (option_name == "verbose") { arg << "-v"; } else if (option_name == "screenshot_template" || option_name == "screenshot_format") { // Not supported } else if (option_name == "enable_streaming_sites_support") { // Not supported } else if (option_name == "hwdec") { // Not supported } else if (option_name == "fontconfig") { bool b = value.toBool(); if (b) arg << "-fontconfig"; else arg << "-nofontconfig"; } else if (option_name == "mute") { // Not supported } else if (option_name == "keepaspect" || option_name == "dr" || option_name == "double" || option_name == "fs" || option_name == "slices" || option_name == "flip-hebrew") { bool b = value.toBool(); if (b) arg << "-" + option_name; else arg << "-no" + option_name; } else { arg << "-" + option_name; if (!value.isNull()) arg << value.toString(); } } void MplayerProcess::addUserOption(const QString & option) { arg << option; } void MplayerProcess::addVF(const QString & filter_name, const QVariant & value) { QString option = value.toString(); if (filter_name == "blur" || filter_name == "sharpen") { arg << "-vf-add" << "unsharp=" + option; } else if (filter_name == "deblock") { arg << "-vf-add" << "pp=" + option; } else if (filter_name == "dering") { arg << "-vf-add" << "pp=dr"; } else if (filter_name == "postprocessing") { arg << "-vf-add" << "pp"; } else if (filter_name == "lb" || filter_name == "l5") { arg << "-vf-add" << "pp=" + filter_name; } else if (filter_name == "subs_on_screenshots") { if (option == "ass") { arg << "-vf-add" << "ass"; } else { arg << "-vf-add" << "expand=osd=1"; } } else if (filter_name == "screenshot") { QString f = "screenshot"; if (!screenshot_dir.isEmpty()) { f += "="+ QDir::toNativeSeparators(screenshot_dir + "/shot"); } arg << "-vf-add" << f; } else if (filter_name == "flip") { // expand + flip doesn't work well, a workaround is to add another // filter between them, so that's why harddup is here arg << "-vf-add" << "harddup,flip"; } else if (filter_name == "expand") { arg << "-vf-add" << "expand=" + option + ",harddup"; // Note: on some videos (h264 for instance) the subtitles doesn't disappear, // appearing the new ones on top of the old ones. It seems adding another // filter after expand fixes the problem. I chose harddup 'cos I think // it will be harmless in mplayer. } else { QString s = filter_name; QString option = value.toString(); if (!option.isEmpty()) s += "=" + option; arg << "-vf-add" << s; } } void MplayerProcess::addStereo3DFilter(const QString & in, const QString & out) { QString filter = "stereo3d=" + in + ":" + out; filter += ",scale"; // In my PC it doesn't work without scale :? arg << "-vf-add" << filter; } void MplayerProcess::addAF(const QString & filter_name, const QVariant & value) { QString s = filter_name; if (!value.isNull()) s += "=" + value.toString(); arg << "-af-add" << s; } void MplayerProcess::quit() { writeToStdin("quit"); } void MplayerProcess::setVolume(int v) { // qDebug() << "111kobe set volume " << v; writeToStdin("volume " + QString::number(v) + " 1"); } void MplayerProcess::setOSD(int o) { writeToStdin(pausing_prefix + " osd " + QString::number(o)); } void MplayerProcess::setAudio(int ID) { writeToStdin("switch_audio " + QString::number(ID)); } void MplayerProcess::setVideo(int ID) { writeToStdin("set_property switch_video " + QString::number(ID)); } void MplayerProcess::setSubtitle(int type, int ID) { switch (type) { case SubData::Vob: writeToStdin( "sub_vob " + QString::number(ID) ); break; case SubData::Sub: writeToStdin( "sub_demux " + QString::number(ID) ); break; case SubData::File: writeToStdin( "sub_file " + QString::number(ID) ); break; default: { qWarning("MplayerProcess::setSubtitle: unknown type!"); } } } void MplayerProcess::disableSubtitles() { writeToStdin("sub_source -1"); } void MplayerProcess::setSubtitlesVisibility(bool b) { writeToStdin(QString("sub_visibility %1").arg(b ? 1 : 0)); } /*kobe: 20170718 * seek [type] * 0 is a relative seek of +/- seconds (default). * 1 is a seek to % in the movie. * 2 is a seek to an absolute position of seconds. * 当播放引擎为mplayer时,定位时的type如果为2,即绝对位置,则有些视频拖动进度后又返回原来的位置,此时只能用type=1。而播放引擎为mpv时无该问题。 */ void MplayerProcess::seek(double secs, int mode, bool precise) { QString s = QString("seek %1 %2").arg(secs).arg(mode); // QString s = QString("seek %1 1").arg(secs); if (precise) s += " 1"; else s += " -1"; // qDebug() << "******************MplayerProcess::seek=" << s;//mplayer:seek 162 2 1 mpv:seek 162 absolute exact writeToStdin(s); } void MplayerProcess::mute(bool b) { writeToStdin(pausing_prefix + " mute " + QString::number(b ? 1 : 0)); } void MplayerProcess::setPause(bool /*b*/) { writeToStdin("pause"); // pauses / unpauses } void MplayerProcess::frameStep() { writeToStdin("frame_step"); } void MplayerProcess::frameBackStep() { qDebug("MplayerProcess::frameBackStep: function not supported by mplayer"); showOSDText(tr("This option is not supported by MPlayer"), 3000, 1); } void MplayerProcess::showOSDText(const QString & text, int duration, int level) { QString str = QString("osd_show_text \"%1\" %2 %3").arg(text).arg(duration).arg(level); if (!pausing_prefix.isEmpty()) str = pausing_prefix + " " + str; writeToStdin(str); } void MplayerProcess::showFilenameOnOSD() { writeToStdin("osd_show_property_text \"${filename}\" 2000 0"); } void MplayerProcess::showTimeOnOSD() { writeToStdin("osd_show_property_text \"${time_pos} / ${length} (${percent_pos}%)\" 2000 0"); } void MplayerProcess::setContrast(int value) { writeToStdin(pausing_prefix + " contrast " + QString::number(value) + " 1"); } void MplayerProcess::setBrightness(int value) { writeToStdin(pausing_prefix + " brightness " + QString::number(value) + " 1"); } void MplayerProcess::setHue(int value) { writeToStdin(pausing_prefix + " hue " + QString::number(value) + " 1"); } void MplayerProcess::setSaturation(int value) { writeToStdin(pausing_prefix + " saturation " + QString::number(value) + " 1"); } void MplayerProcess::setGamma(int value) { writeToStdin(pausing_prefix + " gamma " + QString::number(value) + " 1"); } void MplayerProcess::setChapter(int ID) { writeToStdin("seek_chapter " + QString::number(ID) +" 1"); } void MplayerProcess::setExternalSubtitleFile(const QString & filename) { writeToStdin("sub_load \""+ filename +"\""); } void MplayerProcess::setSubPos(int pos) { writeToStdin("sub_pos " + QString::number(pos) + " 1"); } void MplayerProcess::setSubScale(double value) { writeToStdin("sub_scale " + QString::number(value) + " 1"); } void MplayerProcess::setSubStep(int value) { writeToStdin("sub_step " + QString::number(value)); } //#ifdef MPV_SUPPORT //void MplayerProcess::seekSub(int /*value*/) { // /* Not supported */ // showOSDText(tr("This option is not supported by MPlayer"), 3000, 1); //}; //#endif void MplayerProcess::setSubForcedOnly(bool b) { writeToStdin(QString("forced_subs_only %1").arg(b ? 1 : 0)); } void MplayerProcess::setSpeed(double value) { writeToStdin("speed_set " + QString::number(value)); } void MplayerProcess::enableKaraoke(bool b) { if (b) writeToStdin("af_add karaoke"); else writeToStdin("af_del karaoke"); } void MplayerProcess::enableExtrastereo(bool b) { if (b) writeToStdin("af_add extrastereo"); else writeToStdin("af_del extrastereo"); } void MplayerProcess::enableVolnorm(bool b, const QString & option) { if (b) writeToStdin("af_add volnorm=" + option); else writeToStdin("af_del volnorm"); } void MplayerProcess::setAudioEqualizer(const QString & values) { writeToStdin("af_cmdline equalizer " + values); } void MplayerProcess::setAudioDelay(double delay) { writeToStdin(pausing_prefix + " audio_delay " + QString::number(delay) +" 1"); } void MplayerProcess::setSubDelay(double delay) { writeToStdin(pausing_prefix + " sub_delay " + QString::number(delay) +" 1"); } void MplayerProcess::setLoop(int v) { writeToStdin(QString("loop %1 1").arg(v)); } void MplayerProcess::takeScreenshot(ScreenshotType t, bool /*include_subtitles*/) { qDebug() << "MplayerProcess::takeScreenshot"; if (t == Single) { writeToStdin(pausing_prefix + " screenshot 0"); } else { writeToStdin("screenshot 1"); } } //#ifdef CAPTURE_STREAM //void MplayerProcess::switchCapturing() { // writeToStdin("capturing"); //} //#endif void MplayerProcess::setTitle(int ID) { writeToStdin("switch_title " + QString::number(ID)); } //#if DVDNAV_SUPPORT //void MplayerProcess::discSetMousePos(int x, int y) { // writeToStdin(QString("set_mouse_pos %1 %2").arg(x).arg(y)); //} //void MplayerProcess::discButtonPressed(const QString & button_name) { // writeToStdin("dvdnav " + button_name); //} //#endif void MplayerProcess::setAspect(double aspect) { writeToStdin("switch_ratio " + QString::number(aspect)); } void MplayerProcess::setFullscreen(bool b) { writeToStdin(QString("vo_fullscreen %1").arg(b ? "1" : "0")); } //#if PROGRAM_SWITCH //void MplayerProcess::setTSProgram(int ID) { // writeToStdin("set_property switch_program " + QString::number(ID) ); // writeToStdin("get_property switch_audio"); // writeToStdin("get_property switch_video"); //} //#endif void MplayerProcess::toggleDeinterlace() { writeToStdin("step_property deinterlace"); } void MplayerProcess::askForLength() { writeToStdin(pausing_prefix + " get_property length"); } void MplayerProcess::setOSDScale(double /*value*/) { // not available /* writeToStdin("set_property subfont-osd-scale " + QString::number(value)); */ } void MplayerProcess::changeVF(const QString & /*filter*/, bool /*enable*/, const QVariant & /*option*/) { // not supported } void MplayerProcess::changeStereo3DFilter(bool /*enable*/, const QString & /*in*/, const QString & /*out*/) { // not supported } //void MplayerProcess::setSubStyles(const AssStyles & styles, const QString & assStylesFile) { // if (assStylesFile.isEmpty()) { // qWarning("MplayerProcess::setSubStyles: assStylesFile is invalid"); // return; // } // // Load the styles.ass file // if (!QFile::exists(assStylesFile)) { // // If file doesn't exist, create it // styles.exportStyles(assStylesFile); // } // if (QFile::exists(assStylesFile)) { // setOption("ass-styles", assStylesFile); // } else { // qWarning("MplayerProcess::setSubStyles: '%s' doesn't exist", assStylesFile.toUtf8().constData()); // } //} kylin-video/src/smplayer/core.h0000664000175000017500000003327513233751662015500 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _CORE_H_ #define _CORE_H_ #include #include // For QProcess::ProcessError #include "mediadata.h" #include "mediasettings.h" #include "playerprocess.h" #include "config.h" class FileSettings; class PlayerProcess; class MplayerWindow; class Core : public QObject { Q_OBJECT public: enum State { Stopped = 0, Playing = 1, Paused = 2 }; Core( MplayerWindow *mpw, QWidget* parent = 0 ); ~Core(); MediaData mdat; MediaSettings mset; //! Return the current state State state() { return _state; }; //! Return a string with the name of the current state, //! so it can be printed on debugging messages. QString stateToString(); void addForcedTitle(const QString & file, const QString & title) { forced_titles[file] = title; }; protected: //! Change the current state (Stopped, Playing or Paused) //! And sends the stateChanged() signal. void setState(State s); public slots: //! Generic open, with autodetection of type void open(QString file, int seek=-1); void openFile(QString filename, int seek=-1); void openStream(QString name); /* void openDVD( bool from_folder, QString directory = ""); void openDVD(); // Plays title 1 void openDVD(int title = 1); */ void openDVD(QString dvd_url); //#ifdef BLURAY_SUPPORT // void openBluRay(QString blu_ray_url); //#endif void openVCD(int title = -1); void openAudioCD(int title = -1); void openTV(QString channel_id); //#ifdef YOUTUBE_SUPPORT // void openYT(const QString & url); //#endif void loadSub(const QString & sub); void unloadSub(); //! Forces to use the specified subtitle file. It's not loaded immediately but stored //! and will be used for the next video. After that the variable is cleared. void setInitialSubtitle(const QString & subtitle_file) { initial_subtitle = subtitle_file; }; void loadAudioFile(const QString & audiofile); void unloadAudioFile(); void stop(); void play(); void play_or_pause(); void pause_and_frame_step(); void pause(); void frameStep(); void frameBackStep(); void screenshot(); //!< Take a screenshot of current frame void screenshots(); //!< Start/stop taking screenshot of each frame //#ifdef CAPTURE_STREAM // void switchCapturing(); //#endif //! Public restart, for the GUI. void restart(); //! Reopens the file (no restart) void reload(); //#ifdef SEEKBAR_RESOLUTION void goToPosition( int value ); void goToPos( double perc ); //#else // void goToPos( int perc ); //#endif void goToSec( double sec ); void goToSec(int sec) { goToSec( (double) sec); } void setAMarker(); //!< Set A marker to current sec void setAMarker(int sec); void setBMarker(); //!< Set B marker to current sec void setBMarker(int sec); void clearABMarkers(); // void toggleRepeat(); // void toggleRepeat(bool b); void toggleFlip(); void toggleFlip(bool b); void toggleMirror(); void toggleMirror(bool b); // Audio filters //#ifdef MPLAYER_SUPPORT // void toggleKaraoke(); // void toggleKaraoke(bool b); // void toggleExtrastereo(); // void toggleExtrastereo(bool b); //#endif // void toggleVolnorm(); // void toggleVolnorm(bool b); void setAudioChannels(int channels); void setStereoMode(int mode); // Video filters void toggleAutophase(); void toggleAutophase(bool b); void toggleDeblock(); void toggleDeblock(bool b); void toggleDering(); void toggleDering(bool b); void toggleGradfun(); void toggleGradfun(bool b); void toggleNoise(); void toggleNoise(bool b); void togglePostprocessing(); void togglePostprocessing(bool b); void changeDenoise(int); void changeUnsharp(int); void changeLetterbox(bool); void changeLetterboxOnFullscreen(bool); void changeUpscale(bool); void changeStereo3d(const QString & in, const QString & out); void seek(int secs); void sforward(); // + 10 seconds void srewind(); // - 10 seconds void forward(); // + 1 minute void rewind(); // -1 minute void fastforward(); // + 10 minutes void fastrewind(); // - 10 minutes void forward(int secs); void rewind(int secs); //#ifdef MPV_SUPPORT // void seekToNextSub(); // void seekToPrevSub(); //#endif void wheelUp(); void wheelDown(); void setSpeed( double value ); void incSpeed10(); //!< Inc speed 10% void decSpeed10(); //!< Dec speed 10% void incSpeed4(); //!< Inc speed 4% void decSpeed4(); //!< Dec speed 4% void incSpeed1(); //!< Inc speed 1% void decSpeed1(); //!< Dec speed 1% void doubleSpeed(); void halveSpeed(); void normalSpeed(); void setVolume(int volume, bool force = false); void switchMute(); void mute(bool b); void incVolume(); void decVolume(); bool getMute();//kobe int getVolumn();//kobe void setBrightness(int value); void setContrast(int value); void setGamma(int value); void setHue(int value); void setSaturation(int value); void incBrightness(); void decBrightness(); void incContrast(); void decContrast(); void incGamma(); void decGamma(); void incHue(); void decHue(); void incSaturation(); void decSaturation(); void setSubDelay(int delay); void incSubDelay(); void decSubDelay(); void setAudioDelay(int delay); void incAudioDelay(); void decAudioDelay(); void incSubPos(); void decSubPos(); // void changeSubScale(double value); // void incSubScale(); // void decSubScale(); // void changeOSDScale(double value); // void incOSDScale(); // void decOSDScale(); //! Select next line in subtitle file void incSubStep(); //! Select previous line in subtitle file void decSubStep(); void changeSubVisibility(bool visible); void changeExternalSubFPS(int fps_id); //! Audio equalizer // void setAudioEqualizer(AudioEqualizerList values, bool restart = false); // void setAudioAudioEqualizerRestart(AudioEqualizerList values) { setAudioEqualizer(values, true); }; void updateAudioEqualizer(); void setAudioEq(int eq, int value); void setAudioEq0(int value); void setAudioEq1(int value); void setAudioEq2(int value); void setAudioEq3(int value); void setAudioEq4(int value); void setAudioEq5(int value); void setAudioEq6(int value); void setAudioEq7(int value); void setAudioEq8(int value); void setAudioEq9(int value); void changeDeinterlace(int); void changeSubtitle(int); void nextSubtitle(); //#ifdef MPV_SUPPORT // void changeSecondarySubtitle(int); //#endif void changeAudio(int ID, bool allow_restart = true); void nextAudio(); void changeVideo(int ID, bool allow_restart = true); void nextVideo(); //#if PROGRAM_SWITCH // void changeProgram(int ID); // void nextProgram(); //#endif void changeTitle(int); void changeChapter(int); void prevChapter(); void nextChapter(); void changeAngle(int); void changeAspectRatio(int); void nextAspectRatio(); void changeOSD(int); void nextOSD(); void nextWheelFunction(); //#ifdef BOOKMARKS // void nextBookmark(); // void prevBookmark(); //#endif // #if 0 // void changeSize(int); // Size of the window // void toggleDoubleSize(); // #endif void changeZoom(double); // Zoom on mplayerwindow void changeRotate(int r); //#if USE_ADAPTER // void changeAdapter(int n); //#endif void incZoom(); void decZoom(); void resetZoom(); void autoZoom(); void autoZoomFromLetterbox(double video_aspect); void autoZoomFor169(); void autoZoomFor235(); void showFilenameOnOSD(); void showTimeOnOSD(); void toggleDeinterlace(); // void changeUseCustomSubStyle(bool); // void toggleForcedSubsOnly(bool); // void changeClosedCaptionChannel(int); /* void nextClosedCaptionChannel(); void prevClosedCaptionChannel(); */ //#if DVDNAV_SUPPORT // // dvdnav buttons // void dvdnavUp(); // void dvdnavDown(); // void dvdnavLeft(); // void dvdnavRight(); // void dvdnavMenu(); // void dvdnavSelect(); // void dvdnavPrev(); // void dvdnavMouse(); //#endif //! Change fullscreen when using the player own window void changeFullscreenMode(bool b); //! Wrapper for the osd_show_text slave command void displayTextOnOSD(QString text, int duration = 3000, int level = 1, QString prefix = QString::null); public: //! Returns the number of the first chapter in //! files. In some versions of mplayer is 0, in others 1 // static int firstChapter(); int firstDVDTitle(); int firstBlurayTitle(); //#ifndef NO_USE_INI_FILES void changeFileSettingsMethod(QString method); //#endif protected: //! Returns the prefix to keep pausing on slave commands QString pausing_prefix(); void seek_cmd(double secs, int mode); protected slots: void changeCurrentSec(double sec); void changePause(); void gotWindowResolution( int w, int h ); void gotNoVideo(); void gotVO(QString); void gotAO(QString); void gotStartingTime(double); void gotVideoBitrate(int); void gotAudioBitrate(int); void finishRestart(); void processFinished(); void fileReachedEnd(); void displayMessage(QString text); void displayScreenshotName(QString filename); void displayUpdatingFontCache(); void displayBuffering(); void displayPlaying(); void streamTitleChanged(QString); void streamTitleAndUrlChanged(QString,QString); // Catches mediaInfoChanged and sends mediaPlaying signal void sendMediaInfo(); void watchState(Core::State state); //! Called when a video has just started to play. //! This function checks if the codec of video is ffh264 and if //! the resolution is HD void checkIfVideoIsHD(); #if DELAYED_AUDIO_SETUP_ON_STARTUP void initAudioTrack(); #endif //#if NOTIFY_AUDIO_CHANGES void initAudioTrack(const Tracks &); //#endif #if NOTIFY_VIDEO_CHANGES void initVideoTrack(const Tracks &); #endif #if NOTIFY_SUB_CHANGES void initSubtitleTrack(const SubTracks &); void setSubtitleTrackAgain(const SubTracks &); #endif //#if NOTIFY_CHAPTER_CHANGES // void updateChapterInfo(const Chapters &); //#endif //#if DVDNAV_SUPPORT // void dvdTitleChanged(int); // void durationChanged(double); // void askForInfo(); // void dvdnavUpdateMousePos(QPoint); // void dvdTitleIsMenu(); // void dvdTitleIsMovie(); //#endif void initializeOSD(); //#ifdef YOUTUBE_SUPPORT // void connectingToYT(QString host); // void YTFailed(int error_number, QString error_str); // void YTNoVideoUrl(); //#endif //#if defined(Q_OS_WIN) || defined(Q_OS_OS2) //#ifdef SCREENSAVER_OFF // void enableScreensaver(); // void disableScreensaver(); //#endif //#endif protected: void playNewFile(QString file, int seek=-1); void restartPlay(); void initPlaying(int seek=-1); void newMediaPlaying(); void startMplayer(QString file, double seek = -1 ); void stopMplayer(); //#ifndef NO_USE_INI_FILES void saveMediaInfo(); //#endif void initializeMenus(); void updateWidgets(); //! Returns true if changing the subscale requires to restart mplayer // bool subscale_need_restart(); int adjustVolume(int v, int max_vol); signals: void buffering(); void aboutToStartPlaying(); // Signal emited just before to start mplayer void mediaLoaded(); void mediaInfoChanged(); //! Sends the filename and title of the stream playing in this moment void mediaPlaying(const QString & filename, const QString & title); void stateChanged(Core::State state); void mediaStartPlay(); void mediaFinished(); // Media has arrived to the end. void mediaStoppedByUser(); void show_logo_signal(bool b); void showMessage(QString text); void showMessage(QString text, int time); void menusNeedInitialize(); void widgetsNeedUpdate(); void videoEqualizerNeedsUpdate(); void audioEqualizerNeedsUpdate(); void showTime(double sec, bool flag);//kobe //#ifdef SEEKBAR_RESOLUTION void positionChanged(int); // To connect a slider //#else // void posChanged(int); // To connect a slider //#endif void newDuration(double); // Duration has changed void showFrame(int frame); void ABMarkersChanged(int secs_a, int secs_b); void needResize(int w, int h); void noVideo(); void volumeChanged(int); //#if NOTIFY_AUDIO_CHANGES void audioTracksChanged(); //#endif //! Sent when requested to play, but there is no file to play void noFileToPlay(); //! MPlayer started but finished with exit code != 0 void mplayerFinishedWithError(int exitCode); //! MPlayer didn't started or crashed void mplayerFailed(QProcess::ProcessError error); // Resend signal from mplayerprocess: void failedToParseMplayerVersion(QString line_with_mplayer_version); //! A new line from the mplayer output is available void logLineAvailable(QString); //#ifdef YOUTUBE_SUPPORT // void signatureNotFound(const QString &); // void noSslSupport(); //#endif void receivedForbidden(); protected: PlayerProcess * proc; MplayerWindow * mplayerwindow; //#ifndef NO_USE_INI_FILES FileSettings * file_settings; // FileSettingsBase * tv_settings; //#endif //#if defined(Q_OS_WIN) || defined(Q_OS_OS2) //#ifdef SCREENSAVER_OFF // WinScreenSaver * win_screensaver; //#endif //#endif //#ifdef YOUTUBE_SUPPORT // RetrieveYoutubeUrl * yt; //#endif private: // Some variables to proper restart bool we_are_restarting; bool just_loaded_external_subs; bool just_unloaded_external_subs; State _state; bool change_volume_after_unpause; QString initial_subtitle; //#if DVDNAV_SUPPORT // bool dvdnav_title_is_menu; //#endif QMap forced_titles; }; #endif kylin-video/src/smplayer/mylineedit.h0000664000175000017500000000224313233751662016702 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef MYLINEEDIT_H #define MYLINEEDIT_H #include "../merge/lineedit_with_icon.h" class QToolButton; class MyLineEdit : public LineEditWithIcon { Q_OBJECT public: MyLineEdit(QWidget *parent = 0); protected: virtual void setupButton(); private slots: void updateCloseButton(const QString &text); }; #endif // MYLINEEDIT_H kylin-video/src/smplayer/reminderdialog.ui0000664000175000017500000001166513214706400017707 0ustar fengfeng ReminderDialog 0 0 501 212 Help SMPlayer 100 0 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 255 true QFrame::WinPanel QFrame::Sunken icon Qt::AlignCenter 0 0 text true Qt::Horizontal 40 20 &Remind me later true Qt::Horizontal Qt::Horizontal QDialogButtonBox::Close buttonBox remind_check kylin-video/src/smplayer/mediasettings.h0000664000175000017500000001156413233751662017405 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef MEDIASETTINGS_H #define MEDIASETTINGS_H /* Settings the user has set for this file, and that we need to */ /* restore the video after a restart */ #include #include #include "config.h" class QSettings; class MediaSettings { public: enum Denoise { NoDenoise = 0, DenoiseNormal = 1, DenoiseSoft = 2 }; enum Aspect { AspectAuto = 1, Aspect43 = 2, Aspect54 = 3, Aspect149 = 4, Aspect169 = 5, Aspect1610 = 6, Aspect235 = 7, Aspect11 = 8, Aspect32 = 9, Aspect1410 = 10, Aspect118 = 11, AspectNone = 0 }; enum Deinterlace { NoDeinterlace = 0, L5 = 1, Yadif = 2, LB = 3, Yadif_1 = 4, Kerndeint = 5 }; enum AudioChannels { ChDefault = 0, ChStereo = 2, ChSurround = 4, ChFull51 = 6, ChFull61 = 7, ChFull71 = 8 }; enum StereoMode { Stereo = 0, Left = 1, Right = 2, Mono = 3, Reverse = 4 }; enum Rotate { NoRotate = -1, Clockwise_flip = 0, Clockwise = 1, Counterclockwise = 2, Counterclockwise_flip = 3 }; enum IDs { NoneSelected = -1000, SubNone = 90000 }; enum SubFPS { SFPS_None, SFPS_23, SFPS_24, SFPS_25, SFPS_30, SFPS_23976, SFPS_29970 }; MediaSettings(); virtual ~MediaSettings(); virtual void reset(); double current_sec; int current_sub_id; //#ifdef MPV_SUPPORT // int current_secondary_sub_id; //#endif //#if PROGRAM_SWITCH // int current_program_id; //#endif int current_video_id; int current_audio_id; int current_title_id; int current_chapter_id; int current_angle_id; int aspect_ratio_id; //bool fullscreen; int volume; bool mute; int brightness, contrast, gamma, hue, saturation; // AudioEqualizerList audio_equalizer; QString external_subtitles; int external_subtitles_fps; QString external_audio; // external audio file int sub_delay; int audio_delay; // Subtitles position (0-100) int sub_pos; double sub_scale; double sub_scale_ass; int closed_caption_channel; // 0 = disabled double speed; // Speed of playback: 1.0 = normal speed int current_deinterlacer; bool add_letterbox; // Filters in menu bool phase_filter; bool deblock_filter; bool dering_filter; bool gradfun_filter; bool noise_filter; bool postprocessing_filter; bool upscaling_filter; //!< Software scaling int current_denoiser; int current_unsharp; QString stereo3d_in; QString stereo3d_out; //#ifdef MPLAYER_SUPPORT bool karaoke_filter; bool extrastereo_filter; //#endif bool volnorm_filter; int audio_use_channels; int stereo_mode; double zoom_factor; // mplayerwindow zoom int rotate; bool flip; //!< Flip image bool mirror; //!< Mirrors the image on the Y axis. bool loop; //!< Loop. If true repeat the file int A_marker; int B_marker; //#ifdef BOOKMARKS // QMap bookmarks; //#endif // This a property of the video and it should be // in mediadata, but we have to save it to preserve // this data among restarts. double starting_time; // Some videos don't start at 0 //! The codec of the video is ffh264 and it's high definition bool is264andHD; QString current_demuxer; // Advanced settings QString forced_demuxer; QString forced_video_codec; QString forced_audio_codec; // A copy of the original values, so we can restore them. QString original_demuxer; QString original_video_codec; QString original_audio_codec; // Options to mplayer (for this file only) // QString mplayer_additional_options; // QString mplayer_additional_video_filters; // QString mplayer_additional_audio_filters; // Some things that were before in mediadata // They can vary, because of filters, so better here // Resolution used by mplayer // Can be bigger that video resolution // because of the aspect ratio or expand filter int win_width; int win_height; double win_aspect(); //! Returns the aspect as a double. Returns 0 if aspect == AspectNone. double aspectToNum(Aspect aspect); static QString aspectToString(Aspect aspect); void list(); //#ifndef NO_USE_INI_FILES void save(QSettings * set, int player_id); void load(QSettings * set, int player_id); //#endif }; #endif kylin-video/src/smplayer/mycombobox.cpp0000664000175000017500000001045313233751662017252 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "mycombobox.h" #include #include #include MyComboBox::MyComboBox( QWidget * parent ) : QComboBox(parent) { this->setStyleSheet("QComboBox{width:150px;height:24px;border:1px solid #000000;background:#0f0f0f;font-size:12px;font-family:方正黑体_GBK;background-position:center left;padding-left:5px;color:#999999;selection-color:#ffffff;selection-background-color:#1f1f1f;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox::drop-down {width:17px;border:none;background:transparent;}QComboBox::drop-down:hover {background:transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView{border:1px solid #0a9ff5;background:#262626;outline:none;}"); // this->setStyleSheet("QComboBox{width:150px;height:24px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:enabled {background:#0f0f0f;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox:enabled:hover, QComboBox:enabled:focus {color: #1f1f1f;}QComboBox::drop-down {width: 17px;border: none;background: transparent;}QComboBox::drop-down:hover {background: transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView {border: 1px solid #0a9ff5;background: #1f1f1f;outline: none;}"); } MyComboBox::~MyComboBox() { } void MyComboBox::setCurrentText( const QString & text ) { int i = findText(text); if (i != -1) setCurrentIndex(i); else if (isEditable()) setEditText(text); else setItemText(currentIndex(), text); } void MyComboBox::insertStringList( const QStringList & list, int index ) { insertItems((index < 0 ? count() : index), list); } MyFontComboBox::MyFontComboBox( QWidget * parent ) : QFontComboBox(parent) { } MyFontComboBox::~MyFontComboBox() { } void MyFontComboBox::setCurrentText( const QString & text ) { int i = findText(text); if (i != -1) setCurrentIndex(i); else if (isEditable()) setEditText(text); else setItemText(currentIndex(), text); } void MyFontComboBox::setFontsFromDir(const QString & fontdir) { QString current_text = currentText(); if (fontdir.isEmpty()) { QFontDatabase::removeAllApplicationFonts(); clear(); setWritingSystem(QFontDatabase::Any); } else { QFontDatabase fdb; QStringList fontnames; QStringList fontfiles = QDir(fontdir).entryList(QStringList() << "*.ttf" << "*.otf", QDir::Files); for (int n=0; n < fontfiles.count(); n++) { qDebug() << "MyFontComboBox::setFontsFromDir: adding font:" << fontfiles[n]; int id = fdb.addApplicationFont(fontdir +"/"+ fontfiles[n]); fontnames << fdb.applicationFontFamilies(id); } //fdb.removeAllApplicationFonts(); fontnames.removeDuplicates(); qDebug() << "MyFontComboBox::setFontsFromDir: fontnames:" << fontnames; clear(); QStringListModel *m = qobject_cast(model()); if (m) m->setStringList(fontnames); } setCurrentText(current_text); } kylin-video/src/smplayer/languages.h0000664000175000017500000000246513233751662016513 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef LANGUAGES_H #define LANGUAGES_H #include #include class Languages : public QObject { Q_OBJECT public: //! Returns the ISO_639-1 language list static QMap list(); //! List with the most used languages static QMap most_used_list(); //! Returns the list of translations available static QMap translations(); static QMap encodings(); static QMap enca(); }; #endif kylin-video/src/smplayer/shutdowndialog.h0000664000175000017500000000230513233751662017571 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef SHUTDOWNDIALOG_H #define SHUTDOWNDIALOG_H #include "ui_shutdowndialog.h" class QTimer; class ShutdownDialog : public QDialog, public Ui::ShutdownDialog { Q_OBJECT public: ShutdownDialog( QWidget* parent = 0, Qt::WindowFlags f = 0 ); ~ShutdownDialog(); private slots: void updateCountdown(); private: int countdown; QTimer * timer; QString text; }; #endif kylin-video/src/smplayer/infofile.cpp0000664000175000017500000001777113233751662016701 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "infofile.h" #include #include #include "images.h" InfoFile::InfoFile() { row = 0; } InfoFile::~InfoFile() { } QString InfoFile::getInfo(MediaData md) { QString s; // General QFileInfo fi(md.filename); QString icon; switch (md.type) { case TYPE_FILE : if (md.novideo) icon = "type_audio.png"; else icon = "type_video.png"; break; case TYPE_DVD : icon = "type_dvd.png"; break; case TYPE_VCD : icon = "type_vcd.png"; break; case TYPE_AUDIO_CD : icon = "type_vcd.png"; break; case TYPE_TV : icon = "type_tv.png"; break; case TYPE_STREAM : icon = "type_url.png"; break; //#ifdef BLURAY_SUPPORT // case TYPE_BLURAY : icon = "type_bluray.png"; break; //#endif default : icon = "type_unknown.png"; } icon = icon.replace(".png", ""); // FIXME icon = " "; //#ifdef BLURAY_SUPPORT // if (md.type == TYPE_DVD || md.type == TYPE_BLURAY) //#else // if (md.type == TYPE_DVD) ////#endif // { // DiscData disc_data = DiscName::split(md.filename); // s += title( icon + disc_data.protocol + "://" + QString::number(disc_data.title) ); // } else { // s += title( icon + md.displayName() ); // } s += openPar( tr("General") ); if (fi.exists()) { //s += addItem( tr("Path"), fi.dirPath() ); s += addItem( tr("File"), fi.absoluteFilePath() ); s += addItem( tr("Size"), tr("%1 KB (%2 MB)").arg(fi.size()/1024) .arg(fi.size()/1048576) ); } else { QString url = md.filename; s += addItem( tr("URL"), url ); } s += addItem( tr("Length"), Helper::formatTime((int)md.duration) ); s += addItem( tr("Demuxer"), md.demuxer ); s += closePar(); // Clip info QString c; if (!md.clip_name.isEmpty()) c+= addItem( tr("Name"), md.clip_name ); // if (!m.isEmpty()) c+= addItem( tr("Name"), md.clip_name ); if (!md.clip_artist.isEmpty()) c+= addItem( tr("Artist"), md.clip_artist ); if (!md.clip_author.isEmpty()) c+= addItem( tr("Author"), md.clip_author ); if (!md.clip_album.isEmpty()) c+= addItem( tr("Album"), md.clip_album ); if (!md.clip_genre.isEmpty()) c+= addItem( tr("Genre"), md.clip_genre ); if (!md.clip_date.isEmpty()) c+= addItem( tr("Date"), md.clip_date ); if (!md.clip_track.isEmpty()) c+= addItem( tr("Track"), md.clip_track ); if (!md.clip_copyright.isEmpty()) c+= addItem( tr("Copyright"), md.clip_copyright ); if (!md.clip_comment.isEmpty()) c+= addItem( tr("Comment"), md.clip_comment ); if (!md.clip_software.isEmpty()) c+= addItem( tr("Software"), md.clip_software ); if (!md.stream_title.isEmpty()) c+= addItem( tr("Stream title"), md.stream_title ); if (!md.stream_url.isEmpty()) c+= addItem( tr("Stream URL"), md.stream_url ); if (!c.isEmpty()) { s += openPar( tr("Clip info") ); s += c; s += closePar(); } // Video info if (!md.novideo) { s += openPar( tr("Video") ); s += addItem( tr("Resolution"), QString("%1 x %2").arg(md.video_width).arg(md.video_height) ); s += addItem( tr("Aspect ratio"), QString::number(md.video_aspect) ); s += addItem( tr("Format"), md.video_format ); s += addItem( tr("Bitrate"), tr("%1 kbps").arg(md.video_bitrate / 1000) ); s += addItem( tr("Frames per second"), md.video_fps ); s += addItem( tr("Selected codec"), md.video_codec ); s += closePar(); } // Audio info s += openPar( tr("Initial Audio Stream") ); s += addItem( tr("Format"), md.audio_format ); s += addItem( tr("Bitrate"), tr("%1 kbps").arg(md.audio_bitrate / 1000) ); s += addItem( tr("Rate"), tr("%1 Hz").arg(md.audio_rate) ); s += addItem( tr("Channels"), QString::number(md.audio_nch) ); s += addItem( tr("Selected codec"), md.audio_codec ); s += closePar(); // Audio Tracks if (md.audios.numItems() > 0) { s += openPar( tr("Audio Streams") ); row++; // s += openItem();//kobe 20170627 s += "" + tr("#", "Info for translators: this is a abbreviation for number") + "" + tr("Language") + "" + tr("Name") +"" + tr("ID", "Info for translators: this is a identification code") + ""; s += closeItem(); for (int n = 0; n < md.audios.numItems(); n++) { row++; // s += openItem();//kobe 20170627 QString lang = md.audios.itemAt(n).lang(); if (lang.isEmpty()) lang = "<"+tr("empty")+">"; QString name = md.audios.itemAt(n).name(); if (name.isEmpty()) name = "<"+tr("empty")+">"; s += QString("%1%2%3%4") .arg(n).arg(lang).arg(name) .arg(md.audios.itemAt(n).ID()); s += closeItem(); } s += closePar(); } // Subtitles if (md.subs.numItems() > 0) { s += openPar( tr("Subtitles") ); row++; // s += openItem();//kobe 20170627 s += "" + tr("#", "Info for translators: this is a abbreviation for number") + "" + tr("Type") + "" + tr("Language") + "" + tr("Name") +"" + tr("ID", "Info for translators: this is a identification code") + ""; s += closeItem(); for (int n = 0; n < md.subs.numItems(); n++) { row++; // s += openItem();//kobe 20170627 QString t; switch (md.subs.itemAt(n).type()) { case SubData::File: t = "FILE_SUB"; break; case SubData::Vob: t = "VOB"; break; default: t = "SUB"; } QString lang = md.subs.itemAt(n).lang(); if (lang.isEmpty()) lang = "<"+tr("empty")+">"; QString name = md.subs.itemAt(n).name(); if (name.isEmpty()) name = "<"+tr("empty")+">"; /* s += QString("%1%2%3%4%5") .arg(n).arg(t).arg(lang).arg(name) .arg(md.subs.itemAt(n).ID()); */ s += "" + QString::number(n) + "" + t + "" + lang + "" + name + "" + QString::number(md.subs.itemAt(n).ID()) + ""; s += closeItem(); } s += closePar(); } return ""+ s + ""; } QString InfoFile::title(QString text) { return "

" + text + "

"; } QString InfoFile::openPar(QString text) { //kobe 20170627 return "

" + text + "

" ""; // return "

" + text + "

" // "
"; } QString InfoFile::closePar() { row = 0; return "
"; } QString InfoFile::openItem() { //kobe 20170627 return "";//height="100" bgColor="red" // if (row % 2 == 1) // return ""; // else // return ""; } QString InfoFile::closeItem() { return ""; } QString InfoFile::addItem( QString tag, QString value ) { row++; return openItem() + "" + tag + "" + "" + value + "" + closeItem();// height=\"100px\" } inline QString InfoFile::tr( const char * sourceText, const char * comment, int n ) { #if QT_VERSION >= 0x050000 return QCoreApplication::translate("InfoFile", sourceText, comment, n ); #else return QCoreApplication::translate("InfoFile", sourceText, comment, QCoreApplication::CodecForTr, n ); #endif } kylin-video/src/smplayer/filechooser.h0000664000175000017500000000425513233751662017046 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _FILECHOOSER_H_ #define _FILECHOOSER_H_ #include "../merge/lineedit_with_icon.h" #include class QToolButton; class FileChooser : public LineEditWithIcon { Q_OBJECT Q_PROPERTY(QString text READ text WRITE setText) Q_PROPERTY(QString caption READ caption WRITE setCaption) Q_PROPERTY(QString filter READ filter WRITE setFilter) Q_PROPERTY(DialogType dialogType READ dialogType WRITE setDialogType) Q_PROPERTY(QFileDialog::Options options READ options WRITE setOptions) public: enum DialogType { GetFileName = 0, GetDirectory = 1 }; FileChooser( QWidget* parent = 0 ); ~FileChooser(); QString caption() const { return _caption; }; QString filter() const { return _filter; }; DialogType dialogType() const { return _type; }; QFileDialog::Options options() const { return _options; }; public slots: void setCaption(const QString & caption) { _caption = caption; }; void setFilter(const QString & filter) { _filter = filter; }; void setDialogType( DialogType type) { _type = type; }; void setOptions( QFileDialog::Options options) { _options = options; }; signals: void fileChanged(QString file); protected: virtual void setupButton(); protected slots: virtual void openFileDialog(); protected: QString _caption; QString _filter; DialogType _type; QFileDialog::Options _options; static QString last_dir; }; #endif kylin-video/src/smplayer/myapplication.h0000664000175000017500000000325713233751662017416 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef MYAPPLICATION_H #define MYAPPLICATION_H #include #ifdef SINGLE_INSTANCE #include "QtSingleApplication" class MyApplication : public QtSingleApplication { Q_OBJECT public: MyApplication ( const QString & appId, int & argc, char ** argv ) : QtSingleApplication(appId, argc, argv) {}; virtual void commitData ( QSessionManager & /*manager*/ ) { // Nothing to do, let the application to close } inline static MyApplication * instance() { return qobject_cast(QApplication::instance()); } }; #else #include class MyApplication : public QApplication { Q_OBJECT public: MyApplication ( const QString & appId, int & argc, char ** argv ) : QApplication(argc, argv) {}; virtual void commitData ( QSessionManager & /*manager*/ ) { // Nothing to do, let the application to close } }; #endif #endif kylin-video/src/smplayer/myactiongroup.cpp0000664000175000017500000000613613233751662017777 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "myactiongroup.h" #include #include #include MyActionGroupItem::MyActionGroupItem(QObject * parent, MyActionGroup *group, const char * name, int data, bool autoadd) : MyAction(parent, name, autoadd) { setData(data); setCheckable(true); if (group) group->addAction(this); } MyActionGroupItem::MyActionGroupItem(QObject * parent, MyActionGroup *group, const QString & text, const char * name, int data, bool autoadd) : MyAction(parent, name, autoadd) { setData(data); setText(text); setCheckable(true); if (group) group->addAction(this); } MyActionGroup::MyActionGroup( QObject * parent ) : QActionGroup(parent) { setExclusive(true); connect( this, SIGNAL(triggered(QAction *)), this, SLOT(itemTriggered(QAction *)) ); } void MyActionGroup::setChecked(int ID) { //qDebug("MyActionGroup::setChecked: ID: %d", ID); QList l = actions(); for (int n=0; n < l.count(); n++) { if ( (!l[n]->isSeparator()) && (l[n]->data().toInt() == ID) ) { l[n]->setChecked(true); return; } } } int MyActionGroup::checked() { QAction * a = checkedAction(); if (a) return a->data().toInt(); else return -1; } void MyActionGroup::uncheckAll() { QList l = actions(); for (int n=0; n < l.count(); n++) { l[n]->setChecked(false); } } void MyActionGroup::setActionsEnabled(bool b) { QList l = actions(); for (int n=0; n < l.count(); n++) { l[n]->setEnabled(b); } } void MyActionGroup::clear(bool remove) { while (actions().count() > 0) { QAction * a = actions()[0]; if (a) { removeAction(a); if (remove) a->deleteLater(); } } } void MyActionGroup::itemTriggered(QAction *a) { qDebug("MyActionGroup::itemTriggered: '%s'", a->objectName().toUtf8().data()); int value = a->data().toInt(); qDebug("MyActionGroup::itemTriggered: ID: %d", value); emit activated(value); } void MyActionGroup::addTo(QWidget *w) { w->addActions( actions() ); } void MyActionGroup::removeFrom(QWidget *w) { for (int n=0; n < actions().count(); n++) { w->removeAction( actions()[n] ); } } //#include "moc_myactiongroup.cpp" kylin-video/src/smplayer/myprocess.h0000664000175000017500000000516213233751662016566 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _MY_PROCESS_H_ #define _MY_PROCESS_H_ #include #include #include //! MyProcess is a specialized QProcess designed to properly work with mplayer. /*! It can split the mplayer status line into lines. It also provides some Qt 3 like functions like addArgument(). There are two working modes, controlled by the USE_TEMP_FILE define. If USE_TEMP_FILE is 1 it will send the output of mplayer to a temporary file, and then it will be read from it. Otherwise it will read from standard ouput as usual. */ class MyProcess : public QProcess { Q_OBJECT public: MyProcess ( QObject * parent = 0 ); virtual void setExecutable(const QString & p) { program = p; }; QString executable() { return program; }; virtual void addArgument(const QString & a); //!< Add an argument void clearArguments(); //!< Clear the list of arguments QStringList arguments(); //!< Return the list of arguments void start(); //!< Start the process bool isRunning(); //!< Return true if the process is running static QStringList splitArguments(const QString & args); signals: //! Emitted when there's a line available void lineAvailable(QByteArray ba); protected slots: void readStdOut(); //!< Called for reading from standard output void readTmpFile(); //!< Called for reading from the temp file void procFinished(); //!< Called when the process has finished protected: //! Return true if it's possible to read an entire line. /*! @param from specifies the position to begin. */ int canReadLine(const QByteArray & ba, int from = 0); //! Called from readStdOut() and readTmpFile() to do all the work void genericRead(QByteArray buffer); protected: QString program; QStringList arg; QByteArray remaining_output; QTemporaryFile temp_file; QTimer timer; }; #endif kylin-video/src/smplayer/myaction.cpp0000664000175000017500000000511213233751662016713 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "myaction.h" #include MyAction::MyAction ( QObject * parent, const char * name, bool autoadd ) : QAction(parent) { //qDebug("MyAction::MyAction: name: '%s'", name); setObjectName(name); if (autoadd) addActionToParent(); } MyAction::MyAction( QObject * parent, bool autoadd ) : QAction(parent) { //qDebug("MyAction::MyAction: QObject, bool"); if (autoadd) addActionToParent(); } MyAction::MyAction(const QString & text, QKeySequence accel, QObject * parent, const char * name, bool autoadd ) : QAction(parent) { setObjectName(name); setText(text); setShortcut(accel); if (autoadd) addActionToParent(); } MyAction::MyAction(QKeySequence accel, QObject * parent, const char * name, bool autoadd ) : QAction(parent) { setObjectName(name); setShortcut(accel); if (autoadd) addActionToParent(); } MyAction::~MyAction() { } void MyAction::addShortcut(QKeySequence key) { setShortcuts( shortcuts() << key); } void MyAction::addActionToParent() { if (parent()) { if (parent()->inherits("QWidget")) { QWidget *w = static_cast (parent()); w->addAction(this); } } } void MyAction::change(const QIcon & icon, const QString & text) { setIcon( icon ); change(text); } void MyAction::change(const QString & text ) { setText( text ); QString accel_text = shortcut().toString(); QString s = text; s.replace("&",""); if (!accel_text.isEmpty()) { setToolTip( s + " ("+ accel_text +")"); setIconText( s ); } /* if (text.isEmpty()) { QString s = menuText; s = s.replace("&",""); setText( s ); if (!accel_text.isEmpty()) setToolTip( s + " ("+ accel_text +")"); } else { setText( text ); if (!accel_text.isEmpty()) setToolTip( text + " ("+ accel_text +")"); } */ } kylin-video/src/smplayer/filesettings.cpp0000664000175000017500000000543113233751662017574 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "filesettings.h" #include "mediasettings.h" #include #include FileSettings::FileSettings(QString directory) { output_directory = directory; my_settings = new QSettings(directory + "/kylin_video_files.ini", QSettings::IniFormat); } FileSettings::~FileSettings() { delete my_settings; } QString FileSettings::filenameToGroupname(const QString & filename) { QString s = filename; s = s.replace('/', '_'); s = s.replace('\\', '_'); s = s.replace(':', '_'); s = s.replace('.', '_'); s = s.replace(' ', '_'); QFileInfo fi(filename); if (fi.exists()) { s += "_" + QString::number( fi.size() ); } return s; } bool FileSettings::existSettingsFor(QString filename) { // qDebug("FileSettings::existSettingsFor: '%s'", filename.toUtf8().constData()); QString group_name = filenameToGroupname(filename); // qDebug("FileSettings::existSettingsFor: group_name: '%s'", group_name.toUtf8().constData()); my_settings->beginGroup( group_name ); bool saved = my_settings->value("saved", false).toBool(); my_settings->endGroup(); return saved; } void FileSettings::loadSettingsFor(QString filename, MediaSettings & mset, int player) { // qDebug("FileSettings::loadSettingsFor: '%s'", filename.toUtf8().constData()); QString group_name = filenameToGroupname(filename); // qDebug("FileSettings::loadSettingsFor: group_name: '%s'", group_name.toUtf8().constData()); mset.reset(); my_settings->beginGroup( group_name ); mset.load(my_settings, player); my_settings->endGroup(); } void FileSettings::saveSettingsFor(QString filename, MediaSettings & mset, int player) { // qDebug("FileSettings::saveSettingsFor: '%s'", filename.toUtf8().constData()); QString group_name = filenameToGroupname(filename); // qDebug("FileSettings::saveSettingsFor: group_name: '%s'", group_name.toUtf8().constData()); my_settings->beginGroup( group_name ); my_settings->setValue("saved", true); mset.save(my_settings, player); my_settings->endGroup(); } kylin-video/src/smplayer/deviceinfo.h0000664000175000017500000000262613233751662016657 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _DEVICEINFO_H_ #define _DEVICEINFO_H_ #include #include #include class DeviceData { public: DeviceData() {}; DeviceData(QVariant ID, QString desc) { _id = ID; _desc = desc; }; ~DeviceData() {}; void setID(QVariant ID) { _id = ID; }; void setDesc(QString desc) { _desc = desc; }; QVariant ID() { return _id; }; QString desc() { return _desc; }; private: QVariant _id; QString _desc; }; typedef QList DeviceList; class DeviceInfo { public: static DeviceList alsaDevices(); static DeviceList xvAdaptors(); }; #endif kylin-video/src/smplayer/shutdowndialog.cpp0000664000175000017500000000403113233751662020122 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "shutdowndialog.h" #include "images.h" #include #include ShutdownDialog::ShutdownDialog( QWidget* parent, Qt::WindowFlags f ) : QDialog(parent, f) , countdown(30) , timer(0) { setupUi(this); QPushButton * ok_button = buttonBox->button(QDialogButtonBox::Ok); QPushButton * cancel_button = buttonBox->button(QDialogButtonBox::Cancel); if (ok_button) { ok_button->setDefault(false); ok_button->setAutoDefault(false); } if (cancel_button) { cancel_button->setDefault(true); cancel_button->setAutoDefault(true); } setMinimumSize(QSize(500, 100)); icon_label->setPixmap(Images::icon("shutdown")); text = tr("Playback has finished. SMPlayer is about to exit.") +"
"+ tr("The computer will shut down in %1 seconds.") +"
"+ tr("Press Cancel to abort shutdown."); text_label->setText(text.arg(countdown)); adjustSize(); timer = new QTimer(this); timer->setInterval(1000); connect(timer, SIGNAL(timeout()), this, SLOT(updateCountdown())); timer->start(); } ShutdownDialog::~ShutdownDialog() { } void ShutdownDialog::updateCountdown() { countdown--; text_label->setText(text.arg(countdown)); if (countdown < 1) accept(); } #include "moc_shutdowndialog.cpp" kylin-video/src/smplayer/mycombobox.h0000664000175000017500000000271613233751662016722 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _MYCOMBOBOX_H_ #define _MYCOMBOBOX_H_ #include #include //! This class adds some Qt 3 compatibility functions which don't have a //! direct equivalent in Qt 4. class MyComboBox : public QComboBox { public: MyComboBox( QWidget * parent = 0 ); ~MyComboBox(); void setCurrentText ( const QString & text ); void insertStringList ( const QStringList & list, int index = -1 ); }; class MyFontComboBox : public QFontComboBox { public: MyFontComboBox( QWidget * parent = 0 ); ~MyFontComboBox(); void setCurrentText ( const QString & text ); void setFontsFromDir(const QString & fontdir); }; #endif kylin-video/src/smplayer/colorutils.cpp0000664000175000017500000000415313233751662017273 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "colorutils.h" #include QString ColorUtils::colorToRRGGBBAA(unsigned int color) { QColor c; c.setRgb( color ); QString s; return s.sprintf("%02x%02x%02x00", c.red(), c.green(), c.blue() ); } QString ColorUtils::colorToRRGGBB(unsigned int color) { QColor c; c.setRgb( color ); QString s; return s.sprintf("%02x%02x%02x", c.red(), c.green(), c.blue() ); } QString ColorUtils::colorToRGB(unsigned int color) { QColor c; c.setRgb( color ); QString s; return s.sprintf("0x%02x%02x%02x", c.blue(), c.green(), c.red() ); } QString ColorUtils::colorToAABBGGRR(unsigned int color) { QColor c; c.setRgb( color ); QString s; return s.sprintf("00%02x%02x%02x", c.blue(), c.green(), c.red() ); } void ColorUtils::setForegroundColor(QWidget * w, const QColor & color) { QPalette p = w->palette(); p.setColor(w->foregroundRole(), color); w->setPalette(p); } void ColorUtils::setBackgroundColor(QWidget * w, const QColor & color) { QPalette p = w->palette(); p.setColor(w->backgroundRole(), color); w->setPalette(p); } QString ColorUtils::stripColorsTags(QString s) { QRegExp rx_console_colors("\033\\[\\d\\d?;\\d\\d?m"); int removePos = rx_console_colors.lastIndexIn(s); removePos += rx_console_colors.matchedLength(); return s.remove(0, removePos); } kylin-video/src/smplayer/filesettings.h0000664000175000017500000000261413233751662017241 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _FILESETTINGS_H_ #define _FILESETTINGS_H_ #include class QSettings; class MediaSettings; class FileSettings { public: FileSettings(QString directory); virtual ~FileSettings(); virtual bool existSettingsFor(QString filename); virtual void loadSettingsFor(QString filename, MediaSettings & mset, int player); virtual void saveSettingsFor(QString filename, MediaSettings & mset, int player); static QString filenameToGroupname(const QString & filename); protected: QString output_directory; private: QSettings * my_settings; }; #endif kylin-video/src/smplayer/filechooser.cpp0000664000175000017500000000505513233751662017400 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "filechooser.h" #include #include #include "filedialog.h" #include "images.h" #include "extensions.h" QString FileChooser::last_dir; FileChooser::FileChooser(QWidget * parent) : LineEditWithIcon(parent) { this->setFixedHeight(27); setDialogType(GetFileName); setOptions(0); setupButton(); button->setCursor(Qt::PointingHandCursor); connect(button, SIGNAL(clicked()), this, SLOT(openFileDialog())); } FileChooser::~FileChooser() { } void FileChooser::setupButton() { button->setToolTip( tr("Click to select a file or folder") ); } void FileChooser::openFileDialog() { //kobe: replace this with 0 QString result; QString f; if (dialogType() == GetFileName) { QFileDialog::Options opts = options(); if (opts == 0) opts = QFileDialog::DontResolveSymlinks; QString dir = QFileInfo(text()).absolutePath(); if (dir.isEmpty()) dir = last_dir; if (dir.isEmpty()) dir = QDir::homePath(); result = MyFileDialog::getOpenFileName( 0, caption(), dir, filter(), &f, opts ); if (!result.isEmpty()) last_dir = QFileInfo(result).absolutePath(); } else if (dialogType() == GetDirectory) { QFileDialog::Options opts = options(); if (opts == 0) opts = QFileDialog::ShowDirsOnly; QString dir = text(); if (dir.isEmpty()) dir = last_dir; if (dir.isEmpty()) dir = QDir::homePath(); result = MyFileDialog::getExistingDirectory( 0, caption(), dir, opts); if (!result.isEmpty()) last_dir = result; } if (!result.isEmpty()) { QString old_file = text(); setText(result); if (old_file != result) emit fileChanged(result); } } //#include "moc_filechooser.cpp" kylin-video/src/smplayer/extensions.cpp0000664000175000017500000000472713233751662017302 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "extensions.h" ExtensionList::ExtensionList() : QStringList() { } QString ExtensionList::forFilter() { QString s; for (int n=0; n < count(); n++) { s = s + "*." + at(n) + " "; } if (!s.isEmpty()) s = " (" + s + ")"; return s; } QStringList ExtensionList::forDirFilter() { QStringList l; for (int n=0; n < count(); n++) { QString s = "*." + at(n); l << s; } return l; } QString ExtensionList::forRegExp() { QString s; for (int n=0; n < count(); n++) { if (!s.isEmpty()) s = s + "|"; s = s + "^" + at(n) + "$"; } return s; } Extensions::Extensions() { _video << "avi" << "vfw" << "divx" << "mpg" << "mpeg" << "m1v" << "m2v" << "mpv" << "dv" << "3gp" << "mov" << "mp4" << "m4v" << "mqv" << "dat" << "vcd" << "ogg" << "ogm" << "ogv" << "ogx" << "asf" << "wmv" << "bin" << "iso" << "vob" << "mkv" << "nsv" << "ram" << "flv" << "rm" << "swf" << "ts" << "rmvb" << "dvr-ms" << "m2t" << "m2ts" << "mts" << "rec" << "wtv" << "f4v" << "hdmov" << "webm" << "vp8" << "bik" << "smk" << "m4b" << "wtv"; _audio << "mp3" << "ogg" << "oga" << "wav" << "wma" << "aac" << "ac3" << "dts" << "ra" << "ape" << "flac" << "thd" << "mka" << "m4a";// << "mid"; _subtitles << "srt" << "sub" << "ssa" << "ass" << "idx" << "txt" << "smi" << "rt" << "utf" << "aqt"; _playlist << "m3u" << "m3u8" << "pls"; _multimedia = _video; for (int n = 0; n < _audio.count(); n++) { if (!_multimedia.contains(_audio[n])) _multimedia << _audio[n]; } _all_playable << _multimedia << _playlist; } Extensions::~Extensions() { } kylin-video/src/smplayer/shutdown.h0000664000175000017500000000166213233751662016416 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef SHUTDOWN_H #define SHUTDOWN_H class Shutdown { public: static void shutdown(); }; #endif kylin-video/src/smplayer/mplayerwindow.cpp0000664000175000017500000004726413233751662020007 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "mplayerwindow.h" #include "global.h" #include "desktopinfo.h" #include "colorutils.h" //#ifndef MINILIB #include "images.h" //#endif #include #include #include #include #include #include #include #include #include #include #include #include Screen::Screen(QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f ) , check_mouse_timer(0) , mouse_last_position(QPoint(0,0)) , autohide_cursor(false) , autohide_interval(0) { setMouseTracking(true); setFocusPolicy( Qt::NoFocus ); setMinimumSize( QSize(0,0) ); // this->setWindowOpacity(0.5); // QPalette pal = palette(); // pal.setColor(QPalette::Background, QColor(0x00,0xff,0x00,0x00)); // setPalette(pal); // QPalette bgpal = palette(); // bgpal.setColor (QPalette::Background, QColor (0, 0 , 0, 255));//背景刷成黑色 // //bgpal.setColor (QPalette::Background, Qt::transparent); // bgpal.setColor (QPalette::Foreground, QColor (255,255,255,255));//前景色设为白色 // setPalette (bgpal); // this->setAutoFillBackground(true);//20170615 check_mouse_timer = new QTimer(this); connect(check_mouse_timer, SIGNAL(timeout()), this, SLOT(checkMousePos()) ); setAutoHideInterval(1000); setAutoHideCursor(false); } Screen::~Screen() { } void Screen::setAutoHideCursor(bool b) { // qDebug("Screen::setAutoHideCursor: %d", b); autohide_cursor = b; if (autohide_cursor) { check_mouse_timer->setInterval(autohide_interval); check_mouse_timer->start(); } else { check_mouse_timer->stop(); } } void Screen::checkMousePos() { // qDebug("Screen::checkMousePos"); if (!autohide_cursor) { setCursor(QCursor(Qt::ArrowCursor)); return; } QPoint pos = mapFromGlobal(QCursor::pos()); // qDebug("Screen::checkMousePos: x: %d, y: %d", pos.x(), pos.y()); if (mouse_last_position != pos) { // qDebug("Screen::checkMousePos ArrowCursor"); setCursor(QCursor(Qt::ArrowCursor)); } else { // qDebug("Screen::checkMousePos BlankCursor"); setCursor(QCursor(Qt::BlankCursor)); } mouse_last_position = pos; } void Screen::mouseMoveEvent( QMouseEvent * e ) { // qDebug("Screen::mouseMoveEvent"); emit mouseMoved(e->pos()); if (cursor().shape() != Qt::ArrowCursor) { // emit this->sigShowControls();//0830 // qDebug(" showing mouse cursor" ); setCursor(QCursor(Qt::ArrowCursor)); } } void Screen::playingStarted() { // qDebug("Screen::playingStarted"); setAutoHideCursor(true); } void Screen::playingStopped() { // qDebug("Screen::playingStopped"); setAutoHideCursor(false); } /* ---------------------------------------------------------------------- */ MplayerLayer::MplayerLayer(QWidget* parent, Qt::WindowFlags f) : Screen(parent, f) , playing(false) { #if QT_VERSION < 0x050000 setAttribute(Qt::WA_OpaquePaintEvent); #if QT_VERSION >= 0x040400 setAttribute(Qt::WA_NativeWindow); #endif setAttribute(Qt::WA_PaintUnclipped); //setAttribute(Qt::WA_PaintOnScreen); #endif } MplayerLayer::~MplayerLayer() { } void MplayerLayer::paintEvent( QPaintEvent * e ) { // qDebug("MplayerLayer::paintEvent: repaint_background: %d", repaint_background); if (/*repaint_background || */!playing) {//kobe: if repaint_background is true, Qt5 will call "QPainter::begin: Paint device returned engine == 0, type: 1" // qDebug("MplayerLayer::paintEvent: painting"); QPainter painter(this); painter.eraseRect( e->rect() ); //painter.fillRect( e->rect(), QColor(255,0,0) ); } } //#endif void MplayerLayer::playingStarted() { // qDebug("MplayerLayer::playingStarted"); repaint(); playing = true; //kobe:WA_PaintOnScreen该属性设置会导致播放音频文件时界面不刷新,此时如果显示或隐藏播放列表,则播放列表重影 //#ifndef Q_OS_WIN // setAttribute(Qt::WA_PaintOnScreen); //#endif setAttribute(Qt::WA_NativeWindow, true); Screen::playingStarted(); } void MplayerLayer::playingStopped() { qDebug("MplayerLayer::playingStopped"); playing = false; //kobe:WA_PaintOnScreen该属性设置会导致播放音频文件时界面不刷新,此时如果显示或隐藏播放列表,则播放列表重影 //#ifndef Q_OS_WIN // setAttribute(Qt::WA_PaintOnScreen, false); //#endif setAttribute(Qt::WA_NativeWindow, false); repaint(); Screen::playingStopped(); } /* ---------------------------------------------------------------------- */ MplayerWindow::MplayerWindow(QWidget* parent, Qt::WindowFlags f) : Screen(parent, f) , video_width(0) , video_height(0) , aspect((double) 4/3) , monitoraspect(0) , mplayerlayer(0) , logo(0) , offset_x(0) , offset_y(0) , zoom_factor(1.0) , orig_x(0) , orig_y(0) , orig_width(0) , orig_height(0) , allow_video_movement(false) , left_click_timer(0) , double_clicked(false) , corner_widget(0) , drag_state(NOT_DRAGGING) , start_drag(QPoint(0,0)) , mouse_drag_tracking(false) , stoped(true) { setAutoFillBackground(true); ColorUtils::setBackgroundColor( this, QColor(0,0,0) ); // ColorUtils::setBackgroundColor( this, QColor("#0d87ca") ); mplayerlayer = new MplayerLayer(this); mplayerlayer->setObjectName("mplayerlayer"); mplayerlayer->setAutoFillBackground(true); logo = new QLabel(mplayerlayer); logo->setObjectName("mplayerwindow logo"); logo->setAutoFillBackground(true); ColorUtils::setBackgroundColor(logo, QColor(0,0,0) ); QVBoxLayout * mplayerlayerLayout = new QVBoxLayout(mplayerlayer); mplayerlayerLayout->addWidget(logo, 0, Qt::AlignHCenter | Qt::AlignVCenter); setSizePolicy( QSizePolicy::Expanding , QSizePolicy::Expanding ); setFocusPolicy( Qt::StrongFocus ); installEventFilter(this); mplayerlayer->installEventFilter(this); //logo->installEventFilter(this); //kobe:为了避免双击时触发单击事件,在单击处理函数clicked()中启动一timer,延时 qApp->doubleClickInterval(),而在此timer的timeout()中处理单击事件,在双击处理函数停止此timer left_click_timer = new QTimer(this); left_click_timer->setSingleShot(true); left_click_timer->setInterval(qApp->doubleClickInterval()+10);//10 connect(left_click_timer, SIGNAL(timeout()), this, SIGNAL(leftClicked()));//0621 retranslateStrings(); } MplayerWindow::~MplayerWindow() { if (left_click_timer != NULL) { disconnect(left_click_timer, SIGNAL(timeout()), this, SIGNAL(leftClicked())); if(left_click_timer->isActive()) { left_click_timer->stop(); } delete left_click_timer; left_click_timer = NULL; } } void MplayerWindow::setCornerWidget(QWidget * w) { corner_widget = w; QHBoxLayout * blayout = new QHBoxLayout; blayout->addStretch(); blayout->addWidget(corner_widget); blayout->addStretch(); this->setLayout(blayout); // QHBoxLayout * blayout = new QHBoxLayout; // blayout->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding)); // blayout->addWidget(corner_widget); // QVBoxLayout * layout = new QVBoxLayout(this); // layout->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Expanding)); // layout->addLayout(blayout); } void MplayerWindow::setColorKey( QColor c ) { ColorUtils::setBackgroundColor( mplayerlayer, c ); } void MplayerWindow::retranslateStrings() { logo->setPixmap(Images::icon("background") );//kobe:设置显示区域的背景图 :/default-theme/background.png } void MplayerWindow::setLogoVisible( bool b) { if (corner_widget) { corner_widget->setVisible(false); } if (b) {//Fixed bug: 4979 mplayerlayer->move(0,0); mplayerlayer->resize(this->size()); } stoped = b; logo->setVisible(b); } //void MplayerWindow::show_or_hide_logo(bool b) //{ // logo->setVisible(b); //} /* void MplayerWindow::changePolicy() { setSizePolicy( QSizePolicy::Preferred , QSizePolicy::Preferred ); } */ void MplayerWindow::setResolution( int w, int h) { video_width = w; video_height = h; updateVideoWindow(); } //kobe:窗口尺寸变化响应函数 void MplayerWindow::resizeEvent( QResizeEvent *e) { // qDebug("MplayerWindow::resizeEvent: %d, %d", e->size().width(), e->size().height() ); offset_x = 0; offset_y = 0; updateVideoWindow();//kobe: setZoom(zoom_factor);//0526 } void MplayerWindow::hideLogoForTemporary() { logo->setVisible(false); } void MplayerWindow::update_logo_pos() { if (stoped) {//Fixed bug: 4979 mplayerlayer->move(0,0); mplayerlayer->resize(this->size()); logo->show(); QPropertyAnimation * animation = new QPropertyAnimation(logo, "pos"); animation->setDuration(500); animation->setEasingCurve(QEasingCurve::OutBounce); animation->setStartValue(QPoint(logo->x(), 0 - logo->y()/2)); animation->setEndValue(logo->pos()); animation->start(); // } else { // QPropertyAnimation * animation = new QPropertyAnimation(logo, "pos"); // animation->setDuration(200); // animation->setEasingCurve(QEasingCurve::OutBounce); // animation->setEndValue(QPoint(width(), logo->y())); // animation->setStartValue(logo->pos()); // animation->start(); // connect(animation, SIGNAL(finished()), logo, SLOT(hide())); // //logo->hide(); // } } } void MplayerWindow::setMonitorAspect(double asp) { monitoraspect = asp; } void MplayerWindow::setAspect( double asp) { aspect = asp; if (monitoraspect!=0) { aspect = aspect / monitoraspect * DesktopInfo::desktop_aspectRatio(this); } updateVideoWindow(); } //kobe:设置视频在屏幕上的显示 void MplayerWindow::updateVideoWindow() { //qDebug("aspect= %f", aspect); int w_width = size().width(); int w_height = size().height(); int w = w_width; int h = w_height; int x = 0; int y = 0; if (aspect != 0) { int pos1_w = w_width; int pos1_h = w_width / aspect + 0.5; int pos2_h = w_height; int pos2_w = w_height * aspect + 0.5; // qDebug("pos1_w: %d, pos1_h: %d", pos1_w, pos1_h);//pos1_w: 700, pos1_h: 298 // qDebug("pos2_w: %d, pos2_h: %d", pos2_w, pos2_h);//pos2_w: 1602, pos2_h: 681 if (pos1_h <= w_height) { //qDebug("Pos1!"); w = pos1_w; h = pos1_h; y = (w_height - h) /2; } else { //qDebug("Pos2!"); w = pos2_w; h = pos2_h; x = (w_width - w) /2; } } mplayerlayer->move(x,y); mplayerlayer->resize(w, h);//kobe:主界面全部显示视频刷新时会导致标题栏和控制栏重影 0526 orig_x = x; orig_y = y; //kobe: will cause ghosting, why??? orig_width = w; orig_height = h; // qDebug( "w_width: %d, w_height: %d", w_width, w_height);//w_width: 700, w_height: 681 // qDebug("w: %d, h: %d", w,h);//w: 700, h: 298 emit this->resize_mainwindow(w, h);//add by kobe } void MplayerWindow::mouseReleaseEvent( QMouseEvent * e) { // qDebug( "MplayerWindow::mouseReleaseEvent" ); if (e->button() == Qt::LeftButton) { e->accept(); // if (delay_left_click) { if (!double_clicked) left_click_timer->start(); double_clicked = false; // } else { // emit leftClicked(); // } } else if (e->button() == Qt::MidButton) { e->accept(); emit middleClicked(); } else if (e->button() == Qt::XButton1) { e->accept(); emit xbutton1Clicked(); } else if (e->button() == Qt::XButton2) { e->accept(); emit xbutton2Clicked(); } else if (e->button() == Qt::RightButton) { e->accept(); //emit rightButtonReleased( e->globalPos() ); emit rightClicked(); } else { e->ignore(); } } void MplayerWindow::mouseDoubleClickEvent( QMouseEvent *event) {//0621 if (event->button() == Qt::LeftButton) { event->accept(); // if (delay_left_click) { left_click_timer->stop(); double_clicked = true; // } emit doubleClicked(); } else { event->ignore(); } } void MplayerWindow::wheelEvent( QWheelEvent * e ) { // qDebug("MplayerWindow::wheelEvent: delta: %d", e->delta()); e->accept(); if (e->orientation() == Qt::Vertical) { if (e->delta() >= 0) emit wheelUp(); else emit wheelDown(); } else { qDebug("MplayerWindow::wheelEvent: horizontal event received, doing nothing"); } } //kobe:鼠标放上时显示,移开鼠标则消失 bool MplayerWindow::event(QEvent *event) { // if (event->type() == QEvent::Enter) { // this->escWidget->show(); // return true; // } return QWidget::event(event); } bool MplayerWindow::eventFilter( QObject * object, QEvent * event ) { /*switch (event->type()) {//kobe:0621 case QEvent::Enter: { if (this->isFullScreen()) this->escWidget->show(); break; } case QEvent::Leave: { this->escWidget->hide(); break; } case QEvent::MouseButtonPress: this->escWidget->hide(); break; default: break; }*/ if (!mouse_drag_tracking) return false; QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { drag_state = NOT_DRAGGING; return false; } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_DRAGGING; return false; } drag_state = START_DRAGGING; start_drag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (drag_state != DRAGGING || mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_DRAGGING; return false; } // Stop dragging and eat event drag_state = NOT_DRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (drag_state == NOT_DRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { drag_state = NOT_DRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - start_drag; if (drag_state == START_DRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < DRAG_THRESHOLD && abs(diff.y()) < DRAG_THRESHOLD) return false; drag_state = DRAGGING; } emit mouseMovedDiff(diff); start_drag = pos; event->accept(); return true; //0621 // switch (event->type()) { // /*case QEvent::Enter: { // if (this->hintWidget) { // this->hintWidget->hide(); // } //// QPoint p = parent->mapFromGlobal(mouse_event->globalPos()); ////// qDebug() << "33333AutohideWidget::eventFilter: y:" << p.y(); //// if (p.y() > (parent->height() - height() - spacing)) { //// showWidget(); //// } //// QPoint pos = mapFromGlobal(QCursor::pos()); //// QMouseEvent * mouse_event = dynamic_cast(event); //// QWidget * parent = parentWidget(); //// QPoint p = parent->mapFromGlobal(mouse_event->globalPos()); // QHelpEvent * help_event = static_cast(event); // qDebug() << "TimeSlider::event: total_time:" << total_time << "x:" << help_event->x(); // int pos_in_slider = help_event->x() * maximum() / width(); // int time = pos_in_slider * total_time / maximum(); // qDebug() << "TimeSlider::event: time:" << time; // if (time >= 0 && time <= total_time) { // qDebug () << "test time=" << Helper::formatTime(time); // hintWidget->setText(Helper::formatTime(time)); // } // QPoint centerPos = this->mapToGlobal(this->rect().center()); // QSize sz = this->hintWidget->size(); // centerPos.setX(centerPos.x() - sz.width() / 2); // centerPos.setY(centerPos.y() - 32 - sz.height()); // centerPos = this->hintWidget->mapFromGlobal(centerPos); // centerPos = this->hintWidget->mapToParent(centerPos); // this->hintWidget->move(centerPos); // this->hintWidget->show(); // this->setCursor(QCursor(Qt::PointingHandCursor)); // break; // }*/ // case QEvent::Leave: { // if (this->hintWidget) { // this->hintWidget->hide(); // } // this->unsetCursor(); // break; // } // case QEvent::MouseButtonPress: // if (this->hintWidget) { // this->hintWidget->hide(); // } // break; // default: // break; // } // return QObject::eventFilter(obj, event); } QSize MplayerWindow::sizeHint() const { //qDebug("MplayerWindow::sizeHint"); return QSize( video_width, video_height ); } QSize MplayerWindow::minimumSizeHint () const { return QSize(0,0); } void MplayerWindow::setOffsetX( int d) { offset_x = d; mplayerlayer->move( orig_x + offset_x, mplayerlayer->y() ); } int MplayerWindow::offsetX() { return offset_x; } void MplayerWindow::setOffsetY( int d) { offset_y = d; mplayerlayer->move( mplayerlayer->x(), orig_y + offset_y ); } int MplayerWindow::offsetY() { return offset_y; } void MplayerWindow::setZoom( double d) {//0526 zoom_factor = d; offset_x = 0; offset_y = 0; int x = orig_x; int y = orig_y; int w = orig_width; int h = orig_height; if (zoom_factor != 1.0) { w = w * zoom_factor; h = h * zoom_factor; // Center x = (width() - w) / 2; y = (height() -h) / 2; } mplayerlayer->move(x,y); mplayerlayer->resize(w,h);//kobe:主界面全部显示视频刷新时会导致标题栏和控制栏重影 0526 } double MplayerWindow::zoom() { return zoom_factor; } void MplayerWindow::moveLayer( int offset_x, int offset_y ) { int x = mplayerlayer->x(); int y = mplayerlayer->y(); mplayerlayer->move( x + offset_x, y + offset_y ); } void MplayerWindow::moveLeft() { if ((allow_video_movement) || (mplayerlayer->x()+mplayerlayer->width() > width() )) moveLayer( -16, 0 ); } void MplayerWindow::moveRight() { if ((allow_video_movement) || ( mplayerlayer->x() < 0 )) moveLayer( +16, 0 ); } void MplayerWindow::moveUp() { if ((allow_video_movement) || (mplayerlayer->y()+mplayerlayer->height() > height() )) moveLayer( 0, -16 ); } void MplayerWindow::moveDown() { if ((allow_video_movement) || ( mplayerlayer->y() < 0 )) moveLayer( 0, +16 ); } void MplayerWindow::incZoom() { setZoom( zoom_factor + ZOOM_STEP ); } void MplayerWindow::decZoom() { double zoom = zoom_factor - ZOOM_STEP; if (zoom < ZOOM_MIN) zoom = ZOOM_MIN; setZoom( zoom ); } // Language change stuff //void MplayerWindow::changeEvent(QEvent *e) { // if (e->type() == QEvent::LanguageChange) { // retranslateStrings(); // } else { // QWidget::changeEvent(e); // } //} //#include "moc_mplayerwindow.cpp" kylin-video/src/smplayer/kylinvideo.cpp0000664000175000017500000002031013233751662017242 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "kylinvideo.h" #include "global.h" #include "paths.h" #include "translator.h" #include "version.h" #include "config.h" #include "cleanconfig.h" #include "myapplication.h" #include #include #include #include #include using namespace Global; BaseGui * KylinVideo::main_window = 0; KylinVideo::KylinVideo(const QString &arch, QObject * parent ) : QObject(parent) { arch_type = arch; close_at_end = -1; // Not set start_in_fullscreen = -1; // Not set move_gui = false; resize_gui = false; Paths::setAppPath( qApp->applicationDirPath() ); global_init(); // Application translations translator->load(); showInfo(); } KylinVideo::~KylinVideo() { if (main_window != 0) { deleteGUI(); } global_end(); } BaseGui * KylinVideo::gui() { if (main_window == 0) { // Changes to app path, so smplayer can find a relative mplayer path QDir::setCurrent(Paths::appPath()); main_window = createGUI(this->arch_type/*gui_to_use*/); if (move_gui) { qDebug("KylinVideo::gui: moving main window to %d %d", gui_position.x(), gui_position.y()); main_window->move(gui_position); } if (resize_gui) { qDebug("KylinVideo::gui: resizing main window to %dx%d", gui_size.width(), gui_size.height()); main_window->resize(gui_size); } } return main_window; } BaseGui * KylinVideo::createGUI(QString arch_type/*QString gui_name*/) { BaseGui * gui = 0; gui = new BaseGui(arch_type, 0);//kobe:forced to go here always gui->setForceCloseOnFinish(close_at_end); gui->setForceStartInFullscreen(start_in_fullscreen); connect(gui, SIGNAL(quitSolicited()), qApp, SLOT(quit())); connect(gui, SIGNAL(guiChanged()), this, SLOT(changeGUI()));//kobe 20170710 #if SINGLE_INSTANCE MyApplication * app = MyApplication::instance(); connect(app, SIGNAL(messageReceived(const QString&)), gui, SLOT(handleMessageFromOtherInstances(const QString&))); app->setActivationWindow(gui); #endif return gui; } void KylinVideo::deleteGUI() { delete main_window; main_window = 0; } void KylinVideo::changeGUI() {//kobe 20170710 deleteGUI(); main_window = createGUI(this->arch_type); main_window->show(); } KylinVideo::ExitCode KylinVideo::processArgs(QStringList args) { QString action; // Action to be passed to running instance bool show_help = false; bool add_to_playlist = false; if (args.contains("-delete-config")) { CleanConfig::clean(Paths::configPath()); return NoError; } for (int n = 1; n < args.count(); n++) { QString argument = args[n]; if (argument == "-send-action") { if (n+1 < args.count()) { n++; action = args[n]; } else { printf("Error: expected parameter for -send-action\r\n"); return ErrorArgument; } } else if (argument == "-sub") { if (n+1 < args.count()) { n++; QString file = args[n]; if (QFile::exists(file)) { subtitle_file = QFileInfo(file).absoluteFilePath(); } else { printf("Error: file '%s' doesn't exists\r\n", file.toUtf8().constData()); } } else { printf("Error: expected parameter for -sub\r\n"); return ErrorArgument; } } else if (argument == "-media-title") { if (n+1 < args.count()) { n++; if (media_title.isEmpty()) media_title = args[n]; } } else if (argument == "-pos") { if (n+2 < args.count()) { bool ok_x, ok_y; n++; gui_position.setX( args[n].toInt(&ok_x) ); n++; gui_position.setY( args[n].toInt(&ok_y) ); if (ok_x && ok_y) move_gui = true; } else { printf("Error: expected parameter for -pos\r\n"); return ErrorArgument; } } else if (argument == "-size") { if (n+2 < args.count()) { bool ok_width, ok_height; n++; gui_size.setWidth( args[n].toInt(&ok_width) ); n++; gui_size.setHeight( args[n].toInt(&ok_height) ); if (ok_width && ok_height) resize_gui = true; } else { printf("Error: expected parameter for -resize\r\n"); return ErrorArgument; } } else if ((argument == "--help") || (argument == "-help") || (argument == "-h") || (argument == "-?") ) { show_help = true; } else if (argument == "-close-at-end") { close_at_end = 1; } else if (argument == "-no-close-at-end") { close_at_end = 0; } else if (argument == "-fullscreen") { start_in_fullscreen = 1; } else if (argument == "-no-fullscreen") { start_in_fullscreen = 0; } else if (argument == "-add-to-playlist") { add_to_playlist = true; } else if (argument == "-ontop") { pref->stay_on_top = Preferences::AlwaysOnTop; } else if (argument == "-no-ontop") { pref->stay_on_top = Preferences::NeverOnTop; } else { // File #if QT_VERSION >= 0x040600 QUrl fUrl = QUrl::fromUserInput(argument); if (fUrl.isValid() && fUrl.scheme().toLower() == "file") { argument = fUrl.toLocalFile(); } #endif if (QFile::exists( argument )) { argument = QFileInfo(argument).absoluteFilePath(); } files_to_play.append( argument ); } } for (int n=0; n < files_to_play.count(); n++) { qDebug("KylinVideo::processArgs: files_to_play[%d]: '%s'", n, files_to_play[n].toUtf8().data()); } // Single instance MyApplication * a = MyApplication::instance(); if (a->isRunning()) { a->sendMessage("Hello"); if (!action.isEmpty()) { a->sendMessage("action " + action); } else { if (!subtitle_file.isEmpty()) { a->sendMessage("load_sub " + subtitle_file); } if (!media_title.isEmpty()) { a->sendMessage("media_title " + files_to_play[0] + " <> " + media_title); } if (!files_to_play.isEmpty()) { /* a->sendMessage("open_file " + files_to_play[0]); */ QString command = "open_files"; if (add_to_playlist) command = "add_to_playlist"; a->sendMessage(command +" "+ files_to_play.join(" <> ")); } } return NoError; } return KylinVideo::NoExit; } void KylinVideo::start() { //kobe:托盘启动时显示主界面与否,与配置文件~/.config/smplayer/smplayer.ini的变量mainwindow_visible和文件列表变量files_to_play有关,可修改BaseGuiPlus的构造函数里面的mainwindow_visible=false让软件第一次使用托盘时显示主界面 if (!gui()->startHidden() || !files_to_play.isEmpty() ) gui()->show(); if (!files_to_play.isEmpty()) { if (!subtitle_file.isEmpty()) gui()->setInitialSubtitle(subtitle_file); if (!media_title.isEmpty()) gui()->getCore()->addForcedTitle(files_to_play[0], media_title); gui()->openFiles(files_to_play); } } void KylinVideo::showInfo() { QString s = QObject::tr("This is Kylin Vedio v. %1 running on %2") .arg(Version::printable()) #ifdef Q_OS_LINUX .arg("Linux") #else .arg("Other OS") #endif ; printf("%s\n", s.toLocal8Bit().data() ); qDebug("%s", s.toUtf8().data() ); qDebug("Compiled with Qt v. %s, using %s", QT_VERSION_STR, qVersion()); qDebug(" * application path: '%s'", Paths::appPath().toUtf8().data()); qDebug(" * config path: '%s'", Paths::configPath().toUtf8().data()); qDebug(" * ini path: '%s'", Paths::iniPath().toUtf8().data()); qDebug(" * current path: '%s'", QDir::currentPath().toUtf8().data()); } //#include "moc_kylinvideo.cpp" kylin-video/src/smplayer/global.h0000664000175000017500000000234513233751662016002 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _GLOBAL_H_ #define _GLOBAL_H_ #include // Some global objects class QSettings; class Preferences; class Translator; namespace Global { //! Read and store application settings extern QSettings * settings; //! Prefences extern Preferences * pref; //! Translator (for changing language) extern Translator * translator; void global_init(); void global_end(); }; #endif kylin-video/src/smplayer/languages.cpp0000664000175000017500000002452713233751662017051 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "languages.h" QMap Languages::list() { QMap l; l["aa"] = tr("Afar"); l["ab"] = tr("Abkhazian"); l["ae"] = tr("Avestan"); l["af"] = tr("Afrikaans"); l["ak"] = tr("Akan"); l["am"] = tr("Amharic"); l["an"] = tr("Aragonese"); l["ar"] = tr("Arabic"); l["as"] = tr("Assamese"); l["av"] = tr("Avaric"); l["ay"] = tr("Aymara"); l["az"] = tr("Azerbaijani"); l["ba"] = tr("Bashkir"); l["be"] = tr("Belarusian"); l["bg"] = tr("Bulgarian"); l["bh"] = tr("Bihari"); l["bi"] = tr("Bislama"); l["bm"] = tr("Bambara"); l["bn"] = tr("Bengali"); l["bo"] = tr("Tibetan"); l["br"] = tr("Breton"); l["bs"] = tr("Bosnian"); l["ca"] = tr("Catalan"); l["ce"] = tr("Chechen"); l["co"] = tr("Corsican"); l["cr"] = tr("Cree"); l["cs"] = tr("Czech"); l["cu"] = tr("Church"); l["cv"] = tr("Chuvash"); l["cy"] = tr("Welsh"); l["da"] = tr("Danish"); l["de"] = tr("German"); l["dv"] = tr("Divehi"); l["dz"] = tr("Dzongkha"); l["ee"] = tr("Ewe"); l["el"] = tr("Greek"); l["en"] = tr("English"); l["eo"] = tr("Esperanto"); l["es"] = tr("Spanish"); l["et"] = tr("Estonian"); l["eu"] = tr("Basque"); l["fa"] = tr("Persian"); l["ff"] = tr("Fulah"); l["fi"] = tr("Finnish"); l["fj"] = tr("Fijian"); l["fo"] = tr("Faroese"); l["fr"] = tr("French"); l["fy"] = tr("Frisian"); l["ga"] = tr("Irish"); l["gd"] = tr("Gaelic"); l["gl"] = tr("Galician"); l["gn"] = tr("Guarani"); l["gu"] = tr("Gujarati"); l["gv"] = tr("Manx"); l["ha"] = tr("Hausa"); l["he"] = tr("Hebrew"); l["hi"] = tr("Hindi"); l["ho"] = tr("Hiri"); l["hr"] = tr("Croatian"); l["ht"] = tr("Haitian"); l["hu"] = tr("Hungarian"); l["hy"] = tr("Armenian"); l["hz"] = tr("Herero"); l["ch"] = tr("Chamorro"); l["ia"] = tr("Interlingua"); l["id"] = tr("Indonesian"); l["ie"] = tr("Interlingue"); l["ig"] = tr("Igbo"); l["ii"] = tr("Sichuan"); l["ik"] = tr("Inupiaq"); l["io"] = tr("Ido"); l["is"] = tr("Icelandic"); l["it"] = tr("Italian"); l["iu"] = tr("Inuktitut"); l["ja"] = tr("Japanese"); l["jv"] = tr("Javanese"); l["ka"] = tr("Georgian"); l["kg"] = tr("Kongo"); l["ki"] = tr("Kikuyu"); l["kj"] = tr("Kuanyama"); l["kk"] = tr("Kazakh"); l["kl"] = tr("Greenlandic"); l["km"] = tr("Khmer"); l["kn"] = tr("Kannada"); l["ko"] = tr("Korean"); l["kr"] = tr("Kanuri"); l["ks"] = tr("Kashmiri"); l["ku"] = tr("Kurdish"); l["kv"] = tr("Komi"); l["kw"] = tr("Cornish"); l["ky"] = tr("Kirghiz"); l["la"] = tr("Latin"); l["lb"] = tr("Luxembourgish"); l["lg"] = tr("Ganda"); l["li"] = tr("Limburgan"); l["ln"] = tr("Lingala"); l["lo"] = tr("Lao"); l["lt"] = tr("Lithuanian"); l["lu"] = tr("Luba-Katanga"); l["lv"] = tr("Latvian"); l["mg"] = tr("Malagasy"); l["mh"] = tr("Marshallese"); l["mi"] = tr("Maori"); l["mk"] = tr("Macedonian"); l["ml"] = tr("Malayalam"); l["mn"] = tr("Mongolian"); l["mo"] = tr("Moldavian"); l["mr"] = tr("Marathi"); l["ms"] = tr("Malay"); l["mt"] = tr("Maltese"); l["my"] = tr("Burmese"); l["na"] = tr("Nauru"); l["nb"] = trUtf8("Bokmål"); l["nd"] = tr("Ndebele"); l["ne"] = tr("Nepali"); l["ng"] = tr("Ndonga"); l["nl"] = tr("Dutch"); l["nn"] = tr("Norwegian Nynorsk"); l["no"] = tr("Norwegian"); l["nr"] = tr("Ndebele"); l["nv"] = tr("Navajo"); l["ny"] = tr("Chichewa"); l["oc"] = tr("Occitan"); l["oj"] = tr("Ojibwa"); l["om"] = tr("Oromo"); l["or"] = tr("Oriya"); l["os"] = tr("Ossetian"); l["pa"] = tr("Panjabi"); l["pi"] = tr("Pali"); l["pl"] = tr("Polish"); l["ps"] = tr("Pushto"); l["pt"] = tr("Portuguese"); l["qu"] = tr("Quechua"); l["rm"] = tr("Romansh"); l["rn"] = tr("Rundi"); l["ro"] = tr("Romanian"); l["ru"] = tr("Russian"); l["rw"] = tr("Kinyarwanda"); l["sa"] = tr("Sanskrit"); l["sc"] = tr("Sardinian"); l["sd"] = tr("Sindhi"); l["se"] = tr("Sami"); l["sg"] = tr("Sango"); l["si"] = tr("Sinhala"); l["sk"] = tr("Slovak"); l["sl"] = tr("Slovene"); l["sm"] = tr("Samoan"); l["sn"] = tr("Shona"); l["so"] = tr("Somali"); l["sq"] = tr("Albanian"); l["sr"] = tr("Serbian"); l["ss"] = tr("Swati"); l["st"] = tr("Sotho"); l["su"] = tr("Sundanese"); l["sv"] = tr("Swedish"); l["sw"] = tr("Swahili"); l["ta"] = tr("Tamil"); l["te"] = tr("Telugu"); l["tg"] = tr("Tajik"); l["th"] = tr("Thai"); l["ti"] = tr("Tigrinya"); l["tk"] = tr("Turkmen"); l["tl"] = tr("Tagalog"); l["tn"] = tr("Tswana"); l["to"] = tr("Tonga"); l["tr"] = tr("Turkish"); l["ts"] = tr("Tsonga"); l["tt"] = tr("Tatar"); l["tw"] = tr("Twi"); l["ty"] = tr("Tahitian"); l["ug"] = tr("Uighur"); l["uk"] = tr("Ukrainian"); l["ur"] = tr("Urdu"); l["uz"] = tr("Uzbek"); l["ve"] = tr("Venda"); l["vi"] = tr("Vietnamese"); l["vo"] = trUtf8("Volapük"); l["wa"] = tr("Walloon"); l["wo"] = tr("Wolof"); l["xh"] = tr("Xhosa"); l["yi"] = tr("Yiddish"); l["yo"] = tr("Yoruba"); l["za"] = tr("Zhuang"); l["zh"] = tr("Chinese"); l["zu"] = tr("Zulu"); return l; } QMap Languages::most_used_list() { QMap l; l["de"] = tr("German"); l["en"] = tr("English"); l["es"] = tr("Spanish"); l["fi"] = tr("Finnish"); l["fr"] = tr("French"); l["it"] = tr("Italian"); l["ja"] = tr("Japanese"); l["nl"] = tr("Dutch"); l["no"] = tr("Norwegian"); l["pt"] = tr("Portuguese"); l["ru"] = tr("Russian"); l["sv"] = tr("Swedish"); l["zh"] = tr("Chinese"); return l; } QMap Languages::translations() { QMap m; m["ar"] = QString::fromUtf8("العربية"); //tr("Arabic"); m["ar_SY"] = tr("Arabic - Syria"); m["bg"] = QString::fromUtf8("Български"); //tr("Bulgarian"); m["ca"] = QString::fromUtf8("Català"); //tr("Catalan"); m["cs"] = QString::fromUtf8("Čeština"); //tr("Czech"); m["da"] = "Dansk"; //tr("Danish"); m["de"] = "Deutsch"; //tr("German"); m["el_GR"] = QString::fromUtf8("Ελληνικά"); //tr("Greek"); m["en_GB"] = "British English"; //tr("British English"); m["en_US"] = "English"; //tr("English"); m["es"] = QString::fromUtf8("Español"); //tr("Spanish"); m["et"] = "Eesti"; //tr("Estonian"); m["eu"] = "Euskara"; //tr("Basque"); m["fi"] = "Suomen kieli"; //tr("Finnish"); m["fr"] = QString::fromUtf8("Français"); // tr("French"); m["gl"] = "Galego"; //tr("Galician"); m["he_IL"] = QString::fromUtf8("עברית"); //tr("Hebrew"); m["hr"] = "Hrvatski"; //tr("Croatian"); m["hu"] = "Magyar"; //tr("Hungarian"); m["id"] = "Bahasa Indonesia"; //tr("Indonesian"); m["it"] = "Italiano"; //tr("Italian"); m["ja"] = QString::fromUtf8("日本語"); //tr("Japanese"); m["ka"] = QString::fromUtf8("ქართული"); //tr("Georgian"); m["ko"] = QString::fromUtf8("한국어"); //tr("Korean"); m["ku"] = QString::fromUtf8("Kurdîsh - Kurdî"); //("Kurdish"); m["lt"] = QString::fromUtf8("Lietuvių"); //tr("Lithuanian"); m["mk"] = QString::fromUtf8("Mакедонски"); //tr("Macedonian"); m["ms_MY"] = "Melayu"; //tr("Malay"); m["nl"] = "Nederlands"; //tr("Dutch"); m["nn_NO"] = "Norwegian Nynorsk"; //tr("Norwegian Nynorsk"); m["pl"] = "Polski"; //tr("Polish"); m["pt_BR"] = QString::fromUtf8("Português - Brasil"); //tr("Portuguese - Brazil"); m["pt"] = QString::fromUtf8("Português - Portugal"); //tr("Portuguese - Portugal"); m["ro_RO"] = QString::fromUtf8("Română"); //tr("Romanian"); m["ru_RU"] = QString::fromUtf8("Русский"); //tr("Russian"); m["sk"] = "Slovensky"; //tr("Slovak"); m["sl_SI"] = "Slovenski"; //tr("Slovene"); m["sq_AL"] = "Shqip"; //tr("Albanian"); m["sr"] = QString::fromUtf8("Српски"); //tr("Serbian"); m["sv"] = "Svenska"; //tr("Swedish"); m["th"] = QString::fromUtf8("ไทย"); //tr("Thai"); m["tr"] = QString::fromUtf8("Türkçe"); //tr("Turkish"); m["uk_UA"] = QString::fromUtf8("Українська"); //tr("Ukrainian"); m["uz"] = QString::fromUtf8("O‘zbek"); //tr("Uzbek"); m["vi_VN"] = QString::fromUtf8("Tiếng Việt"); //tr("Vietnamese"); m["zh_CN"] = QString::fromUtf8("简体中文"); //tr("Simplified-Chinese"); m["zh_TW"] = QString::fromUtf8("正體中文"); //tr("Traditional Chinese"); return m; } QMap Languages::encodings() { QMap l; l["UTF-16"] = tr("Unicode"); l["UTF-8"] = tr("UTF-8"); l["ISO-8859-1"] = tr("Western European Languages"); l["ISO-8859-15"] = tr("Western European Languages with Euro"); l["ISO-8859-2"] = tr("Slavic/Central European Languages"); l["ISO-8859-3"] = tr("Esperanto, Galician, Maltese, Turkish"); l["ISO-8859-4"] = tr("Old Baltic charset"); l["ISO-8859-5"] = tr("Cyrillic"); l["ISO-8859-6"] = tr("Arabic"); l["ISO-8859-7"] = tr("Modern Greek"); l["ISO-8859-9"] = tr( "Turkish"); l["ISO-8859-13"] = tr( "Baltic"); l["ISO-8859-14"] = tr( "Celtic"); l["ISO-8859-16"] = tr( "South-Eastern European"); l["ISO-8859-8"] = tr( "Hebrew charsets"); l["KOI8-R"] = tr( "Russian"); l["KOI8-U/RU"] = tr( "Ukrainian, Belarusian"); l["CP936"] = tr( "Simplified Chinese charset"); l["BIG5"] = tr( "Traditional Chinese charset"); l["SHIFT-JIS"] = tr( "Japanese charsets"); l["CP949"] = tr( "Korean charset"); l["CP874"] = tr( "Thai charset"); l["CP1251"] = tr( "Cyrillic Windows"); l["CP1250"] = tr( "Slavic/Central European Windows"); l["CP1256"] = tr( "Arabic Windows"); l["CP1253"] = tr("Modern Greek Windows"); return l; } QMap Languages::enca() { QMap l; l["be"] = tr("Belarusian"); l["bg"] = tr("Bulgarian"); l["cs"] = tr("Czech"); l["et"] = tr("Estonian"); l["hr"] = tr("Croatian"); l["hu"] = tr("Hungarian"); l["lt"] = tr("Lithuanian"); l["lv"] = tr("Latvian"); l["pl"] = tr("Polish"); l["ru"] = tr("Russian"); l["sk"] = tr("Slovak"); l["sl"] = tr("Slovene"); l["uk"] = tr("Ukrainian"); l["zh"] = tr("Chinese"); return l; } //#include "moc_languages.cpp" kylin-video/src/smplayer/shortcutgetter.h0000664000175000017500000000410113233751662017620 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 Note: The ShortcutGetter class is taken from the source code of Edyuk (http://www.edyuk.org/), from file 3rdparty/qcumber/qshortcutdialog.cpp Copyright (C) 2006 FullMetalCoder License: GPL I modified it to support multiple shortcuts and some other few changes. */ #ifndef SHORTCUTGETTER_H #define SHORTCUTGETTER_H #include #include class QLineEdit; enum SCDragState {NOT_SCDRAGGING, START_SCDRAGGING, SCDRAGGING}; class ShortcutGetter : public QDialog { Q_OBJECT public: ShortcutGetter(/*bool isbtn = false, */QWidget *parent = 0); QString exec(const QString& s); protected slots: void setCaptureKeyboard(bool b); void rowChanged(int row); void textChanged(const QString & text); void addItemClicked(); void removeItemClicked(); protected: bool captureKeyboard() { return capture; }; bool event(QEvent *e); bool eventFilter(QObject *o, QEvent *e); void setText(); // virtual bool eventFilter(QObject *, QEvent *); // void moveDialog(QPoint diff); private: bool bStop; QLineEdit *leKey; QStringList lKeys; bool capture; QListWidget * list; QPushButton * addItem; QPushButton * removeItem; QPushButton *closeBtn; SCDragState drag_state; QPoint start_drag; }; #endif kylin-video/src/smplayer/timeslider.cpp0000664000175000017500000002356313233751662017243 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "timeslider.h" #include "helper.h" #include #include #include #include #include #include #include "../kylin/timetip.h" TimeSlider::TimeSlider( QWidget * parent ) : MySlider(parent) , dont_update(false) , position(0) , total_time(0) { setMinimum(0); setMaximum(SEEKBAR_RESOLUTION); setFocusPolicy( Qt::NoFocus ); setSizePolicy( QSizePolicy::Expanding , QSizePolicy::Fixed ); preview = false; connect( this, SIGNAL( sliderPressed() ), this, SLOT( stopUpdate() ) ); connect( this, SIGNAL( sliderReleased() ), this, SLOT( resumeUpdate() ) ); connect( this, SIGNAL( sliderReleased() ), this, SLOT( mouseReleased() ) ); connect( this, SIGNAL( valueChanged(int) ), this, SLOT( valueChanged_slot(int) ) ); connect( this, SIGNAL(draggingPos(int) ), this, SLOT(checkDragging(int)) ); cur_pos = QPoint(0,0); last_pos_to_send = -1; timer = new QTimer(this); connect( timer, SIGNAL(timeout()), this, SLOT(sendDelayedPos()) ); timer->start(200); hintWidget = new TimeTip("00:00:00", this); // hintWidget->setFixedHeight(60); hintWidget->setFixedSize(67,60);//kobe: 如果不设置固定宽度,则宽度初始值默认为100,后续自动变为67,导致第一次使用默认值时显示的时间信息的坐标有偏移 installEventFilter(this); } TimeSlider::~TimeSlider() { } void TimeSlider::hideTip() { this->hintWidget->hide(); } void TimeSlider::stopUpdate() { dont_update = true; } void TimeSlider::resumeUpdate() { dont_update = false; } void TimeSlider::mouseReleased() { emit posChanged( value() ); } void TimeSlider::valueChanged_slot(int v) { // Only to make things clear: bool dragging = dont_update; if (!dragging) { if (v!=position) { emit posChanged(v); } } else { emit draggingPos(v); } } void TimeSlider::setDragDelay(int d) { // qDebug("TimeSlider::setDragDelay: %d", d); timer->setInterval(d); } int TimeSlider::dragDelay() { return timer->interval(); } void TimeSlider::checkDragging(int v) { // qDebug("TimeSlider::checkDragging: %d", v); last_pos_to_send = v; } void TimeSlider::sendDelayedPos() { // qDebug("TimeSlider::sendDelayedPos: %d", last_pos_to_send); if (last_pos_to_send != -1) { emit delayedDraggingPos(last_pos_to_send); last_pos_to_send = -1; } } void TimeSlider::setPos(int v) { if (v!=pos()) { if (!dont_update) { position = v; setValue(v); } } } int TimeSlider::pos() { return position; } void TimeSlider::wheelEvent(QWheelEvent * e) { //e->ignore(); // qDebug("TimeSlider::wheelEvent: delta: %d", e->delta()); e->accept(); if (e->orientation() == Qt::Vertical) { if (e->delta() >= 0) emit wheelUp(); else emit wheelDown(); } else { qDebug("Timeslider::wheelEvent: horizontal event received, doing nothing"); } } void TimeSlider::enterEvent(QEvent *) { emit this->active_status(true);//kobe } void TimeSlider::leaveEvent(QEvent *) { emit this->active_status(false);//kobe } void TimeSlider::show_time_value(int time) { // hintWidget->setFixedHeight(60); hintWidget->setFixedSize(67,60);//kobe: 如果不设置固定宽度,则宽度初始值默认为100,后续自动变为67,导致第一次使用默认值时显示的时间信息的坐标有偏移 hintWidget->setText(Helper::formatTime(time)); QPoint curPos = this->mapToGlobal(cur_pos); QSize sz = this->hintWidget->size(); curPos.setX(curPos.x() - sz.width() / 2); curPos.setY(curPos.y() - sz.height());//- 32 curPos = this->hintWidget->mapFromGlobal(curPos); curPos = this->hintWidget->mapToParent(curPos); this->hintWidget->move(curPos); this->hintWidget->show(); this->setCursor(QCursor(Qt::PointingHandCursor)); } void TimeSlider::set_preview_flag(bool b) { preview = b; if (!preview) { hintWidget->setFixedSize(67,60); } } void TimeSlider::show_save_preview_image(int time, QString filepath) { if (filepath.isEmpty()) { this->show_time_value(time); } else { QPixmapCache::clear(); // QPixmapCache::setCacheLimit(1); QPixmap picture; if (!picture.load(filepath)) { this->show_time_value(time); return; } QPixmap scaled_picture = picture.scaledToWidth(200, Qt::SmoothTransformation); // hintWidget->setFixedHeight(200); hintWidget->setFixedSize(200, scaled_picture.size().height() + 30);//kobe: 如果不设置固定宽度,则宽度初始值默认为100,后续自动变为67,导致第一次使用默认值时显示的时间信息的坐标有偏移 hintWidget->setPixMapAndTime(scaled_picture, Helper::formatTime(time)); QPoint curPos = this->mapToGlobal(cur_pos); QSize sz = this->hintWidget->size(); curPos.setX(curPos.x() - sz.width() / 2); curPos.setY(curPos.y() - sz.height());//- 32 curPos = this->hintWidget->mapFromGlobal(curPos); curPos = this->hintWidget->mapToParent(curPos); this->hintWidget->move(curPos); this->hintWidget->show(); this->setCursor(QCursor(Qt::PointingHandCursor)); } } //kobe:鼠标放在进度条上时显示时间进度,移开鼠标则消失 bool TimeSlider::event(QEvent *event) { if (event->type() == QEvent::ToolTip) { QHelpEvent * help_event = static_cast(event); int pos_in_slider = help_event->x() * maximum() / width(); cur_pos = help_event->pos(); int time = pos_in_slider * total_time / maximum(); if (time >= 0 && time <= total_time) { //QToolTip::showText(help_event->globalPos(), Helper::formatTime(time), this); if (preview) { emit this->need_to_save_pre_image(time); } else { hintWidget->setText(Helper::formatTime(time)); // QPoint centerPos = this->mapToGlobal(this->rect().center()); // QSize sz = this->hintWidget->size(); // centerPos.setX(centerPos.x() - sz.width() / 2); // centerPos.setY(centerPos.y() - 32 - sz.height()); // centerPos = this->hintWidget->mapFromGlobal(centerPos); // centerPos = this->hintWidget->mapToParent(centerPos); // this->hintWidget->move(centerPos); QPoint curPos = this->mapToGlobal(help_event->pos()); QSize sz = this->hintWidget->size(); curPos.setX(curPos.x() - sz.width() / 2); curPos.setY(curPos.y() - sz.height());//- 32 curPos = this->hintWidget->mapFromGlobal(curPos); curPos = this->hintWidget->mapToParent(curPos); this->hintWidget->move(curPos); this->hintWidget->show(); this->setCursor(QCursor(Qt::PointingHandCursor)); } // } else { cur_pos = QPoint(0,0); // QToolTip::hideText(); event->ignore(); } return true; } return QWidget::event(event); } //kobe 0620 bool TimeSlider::eventFilter(QObject *obj, QEvent *event) { switch (event->type()) { /*case QEvent::Enter: { if (this->hintWidget) { this->hintWidget->hide(); } // QPoint p = parent->mapFromGlobal(mouse_event->globalPos()); //// qDebug() << "33333AutohideWidget::eventFilter: y:" << p.y(); // if (p.y() > (parent->height() - height() - spacing)) { // showWidget(); // } // QPoint pos = mapFromGlobal(QCursor::pos()); // QMouseEvent * mouse_event = dynamic_cast(event); // QWidget * parent = parentWidget(); // QPoint p = parent->mapFromGlobal(mouse_event->globalPos()); QHelpEvent * help_event = static_cast(event); qDebug() << "TimeSlider::event: total_time:" << total_time << "x:" << help_event->x(); int pos_in_slider = help_event->x() * maximum() / width(); int time = pos_in_slider * total_time / maximum(); qDebug() << "TimeSlider::event: time:" << time; if (time >= 0 && time <= total_time) { qDebug () << "test time=" << Helper::formatTime(time); hintWidget->setText(Helper::formatTime(time)); } QPoint centerPos = this->mapToGlobal(this->rect().center()); QSize sz = this->hintWidget->size(); centerPos.setX(centerPos.x() - sz.width() / 2); centerPos.setY(centerPos.y() - 32 - sz.height()); centerPos = this->hintWidget->mapFromGlobal(centerPos); centerPos = this->hintWidget->mapToParent(centerPos); this->hintWidget->move(centerPos); this->hintWidget->show(); this->setCursor(QCursor(Qt::PointingHandCursor)); break; }*/ case QEvent::Leave: { if (this->hintWidget) { this->hintWidget->hide(); } this->unsetCursor(); break; } case QEvent::MouseButtonPress: if (this->hintWidget) { this->hintWidget->hide(); } break; default: break; } return QObject::eventFilter(obj, event); } //#include "moc_timeslider.cpp" kylin-video/src/smplayer/playerid.h0000664000175000017500000000205113233751662016345 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef PLAYERID_H #define PLAYERID_H #include #define PLAYER_NAME "MPlayer/mpv" class PlayerID { public: enum Player { MPLAYER = 0, MPV = 1 }; static Player player(const QString & player_bin); }; #endif kylin-video/src/smplayer/playerid.cpp0000664000175000017500000000247713233751662016714 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "playerid.h" #include #include PlayerID::Player PlayerID::player(const QString & player_bin) { Player p; QString bin_name; QFileInfo fi(player_bin); if (fi.exists() && fi.isExecutable() && !fi.isDir()) { bin_name = fi.fileName(); } else { bin_name = player_bin; } // qDebug() << "PlayerID::Player: player_bin:" << player_bin << "filename:" << bin_name; if (bin_name.toLower().startsWith("mplayer")) { p = MPLAYER; } else { p = MPV; } return p; } kylin-video/src/smplayer/inforeader.cpp0000664000175000017500000001503313233751662017211 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "inforeader.h" #include "global.h" #include "preferences.h" #include "playerprocess.h" #include "paths.h" #include #include #include #include #include "inforeadermpv.h" #include "inforeadermplayer.h" #define INFOREADER_SAVE_VERSION 2 using namespace Global; InfoReader * InfoReader::static_obj = 0; InfoReader * InfoReader::obj(const QString & mplayer_bin) { QString player_bin = mplayer_bin; if (player_bin.isEmpty()) { player_bin = pref->mplayer_bin; } if (!static_obj) { static_obj = new InfoReader(player_bin); } else { static_obj->setPlayerBin(player_bin); } return static_obj; } InfoReader::InfoReader(QString mplayer_bin, QObject * parent) : QObject(parent) , mplayer_svn(0) // , is_mplayer2(false) , is_mpv(false) { setPlayerBin(mplayer_bin); } InfoReader::~InfoReader() { } void InfoReader::setPlayerBin(const QString & bin) { mplayerbin = bin; QFileInfo fi(mplayerbin); if (fi.exists() && fi.isExecutable() && !fi.isDir()) { // mplayerbin = fi.absoluteFilePath(); } #ifdef Q_OS_LINUX else { QString fplayer = Helper::findExecutable(mplayerbin); qDebug() << "InfoReader::setPlayerBin: fplayer:" << fplayer; if (!fplayer.isEmpty()) mplayerbin = fplayer; } #endif qDebug() << "InfoReader::setPlayerBin: mplayerbin:" << mplayerbin; } void InfoReader::getInfo() { QString inifile = Paths::configPath() + "/player_info.ini"; QSettings set(inifile, QSettings::IniFormat); QString version_group = "version_" + QString::number(INFOREADER_SAVE_VERSION); QString sname = mplayerbin; sname = sname.replace("/", "_").replace("\\", "_").replace(".", "_").replace(":", "_"); QFileInfo fi(mplayerbin); if (fi.exists()) { sname += "_" + QString::number(fi.size()); qDebug() << "InfoReader::getInfo: sname:" << sname;//_usr_bin_mplayer_4027216 // Check if we already have info about the player in the ini file bool got_info = false; set.beginGroup(version_group +"/"+ sname); if (set.value("size", -1).toInt() == fi.size()) { got_info = true; vo_list = convertListToInfoList(set.value("vo_list").toStringList()); ao_list = convertListToInfoList(set.value("ao_list").toStringList()); demuxer_list = convertListToInfoList(set.value("demuxer_list").toStringList()); vc_list = convertListToInfoList(set.value("vc_list").toStringList()); ac_list = convertListToInfoList(set.value("ac_list").toStringList()); vf_list = set.value("vf_list").toStringList(); option_list = set.value("option_list").toStringList(); //qDebug() << "InfoReader::getInfo: option_list:" << option_list; mplayer_svn = set.value("mplayer_svn").toInt(); mpv_version = set.value("mpv_version").toString(); // mplayer2_version = set.value("mplayer2_version").toString(); // is_mplayer2 = set.value("is_mplayer2").toBool(); is_mpv = set.value("is_mpv").toBool(); } set.endGroup(); if (got_info) { qDebug() << "InfoReader::getInfo: loaded info from" << inifile; return; } } if (PlayerID::player(mplayerbin) == PlayerID::MPV) { qDebug("InfoReader::getInfo: mpv"); InfoReaderMPV ir(mplayerbin, this); ir.getInfo(); vo_list = ir.voList(); ao_list = ir.aoList(); demuxer_list = ir.demuxerList(); vc_list = ir.vcList(); ac_list = ir.acList(); vf_list = ir.vfList(); option_list = ir.optionList(); mplayer_svn = ir.mplayerSVN(); mpv_version = ir.mpvVersion(); // mplayer2_version = ""; // is_mplayer2 = false; is_mpv = true; } else { qDebug("InfoReader::getInfo: mplayer"); InfoReaderMplayer ir(mplayerbin, this); ir.getInfo(); vo_list = ir.voList(); ao_list = ir.aoList(); demuxer_list = ir.demuxerList(); vc_list = ir.vcList(); ac_list = ir.acList(); vf_list.clear(); option_list.clear(); mplayer_svn = ir.mplayerSVN(); // qDebug() << "mplayer_svn:" << mplayer_svn; mpv_version = ""; // mplayer2_version = ir.mplayer2Version(); // is_mplayer2 = ir.isMplayer2(); is_mpv = false; } if (fi.exists()) { qDebug() << "InfoReader::getInfo: saving info to" << inifile; set.beginGroup(version_group +"/"+ sname); set.setValue("size", fi.size()); set.setValue("date", fi.lastModified()); set.setValue("vo_list", convertInfoListToList(vo_list)); set.setValue("ao_list", convertInfoListToList(ao_list)); set.setValue("demuxer_list", convertInfoListToList(demuxer_list)); set.setValue("vc_list", convertInfoListToList(vc_list)); set.setValue("ac_list", convertInfoListToList(ac_list)); set.setValue("vf_list", vf_list); set.setValue("option_list", option_list); set.setValue("mplayer_svn", mplayer_svn); set.setValue("mpv_version", mpv_version); // set.setValue("mplayer2_version", mplayer2_version); // set.setValue("is_mplayer2", is_mplayer2); set.setValue("is_mpv", is_mpv); set.endGroup(); } } QString InfoReader::playerVersion() { // QString player = QString("MPlayer SVN r%1").arg(mplayer_svn); QString player; if (is_mpv) { player = "MPV " + mpv_version; } else { player = QString("MPlayer SVN r%1").arg(mplayer_svn); } // if (is_mplayer2) { // player = "MPlayer2 " + mplayer2_version; // } // else // if (is_mpv) { // player = "MPV " + mpv_version; // } return player; } QStringList InfoReader::convertInfoListToList(InfoList l) { QStringList r; for (int n = 0; n < l.count(); n++) { r << l[n].name() + "|" + l[n].desc(); } return r; } InfoList InfoReader::convertListToInfoList(QStringList l) { InfoList r; for (int n = 0; n < l.count(); n++) { QStringList s = l[n].split("|"); if (s.count() >= 2) { r.append(InfoData(s[0], s[1])); } } return r; } //#include "moc_inforeader.cpp" kylin-video/src/smplayer/config.h0000664000175000017500000000720013233751662016002 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _CONFIG_H_ #define _CONFIG_H_ #include #define NOTIFY_SUB_CHANGES 1 #define NOTIFY_AUDIO_CHANGES 1 #define NOTIFY_VIDEO_CHANGES 0 #define NOTIFY_CHAPTER_CHANGES 1 #define TOP_TOOLBAR_HEIGHT 39 #define BOTTOM_TOOLBAR_HEIGHT 79 #define BOTTOM_S_TOOLBAR_HEIGHT 63 #define EXTENSION_PANEL_WIDTH 240 #define ANIMATIONDELAY 400 #define WINDOW_MIN_WIDTH 400 #define WINDOW_MIN_HEIGHT 300 // STYLE_SWITCHING // if 1, the preferences dialog will have an option to switch // the Qt style #define STYLE_SWITCHING 1 // EXTERNAL_SLEEP // if 1, it will be used the function usleep() from unistd.h // instead of QThread::msleep() // It can be useful if your Qt doesn't have QThread support. // Note: not much test it // Note 2: not used anymore #define EXTERNAL_SLEEP 0 // SEEKBAR_RESOLUTION // if SEEKBAR_RESOLUTION is defined, it specified the // maximum value of the time slider #define SEEKBAR_RESOLUTION 1000 // SMART_DVD_CHAPTERS // if set to 1, the slave command "chapter" will use if not using a cache, // otherwise mplayer will be restarted and -chapter will be used. #define SMART_DVD_CHAPTERS 1 // ALLOW_TO_HIDE_VIDEO_WINDOW_ON_AUDIO_FILES // if 1, the video window may be hidden when playing audio files // depending on the hide_video_window_on_audio_files option in // the config file #define ALLOW_TO_HIDE_VIDEO_WINDOW_ON_AUDIO_FILES 1 // DELAYED_AUDIO_SETUP_ON_STARTUP // if 1, the audio track will be initialized later once the file // has begun to play #define DELAYED_AUDIO_SETUP_ON_STARTUP 0 // CHECK_VIDEO_CODEC_FOR_NO_VIDEO // if 1, the video codec will be checked to decide if the file // has video or not. If it's empty it has no video. // If 0, it will check for the line "Video: no video" #define CHECK_VIDEO_CODEC_FOR_NO_VIDEO 1 // Just for testing, possibility to disable the use of the colorkey //#define USE_COLORKEY 1 // USE_MINIMUMSIZE // if 1, the main window will not be smaller than the control widget // size hint or pref->gui_minimum_width. #define USE_MINIMUMSIZE 1 // DVDNAV_SUPPORT // if 1, smplayer will be compiled with support for mplayer's dvdnav //#ifdef MPLAYER_SUPPORT //#define DVDNAV_SUPPORT 1 //#endif // PROGRAM_SWITCH // support for program switch in ts files //#define PROGRAM_SWITCH 0 // Adds or not the "Repaint the background of the video window" option. //#ifndef Q_OS_WIN //#define REPAINT_BACKGROUND_OPTION 1 //#endif // Enables/disables the use of -adapter //#ifdef Q_OS_WIN //#define USE_ADAPTER 1 //#define OVERLAY_VO "directx" ////#define OVERLAY_VO "xv" //#endif // If 1, smplayer will check if mplayer is old // and in that case it will report to the user //#if !defined(Q_OS_WIN) && !defined(Q_OS_OS2) //#define REPORT_OLD_MPLAYER 1 //#endif // If 1, the background logo will be animated #if QT_VERSION >= 0x040600 /* #define LOGO_ANIMATION 1 */ #endif #endif kylin-video/src/smplayer/tracks.h0000664000175000017500000000415013233751662016025 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _TRACKS_H_ #define _TRACKS_H_ #include #include /* Class to store info about video/audio tracks */ class TrackData { public: TrackData() { _lang = ""; _name = "";_ID = -1; }; ~TrackData() {}; void setLang( const QString & l ) { _lang = l; }; void setName( const QString & n ) { _name = n; }; void setID( int id ) { _ID = id; }; QString lang() const { return _lang; }; QString name() const { return _name; }; int ID() const { return _ID; }; QString displayName() const { QString dname=""; if (!_name.isEmpty()) { dname = _name; if (!_lang.isEmpty()) { dname += " ["+ _lang + "]"; } } else if (!_lang.isEmpty()) { dname = _lang; } else dname = QString::number(_ID); return dname; } protected: /* Language code: es, en, etc. */ QString _lang; /* spanish, english... */ QString _name; int _ID; }; class Tracks { public: Tracks(); ~Tracks(); void clear(); void list(); void addLang(int ID, QString lang); void addName(int ID, QString name); void addID(int ID); int numItems(); bool existsItemAt(int n); TrackData itemAt(int n); TrackData item(int ID); int find(int ID); int findLang(QString expr); protected: typedef QMap TrackMap; TrackMap tm; }; #endif kylin-video/src/smplayer/tristatecombo.cpp0000664000175000017500000000661413233751662017757 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "tristatecombo.h" #include TristateCombo::TristateCombo( QWidget * parent ) : QComboBox(parent) { retranslateStrings(); this->setStyleSheet("QComboBox{width:150px;height:24px;border:1px solid #000000;background:#0f0f0f;font-size:12px;font-family:方正黑体_GBK;background-position:center left;padding-left:5px;color:#999999;selection-color:#ffffff;selection-background-color:#1f1f1f;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox::drop-down {width:17px;border:none;background:transparent;}QComboBox::drop-down:hover {background:transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView{border:1px solid #0a9ff5;background:#262626;outline:none;}"); // this->setStyleSheet("QComboBox{width:150px;height:24px;border: 1px solid #000000;background: #0f0f0f;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox::hover{background-color:#0f0f0f;border:1px solid #0a9ff5;font-family:方正黑体_GBK;font-size:12px;color:#999999;}QComboBox:enabled {background:#0f0f0f;color:#999999;}QComboBox:!enabled {background:#0f0f0f;color:#383838;}QComboBox:enabled:hover, QComboBox:enabled:focus {color: #1f1f1f;}QComboBox::drop-down {width: 17px;border: none;background: transparent;}QComboBox::drop-down:hover {background: transparent;}QComboBox::down-arrow{image:url(:/res/combobox_arrow_normal.png);}QComboBox::down-arrow:hover{image:url(:/res/combobox_arrow_hover.png);}QComboBox::down-arrow:pressed{image:url(:/res/combobox_arrow_press.png);}QComboBox QAbstractItemView {border: 1px solid #0a9ff5;background: #1f1f1f;outline: none;}"); } TristateCombo::~TristateCombo() { } void TristateCombo::retranslateStrings() { int i = currentIndex(); clear(); addItem( tr("Auto"), Preferences::Detect ); addItem( tr("Yes"), Preferences::Enabled ); addItem( tr("No"), Preferences::Disabled ); setCurrentIndex(i); } void TristateCombo::setState( Preferences::OptionState v ) { setCurrentIndex( findData(v) ); } Preferences::OptionState TristateCombo::state() { return (Preferences::OptionState) itemData( currentIndex() ).toInt(); } // Language change stuff void TristateCombo::changeEvent(QEvent *e) { if (e->type() == QEvent::LanguageChange) { retranslateStrings(); } else { QComboBox::changeEvent(e); } } //#include "moc_tristatecombo.cpp" kylin-video/src/smplayer/screensaver.h0000664000175000017500000000271413233751662017062 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ //! This class disables and restores the windows screensaver #ifndef _WINSCREENSAVER_H_ #define _WINSCREENSAVER_H_ #ifdef Q_OS_OS2 #include #else #undef _WIN32_WINNT #define _WIN32_WINNT 0x0501 #endif class WinScreenSaver { public: WinScreenSaver(); ~WinScreenSaver(); void disable(); void enable(); private: void retrieveState(); void restoreState(); #ifdef Q_OS_OS2 void unload(); #endif private: #ifndef Q_OS_OS2 int lowpower, poweroff, screensaver; #else QLibrary *SSaver; typedef int (*FuncPtr) (void); FuncPtr SSCore_TempDisable; FuncPtr SSCore_TempEnable; #endif bool state_saved, modified; }; #endif kylin-video/src/smplayer/core.cpp0000664000175000017500000035403613233751662016034 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "core.h" #include #include #include #include #include #include #include "mplayerwindow.h" #include "desktopinfo.h" #include "helper.h" #include "paths.h" #include "preferences.h" #include "global.h" #include "config.h" #include "mplayerversion.h" #include "colorutils.h" #include "filesettings.h" using namespace Global; Core::Core( MplayerWindow *mpw, QWidget* parent ) : QObject( parent ) { qRegisterMetaType("Core::State"); mplayerwindow = mpw; _state = Stopped; we_are_restarting = false; just_loaded_external_subs = false; just_unloaded_external_subs = false; change_volume_after_unpause = false; //#if DVDNAV_SUPPORT // dvdnav_title_is_menu = true; // Enabled by default for compatibility with previous versions of mplayer //#endif //kobe:pref->file_settings_method 记住时间位置的配置设置在一个ini文件时为normal,在多个ini文件时为hash // Create file_settings file_settings = 0; changeFileSettingsMethod("normal"/*pref->file_settings_method*/);//normal or hash proc = PlayerProcess::createPlayerProcess(pref->mplayer_bin); // Do this the first connect( proc, SIGNAL(processExited()), mplayerwindow->videoLayer(), SLOT(playingStopped()) ); connect( proc, SIGNAL(error(QProcess::ProcessError)), mplayerwindow->videoLayer(), SLOT(playingStopped()) ); // Necessary to hide/unhide mouse cursor on black borders connect( proc, SIGNAL(processExited()), mplayerwindow, SLOT(playingStopped()) ); connect( proc, SIGNAL(error(QProcess::ProcessError)), mplayerwindow, SLOT(playingStopped()) ); connect( proc, SIGNAL(receivedCurrentSec(double)), this, SLOT(changeCurrentSec(double)) ); connect( proc, SIGNAL(receivedCurrentFrame(int)), this, SIGNAL(showFrame(int)) ); connect( proc, SIGNAL(receivedPause()), this, SLOT(changePause()) ); connect( proc, SIGNAL(processExited()), this, SLOT(processFinished()), Qt::QueuedConnection ); connect( proc, SIGNAL(mplayerFullyLoaded()), this, SLOT(finishRestart()), Qt::QueuedConnection ); connect( proc, SIGNAL(lineAvailable(QString)), this, SIGNAL(logLineAvailable(QString)) ); connect( proc, SIGNAL(receivedCacheMessage(QString)), this, SLOT(displayMessage(QString)) ); /* connect( proc, SIGNAL(receivedCacheMessage(QString)), this, SIGNAL(buffering())); */ connect( proc, SIGNAL(receivedBuffering()), this, SIGNAL(buffering())); connect( proc, SIGNAL(receivedPlaying()), this, SLOT(displayPlaying())); connect( proc, SIGNAL(receivedCacheEmptyMessage(QString)), this, SIGNAL(buffering())); connect( proc, SIGNAL(receivedCreatingIndex(QString)), this, SLOT(displayMessage(QString)) ); connect( proc, SIGNAL(receivedCreatingIndex(QString)), this, SIGNAL(buffering())); connect( proc, SIGNAL(receivedConnectingToMessage(QString)), this, SLOT(displayMessage(QString)) ); connect( proc, SIGNAL(receivedConnectingToMessage(QString)), this, SIGNAL(buffering())); connect( proc, SIGNAL(receivedResolvingMessage(QString)), this, SLOT(displayMessage(QString)) ); connect( proc, SIGNAL(receivedResolvingMessage(QString)), this, SIGNAL(buffering())); connect( proc, SIGNAL(receivedScreenshot(QString)), this, SLOT(displayScreenshotName(QString)) ); connect( proc, SIGNAL(receivedUpdatingFontCache()), this, SLOT(displayUpdatingFontCache()) ); connect( proc, SIGNAL(receivedScanningFont(QString)), this, SLOT(displayMessage(QString)) ); connect( proc, SIGNAL(receivedWindowResolution(int,int)), this, SLOT(gotWindowResolution(int,int)) ); connect( proc, SIGNAL(receivedNoVideo()), this, SLOT(gotNoVideo()) ); connect( proc, SIGNAL(receivedVO(QString)), this, SLOT(gotVO(QString)) ); connect( proc, SIGNAL(receivedAO(QString)), this, SLOT(gotAO(QString)) ); connect( proc, SIGNAL(receivedEndOfFile()), this, SLOT(fileReachedEnd()), Qt::QueuedConnection ); connect( proc, SIGNAL(receivedStartingTime(double)), this, SLOT(gotStartingTime(double)) ); connect( proc, SIGNAL(receivedVideoBitrate(int)), this, SLOT(gotVideoBitrate(int)) ); connect( proc, SIGNAL(receivedAudioBitrate(int)), this, SLOT(gotAudioBitrate(int)) ); connect( proc, SIGNAL(receivedStreamTitle(QString)), this, SLOT(streamTitleChanged(QString)) ); connect( proc, SIGNAL(receivedStreamTitleAndUrl(QString,QString)), this, SLOT(streamTitleAndUrlChanged(QString,QString)) ); connect( proc, SIGNAL(failedToParseMplayerVersion(QString)), this, SIGNAL(failedToParseMplayerVersion(QString)) ); connect( this, SIGNAL(mediaLoaded()), this, SLOT(checkIfVideoIsHD()), Qt::QueuedConnection ); #if DELAYED_AUDIO_SETUP_ON_STARTUP connect( this, SIGNAL(mediaLoaded()), this, SLOT(initAudioTrack()), Qt::QueuedConnection ); #endif #if NOTIFY_SUB_CHANGES connect( proc, SIGNAL(subtitleInfoChanged(const SubTracks &)), this, SLOT(initSubtitleTrack(const SubTracks &)), Qt::QueuedConnection ); connect( proc, SIGNAL(subtitleInfoReceivedAgain(const SubTracks &)), this, SLOT(setSubtitleTrackAgain(const SubTracks &)), Qt::QueuedConnection ); #endif //#if NOTIFY_AUDIO_CHANGES connect( proc, SIGNAL(audioInfoChanged(const Tracks &)), this, SLOT(initAudioTrack(const Tracks &)), Qt::QueuedConnection ); //#endif #if NOTIFY_VIDEO_CHANGES connect( proc, SIGNAL(videoInfoChanged(const Tracks &)), this, SLOT(initVideoTrack(const Tracks &)), Qt::QueuedConnection ); #endif //#if DVDNAV_SUPPORT // connect( proc, SIGNAL(receivedDVDTitle(int)), // this, SLOT(dvdTitleChanged(int)), Qt::QueuedConnection ); // connect( proc, SIGNAL(receivedDuration(double)), // this, SLOT(durationChanged(double)), Qt::QueuedConnection ); // QTimer * ask_timer = new QTimer(this); // connect( ask_timer, SIGNAL(timeout()), this, SLOT(askForInfo()) ); // ask_timer->start(5000); // connect( proc, SIGNAL(receivedTitleIsMenu()), // this, SLOT(dvdTitleIsMenu()) ); // connect( proc, SIGNAL(receivedTitleIsMovie()), // this, SLOT(dvdTitleIsMovie()) ); //#endif connect( proc, SIGNAL(receivedForbiddenText()), this, SIGNAL(receivedForbidden()) ); connect( this, SIGNAL(stateChanged(Core::State)), this, SLOT(watchState(Core::State)) ); connect( this, SIGNAL(mediaInfoChanged()), this, SLOT(sendMediaInfo()) ); connect( proc, SIGNAL(error(QProcess::ProcessError)), this, SIGNAL(mplayerFailed(QProcess::ProcessError)) ); //pref->load(); mset.reset(); // Mplayerwindow connect( this, SIGNAL(aboutToStartPlaying()), mplayerwindow->videoLayer(), SLOT(playingStarted()) ); // Necessary to hide/unhide mouse cursor on black borders connect( this, SIGNAL(aboutToStartPlaying()), mplayerwindow, SLOT(playingStarted()) ); //#if DVDNAV_SUPPORT // connect( mplayerwindow->videoLayer(), SIGNAL(mouseMoved(QPoint)), // this, SLOT(dvdnavUpdateMousePos(QPoint)) ); //#endif connect(this, SIGNAL(buffering()), this, SLOT(displayBuffering())); } Core::~Core() { saveMediaInfo(); if (proc->isRunning()) stopMplayer(); proc->terminate(); delete proc; delete file_settings; } void Core::changeFileSettingsMethod(QString method) { // qDebug("Core::changeFileSettingsMethod: %s", method.toUtf8().constData()); if (file_settings) delete file_settings; file_settings = new FileSettings(Paths::iniPath()); } void Core::setState(State s) { if (s != _state) { _state = s; emit stateChanged(_state); //kobe 0606 if (_state == Stopped) { mset.current_sec = 0; emit showTime(mset.current_sec, true);//kobe emit positionChanged(0); } } } QString Core::stateToString() { if (state()==Playing) return "Playing"; else if (state()==Stopped) return "Stopped"; else if (state()==Paused) return "Paused"; else return "Unknown"; } // Public restart void Core::restart() { qDebug("Core::restart"); if (proc->isRunning()) { restartPlay(); } else { qDebug("Core::restart: mplayer is not running"); } } void Core::reload() { // qDebug("Core::reload"); stopMplayer(); we_are_restarting = false; initPlaying(); } void Core::saveMediaInfo() { // qDebug("Core::saveMediaInfo"); if ( (mdat.type == TYPE_FILE) && (!mdat.filename.isEmpty()) ) { file_settings->saveSettingsFor(mdat.filename, mset, proc->player()); } } void Core::updateWidgets() { emit widgetsNeedUpdate(); } void Core::changeFullscreenMode(bool b) { proc->setFullscreen(b); } void Core::displayTextOnOSD(QString text, int duration, int level, QString prefix) { // qDebug("Core::displayTextOnOSD: '%s'", text.toUtf8().constData()); if (proc->isRunning()) { proc->setPausingPrefix(prefix); proc->showOSDText(text, duration, level); } } // Generic open, autodetect type void Core::open(QString file, int seek) { // qDebug("Core::open: '%s'", file.toUtf8().data()); if (file.startsWith("file:")) { file = QUrl(file).toLocalFile(); qDebug("Core::open: converting url to local file: %s", file.toUtf8().constData()); } QFileInfo fi(file); if ( (fi.exists()) && (fi.suffix().toLower()=="iso") ) { qDebug("Core::open: * identified as a dvd iso"); //#if DVDNAV_SUPPORT // openDVD( DiscName::joinDVD(0, file, pref->use_dvdnav) ); //#else // openDVD( DiscName::joinDVD(firstDVDTitle(), file, false) ); //#endif } else if ( (fi.exists()) && (!fi.isDir()) ) { qDebug("Core::open: * identified as local file"); // Local file file = QFileInfo(file).absoluteFilePath(); openFile(file, seek); } else if ((fi.exists()) && (fi.isDir())) { // Directory qDebug("Core::open: * identified as a directory"); qDebug("Core::open: checking if contains a dvd"); file = QFileInfo(file).absoluteFilePath(); if (Helper::directoryContainsDVD(file)) { qDebug("Core::open: * directory contains a dvd"); //#if DVDNAV_SUPPORT // openDVD( DiscName::joinDVD(firstDVDTitle(), file, pref->use_dvdnav) ); //#else // openDVD( DiscName::joinDVD(firstDVDTitle(), file, false) ); //#endif } else { qDebug("Core::open: * directory doesn't contain a dvd"); qDebug("Core::open: opening nothing"); } } else if ((file.toLower().startsWith("dvd:")) || (file.toLower().startsWith("dvdnav:"))) { qDebug("Core::open: * identified as dvd"); openDVD(file); /* QString f = file.lower(); QRegExp s("^dvd://(\\d+)"); if (s.indexIn(f) != -1) { int title = s.cap(1).toInt(); openDVD(title); } else { qWarning("Core::open: couldn't parse dvd title, playing first one"); openDVD(); } */ } else //#ifdef BLURAY_SUPPORT // if (file.toLower().startsWith("br:")) { // qDebug("Core::open: * identified as blu-ray"); // openBluRay(file); // } // else //#endif if (file.toLower().startsWith("vcd:")) { qDebug("Core::open: * identified as vcd"); QString f = file.toLower(); QRegExp s("^vcd://(\\d+)"); if (s.indexIn(f) != -1) { int title = s.cap(1).toInt(); openVCD(title); } else { // qWarning("Core::open: couldn't parse vcd title, playing first one"); openVCD(); } } else if (file.toLower().startsWith("cdda:")) { qDebug("Core::open: * identified as cdda"); QString f = file.toLower(); QRegExp s("^cdda://(\\d+)"); if (s.indexIn(f) != -1) { int title = s.cap(1).toInt(); openAudioCD(title); } else { // qWarning("Core::open: couldn't parse cdda title, playing first one"); openAudioCD(); } } else if ((file.toLower().startsWith("dvb:")) || (file.toLower().startsWith("tv:"))) { qDebug("Core::open: * identified as TV"); openTV(file); } else { qDebug("Core::open: * not identified, playing as stream file=%s", file); openStream(file); } } void Core::openFile(QString filename, int seek) { qDebug("Core::openFile: '%s'", filename.toUtf8().data()); QFileInfo fi(filename); if (fi.exists()) { playNewFile(fi.absoluteFilePath(), seek); // qDebug() << "openFile finish................"; } else { //File doesn't exists //TODO: error message } } //#ifdef YOUTUBE_SUPPORT //void Core::openYT(const QString & url) { // qDebug("Core::openYT: %s", url.toUtf8().constData()); // openStream(url); // yt->close(); //} //void Core::connectingToYT(QString host) { // emit showMessage( tr("Connecting to %1").arg(host) ); //} //void Core::YTFailed(int /*error_number*/, QString /*error_str*/) { // emit showMessage( tr("Unable to retrieve the Youtube page") ); //} //void Core::YTNoVideoUrl() { // emit showMessage( tr("Unable to locate the URL of the video") ); //} //#endif //#if defined(Q_OS_WIN) || defined(Q_OS_OS2) //#ifdef SCREENSAVER_OFF //void Core::enableScreensaver() { // qDebug("Core::enableScreensaver"); // if (pref->turn_screensaver_off) { // win_screensaver->enable(); // } //} //void Core::disableScreensaver() { // qDebug("Core::disableScreensaver"); // if (pref->turn_screensaver_off) { // win_screensaver->disable(); // } //} //#endif //#endif void Core::loadSub(const QString & sub ) { if ( (!sub.isEmpty()) && (QFile::exists(sub)) ) { #if NOTIFY_SUB_CHANGES mset.external_subtitles = sub; just_loaded_external_subs = true; QFileInfo fi(sub); bool is_idx = (fi.suffix().toLower() == "idx"); if (proc->isMPV()) is_idx = false; // Hack to ignore the idx extension with mpv if (/*(pref->fast_load_sub) && */(!is_idx) && (mset.external_subtitles_fps == MediaSettings::SFPS_None)) { QString sub_file = sub; // #ifdef Q_OS_WIN // if (pref->use_short_pathnames) { // sub_file = Helper::shortPathName(sub); // // For some reason it seems it's necessary to change the path separator to unix style // // otherwise mplayer fails to load it // sub_file = sub_file.replace("\\","/"); // } // #endif proc->setExternalSubtitleFile(sub_file); } else { restartPlay(); } #else mset.external_subtitles = sub; just_loaded_external_subs = true; restartPlay(); #endif } else { // qWarning("Core::loadSub: file '%s' is not valid", sub.toUtf8().constData()); } } void Core::unloadSub() { if ( !mset.external_subtitles.isEmpty() ) { mset.external_subtitles = ""; just_unloaded_external_subs = true; restartPlay(); } } void Core::loadAudioFile(const QString & audiofile) { if (!audiofile.isEmpty()) { mset.external_audio = audiofile; restartPlay(); } } void Core::unloadAudioFile() { if (!mset.external_audio.isEmpty()) { mset.external_audio = ""; restartPlay(); } } void Core::openVCD(int title) { } void Core::openAudioCD(int title) { } void Core::openDVD(QString dvd_url) { } void Core::openTV(QString channel_id) { } void Core::openStream(QString name) { qDebug("Core::openStream: '%s'", name.toUtf8().data()); //#ifdef YOUTUBE_SUPPORT // if (pref->enable_yt_support) { // // Check if the stream is a youtube url // QString yt_full_url = yt->fullUrl(name); // if (!yt_full_url.isEmpty()) { // qDebug("Core::openStream: youtube url detected: %s", yt_full_url.toLatin1().constData()); // name = yt_full_url; // yt->setPreferredQuality( (RetrieveYoutubeUrl::Quality) pref->yt_quality ); // qDebug("Core::openStream: user_agent: '%s'", pref->yt_user_agent.toUtf8().constData()); // /*if (!pref->yt_user_agent.isEmpty()) yt->setUserAgent(pref->yt_user_agent); */ // yt->setUserAgent(pref->yt_user_agent); // #ifdef YT_USE_YTSIG // YTSig::setScriptFile( Paths::configPath() + "/yt.js" ); // #endif // yt->fetchPage(name); // return; // } // } //#endif if (proc->isRunning()) { stopMplayer(); we_are_restarting = false; } // Save data of previous file: saveMediaInfo(); mdat.reset(); mdat.filename = name; mdat.type = TYPE_STREAM; mset.reset(); initPlaying(); } void Core::playNewFile(QString file, int seek) { //kobe:打开一个新的视频文件时走这里开始播放 // qDebug("Core::playNewFile: '%s'", file.toUtf8().data()); if (proc->isRunning()) { stopMplayer(); we_are_restarting = false; } // Save data of previous file: //#ifndef NO_USE_INI_FILES saveMediaInfo(); //#endif mdat.reset(); mdat.filename = file; mdat.type = TYPE_FILE; int old_volume = mset.volume; mset.reset(); //#ifndef NO_USE_INI_FILES // Check if we already have info about this file if (file_settings->existSettingsFor(file)) { // qDebug("Core::playNewFile: We have settings for this file!!!"); // In this case we read info from config // if (!pref->dont_remember_media_settings) { file_settings->loadSettingsFor(file, mset, proc->player()); // qDebug("Core::playNewFile: Media settings read"); // Resize the window and set the aspect as soon as possible int saved_width = mset.win_width; int saved_height = mset.win_height; // 400x300 is the default size for win_width and win_height // so we set them to 0 to avoid to resize the window on // audio files if ((saved_width == 400) && (saved_height == 300)) { saved_width = 0; saved_height = 0; } if ((saved_width > 0) && (saved_height > 0)) { emit needResize(mset.win_width, mset.win_height); changeAspectRatio(mset.aspect_ratio_id); } // if (pref->dont_remember_time_pos) { // mset.current_sec = 0; // qDebug("Core::playNewFile: Time pos reset to 0"); // } // } else { // qDebug("Core::playNewFile: Media settings have not read because of preferences setting"); // } } else { // Recover volume mset.volume = old_volume; } initPlaying(seek); } void Core::restartPlay() { we_are_restarting = true; initPlaying(); } void Core::initPlaying(int seek) { // qDebug("Core::initPlaying"); /* mdat.list(); mset.list(); */ /* updateWidgets(); */ mplayerwindow->hideLogo(); if (proc->isRunning()) { stopMplayer(); } int start_sec = (int) mset.current_sec; if (seek > -1) start_sec = seek; //#ifdef YOUTUBE_SUPPORT // if (pref->enable_yt_support) { // // Avoid to pass to mplayer the youtube page url // if (mdat.type == TYPE_STREAM) { // if (mdat.filename == yt->origUrl()) { // mdat.filename = yt->latestPreferredUrl(); // } // } // } //#endif startMplayer( mdat.filename, start_sec ); } // This is reached when a new video has just started playing // and maybe we need to give some defaults void Core::newMediaPlaying() { // qDebug("Core::newMediaPlaying: --- start ---"); QString file = mdat.filename; int type = mdat.type; mdat = proc->mediaData(); mdat.filename = file; mdat.type = type; // Copy the demuxer mset.current_demuxer = mdat.demuxer; // Video if ( (mset.current_video_id == MediaSettings::NoneSelected) && (mdat.videos.numItems() > 0) ) { changeVideo( mdat.videos.itemAt(0).ID(), false ); // Don't allow to restart } #if !DELAYED_AUDIO_SETUP_ON_STARTUP && !NOTIFY_AUDIO_CHANGES // First audio if none selected if ( (mset.current_audio_id == MediaSettings::NoneSelected) && (mdat.audios.numItems() > 0) ) { // Don't set mset.current_audio_id here! changeAudio will do. // Otherwise changeAudio will do nothing. int audio = mdat.audios.itemAt(0).ID(); // First one if (mdat.audios.existsItemAt(0)) {//pref->initial_audio_track-1 audio = mdat.audios.itemAt(0).ID();//pref->initial_audio_track-1 } // Check if one of the audio tracks is the user preferred. // if (!pref->audio_lang.isEmpty()) { // int res = mdat.audios.findLang( pref->audio_lang ); // if (res != -1) audio = res; // } // // Change the audio without restarting mplayer, it's not // // safe to do it here. // changeAudio( audio, false ); } #endif //#if !NOTIFY_SUB_CHANGES // Subtitles if (mset.external_subtitles.isEmpty()) { // if (pref->autoload_sub) { //Select first subtitle if none selected if (mset.current_sub_id == MediaSettings::NoneSelected) { int sub = mdat.subs.selectOne(/* pref->subtitle_lang, */"", 0/*pref->initial_subtitle_track-1 */); changeSubtitle( sub ); } // } else { // changeSubtitle( MediaSettings::SubNone ); // } } //#endif // if (mdat.n_chapters > 0) { // // Just to show the first chapter checked in the menu // mset.current_chapter_id = firstChapter(); // } mdat.initialized = true; // MPlayer doesn't display the length in ID_LENGTH for audio CDs... if ((mdat.duration == 0) && (mdat.type == TYPE_AUDIO_CD)) { /* qDebug(" *** get duration here from title info *** "); qDebug(" *** current title: %d", mset.current_title_id ); */ if (mset.current_title_id > 0) { mdat.duration = mdat.titles.item(mset.current_title_id).duration(); } } /* updateWidgets(); */ mdat.list(); mset.list(); // qDebug() << "Core::newMediaPlaying: --- end ---mdat.duration=" << mdat.duration; } void Core::finishRestart() { // qDebug("Core::finishRestart: --- start ---"); if (!we_are_restarting) { newMediaPlaying(); //QTimer::singleShot(1000, this, SIGNAL(mediaStartPlay())); emit mediaStartPlay(); } if (we_are_restarting) { // Update info about codecs and demuxer mdat.video_codec = proc->mediaData().video_codec; mdat.audio_codec = proc->mediaData().audio_codec; mdat.demuxer = proc->mediaData().demuxer; } if (forced_titles.contains(mdat.filename)) { mdat.clip_name = forced_titles[mdat.filename]; } //#ifdef YOUTUBE_SUPPORT // if (pref->enable_yt_support) { // // Change the real url with the youtube page url and set the title // if (mdat.type == TYPE_STREAM) { // if (mdat.filename == yt->latestPreferredUrl()) { // mdat.filename = yt->origUrl(); // mdat.stream_title = yt->urlTitle(); // } // } // } //#endif #if !NOTIFY_SUB_CHANGES // Subtitles //if (we_are_restarting) { if ( (just_loaded_external_subs) || (just_unloaded_external_subs) ) { // qDebug("Core::finishRestart: processing new subtitles"); // Just to simplify things if (mset.current_sub_id == MediaSettings::NoneSelected) { mset.current_sub_id = MediaSettings::SubNone; } // Save current sub SubData::Type type; int ID; int old_item = -1; if ( mset.current_sub_id != MediaSettings::SubNone ) { old_item = mset.current_sub_id; type = mdat.subs.itemAt(old_item).type(); ID = mdat.subs.itemAt(old_item).ID(); } // Use the subtitle info from mplayerprocess // qDebug( "Core::finishRestart: copying sub data from proc to mdat"); mdat.subs = proc->mediaData().subs; int item = MediaSettings::SubNone; // Try to recover old subtitle if (just_unloaded_external_subs) { if (old_item > -1) { int new_item = mdat.subs.find(type, ID); if (new_item > -1) item = new_item; } } // If we've just loaded a subtitle file // select one if the user wants to autoload // one subtitle if (just_loaded_external_subs) { // if ( (pref->autoload_sub) && (item == MediaSettings::SubNone) ) { if (item == MediaSettings::SubNone) { // qDebug("Core::finishRestart: cannot find previous subtitle"); // qDebug("Core::finishRestart: selecting a new one"); item = mdat.subs.selectOne(""/* pref->subtitle_lang */); } } changeSubtitle( item ); just_loaded_external_subs = false; just_unloaded_external_subs = false; } else { // Normal restart, subtitles haven't changed // Recover current subtitle changeSubtitle( mset.current_sub_id ); changeSecondarySubtitle( mset.current_secondary_sub_id ); } #endif we_are_restarting = false; changeAspectRatio(mset.aspect_ratio_id); // if (pref->mplayer_additional_options.contains("-volume")) { // qDebug("Core::finishRestart: don't set volume since -volume is used"); // } else { // Code to set the volume, used when mplayer didn't have the -volume option /* if (pref->global_volume) { bool was_muted = pref->mute; setVolume( pref->volume, true); if (was_muted) mute(true); } else { bool was_muted = mset.mute; setVolume( mset.volume, true ); if (was_muted) mute(true); } */ int vol = (pref->global_volume ? pref->volume : mset.volume); volumeChanged(vol); if (proc->isMPlayer() && pref->mute) { // Set mute here because mplayer doesn't have an option to set mute from the command line mute(true); } // } //#if 0 //// Old. Gamma already set with option -gamma // if (pref->change_video_equalizer_on_startup && (mset.gamma != 0)) { // int gamma = mset.gamma; // mset.gamma = -1000; // if mset.gamma == new value, mset.gamma is not changed! // setGamma( gamma ); // } //#endif // Hack to be sure that the equalizers are up to date emit videoEqualizerNeedsUpdate(); emit audioEqualizerNeedsUpdate(); changeZoom(mset.zoom_factor); // Toggle subtitle visibility changeSubVisibility(pref->sub_visibility); // A-B marker emit ABMarkersChanged(mset.A_marker, mset.B_marker); // Initialize the OSD level QTimer::singleShot(pref->osd_delay, this, SLOT(initializeOSD())); emit mediaLoaded(); emit mediaInfoChanged(); emit newDuration(mdat.duration); updateWidgets(); // New // qDebug("Core::finishRestart: --- end ---"); } void Core::initializeOSD() { changeOSD(pref->osd); } void Core::stop() { qDebug("Core::stop"); qDebug("Core::stop: state: %s", stateToString().toUtf8().data()); if (state()==Stopped) { // if pressed stop twice, reset video to the beginning qDebug("Core::stop: mset.current_sec: %f", mset.current_sec); mset.current_sec = 0; qDebug("Core::stop: mset.current_sec set to 0"); emit showTime(mset.current_sec, true);//kobe 0606 // #ifdef SEEKBAR_RESOLUTION emit positionChanged(0); // #else // emit posChanged( 0 ); // #endif //updateWidgets(); } stopMplayer(); emit mediaStoppedByUser();//kobe:此处信号会让一些按钮处于禁用状态 // if (pref->reset_stop) { // mset.current_sec = 0; // emit showTime( mset.current_sec ); // #ifdef SEEKBAR_RESOLUTION // emit positionChanged( 0 ); // #else // emit posChanged( 0 ); // #endif // } } void Core::play() { qDebug("Core::play"); if ((proc->isRunning()) && (state()==Paused)) { proc->setPause(false); } else if ((proc->isRunning()) && (state()==Playing)) { // nothing to do, continue playing } else { // if we're stopped, play it again if ( !mdat.filename.isEmpty() ) { /* qDebug( "current_sec: %f, duration: %f", mset.current_sec, mdat.duration); if ( (floor(mset.current_sec)) >= (floor(mdat.duration)) ) { mset.current_sec = 0; } */ restartPlay(); } else { emit noFileToPlay();//kobe:当前播放的文件不存在时,去播放下一个 } } } void Core::pause_and_frame_step() { qDebug("Core::pause_and_frame_step"); if (proc->isRunning()) { if (state() == Paused) { proc->frameStep(); } else { proc->setPause(true); } } } void Core::pause() { qDebug("Core::pause: current state: %s", stateToString().toUtf8().data()); if (proc->isRunning()) { // Pauses and unpauses if (state() == Paused) proc->setPause(false); else proc->setPause(true); } } void Core::play_or_pause() { if (proc->isRunning()) { pause(); } else { play(); } } void Core::frameStep() { qDebug("Core::frameStep"); if (proc->isRunning()) { proc->frameStep(); } } void Core::frameBackStep() { qDebug("Core::frameBackStep"); if (proc->isRunning()) { proc->frameBackStep(); } } void Core::screenshot() { // qDebug("Core::screenshot"); if ( (!pref->screenshot_directory.isEmpty()) && (QFileInfo(pref->screenshot_directory).isDir()) ) { proc->setPausingPrefix(pausing_prefix()); proc->takeScreenshot(PlayerProcess::Single, false/*pref->subtitles_on_screenshots*/);//kobe0417屏幕截图 path=~/图片/kylin_video_screenshots/ // qDebug("Core::screenshot: taken screenshot"); } else { qDebug("Core::screenshot: error: directory for screenshots not valid"); emit showMessage( tr("Screenshot NOT taken, folder not configured") ); } } void Core::screenshots() { // qDebug("Core::screenshots"); if ( (!pref->screenshot_directory.isEmpty()) && (QFileInfo(pref->screenshot_directory).isDir()) ) { proc->takeScreenshot(PlayerProcess::Multiple, false/*pref->subtitles_on_screenshots*/); } else { qDebug("Core::screenshots: error: directory for screenshots not valid"); emit showMessage( tr("Screenshots NOT taken, folder not configured") ); } } //#ifdef CAPTURE_STREAM //void Core::switchCapturing() { // qDebug("Core::switchCapturing"); // proc->switchCapturing(); //} //#endif void Core::processFinished() { // qDebug("Core::processFinished"); // qDebug("Core::processFinished: we_are_restarting: %d", we_are_restarting); //mset.current_sec = 0; if (!we_are_restarting) { qDebug("Core::processFinished: play has finished!"); setState(Stopped); // emit this->mediaStoppedByUser(); //emit stateChanged(state()); } emit this->show_logo_signal(true); int exit_code = proc->exitCode(); // qDebug("Core::processFinished: exit_code: %d", exit_code); if (exit_code != 0) { emit mplayerFinishedWithError(exit_code); emit this->mediaStoppedByUser(); } } void Core::fileReachedEnd() { qDebug() << "Core::fileReachedEnd()"; // If we're at the end of the movie, reset to 0 mset.current_sec = 0; updateWidgets(); emit mediaFinished();//kobe:播放结束后发送信号去播放下一个 } //#if SEEKBAR_RESOLUTION void Core::goToPosition(int value) { // qDebug("***************Core::goToPosition: value: %d", value); /*kobe: 20170718 * seek [type] * 0 is a relative seek of +/- seconds (default). * 1 is a seek to % in the movie. * 2 is a seek to an absolute position of seconds. * 当播放引擎为mplayer时,定位时的type如果为2,即绝对位置,则有些视频拖动进度后又返回原来的位置,此时只能用type=1。而播放引擎为mpv时无该问题。 */ if (pref->mplayer_bin.contains("mpv")) { if (mdat.duration > 0) { int jump_time = (int) mdat.duration * value / SEEKBAR_RESOLUTION; // qDebug("***************Core::goToPosition 1111111111111111 mdat.duration=%f and jump_time=%d", mdat.duration, jump_time); goToSec(jump_time); } } else { // qDebug("***************Core::goToPos 22222222222 jump_time=%f", (double) value / (SEEKBAR_RESOLUTION / 100)); goToPos((double) value / (SEEKBAR_RESOLUTION / 100)); } /* // if (pref->relative_seeking) { // goToPos((double) value / (SEEKBAR_RESOLUTION / 100) ); // } // else { if (mdat.duration > 0) { int jump_time = (int) mdat.duration * value / SEEKBAR_RESOLUTION; qDebug("***************Core::goToPosition 1111111111111111 mdat.duration=%f and jump_time=%d", mdat.duration, jump_time); goToSec(jump_time); } else qDebug("***************Core::goToPosition 22222222222222222222"); // }*/ } //kobe:Enable precise_seeking (only available with mplayer2) void Core::goToPos(double perc) { // qDebug("Core::goToPos: per: %f", perc); seek_cmd(perc, 1); } //#else //void Core::goToPos(int perc) { // qDebug("Core::goToPos: per: %d", perc); // seek_cmd(perc, 1); //} //#endif void Core::startMplayer( QString file, double seek ) { // qDebug("Core::startMplayer %s", file.toUtf8().data()); if (file.isEmpty()) { qWarning("Core:startMplayer: file is empty!"); return; } if (proc->isRunning()) { qWarning("Core::startMplayer: MPlayer still running!"); return; } //#ifdef YOUTUBE_SUPPORT // // Stop any pending request // #if 0 // qDebug("Core::startMplayer: yt state: %d", yt->state()); // if (yt->state() != QHttp::Unconnected) { // //yt->abort(); /* Make the app to crash, don't know why */ // } // #endif // yt->close(); //#endif // DVD QString dvd_folder; // int dvd_title = -1; if (mdat.type==TYPE_DVD) { // DiscData disc_data = DiscName::split(file); // dvd_folder = disc_data.device; // if (dvd_folder.isEmpty()) dvd_folder = pref->dvd_device; // dvd_title = disc_data.title; // file = disc_data.protocol + "://"; // if (dvd_title > -1) file += QString::number(dvd_title); } // Check URL playlist kobe 20170712 /*bool url_is_playlist = false; if (file.endsWith("|playlist")) { url_is_playlist = true; file = file.remove("|playlist"); } else { QUrl url(file); qDebug("Core::startMplayer: checking if stream is a playlist"); qDebug("Core::startMplayer: url path: '%s'", url.path().toUtf8().constData());///home/lixiang/东成西就.rmvb if (url.scheme().toLower() != "ffmpeg") { QRegExp rx("\\.ram$|\\.asx$|\\.m3u$|\\.m3u8$|\\.pls$", Qt::CaseInsensitive); url_is_playlist = (rx.indexIn(url.path()) != -1); } } qDebug("Core::startMplayer: url_is_playlist: %d", url_is_playlist);//0*/ // Check if a m4a file exists with the same name of file, in that cause if will be used as audio if (/*pref->autoload_m4a && */mset.external_audio.isEmpty()) {//kobe QFileInfo fi(file); if (fi.exists() && !fi.isDir()) { if (fi.suffix().toLower() == "mp4") { QString file2 = fi.path() + "/" + fi.completeBaseName() + ".m4a"; //qDebug("Core::startMplayer: file2: %s", file2.toUtf8().constData()); if (!QFile::exists(file2)) { // Check for upper case file2 = fi.path() + "/" + fi.completeBaseName() + ".M4A"; } if (QFile::exists(file2)) { qDebug("Core::startMplayer: found %s, so it will be used as audio file", file2.toUtf8().constData()); mset.external_audio = file2; } } } } bool screenshot_enabled = ( (pref->use_screenshot) && (!pref->screenshot_directory.isEmpty()) && (QFileInfo(pref->screenshot_directory).isDir()) ); proc->clearArguments(); // Set the screenshot directory // #ifdef Q_OS_WIN // if (pref->use_short_pathnames) { // proc->setScreenshotDirectory(Helper::shortPathName(pref->screenshot_directory)); // } // else // #endif { proc->setScreenshotDirectory(pref->screenshot_directory); } // Use absolute path, otherwise after changing to the screenshot directory // the mplayer path might not be found if it's a relative path // (seems to be necessary only for linux) QString mplayer_bin = pref->mplayer_bin; QFileInfo fi(mplayer_bin); if (fi.exists() && fi.isExecutable() && !fi.isDir()) { mplayer_bin = fi.absoluteFilePath(); } // debian/ubuntu specific check if we are using mplayer2 // if ((fi.baseName().toLower() == "mplayer2") || !access("/usr/share/doc/mplayer2/copyright", F_OK)) { // qDebug("Core::startMplayer: this seems mplayer2"); // if (!pref->mplayer_is_mplayer2) { // pref->mplayer_is_mplayer2 = true; // } // } proc->setExecutable(mplayer_bin);// /usr/bin/mplayer proc->setFixedOptions(); //#ifdef LOG_MPLAYER if (pref->verbose_log) { proc->setOption("verbose"); } //#endif // if (pref->fullscreen && pref->use_mplayer_window) { // proc->setOption("fs", true); // } else { // No mplayer fullscreen mode proc->setOption("fs", false); // } // Demuxer and audio and video codecs: if (!mset.forced_demuxer.isEmpty()) { proc->setOption("demuxer", mset.forced_demuxer); } if (!mset.forced_audio_codec.isEmpty()) { proc->setOption("ac", mset.forced_audio_codec); } if (!mset.forced_video_codec.isEmpty()) { proc->setOption("vc", mset.forced_video_codec); } else { // #ifndef Q_OS_WIN //// if (pref->vo.startsWith("x11")) { // My card doesn't support vdpau, I use x11 to test if (pref->vo.startsWith("vdpau")) { QString c; if (pref->vdpau.ffh264vdpau) c += "ffh264vdpau,"; if (pref->vdpau.ffmpeg12vdpau) c += "ffmpeg12vdpau,"; if (pref->vdpau.ffwmv3vdpau) c += "ffwmv3vdpau,"; if (pref->vdpau.ffvc1vdpau) c += "ffvc1vdpau,"; if (pref->vdpau.ffodivxvdpau) c += "ffodivxvdpau,"; if (!c.isEmpty()) { proc->setOption("vc", c); } } else { // #endif // if (pref->coreavc) {//没有指定其他编解码器时使用 CoreAVC proc->setOption("vc", "vda,"); proc->setOption("vc", "coreserve,");//−vc <[-]编解码器1,[-]编解码器2,...[,]> 设置可用编解码器的优先级列表, 按照它们在codecs.conf中的编解码器 名称. 在名称前加’-’表示忽略该编解码器 // } // #ifndef Q_OS_WIN } // #endif } // if (pref->use_hwac3) { // proc->setOption("afm", "hwac3"); // } if (proc->isMPlayer()) { // MPlayer QString lavdopts; // if ( (pref->h264_skip_loop_filter == Preferences::LoopDisabled) || // ((pref->h264_skip_loop_filter == Preferences::LoopDisabledOnHD) && // (mset.is264andHD)) ) // { // if (!lavdopts.isEmpty()) lavdopts += ":"; // lavdopts += "skiploopfilter=all"; // } if (pref->threads > 1) { if (!lavdopts.isEmpty()) lavdopts += ":"; lavdopts += "threads=" + QString::number(pref->threads); } if (!lavdopts.isEmpty()) { proc->setOption("lavdopts", lavdopts);//使用libavcodec编码 } } else { // MPV // if ( (pref->h264_skip_loop_filter == Preferences::LoopDisabled) || // ((pref->h264_skip_loop_filter == Preferences::LoopDisabledOnHD) && // (mset.is264andHD)) ) // { // proc->setOption("skiploopfilter"); // } if (pref->threads > 1) { proc->setOption("threads", QString::number(pref->threads)); } } if (!pref->hwdec.isEmpty()) proc->setOption("hwdec", pref->hwdec); proc->setOption("sub-fuzziness", 1/*pref->subfuzziness*/); // From mplayer SVN r27667 the number of chapters can be obtained from ID_CHAPTERS mset.current_chapter_id = 0; // Reset chapters // TODO: I think the current_chapter_id thing has to be deleted if (pref->vo != "player_default") { if (!pref->vo.isEmpty()) { proc->setOption("vo", pref->vo ); } else { // #ifdef Q_OS_WIN // if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA) { // proc->setOption("vo", "direct3d,"); // } else { // proc->setOption("vo", "directx,"); // } // #else proc->setOption("vo", "xv,"); // #endif } } //#if USE_ADAPTER // if (pref->adapter > -1) { // proc->setOption("adapter", QString::number(pref->adapter)); // } //#endif if (pref->ao != "player_default") { if (!pref->ao.isEmpty()) { proc->setOption("ao", pref->ao ); } } //#if !defined(Q_OS_WIN) && !defined(Q_OS_OS2) if (pref->vo.startsWith("x11")) { proc->setOption("zoom"); } //#endif // Performance options // #ifdef Q_OS_WIN // QString p; // int app_p = NORMAL_PRIORITY_CLASS; // switch (pref->priority) { // case Preferences::Realtime: p = "realtime"; // app_p = REALTIME_PRIORITY_CLASS; // break; // case Preferences::High: p = "high"; // app_p = REALTIME_PRIORITY_CLASS; // break; // case Preferences::AboveNormal: p = "abovenormal"; // app_p = HIGH_PRIORITY_CLASS; // break; // case Preferences::Normal: p = "normal"; // app_p = ABOVE_NORMAL_PRIORITY_CLASS; // break; // case Preferences::BelowNormal: p = "belownormal"; break; // case Preferences::Idle: p = "idle"; break; // default: p = "normal"; // } // proc->setOption("priority", p); // /* // SetPriorityClass(GetCurrentProcess(), app_p); // qDebug("Core::startMplayer: priority of smplayer process set to %d", app_p); // */ // #endif // if (pref->frame_drop && pref->hard_frame_drop) { // proc->setOption("framedrop", "decoder+vo"); // } // else // if (pref->frame_drop) { // proc->setOption("framedrop", "vo"); // } // else // if (pref->hard_frame_drop) { // proc->setOption("framedrop", "decoder"); // } /*-framedrop(另见 -hardframedrop,未使用 -nocorrect-pts 时只可用于测试) 跳过某些帧的显示从而在运行慢的机器上保持音视频同步。视频过滤器不会应用到这些帧上。对于 B-帧来说,甚至解码也完全跳过。 -hardframedrop(未使用 -nocorrect-pts 时只可用于实验) 更加密集地丢帧(中断解码过程)。会导致图像失真!注意,libmpeg2 解码器尤其可能在使用该选项后崩溃,所以请考虑使用“-vc ffmpeg12,”。*/ proc->setOption("framedrop", "vo"); if (pref->autosync) { proc->setOption("autosync", QString::number(pref->autosync_factor));//30 } // if (pref->use_mc) { proc->setOption("mc", "0"/*QString::number(pref->mc_value)*/); // } proc->setOption("dr", pref->use_direct_rendering); proc->setOption("double", pref->use_double_buffer); #ifdef Q_WS_X11 proc->setOption("stop-xscreensaver", true/*pref->disable_screensaver*/);//kobe:播放时禁用屏幕保护程序 #endif // if (!pref->use_mplayer_window) { proc->disableInput(); proc->setOption("keepaspect", false); //#if defined(Q_OS_OS2) // #define WINIDFROMHWND(hwnd) ( ( hwnd ) - 0x80000000UL ) // proc->setOption("wid", QString::number( WINIDFROMHWND( (int) mplayerwindow->videoLayer()->winId() ) )); //#else //kobe 将视频输出到控件: mplayer -wid WINDOWID proc->setOption("wid", QString::number( (qint64) mplayerwindow->videoLayer()->winId() ) );//kobe 0615:将视频输出定位到widget窗体部件中,-wid参数只在X11、directX和OpenGL中适用 //#endif //#if USE_COLORKEY // #if defined(Q_OS_WIN) || defined(Q_OS_OS2) // if ((pref->vo.startsWith("directx")) || (pref->vo.startsWith("kva")) || (pref->vo.isEmpty())) { // proc->setOption("colorkey", ColorUtils::colorToRGB(pref->color_key)); // } else { // #endif /* qDebug("Core::startMplayer: * not using -colorkey for %s", pref->vo.toUtf8().data()); qDebug("Core::startMplayer: * report if you can't see the video"); */ // #if defined(Q_OS_WIN) || defined(Q_OS_OS2) // } // #endif //#endif // Square pixels proc->setOption("monitorpixelaspect", "1"); // } else { // // no -wid // proc->setOption("keepaspect", true); // if (!pref->monitor_aspect.isEmpty()) { // proc->setOption("monitoraspect", pref->monitor_aspect); // } // } // OSD proc->setOption("osd-scale", proc->isMPlayer() ? pref->subfont_osd_scale : pref->osd_scale); // Subtitles fonts // if ((pref->use_ass_subtitles) && (pref->freetype_support)) { // // ASS: // proc->setOption("ass"); // proc->setOption("embeddedfonts"); // proc->setOption("ass-line-spacing", 0/*QString::number(pref->ass_line_spacing)*/); // proc->setOption("ass-font-scale", QString::number(mset.sub_scale_ass)); // if (!pref->mplayer_is_mplayer2) { // proc->setOption("flip-hebrew",false); // It seems to be necessary to display arabic subtitles correctly when using -ass // } //kobe // if (pref->enable_ass_styles) { // QString ass_force_style; // if (!pref->user_forced_ass_style.isEmpty()) { // ass_force_style = pref->user_forced_ass_style; // } else { // ass_force_style = pref->ass_styles.toString(); // } // if (proc->isMPV()) { // // MPV // proc->setSubStyles(pref->ass_styles); // if (pref->force_ass_styles) { // proc->setOption("ass-force-style", ass_force_style); // } // } else { // // MPlayer // if (!pref->force_ass_styles) { // proc->setSubStyles(pref->ass_styles, Paths::subtitleStyleFile()); // } else { // proc->setOption("ass-force-style", ass_force_style); // } // } // } // Use the same font for OSD // deleted // Set the size of OSD // deleted // } else { // // NO ASS: // if (pref->freetype_support) proc->setOption("noass"); // proc->setOption("subfont-text-scale", QString::number(mset.sub_scale)); // } // Subtitle encoding { QString encoding; if ( (pref->use_enca) && (!pref->enca_lang.isEmpty()) ) { encoding = "enca:"+ pref->enca_lang; if (!pref->subcp.isEmpty()) { encoding += ":"+ pref->subcp; } } else if (!pref->subcp.isEmpty()) { encoding = pref->subcp; } if (!encoding.isEmpty()) { proc->setOption("subcp", encoding); } } // proc->setOption("subcp", "ISO-8859-1"); if (mset.closed_caption_channel > 0) { proc->setOption("subcc", QString::number(mset.closed_caption_channel)); } // if (pref->use_forced_subs_only) { // proc->setOption("forcedsubsonly"); // } //#if PROGRAM_SWITCH // if ( (mset.current_program_id != MediaSettings::NoneSelected) /*&& // (mset.current_video_id == MediaSettings::NoneSelected) && // (mset.current_audio_id == MediaSettings::NoneSelected)*/ ) // { // proc->setOption("tsprog", QString::number(mset.current_program_id)); // } // // Don't set video and audio track if using -tsprog // else { //#endif #if 1 if (mset.current_video_id != MediaSettings::NoneSelected) { proc->setOption("vid", QString::number(mset.current_video_id)); } if (mset.external_audio.isEmpty()) { if (mset.current_audio_id != MediaSettings::NoneSelected) { // Workaround for MPlayer bug #1321 (http://bugzilla.mplayerhq.hu/show_bug.cgi?id=1321) if (mdat.audios.numItems() != 1) { proc->setOption("aid", QString::number(mset.current_audio_id)); } } } #endif //#if PROGRAM_SWITCH // } //#endif if (!initial_subtitle.isEmpty()) { mset.external_subtitles = initial_subtitle; initial_subtitle = ""; just_loaded_external_subs = true; // Big ugly hack :( } if (!mset.external_subtitles.isEmpty()) { bool is_idx = (QFileInfo(mset.external_subtitles).suffix().toLower()=="idx"); if (proc->isMPV()) is_idx = false; // Hack to ignore the idx extension with mpv if (is_idx) { // sub/idx subtitles QFileInfo fi; // #ifdef Q_OS_WIN // if (pref->use_short_pathnames) // fi.setFile(Helper::shortPathName(mset.external_subtitles)); // else // #endif fi.setFile(mset.external_subtitles); QString s = fi.path() +"/"+ fi.completeBaseName(); qDebug("Core::startMplayer: subtitle file without extension: '%s'", s.toUtf8().data()); proc->setOption("vobsub", s); } else { // #ifdef Q_OS_WIN // if (pref->use_short_pathnames) // proc->setOption("sub", Helper::shortPathName(mset.external_subtitles)); // else // #endif { proc->setOption("sub", mset.external_subtitles); } } if (mset.external_subtitles_fps != MediaSettings::SFPS_None) { QString fps; switch (mset.external_subtitles_fps) { case MediaSettings::SFPS_23: fps = "23"; break; case MediaSettings::SFPS_24: fps = "24"; break; case MediaSettings::SFPS_25: fps = "25"; break; case MediaSettings::SFPS_30: fps = "30"; break; case MediaSettings::SFPS_23976: fps = "24000/1001"; break; case MediaSettings::SFPS_29970: fps = "30000/1001"; break; default: fps = "25"; } proc->setOption("subfps", fps); } } if (!mset.external_audio.isEmpty()) { // #ifdef Q_OS_WIN // if (pref->use_short_pathnames) // proc->setOption("audiofile", Helper::shortPathName(mset.external_audio)); // else // #endif { proc->setOption("audiofile", mset.external_audio); } } proc->setOption("subpos", QString::number(mset.sub_pos)); if (mset.audio_delay != 0) { proc->setOption("delay", QString::number((double) mset.audio_delay/1000)); } if (mset.sub_delay != 0) { proc->setOption("subdelay", QString::number((double) mset.sub_delay/1000)); } // Contrast, brightness... // if (pref->change_video_equalizer_on_startup) { if (mset.contrast != 0) { proc->setOption("contrast", QString::number(mset.contrast)); } if (mset.brightness != 0) { proc->setOption("brightness", QString::number(mset.brightness)); } if (mset.hue != 0) { proc->setOption("hue", QString::number(mset.hue)); } if (mset.saturation != 0) { proc->setOption("saturation", QString::number(mset.saturation)); } if (mset.gamma != 0) { proc->setOption("gamma", QString::number(mset.gamma)); } // } // if (pref->mplayer_additional_options.contains("-volume")) { // qDebug("Core::startMplayer: don't set volume since -volume is used"); // } else { int vol = (pref->global_volume ? pref->volume : mset.volume); // if (proc->isMPV()) { // vol = adjustVolume(vol, pref->use_soft_vol ? pref->softvol_max : 100); // } proc->setOption("volume", QString::number(vol)); // } if (pref->mute) { proc->setOption("mute"); } if (mdat.type==TYPE_DVD) { if (!dvd_folder.isEmpty()) { // #ifdef Q_OS_WIN // if (pref->use_short_pathnames) { // proc->setOption("dvd-device", Helper::shortPathName(dvd_folder)); // } // else // #endif proc->setOption("dvd-device", dvd_folder); } else { // qWarning("Core::startMplayer: dvd device is empty!"); } } if ((mdat.type==TYPE_VCD) || (mdat.type==TYPE_AUDIO_CD)) { // if (!pref->cdrom_device.isEmpty()) { // proc->setOption("cdrom-device", pref->cdrom_device); // } } /* if (mset.current_chapter_id > 0) { int chapter = mset.current_chapter_id; // Fix for older versions of mplayer: if ((mdat.type == TYPE_DVD) && (firstChapter() == 0)) chapter++; proc->setOption("chapter", QString::number(chapter)); } */ if (mset.current_angle_id > 0) { proc->setOption("dvdangle", QString::number( mset.current_angle_id)); } int cache = 0; switch (mdat.type) { case TYPE_FILE : cache = pref->cache_for_files; break; case TYPE_DVD : // cache = pref->cache_for_dvds; // #if DVDNAV_SUPPORT // if (file.startsWith("dvdnav:")) cache = 0; // #endif cache = 0; break; case TYPE_STREAM : cache = pref->cache_for_streams; break; case TYPE_VCD : // cache = pref->cache_for_vcds; cache = 0; break; case TYPE_AUDIO_CD : // cache = pref->cache_for_audiocds; break; cache = 0; break; case TYPE_TV : // cache = pref->cache_for_tv; break; cache = 0; break; //#ifdef BLURAY_SUPPORT // case TYPE_BLURAY : cache = pref->cache_for_dvds; break; // FIXME: use cache for bluray? //#endif default: cache = 0; } proc->setOption("cache", QString::number(cache)); if (mset.speed != 1.0) { proc->setOption("speed", QString::number(mset.speed)); } if (mdat.type != TYPE_TV) { // Play A - B if ((mset.A_marker > -1) && (mset.B_marker > mset.A_marker)) { proc->setOption("ss", QString::number(mset.A_marker)); proc->setOption("endpos", QString::number(mset.B_marker - mset.A_marker)); } else // If seek < 5 it's better to allow the video to start from the beginning if ((seek >= 5) && (!mset.loop)) { proc->setOption("ss", QString::number(seek)); } } // Enable the OSD later, to avoid a lot of messages to be // printed on startup proc->setOption("osdlevel", "0"); if (pref->use_idx) { proc->setOption("idx"); } if (mdat.type == TYPE_STREAM) { if (pref->prefer_ipv4) { proc->setOption("prefer-ipv4"); } else { proc->setOption("prefer-ipv6"); } } // if (pref->use_correct_pts != Preferences::Detect) { // proc->setOption("correct-pts", (pref->use_correct_pts == Preferences::Enabled)); // } bool force_noslices = false; //#ifndef Q_OS_WIN if (proc->isMPlayer()) { if ((pref->vdpau.disable_video_filters) && (pref->vo.startsWith("vdpau"))) { qDebug("Core::startMplayer: using vdpau, video filters are ignored"); goto end_video_filters; } } else { // MPV if (!pref->hwdec.isEmpty() && pref->hwdec != "no") { qDebug("Core::startMplayer: hardware decoding is enabled. The video filters will be ignored"); goto end_video_filters; } } //#endif // Video filters: // Phase if (mset.phase_filter) { proc->addVF("phase", "A"); } // Deinterlace if (mset.current_deinterlacer != MediaSettings::NoDeinterlace) { switch (mset.current_deinterlacer) { case MediaSettings::L5: proc->addVF("l5"); break; case MediaSettings::Yadif: proc->addVF("yadif"); break; case MediaSettings::LB: proc->addVF("lb"); break; case MediaSettings::Yadif_1: proc->addVF("yadif", "1"); break; case MediaSettings::Kerndeint: proc->addVF("kerndeint", "5"); break; } } // 3D stereo if (mset.stereo3d_in != "none" && !mset.stereo3d_out.isEmpty()) { proc->addStereo3DFilter(mset.stereo3d_in, mset.stereo3d_out); } // // Denoise // if (mset.current_denoiser != MediaSettings::NoDenoise) { // if (mset.current_denoiser==MediaSettings::DenoiseSoft) { // proc->addVF("hqdn3d", pref->filters->item("denoise_soft").options()); // } else { // proc->addVF("hqdn3d", pref->filters->item("denoise_normal").options()); // } // } // // Unsharp // if (mset.current_unsharp != 0) { // if (mset.current_unsharp == 1) { // proc->addVF("blur", pref->filters->item("blur").options()); // } else { // proc->addVF("sharpen", pref->filters->item("sharpen").options()); // } // } // // Deblock // if (mset.deblock_filter) { // proc->addVF("deblock", pref->filters->item("deblock").options()); // } // Dering if (mset.dering_filter) { proc->addVF("dering"); } // Gradfun // if (mset.gradfun_filter) { // proc->addVF("gradfun", pref->filters->item("gradfun").options()); // } // Upscale if (mset.upscaling_filter) { int width = DesktopInfo::desktop_size(mplayerwindow).width(); proc->setOption("sws", "9"); proc->addVF("scale", QString::number(width) + ":-2"); } // Addnoise // if (mset.noise_filter) { // proc->addVF("noise", pref->filters->item("noise").options()); // } // Postprocessing if (mset.postprocessing_filter) { proc->addVF("postprocessing"); proc->setOption("autoq", "6"/*QString::number(pref->autoq)*/); } // Letterbox (expand) // if ((mset.add_letterbox) || (pref->fullscreen && pref->add_blackborders_on_fullscreen)) { // proc->addVF("expand", QString("aspect=%1").arg( DesktopInfo::desktop_aspectRatio(mplayerwindow))); // } // Software equalizer if ( (pref->use_soft_video_eq) ) { proc->addVF("eq2"); proc->addVF("hue"); if ( (pref->vo == "gl") || (pref->vo == "gl2") || (pref->vo == "gl_tiled") //#ifdef Q_OS_WIN // || (pref->vo == "directx:noaccel") //#endif ) { proc->addVF("scale"); } } // Additional video filters, supplied by user // // File // if ( !mset.mplayer_additional_video_filters.isEmpty() ) { // proc->setOption("vf-add", mset.mplayer_additional_video_filters); // } // // Global // if ( !pref->mplayer_additional_video_filters.isEmpty() ) { // proc->setOption("vf-add", pref->mplayer_additional_video_filters); // } // Filters for subtitles on screenshots // if ((screenshot_enabled) && (pref->subtitles_on_screenshots)) // { //// if (pref->use_ass_subtitles) { //// proc->addVF("subs_on_screenshots", "ass"); //// } else { // proc->addVF("subs_on_screenshots"); // force_noslices = true; //// } // } // Rotate if (mset.rotate != MediaSettings::NoRotate) { proc->addVF("rotate", QString::number(mset.rotate)); } // Flip if (mset.flip) { proc->addVF("flip"); } // Mirror if (mset.mirror) { proc->addVF("mirror"); } // Screenshots if (screenshot_enabled) { proc->addVF("screenshot"); } //#ifndef Q_OS_WIN end_video_filters: //#endif //0621 //#ifdef MPV_SUPPORT // Template for screenshots (only works with mpv) if (screenshot_enabled) { if (!pref->screenshot_template.isEmpty()) { proc->setOption("screenshot_template", pref->screenshot_template); } if (!pref->screenshot_format.isEmpty()) { proc->setOption("screenshot_format", pref->screenshot_format); } } //#endif // slices if ((pref->use_slices) && (!force_noslices)) { proc->setOption("slices", true); } else { proc->setOption("slices", false); } // Audio channels if (mset.audio_use_channels != 0) { proc->setOption("channels", QString::number(mset.audio_use_channels)); } // if (!pref->use_hwac3) { // Audio filters // #ifdef MPLAYER_SUPPORT if (mset.karaoke_filter) { proc->addAF("karaoke"); } // #endif // Stereo mode if (mset.stereo_mode != 0) { switch (mset.stereo_mode) { case MediaSettings::Left: proc->addAF("channels", "2:2:0:1:0:0"); break; case MediaSettings::Right: proc->addAF("channels", "2:2:1:0:1:1"); break; case MediaSettings::Mono: proc->addAF("pan", "1:0.5:0.5"); break; case MediaSettings::Reverse: proc->addAF("channels", "2:2:0:1:1:0"); break; } } // #ifdef MPLAYER_SUPPORT if (mset.extrastereo_filter) { proc->addAF("extrastereo"); } // #endif // if (mset.volnorm_filter) { // proc->addAF("volnorm", pref->filters->item("volnorm").options()); // } // bool use_scaletempo = (pref->use_scaletempo == Preferences::Enabled); // if (pref->use_scaletempo == Preferences::Detect) { // use_scaletempo = (MplayerVersion::isMplayerAtLeast(24924)); // } // bool use_scaletempo = (MplayerVersion::isMplayerAtLeast(24924)); // if (use_scaletempo) { proc->addAF("scaletempo"); // } // Audio equalizer // if (pref->use_audio_equalizer) { // AudioEqualizerList l = pref->global_audio_equalizer ? pref->audio_equalizer : mset.audio_equalizer; // proc->addAF("equalizer", Helper::equalizerListToString(l)); // } //kobe double v0 = (double) 0 / 10; QString s = QString::number(v0) + ":" + QString::number(v0) + ":" + QString::number(v0) + ":" + QString::number(v0) + ":" + QString::number(v0) + ":" + QString::number(v0) + ":" + QString::number(v0) + ":" + QString::number(v0) + ":" + QString::number(v0) + ":" + QString::number(v0); proc->addAF("equalizer", s); // Additional audio filters, supplied by user // File // if ( !pref->mplayer_additional_audio_filters.isEmpty() ) { // proc->setOption("af-add", pref->mplayer_additional_audio_filters); // } // // Global // if ( !mset.mplayer_additional_audio_filters.isEmpty() ) { // proc->setOption("af-add", mset.mplayer_additional_audio_filters); // } /* } else { // Don't use audio filters if using the S/PDIF output qDebug("Core::startMplayer: audio filters are disabled when using the S/PDIF output!"); }*/ if (pref->use_soft_vol) { proc->setOption("softvol"); proc->setOption("softvol-max", QString::number(pref->softvol_max)); } //#ifdef MPV_SUPPORT // proc->setOption("enable_streaming_sites_support", pref->enable_streaming_sites); //#endif //#ifndef Q_OS_WIN // if (proc->isMPV() && file.startsWith("dvb:")) { // QString channels_file = TVList::findChannelsFile(); // qDebug("Core::startMplayer: channels_file: %s", channels_file.toUtf8().constData()); // if (!channels_file.isEmpty()) proc->setChannelsFile(channels_file); // } //#endif //#ifdef CAPTURE_STREAM // // Set the capture directory // proc->setCaptureDirectory(pref->capture_directory); //#endif // Load edl file if (pref->use_edl_files) { QString edl_f; QFileInfo f(file); QString basename = f.path() + "/" + f.completeBaseName(); //qDebug("Core::startMplayer: file basename: '%s'", basename.toUtf8().data()); if (QFile::exists(basename+".edl")) edl_f = basename+".edl"; else if (QFile::exists(basename+".EDL")) edl_f = basename+".EDL"; qDebug("Core::startMplayer: edl file: '%s'", edl_f.toUtf8().data()); if (!edl_f.isEmpty()) { proc->setOption("edl", edl_f); } } // Additional options supplied by the user // File // if (!mset.mplayer_additional_options.isEmpty()) { // QStringList args = MyProcess::splitArguments(mset.mplayer_additional_options); // for (int n = 0; n < args.count(); n++) { // QString arg = args[n].simplified(); // if (!arg.isEmpty()) { // proc->addUserOption(arg); // } // } // } // Global // if (!pref->mplayer_additional_options.isEmpty()) { // QString additional_options = pref->mplayer_additional_options; // // mplayer2 doesn't support -fontconfig and -nofontconfig //// if (pref->mplayer_is_mplayer2) { //// additional_options.replace("-fontconfig", ""); //// additional_options.replace("-nofontconfig", ""); //// } // QStringList args = MyProcess::splitArguments(additional_options); // for (int n = 0; n < args.count(); n++) { // QString arg = args[n].simplified(); // if (!arg.isEmpty()) { // qDebug("arg %d: %s", n, arg.toUtf8().constData()); // proc->addUserOption(arg); // } // } // } // Last checks for the file // Open https URLs with ffmpeg // #if 0 // // It doesn't seem necessary anymore // if (proc->isMPlayer() && file.startsWith("https")) { // file = "ffmpeg://" + file; // } // #endif //#if DVDNAV_SUPPORT // if (proc->isMPV() && file.startsWith("dvdnav:")) { // // Hack to open the DVD menu with MPV // file = "dvd://menu"; // } //#endif //#ifdef Q_OS_WIN // if (pref->use_short_pathnames) { // file = Helper::shortPathName(file); // } //#endif if (proc->isMPlayer()) { // proc->setMedia(file, pref->use_playlist_option ? url_is_playlist : false); proc->setMedia(file, false);//20170712 } else { proc->setMedia(file, false); // Don't use playlist with mpv } // It seems the loop option must be after the filename if (mset.loop) { proc->setOption("loop", "0"); } emit aboutToStartPlaying();//先清空内存记录的日志mplayer_log QString commandline = proc->arguments().join(" "); // qDebug("Kobe Core::startMplayer: command: '%s'", commandline.toUtf8().data()); // /usr/bin/mplayer -noquiet -slave -identify -nofs -sub-fuzziness 1 -vo xv -ao pulse -nodr -double -nomouseinput -input nodefault-bindings:conf=/dev/null -nokeepaspect -wid 81788950 -monitorpixelaspect 1 -subfont-osd-scale 3 -ass -embeddedfonts -ass-line-spacing 0 -ass-font-scale 1 -noflip-hebrew -subcp ISO-8859-1 -subpos 100 -volume 56 -cache 2048 -osdlevel 0 -vf-add screenshot=/home/lixiang/图片/kylin_video_screenshots/shot -noslices -channels 2 -af-add scaletempo -softvol -softvol-max 110 /home/lixiang/东成西就.rmvb //kobe //Debug: Core::startMplayer: command: '/usr/bin/mpv --no-config --no-quiet --terminal --no-msg-color --input-file=/dev/stdin --no-fs --hwdec=no --sub-auto=fuzzy --vo=xv --ao=pulse --no-input-default-bindings --input-x11-keyboard=no --no-input-cursor --cursor-autohide=no --no-keepaspect --wid=100663330 --monitorpixelaspect=1 --osd-scale=1 --sub-ass --embeddedfonts --ass-line-spacing=0 --sub-scale=1 --sub-text-font=Arial --sub-text-color=#ffffff --sub-text-shadow-color=#000000 --sub-text-border-color=#000000 --sub-text-border-size=2.5 --sub-text-shadow-offset=5 --sub-codepage=utf8:ISO-8859-1 --sub-pos=100 --volume=7 --cache=2048 --osd-level=0 --screenshot-directory=/home/jack/图片/kylin_video_screenshots --screenshot-template=cap_%F_%p_%02n --screenshot-format=jpg --audio-channels=2 --af-add=scaletempo --af-add=equalizer=0:0:0:0:0:0:0:0:0:0 --softvol=yes --softvol-max=110 --ytdl=no --term-playing-msg=MPV_VERSION=${=mpv-version:} //kobe test // commandline = "'/usr/bin/mplayer -noquiet -slave -identify -nofs -lavdopts threads=8 -sub-fuzziness 1 -vo xv -ao pulse -nodr -double -stop-xscreensaver -nomouseinput -input nodefault-bindings:conf=/dev/null -nokeepaspect -wid 79691823 -monitorpixelaspect 1 -subfont-osd-scale 3 -ass -embeddedfonts -ass-line-spacing 0 -ass-font-scale 1 -noflip-hebrew -ass-styles /home/lixiang/.config/smplayer/styles.ass -subcp ISO-8859-1 -subpos 100 -hue 24 -volume 56 -cache 2048 -osdlevel 0 -vf-add screenshot=/home/lixiang/图片/kylin_video_screenshots/shot -noslices -channels 2 -af-add scaletempo -af-add equalizer=0:0:0:0:0:0:0:0:0:0 -softvol -softvol-max 110 /home/lixiang/resources/[大水怪] 少女時代 - My oh My (2013.12.11)[1440x1080i MPEG2 M-ON! HD].ts'"; //Log command QString line_for_log = commandline + "\n"; emit logLineAvailable(line_for_log); QProcessEnvironment env = QProcessEnvironment::systemEnvironment();//返回的结果以类似键、值的形式存储。 // if ((pref->use_proxy) && (pref->proxy_type == QNetworkProxy::HttpProxy) && (!pref->proxy_host.isEmpty())) { // QString proxy = QString("http://%1:%2@%3:%4").arg(pref->proxy_username).arg(pref->proxy_password).arg(pref->proxy_host).arg(pref->proxy_port); // env.insert("http_proxy", proxy); // } //qDebug("Core::startMplayer: env: %s", env.toStringList().join(",").toUtf8().constData()); // #ifdef Q_OS_WIN // if (!pref->use_windowsfontdir) { // env.insert("FONTCONFIG_FILE", Paths::configPath() + "/fonts.conf"); // } // #endif proc->setProcessEnvironment(env);//kobe:设置进程的环境变量 QString name = QProcessEnvironment::systemEnvironment().value("USERNAME"); if ( !proc->start() ) { // error handling qWarning("Core::startMplayer: mplayer process didn't start"); } // else // qDebug() << "proc start success....................................."; } void Core::stopMplayer() { // qDebug("Core::stopMplayer"); if (!proc->isRunning()) { qWarning("Core::stopMplayer: mplayer is not running!"); return; } //#ifdef Q_OS_OS2 // QEventLoop eventLoop; // connect(proc, SIGNAL(processExited()), &eventLoop, SLOT(quit())); // proc->quit(); // QTimer::singleShot(5000, &eventLoop, SLOT(quit())); // eventLoop.exec(QEventLoop::ExcludeUserInputEvents); // if (proc->isRunning()) { //// qWarning("Core::stopMplayer: process didn't finish. Killing it..."); // proc->kill(); // } //#else proc->quit(); qDebug("Core::stopMplayer: Waiting mplayer to finish..."); if (!proc->waitForFinished(pref->time_to_kill_mplayer)) { qWarning("Core::stopMplayer: process didn't finish. Killing it..."); proc->kill(); } //#endif qDebug("Core::stopMplayer: Finished. (I hope)"); } void Core::goToSec( double sec ) { // qDebug("**********************Core::goToSec: %f", sec); if (sec < 0) sec = 0; if (sec > mdat.duration ) sec = mdat.duration - 20; seek_cmd(sec, 2); } void Core::seek(int secs) { // qDebug("**************Core::seek: %d", secs); if ( (proc->isRunning()) && (secs!=0) ) { seek_cmd(secs, 0); } } void Core::seek_cmd(double secs, int mode) { // qDebug("**************Core::seek_cmd: %f", secs); proc->seek(secs, mode, false/*pref->precise_seeking*/);//kobe:Enable precise_seeking (only available with mplayer2) } void Core::sforward() { // qDebug("Core::sforward"); seek( pref->seeking1 ); // +10s } void Core::srewind() { // qDebug("Core::srewind"); seek( -pref->seeking1 ); // -10s } void Core::forward() { // qDebug("Core::forward"); seek( pref->seeking2 ); // +1m } void Core::rewind() { // qDebug("Core::rewind"); seek( -pref->seeking2 ); // -1m } void Core::fastforward() { // qDebug("Core::fastforward"); seek( pref->seeking3 ); // +10m } void Core::fastrewind() { // qDebug("Core::fastrewind"); seek( -pref->seeking3 ); // -10m } void Core::forward(int secs) { // qDebug("Core::forward: %d", secs); seek(secs); } void Core::rewind(int secs) { // qDebug("Core::rewind: %d", secs); seek(-secs); } //#ifdef MPV_SUPPORT //void Core::seekToNextSub() { // qDebug("Core::seekToNextSub"); // proc->seekSub(1); //} //void Core::seekToPrevSub() { // qDebug("Core::seekToPrevSub"); // proc->seekSub(-1); //} //#endif void Core::wheelUp() { // qDebug("Core::wheelUp"); switch (pref->wheel_function) { case Preferences::Volume : incVolume(); break; case Preferences::Zoom : incZoom(); break; case Preferences::Seeking : pref->wheel_function_seeking_reverse ? rewind( pref->seeking4 ) : forward( pref->seeking4 ); break; case Preferences::ChangeSpeed : incSpeed10(); break; default : {} // do nothing } } void Core::wheelDown() { // qDebug("Core::wheelDown"); switch (pref->wheel_function) { case Preferences::Volume : decVolume(); break; case Preferences::Zoom : decZoom(); break; case Preferences::Seeking : pref->wheel_function_seeking_reverse ? forward( pref->seeking4 ) : rewind( pref->seeking4 ); break; case Preferences::ChangeSpeed : decSpeed10(); break; default : {} // do nothing } } void Core::setAMarker() { setAMarker((int)mset.current_sec); } void Core::setAMarker(int sec) { qDebug("Core::setAMarker: %d", sec); mset.A_marker = sec; displayMessage( tr("\"A\" marker set to %1").arg(Helper::formatTime(sec)) ); if (mset.B_marker > mset.A_marker) { if (proc->isRunning()) restartPlay(); } emit ABMarkersChanged(mset.A_marker, mset.B_marker); } void Core::setBMarker() { setBMarker((int)mset.current_sec); } void Core::setBMarker(int sec) { qDebug("Core::setBMarker: %d", sec); mset.B_marker = sec; displayMessage( tr("\"B\" marker set to %1").arg(Helper::formatTime(sec)) ); if ((mset.A_marker > -1) && (mset.A_marker < mset.B_marker)) { if (proc->isRunning()) restartPlay(); } emit ABMarkersChanged(mset.A_marker, mset.B_marker); } void Core::clearABMarkers() { qDebug("Core::clearABMarkers"); if ((mset.A_marker != -1) || (mset.B_marker != -1)) { mset.A_marker = -1; mset.B_marker = -1; displayMessage( tr("A-B markers cleared") ); if (proc->isRunning()) restartPlay(); } emit ABMarkersChanged(mset.A_marker, mset.B_marker); } //void Core::toggleRepeat() { // qDebug("Core::toggleRepeat"); // toggleRepeat( !mset.loop ); //} //void Core::toggleRepeat(bool b) { // qDebug("Core::toggleRepeat: %d", b); // if ( mset.loop != b ) { // mset.loop = b; // if (MplayerVersion::isMplayerAtLeast(23747)) { // // Use slave command // int v = -1; // no loop // if (mset.loop) v = 0; // infinite loop // proc->setLoop(v); // } else { // // Restart mplayer // if (proc->isRunning()) restartPlay(); // } // } //} //// Audio filters //#ifdef MPLAYER_SUPPORT //void Core::toggleKaraoke() { // toggleKaraoke( !mset.karaoke_filter ); //} //void Core::toggleKaraoke(bool b) { // qDebug("Core::toggleKaraoke: %d", b); // if (b != mset.karaoke_filter) { // mset.karaoke_filter = b; // if (MplayerVersion::isMplayerAtLeast(31030)) { // // Change filter without restarting // proc->enableKaraoke(b); // } else { // restartPlay(); // } // } //} //void Core::toggleExtrastereo() { // toggleExtrastereo( !mset.extrastereo_filter ); //} //void Core::toggleExtrastereo(bool b) { // qDebug("Core::toggleExtrastereo: %d", b); // if (b != mset.extrastereo_filter) { // mset.extrastereo_filter = b; // if (MplayerVersion::isMplayerAtLeast(31030)) { // // Change filter without restarting // proc->enableExtrastereo(b); // } else { // restartPlay(); // } // } //} //#endif //void Core::toggleVolnorm() { // toggleVolnorm( !mset.volnorm_filter ); //} //void Core::toggleVolnorm(bool b) { // qDebug("Core::toggleVolnorm: %d", b); // if (b != mset.volnorm_filter) { // mset.volnorm_filter = b; // if (MplayerVersion::isMplayerAtLeast(31030)) { // // Change filter without restarting //// QString f = pref->filters->item("volnorm").filter(); //// proc->enableVolnorm(b, pref->filters->item("volnorm").options()); // } else { // restartPlay(); // } // } //} void Core::setAudioChannels(int channels) { qDebug("Core::setAudioChannels:%d", channels); if (channels != mset.audio_use_channels ) { mset.audio_use_channels = channels; restartPlay(); } } void Core::setStereoMode(int mode) { qDebug("Core::setStereoMode:%d", mode); if (mode != mset.stereo_mode ) { mset.stereo_mode = mode; restartPlay(); } } // Video filters #define CHANGE_VF(Filter, Enable, Option) \ if (proc->isMPV()) { \ proc->changeVF(Filter, Enable, Option); \ } else { \ restartPlay(); \ } void Core::toggleFlip() { qDebug("Core::toggleFlip"); toggleFlip( !mset.flip ); } void Core::toggleFlip(bool b) { qDebug("Core::toggleFlip: %d", b); if (mset.flip != b) { mset.flip = b; CHANGE_VF("flip", b, QVariant()); } } void Core::toggleMirror() { qDebug("Core::toggleMirror"); toggleMirror( !mset.mirror ); } void Core::toggleMirror(bool b) { qDebug("Core::toggleMirror: %d", b); if (mset.mirror != b) { mset.mirror = b; CHANGE_VF("mirror", b, QVariant()); } } void Core::toggleAutophase() { toggleAutophase( !mset.phase_filter ); } void Core::toggleAutophase( bool b ) { qDebug("Core::toggleAutophase: %d", b); if ( b != mset.phase_filter) { mset.phase_filter = b; CHANGE_VF("phase", b, "A"); } } void Core::toggleDeblock() { toggleDeblock( !mset.deblock_filter ); } void Core::toggleDeblock(bool b) { qDebug("Core::toggleDeblock: %d", b); if ( b != mset.deblock_filter ) { mset.deblock_filter = b; // CHANGE_VF("deblock", b, pref->filters->item("deblock").options()); } } void Core::toggleDering() { toggleDering( !mset.dering_filter ); } void Core::toggleDering(bool b) { qDebug("Core::toggleDering: %d", b); if ( b != mset.dering_filter) { mset.dering_filter = b; CHANGE_VF("dering", b, QVariant()); } } void Core::toggleGradfun() { toggleGradfun( !mset.gradfun_filter ); } void Core::toggleGradfun(bool b) { // qDebug("Core::toggleGradfun: %d", b); // if ( b != mset.gradfun_filter) { // mset.gradfun_filter = b; // CHANGE_VF("gradfun", b, pref->filters->item("gradfun").options()); // } } void Core::toggleNoise() { toggleNoise( !mset.noise_filter ); } void Core::toggleNoise(bool b) { qDebug("Core::toggleNoise: %d", b); if ( b != mset.noise_filter ) { mset.noise_filter = b; CHANGE_VF("noise", b, QVariant()); } } void Core::togglePostprocessing() { togglePostprocessing( !mset.postprocessing_filter ); } void Core::togglePostprocessing(bool b) { qDebug("Core::togglePostprocessing: %d", b); if ( b != mset.postprocessing_filter ) { mset.postprocessing_filter = b; CHANGE_VF("postprocessing", b, QVariant()); } } void Core::changeDenoise(int id) { qDebug( "Core::changeDenoise: %d", id ); if (id != mset.current_denoiser) { if (proc->isMPlayer()) { mset.current_denoiser = id; restartPlay(); } else { // MPV // QString dsoft = pref->filters->item("denoise_soft").options(); // QString dnormal = pref->filters->item("denoise_normal").options(); // // Remove previous filter // switch (mset.current_denoiser) { // case MediaSettings::DenoiseSoft: proc->changeVF("hqdn3d", false, dsoft); break; // case MediaSettings::DenoiseNormal: proc->changeVF("hqdn3d", false, dnormal); break; // } // // New filter // mset.current_denoiser = id; // switch (mset.current_denoiser) { // case MediaSettings::DenoiseSoft: proc->changeVF("hqdn3d", true, dsoft); break; // case MediaSettings::DenoiseNormal: proc->changeVF("hqdn3d", true, dnormal); break; // } } } } void Core::changeUnsharp(int id) { qDebug( "Core::changeUnsharp: %d", id ); if (id != mset.current_unsharp) { if (proc->isMPlayer()) { mset.current_unsharp = id; restartPlay(); } else { // MPV // Remove previous filter switch (mset.current_unsharp) { // Current is blur case 1: proc->changeVF("blur", false); break; // Current if sharpen case 2: proc->changeVF("sharpen", false); break; } // New filter mset.current_unsharp = id; switch (mset.current_unsharp) { case 1: proc->changeVF("blur", true); break; case 2: proc->changeVF("sharpen", true); break; } } } } void Core::changeUpscale(bool b) { qDebug( "Core::changeUpscale: %d", b ); if (mset.upscaling_filter != b) { mset.upscaling_filter = b; int width = DesktopInfo::desktop_size(mplayerwindow).width(); CHANGE_VF("scale", b, QString::number(width) + ":-2"); } } void Core::changeStereo3d(const QString & in, const QString & out) { qDebug("Core::changeStereo3d: in: %s out: %s", in.toUtf8().constData(), out.toUtf8().constData()); if ((mset.stereo3d_in != in) || (mset.stereo3d_out != out)) { if (proc->isMPlayer()) { mset.stereo3d_in = in; mset.stereo3d_out = out; restartPlay(); } else { // Remove previous filter if (mset.stereo3d_in != "none" && !mset.stereo3d_out.isEmpty()) { proc->changeStereo3DFilter(false, mset.stereo3d_in, mset.stereo3d_out); } // New filter mset.stereo3d_in = in; mset.stereo3d_out = out; if (mset.stereo3d_in != "none" && !mset.stereo3d_out.isEmpty()) { proc->changeStereo3DFilter(true, mset.stereo3d_in, mset.stereo3d_out); } } } } void Core::setBrightness(int value) { qDebug("Core::setBrightness: %d", value); if (value > 100) value = 100; if (value < -100) value = -100; if (value != mset.brightness) { proc->setPausingPrefix(pausing_prefix()); proc->setBrightness(value); mset.brightness = value; displayMessage( tr("Brightness: %1").arg(value) ); emit videoEqualizerNeedsUpdate(); } } void Core::setContrast(int value) { qDebug("Core::setContrast: %d", value); if (value > 100) value = 100; if (value < -100) value = -100; if (value != mset.contrast) { proc->setPausingPrefix(pausing_prefix()); proc->setContrast(value); mset.contrast = value; displayMessage( tr("Contrast: %1").arg(value) ); emit videoEqualizerNeedsUpdate(); } } void Core::setGamma(int value) { qDebug("Core::setGamma: %d", value); if (value > 100) value = 100; if (value < -100) value = -100; if (value != mset.gamma) { proc->setPausingPrefix(pausing_prefix()); proc->setGamma(value); mset.gamma= value; displayMessage( tr("Gamma: %1").arg(value) ); emit videoEqualizerNeedsUpdate(); } } void Core::setHue(int value) { qDebug("Core::setHue: %d", value); if (value > 100) value = 100; if (value < -100) value = -100; if (value != mset.hue) { proc->setPausingPrefix(pausing_prefix()); proc->setHue(value); mset.hue = value; displayMessage( tr("Hue: %1").arg(value) ); emit videoEqualizerNeedsUpdate(); } } void Core::setSaturation(int value) { qDebug("Core::setSaturation: %d", value); if (value > 100) value = 100; if (value < -100) value = -100; if (value != mset.saturation) { proc->setPausingPrefix(pausing_prefix()); proc->setSaturation(value); mset.saturation = value; displayMessage( tr("Saturation: %1").arg(value) ); emit videoEqualizerNeedsUpdate(); } } void Core::incBrightness() { setBrightness(mset.brightness + pref->min_step); } void Core::decBrightness() { setBrightness(mset.brightness - pref->min_step); } void Core::incContrast() { setContrast(mset.contrast + pref->min_step); } void Core::decContrast() { setContrast(mset.contrast - pref->min_step); } void Core::incGamma() { setGamma(mset.gamma + pref->min_step); } void Core::decGamma() { setGamma(mset.gamma - pref->min_step); } void Core::incHue() { setHue(mset.hue + pref->min_step); } void Core::decHue() { setHue(mset.hue - pref->min_step); } void Core::incSaturation() { setSaturation(mset.saturation + pref->min_step); } void Core::decSaturation() { setSaturation(mset.saturation - pref->min_step); } void Core::setSpeed( double value ) { // qDebug("Core::setSpeed: %f", value); if (value < 0.10) value = 0.10; if (value > 100) value = 100; mset.speed = value; proc->setSpeed(value); displayMessage( tr("Speed: %1").arg(value) ); } void Core::incSpeed10() { // qDebug("Core::incSpeed10"); setSpeed( (double) mset.speed + 0.1 ); } void Core::decSpeed10() { // qDebug("Core::decSpeed10"); setSpeed( (double) mset.speed - 0.1 ); } void Core::incSpeed4() { qDebug("Core::incSpeed4"); setSpeed( (double) mset.speed + 0.04 ); } void Core::decSpeed4() { // qDebug("Core::decSpeed4"); setSpeed( (double) mset.speed - 0.04 ); } void Core::incSpeed1() { // qDebug("Core::incSpeed1"); setSpeed( (double) mset.speed + 0.01 ); } void Core::decSpeed1() { // qDebug("Core::decSpeed1"); setSpeed( (double) mset.speed - 0.01 ); } void Core::doubleSpeed() { // qDebug("Core::doubleSpeed"); setSpeed( (double) mset.speed * 2 ); } void Core::halveSpeed() { // qDebug("Core::halveSpeed"); setSpeed( (double) mset.speed / 2 ); } void Core::normalSpeed() { setSpeed(1); } int Core::adjustVolume(int v, int max_vol) { //qDebug() << "Core::adjustVolume: v:" << v << "max_vol:" << max_vol; if (max_vol < 100) max_vol = 100; int vol = v * max_vol / 100; return vol; } void Core::setVolume(int volume, bool force) { // qDebug("Core::setVolume: %d", volume); int current_volume = (pref->global_volume ? pref->volume : mset.volume); if ((volume == current_volume) && (!force)) return; current_volume = volume; if (current_volume > 100) current_volume = 100; if (current_volume < 0) current_volume = 0; if (proc->isMPV()) { // MPV int vol = adjustVolume(current_volume, pref->use_soft_vol ? pref->softvol_max : 100); proc->setVolume(vol); } else { // MPlayer if (state() == Paused) { // Change volume later, after quiting pause change_volume_after_unpause = true; } else { proc->setVolume(current_volume); } } if (pref->global_volume) { pref->volume = current_volume; // qDebug() << "-------------77777---------------muted=" << pref->mute; if (pref->volume <= 0) {//kobe pref->mute = true; } else { pref->mute = false; } // qDebug() << "-------------88888---------------muted=" << pref->mute; } else { mset.volume = current_volume; if (mset.volume <= 0) {//kobe mset.mute = true; } else { mset.mute = false; } } updateWidgets(); displayMessage( tr("Volume: %1").arg(current_volume) ); emit volumeChanged( current_volume ); } void Core::switchMute() { // qDebug("Core::switchMute"); mset.mute = !mset.mute; mute(mset.mute); } //add by kobe int Core::getVolumn() { return pref->volume; } //add by kobe bool Core::getMute() { // return mset.mute; // return pref->mute; return (pref->global_volume ? pref->mute : mset.mute);//kobe 0606 } void Core::mute(bool b) { // qDebug() << "~~~~~~~~~~~~~Core::mute=" << b; proc->setPausingPrefix(pausing_prefix()); proc->mute(b); if (pref->global_volume) { pref->mute = b; } else { mset.mute = b; } updateWidgets(); } void Core::incVolume() { // qDebug("Core::incVolume"); int new_vol = (pref->global_volume ? pref->volume + pref->min_step : mset.volume + pref->min_step); setVolume(new_vol); } void Core::decVolume() { // qDebug("Core::incVolume"); int new_vol = (pref->global_volume ? pref->volume - pref->min_step : mset.volume - pref->min_step); setVolume(new_vol); } void Core::setSubDelay(int delay) { qDebug("Core::setSubDelay: %d", delay); mset.sub_delay = delay; proc->setPausingPrefix(pausing_prefix()); proc->setSubDelay((double) mset.sub_delay/1000); displayMessage( tr("Subtitle delay: %1 ms").arg(delay) ); } void Core::incSubDelay() { // qDebug("Core::incSubDelay"); setSubDelay(mset.sub_delay + 100); } void Core::decSubDelay() { // qDebug("Core::decSubDelay"); setSubDelay(mset.sub_delay - 100); } void Core::setAudioDelay(int delay) { qDebug("Core::setAudioDelay: %d", delay); mset.audio_delay = delay; proc->setPausingPrefix(pausing_prefix()); proc->setAudioDelay((double) mset.audio_delay/1000); displayMessage( tr("Audio delay: %1 ms").arg(delay) ); } void Core::incAudioDelay() { // qDebug("Core::incAudioDelay"); setAudioDelay(mset.audio_delay + 100); } void Core::decAudioDelay() { // qDebug("Core::decAudioDelay"); setAudioDelay(mset.audio_delay - 100); } void Core::incSubPos() { // qDebug("Core::incSubPos"); mset.sub_pos++; if (mset.sub_pos > 100) mset.sub_pos = 100; proc->setSubPos(mset.sub_pos); } void Core::decSubPos() { // qDebug("Core::decSubPos"); mset.sub_pos--; if (mset.sub_pos < 0) mset.sub_pos = 0; proc->setSubPos(mset.sub_pos); } //bool Core::subscale_need_restart() { // bool need_restart = false; // need_restart = (!MplayerVersion::isMplayerAtLeast(25843)); // return need_restart; //// need_restart = (pref->change_sub_scale_should_restart == Preferences::Enabled); //// if (pref->change_sub_scale_should_restart == Preferences::Detect) { ////// if (pref->use_ass_subtitles) //// need_restart = (!MplayerVersion::isMplayerAtLeast(25843)); ////// else ////// need_restart = (!MplayerVersion::isMplayerAtLeast(23745)); //// } //// return need_restart; //} //void Core::changeSubScale(double value) { //// qDebug("Core::changeSubScale: %f", value); // bool need_restart = subscale_need_restart(); // if (value < 0) value = 0; //// if (pref->use_ass_subtitles) { // if (value != mset.sub_scale_ass) { // mset.sub_scale_ass = value; // if (need_restart) { // restartPlay(); // } else { // proc->setSubScale(mset.sub_scale_ass); // } // displayMessage( tr("Font scale: %1").arg(mset.sub_scale_ass) ); // } //// } else { //// // No ass //// if (value != mset.sub_scale) { //// mset.sub_scale = value; //// if (need_restart) { //// restartPlay(); //// } else { //// proc->setSubScale(mset.sub_scale); //// } //// displayMessage( tr("Font scale: %1").arg(mset.sub_scale) ); //// } //// } //} //void Core::incSubScale() { // double step = 0.20; //// if (pref->use_ass_subtitles) { // changeSubScale( mset.sub_scale_ass + step ); //// } else { //// if (subscale_need_restart()) step = 1; //// changeSubScale( mset.sub_scale + step ); //// } //} //void Core::decSubScale() { // double step = 0.20; //// if (pref->use_ass_subtitles) { // changeSubScale( mset.sub_scale_ass - step ); //// } else { //// if (subscale_need_restart()) step = 1; //// changeSubScale( mset.sub_scale - step ); //// } //} //void Core::changeOSDScale(double value) { //// qDebug("Core::changeOSDScale: %f", value); // if (value < 0) value = 0; // if (proc->isMPlayer()) { // if (value != pref->subfont_osd_scale) { // pref->subfont_osd_scale = value; // restartPlay(); // } // } else { // if (value != pref->osd_scale) { // pref->osd_scale = value; // proc->setOSDScale(pref->osd_scale); // } // } //} //void Core::incOSDScale() { // if (proc->isMPlayer()) { // changeOSDScale(pref->subfont_osd_scale + 1); // } else { // changeOSDScale(pref->osd_scale + 0.20); // } //} //void Core::decOSDScale() { // if (proc->isMPlayer()) { // changeOSDScale(pref->subfont_osd_scale - 1); // } else { // changeOSDScale(pref->osd_scale - 0.20); // } //} void Core::incSubStep() { // qDebug("Core::incSubStep"); proc->setSubStep(+1); } void Core::decSubStep() { // qDebug("Core::decSubStep"); proc->setSubStep(-1); } void Core::changeSubVisibility(bool visible) { // qDebug("Core::changeSubVisilibity: %d", visible); pref->sub_visibility = visible; proc->setSubtitlesVisibility(pref->sub_visibility); if (pref->sub_visibility) displayMessage( tr("Subtitles on") ); else displayMessage( tr("Subtitles off") );//字幕关闭 } void Core::changeExternalSubFPS(int fps_id) { // qDebug("Core::setExternalSubFPS: %d", fps_id); mset.external_subtitles_fps = fps_id; if (!mset.external_subtitles.isEmpty()) { restartPlay(); } } // Audio equalizer functions //void Core::setAudioEqualizer(AudioEqualizerList values, bool restart) { // if (pref->global_audio_equalizer) { // pref->audio_equalizer = values; // } else { // mset.audio_equalizer = values; // } // if (!restart) { // proc->setAudioEqualizer(Helper::equalizerListToString(values)); // } else { // restartPlay(); // } // // Infinite recursion // //emit audioEqualizerNeedsUpdate(); //} void Core::updateAudioEqualizer() { // setAudioEqualizer(pref->global_audio_equalizer ? pref->audio_equalizer : mset.audio_equalizer); } void Core::setAudioEq(int eq, int value) { // if (pref->global_audio_equalizer) { // pref->audio_equalizer[eq] = value; // } else { // mset.audio_equalizer[eq] = value; // } // updateAudioEqualizer(); } void Core::setAudioEq0(int value) { setAudioEq(0, value); } void Core::setAudioEq1(int value) { setAudioEq(1, value); } void Core::setAudioEq2(int value) { setAudioEq(2, value); } void Core::setAudioEq3(int value) { setAudioEq(3, value); } void Core::setAudioEq4(int value) { setAudioEq(4, value); } void Core::setAudioEq5(int value) { setAudioEq(5, value); } void Core::setAudioEq6(int value) { setAudioEq(6, value); } void Core::setAudioEq7(int value) { setAudioEq(7, value); } void Core::setAudioEq8(int value) { setAudioEq(8, value); } void Core::setAudioEq9(int value) { setAudioEq(9, value); } void Core::changeCurrentSec(double sec) { mset.current_sec = sec; if (mset.starting_time != -1) { mset.current_sec -= mset.starting_time; // handle PTS rollover at MPEG-TS if (mset.current_sec < 0 && mset.current_demuxer == "mpegts") { mset.current_sec += 8589934592.0 / 90000.0; // 2^33 / 90 kHz } } if (state() != Playing) { setState(Playing); qDebug("Core::changeCurrentSec: mplayer reports that now it's playing"); emit this->show_logo_signal(false); //emit mediaStartPlay(); //emit stateChanged(state()); } emit showTime(mset.current_sec, false);//kobe // Emit posChanged: static int last_second = 0; if (floor(sec)==last_second) return; // Update only once per second last_second = (int) floor(sec); //#ifdef SEEKBAR_RESOLUTION int value = 0; if ( (mdat.duration > 1) && (mset.current_sec > 1) && (mdat.duration > mset.current_sec) ) { value = ( (int) mset.current_sec * SEEKBAR_RESOLUTION) / (int) mdat.duration; } emit positionChanged(value); //#else // int perc = 0; // if ( (mdat.duration > 1) && (mset.current_sec > 1) && // (mdat.duration > mset.current_sec) ) // { // perc = ( (int) mset.current_sec * 100) / (int) mdat.duration; // } // emit posChanged( perc ); //#endif } void Core::gotStartingTime(double time) { qDebug("Core::gotStartingTime: %f", time); qDebug("Core::gotStartingTime: current_sec: %f", mset.current_sec); if ((mset.starting_time == -1.0) && (mset.current_sec == 0)) { mset.starting_time = time; qDebug("Core::gotStartingTime: starting time set to %f", time); } } void Core::gotVideoBitrate(int b) { mdat.video_bitrate = b; } void Core::gotAudioBitrate(int b) { mdat.audio_bitrate = b; } void Core::changePause() { // qDebug("Core::changePause"); qDebug("Core::changePause: mplayer reports that it's paused"); setState(Paused); //emit stateChanged(state()); } void Core::changeDeinterlace(int ID) { qDebug("Core::changeDeinterlace: %d", ID); if (ID != mset.current_deinterlacer) { if (proc->isMPlayer()) { mset.current_deinterlacer = ID; restartPlay(); } else { // MPV // Remove previous filter switch (mset.current_deinterlacer) { case MediaSettings::L5: proc->changeVF("l5", false); break; case MediaSettings::Yadif: proc->changeVF("yadif", false); break; case MediaSettings::LB: proc->changeVF("lb", false); break; case MediaSettings::Yadif_1: proc->changeVF("yadif", false, "1"); break; case MediaSettings::Kerndeint: proc->changeVF("kerndeint", false, "5"); break; } mset.current_deinterlacer = ID; // New filter switch (mset.current_deinterlacer) { case MediaSettings::L5: proc->changeVF("l5", true); break; case MediaSettings::Yadif: proc->changeVF("yadif", true); break; case MediaSettings::LB: proc->changeVF("lb", true); break; case MediaSettings::Yadif_1: proc->changeVF("yadif", true, "1"); break; case MediaSettings::Kerndeint: proc->changeVF("kerndeint", true, "5"); break; } } } } void Core::changeSubtitle(int ID) { qDebug("Core::changeSubtitle: %d", ID); mset.current_sub_id = ID; if (ID==MediaSettings::SubNone) { ID=-1; } if (ID==MediaSettings::NoneSelected) { ID=-1; qDebug("Core::changeSubtitle: subtitle is NoneSelected, this shouldn't happen. ID set to -1."); } qDebug("Core::changeSubtitle: ID: %d", ID); int real_id = -1; if (ID == -1) { proc->disableSubtitles(); } else { bool valid_item = ( (ID >= 0) && (ID < mdat.subs.numItems()) ); if (!valid_item) qWarning("Core::changeSubtitle: ID: %d is not valid!", ID); if ( (mdat.subs.numItems() > 0) && (valid_item) ) { real_id = mdat.subs.itemAt(ID).ID(); proc->setSubtitle(mdat.subs.itemAt(ID).type(), real_id); } else { // qWarning("Core::changeSubtitle: subtitle list is empty!"); } } updateWidgets(); } void Core::nextSubtitle() { qDebug("Core::nextSubtitle"); if ( (mset.current_sub_id == MediaSettings::SubNone) && (mdat.subs.numItems() > 0) ) { changeSubtitle(0); } else { int item = mset.current_sub_id + 1; if (item >= mdat.subs.numItems()) { item = MediaSettings::SubNone; } changeSubtitle( item ); } } //#ifdef MPV_SUPPORT //void Core::changeSecondarySubtitle(int ID) { // // MPV only // qDebug("Core::changeSecondarySubtitle: %d", ID); // mset.current_secondary_sub_id = ID; // if (ID == MediaSettings::SubNone) { // ID = -1; // } // if (ID == MediaSettings::NoneSelected) { // ID = -1; // } // if (ID == -1) { // proc->disableSecondarySubtitles(); // } else { // int real_id = -1; // bool valid_item = ( (ID >= 0) && (ID < mdat.subs.numItems()) ); // if (!valid_item) qWarning("Core::changeSecondarySubtitle: ID: %d is not valid!", ID); // if ( (mdat.subs.numItems() > 0) && (valid_item) ) { // real_id = mdat.subs.itemAt(ID).ID(); // proc->setSecondarySubtitle(real_id); // } // } //} //#endif void Core::changeAudio(int ID, bool allow_restart) { qDebug("Core::changeAudio: ID: %d, allow_restart: %d", ID, allow_restart); // if (ID!=mset.current_audio_id) { // mset.current_audio_id = ID; // qDebug("changeAudio: ID: %d", ID); // bool need_restart = false; // if (allow_restart) { // need_restart = (!MplayerVersion::isMplayerAtLeast(21441)); //// need_restart = (pref->fast_audio_change == Preferences::Disabled); //// if (pref->fast_audio_change == Preferences::Detect) { //// need_restart = (!MplayerVersion::isMplayerAtLeast(21441)); //// } // } // if (need_restart) { // restartPlay(); // } else { // proc->setAudio(ID); // // Workaround for a mplayer problem in windows, // // volume is too loud after changing audio. // // Workaround too for a mplayer problem in linux, // // the volume is reduced if using -softvol-max. // if (proc->isMPlayer()) { //// if (pref->mplayer_additional_options.contains("-volume")) { //// qDebug("Core::changeAudio: don't set volume since -volume is used"); //// } else { // if (pref->global_volume) { // setVolume( pref->volume, true); // if (pref->mute) mute(true); // } else { // setVolume( mset.volume, true ); // if (mset.mute) mute(true); // if muted, mute again // } // } //// } // updateWidgets(); // } // } } void Core::nextAudio() { qDebug("Core::nextAudio"); int item = mdat.audios.find( mset.current_audio_id ); if (item == -1) { // qWarning("Core::nextAudio: audio ID %d not found!", mset.current_audio_id); } else { // qDebug( "Core::nextAudio: numItems: %d, item: %d", mdat.audios.numItems(), item); item++; if (item >= mdat.audios.numItems()) item=0; int ID = mdat.audios.itemAt(item).ID(); qDebug( "Core::nextAudio: item: %d, ID: %d", item, ID); changeAudio( ID ); } } void Core::changeVideo(int ID, bool allow_restart) { qDebug("Core::changeVideo: ID: %d, allow_restart: %d", ID, allow_restart); if (ID != mset.current_video_id) { mset.current_video_id = ID; qDebug("Core::changeVideo: ID set to: %d", ID); bool need_restart = false; if (allow_restart) { // afaik lavf doesn't require to restart, any other? need_restart = ((mdat.demuxer != "lavf") && (mdat.demuxer != "mpegts")); } if (need_restart) { restartPlay(); } else { if (mdat.demuxer == "nsv") { // Workaround a problem with the nsv demuxer qWarning("Core::changeVideo: not changing the video with nsv to prevent mplayer go crazy"); } else { proc->setVideo(ID); } } } } void Core::nextVideo() { // qDebug("Core::nextVideo"); int item = mdat.videos.find( mset.current_video_id ); if (item == -1) { // qWarning("Core::nextVideo: video ID %d not found!", mset.current_video_id); } else { // qDebug( "Core::nextVideo: numItems: %d, item: %d", mdat.videos.numItems(), item); item++; if (item >= mdat.videos.numItems()) item=0; int ID = mdat.videos.itemAt(item).ID(); // qDebug( "Core::nextVideo: item: %d, ID: %d", item, ID); changeVideo( ID ); } } //#if PROGRAM_SWITCH //void Core::changeProgram(int ID) { // qDebug("Core::changeProgram: %d", ID); // if (ID != mset.current_program_id) { // mset.current_program_id = ID; // proc->setTSProgram(ID); // /* // mset.current_video_id = MediaSettings::NoneSelected; // mset.current_audio_id = MediaSettings::NoneSelected; // updateWidgets(); // */ // } //} //void Core::nextProgram() { // qDebug("Core::nextProgram"); // // Not implemented yet //} //#endif void Core::changeTitle(int ID) { if (mdat.type == TYPE_VCD) { // VCD openVCD( ID ); } else if (mdat.type == TYPE_AUDIO_CD) { // AUDIO CD openAudioCD( ID ); } else if (mdat.type == TYPE_DVD) { // #if DVDNAV_SUPPORT // if (mdat.filename.startsWith("dvdnav:")) { // proc->setTitle(ID); // } else { // #endif // DiscData disc_data = DiscName::split(mdat.filename); // disc_data.title = ID; // QString dvd_url = DiscName::join(disc_data); // openDVD( DiscName::join(disc_data) ); // #if DVDNAV_SUPPORT // } // #endif } //#ifdef BLURAY_SUPPORT // else // if (mdat.type == TYPE_BLURAY) { // //DiscName::test(); // DiscData disc_data = DiscName::split(mdat.filename); // disc_data.title = ID; // QString bluray_url = DiscName::join(disc_data); // qDebug("Core::changeTitle: bluray_url: %s", bluray_url.toUtf8().constData()); // openBluRay(bluray_url); // } //#endif } void Core::changeChapter(int ID) { qDebug("Core::changeChapter: ID: %d", ID); if (mdat.type != TYPE_DVD) { /* if (mdat.chapters.find(ID) > -1) { double start = mdat.chapters.item(ID).start(); qDebug("Core::changeChapter: start: %f", start); goToSec(start); mset.current_chapter_id = ID; } else { */ proc->setChapter(ID); mset.current_chapter_id = ID; //updateWidgets(); /* } */ } else { //#if SMART_DVD_CHAPTERS // if (pref->cache_for_dvds == 0) { //#else // if (pref->fast_chapter_change) { ////#endif // proc->setChapter(ID); // mset.current_chapter_id = ID; // updateWidgets(); // } else { stopMplayer(); mset.current_chapter_id = ID; //goToPos(0); mset.current_sec = 0; restartPlay(); // } } } //int Core::firstChapter() { // if ( (MplayerVersion::isMplayerAtLeast(25391)) && // (!MplayerVersion::isMplayerAtLeast(29407)) ) // return 1; // else // return 0; //} int Core::firstDVDTitle() { if (proc->isMPV()) { return 0; } else { return 1; } } int Core::firstBlurayTitle() { if (proc->isMPV()) { return 0; } else { return 1; } } void Core::prevChapter() { // qDebug("Core::prevChapter"); // int last_chapter = 0; // int first_chapter = firstChapter(); // int ID = mdat.chapters.itemBeforeTime(mset.current_sec).ID(); // if (ID == -1) { // last_chapter = mdat.n_chapters + firstChapter() - 1; // ID = mset.current_chapter_id - 1; // if (ID < first_chapter) { // ID = last_chapter; // } // } // changeChapter(ID); } void Core::nextChapter() { // qDebug("Core::nextChapter"); // int last_chapter = mdat.n_chapters + firstChapter() - 1; // int ID = mdat.chapters.itemAfterTime(mset.current_sec).ID(); // if (ID == -1) { // ID = mset.current_chapter_id + 1; // if (ID > last_chapter) { // ID = firstChapter(); // } // } // changeChapter(ID); } void Core::changeAngle(int ID) { qDebug("Core::changeAngle: ID: %d", ID); if (ID != mset.current_angle_id) { mset.current_angle_id = ID; restartPlay(); } } void Core::changeAspectRatio( int ID ) { // qDebug("Core::changeAspectRatio: %d", ID); mset.aspect_ratio_id = ID; double asp = mset.aspectToNum( (MediaSettings::Aspect) ID); // if (!pref->use_mplayer_window) { mplayerwindow->setAspect(asp); // } else { // // Using mplayer own window // if (!mdat.novideo) { // if (ID == MediaSettings::AspectAuto) { // asp = mdat.video_aspect; // } // proc->setAspect(asp); // } // } QString asp_name = MediaSettings::aspectToString( (MediaSettings::Aspect) mset.aspect_ratio_id); displayMessage( tr("Aspect ratio: %1").arg(asp_name) ); } void Core::nextAspectRatio() { // Ordered list QList s; s << MediaSettings::AspectNone << MediaSettings::AspectAuto << MediaSettings::Aspect11 // 1 << MediaSettings::Aspect54 // 1.25 << MediaSettings::Aspect43 // 1.33 << MediaSettings::Aspect118 // 1.37 << MediaSettings::Aspect1410 // 1.4 << MediaSettings::Aspect32 // 1.5 << MediaSettings::Aspect149 // 1.55 << MediaSettings::Aspect1610 // 1.6 << MediaSettings::Aspect169 // 1.77 << MediaSettings::Aspect235; // 2.35 int i = s.indexOf( mset.aspect_ratio_id ) + 1; if (i >= s.count()) i = 0; int new_aspect_id = s[i]; changeAspectRatio( new_aspect_id ); updateWidgets(); } void Core::nextWheelFunction() { int a = pref->wheel_function; bool done = false; if(((int ) pref->wheel_function_cycle)==0) return; while(!done){ // get next a a = a*2; if(a==32) a = 2; // See if we are done if (pref->wheel_function_cycle.testFlag((Preferences::WheelFunction)a)) done = true; } pref->wheel_function = a; QString m = ""; switch(a){ case Preferences::Seeking: m = tr("Mouse wheel seeks now"); break; case Preferences::Volume: m = tr("Mouse wheel changes volume now"); break; case Preferences::Zoom: m = tr("Mouse wheel changes zoom level now"); break; case Preferences::ChangeSpeed: m = tr("Mouse wheel changes speed now"); break; } displayMessage(m); } void Core::changeLetterbox(bool b) { qDebug("Core::changeLetterbox: %d", b); if (mset.add_letterbox != b) { mset.add_letterbox = b; CHANGE_VF("letterbox", b, DesktopInfo::desktop_aspectRatio(mplayerwindow)); } } void Core::changeLetterboxOnFullscreen(bool b) { qDebug("Core::changeLetterboxOnFullscreen: %d", b); CHANGE_VF("letterbox", b, DesktopInfo::desktop_aspectRatio(mplayerwindow)); } void Core::changeOSD(int v) { qDebug("Core::changeOSD: %d", v); //kobe:选项->屏幕显示->仅字幕,该版本会屏蔽“屏幕显示”菜单,全部默认为仅字幕,即配置文件~/.config/smplayer/smplayer.ini的osd字段不管是多少,定制版播放器启动后都重新设置该值为0(仅字幕) pref->osd = 0; // pref->osd = v; proc->setPausingPrefix(pausing_prefix()); proc->setOSD(pref->osd); updateWidgets(); } void Core::nextOSD() { int osd = pref->osd + 1; if (osd > Preferences::SeekTimerTotal) { osd = Preferences::None; } changeOSD( osd ); } void Core::changeRotate(int r) { qDebug("Core::changeRotate: %d", r); if (mset.rotate != r) { if (proc->isMPlayer()) { mset.rotate = r; restartPlay(); } else { // MPV // Remove previous filter switch (mset.rotate) { case MediaSettings::Clockwise_flip: proc->changeVF("rotate", false, MediaSettings::Clockwise_flip); break; case MediaSettings::Clockwise: proc->changeVF("rotate", false, MediaSettings::Clockwise); break; case MediaSettings::Counterclockwise: proc->changeVF("rotate", false, MediaSettings::Counterclockwise); break; case MediaSettings::Counterclockwise_flip: proc->changeVF("rotate", false, MediaSettings::Counterclockwise_flip); break; } mset.rotate = r; // New filter switch (mset.rotate) { case MediaSettings::Clockwise_flip: proc->changeVF("rotate", true, MediaSettings::Clockwise_flip); break; case MediaSettings::Clockwise: proc->changeVF("rotate", true, MediaSettings::Clockwise); break; case MediaSettings::Counterclockwise: proc->changeVF("rotate", true, MediaSettings::Counterclockwise); break; case MediaSettings::Counterclockwise_flip: proc->changeVF("rotate", true, MediaSettings::Counterclockwise_flip); break; } } } } //#if USE_ADAPTER //void Core::changeAdapter(int n) { // qDebug("Core::changeScreen: %d", n); // if (pref->adapter != n) { // pref->adapter = n; // restartPlay(); // } //} //#endif //#if 0 //void Core::changeSize(int n) { // if ( /*(n != pref->size_factor) &&*/ (!pref->use_mplayer_window) ) { // pref->size_factor = n; // emit needResize(mset.win_width, mset.win_height); // updateWidgets(); // } //} //void Core::toggleDoubleSize() { // if (pref->size_factor != 100) // changeSize(100); // else // changeSize(200); //} //#endif void Core::changeZoom(double p) { // qDebug("Core::changeZoom: %f", p); if (p < ZOOM_MIN) p = ZOOM_MIN; mset.zoom_factor = p; mplayerwindow->setZoom(p); displayMessage( tr("Zoom: %1").arg(mset.zoom_factor) ); } void Core::resetZoom() { changeZoom(1.0); } void Core::autoZoom() { double video_aspect = mset.aspectToNum( (MediaSettings::Aspect) mset.aspect_ratio_id); if (video_aspect <= 0) { QSize w = mplayerwindow->videoLayer()->size(); video_aspect = (double) w.width() / w.height(); } double screen_aspect = DesktopInfo::desktop_aspectRatio(mplayerwindow); double zoom_factor; if (video_aspect > screen_aspect) zoom_factor = video_aspect / screen_aspect; else zoom_factor = screen_aspect / video_aspect; qDebug("Core::autoZoom: video_aspect: %f", video_aspect); qDebug("Core::autoZoom: screen_aspect: %f", screen_aspect); qDebug("Core::autoZoom: zoom_factor: %f", zoom_factor); changeZoom(zoom_factor); } void Core::autoZoomFromLetterbox(double aspect) { qDebug("Core::autoZoomFromLetterbox: %f", aspect); // Probably there's a much easy way to do this, but I'm not good with maths... QSize desktop = DesktopInfo::desktop_size(mplayerwindow); double video_aspect = mset.aspectToNum( (MediaSettings::Aspect) mset.aspect_ratio_id); if (video_aspect <= 0) { QSize w = mplayerwindow->videoLayer()->size(); video_aspect = (double) w.width() / w.height(); } // Calculate size of the video in fullscreen QSize video; video.setHeight( desktop.height() );; video.setWidth( (int) (video.height() * video_aspect) ); if (video.width() > desktop.width()) { video.setWidth( desktop.width() );; video.setHeight( (int) (video.width() / video_aspect) ); } qDebug("Core::autoZoomFromLetterbox: max. size of video: %d %d", video.width(), video.height()); // Calculate the size of the actual video inside the letterbox QSize actual_video; actual_video.setWidth( video.width() ); actual_video.setHeight( (int) (actual_video.width() / aspect) ); qDebug("Core::autoZoomFromLetterbox: calculated size of actual video for aspect %f: %d %d", aspect, actual_video.width(), actual_video.height()); double zoom_factor = (double) desktop.height() / actual_video.height(); qDebug("Core::autoZoomFromLetterbox: calculated zoom factor: %f", zoom_factor); changeZoom(zoom_factor); } void Core::autoZoomFor169() { autoZoomFromLetterbox((double) 16 / 9); } void Core::autoZoomFor235() { autoZoomFromLetterbox(2.35); } void Core::incZoom() { qDebug("Core::incZoom"); changeZoom( mset.zoom_factor + ZOOM_STEP ); } void Core::decZoom() { qDebug("Core::decZoom"); changeZoom( mset.zoom_factor - ZOOM_STEP ); } void Core::showFilenameOnOSD() { proc->showFilenameOnOSD(); } void Core::showTimeOnOSD() { proc->showTimeOnOSD(); } void Core::toggleDeinterlace() { qDebug("Core::toggleDeinterlace"); proc->toggleDeinterlace(); } //void Core::changeUseCustomSubStyle(bool b) { // qDebug("Core::changeUseCustomSubStyle: %d", b); // if (pref->enable_ass_styles != b) { // pref->enable_ass_styles = b; // if (proc->isRunning()) restartPlay(); // } //} //void Core::toggleForcedSubsOnly(bool b) { // qDebug("Core::toggleForcedSubsOnly: %d", b); // if (pref->use_forced_subs_only != b) { // pref->use_forced_subs_only = b; // //if (proc->isRunning()) restartPlay(); // proc->setSubForcedOnly(b); // } //} //void Core::changeClosedCaptionChannel(int c) { // qDebug("Core::changeClosedCaptionChannel: %d", c); // if (c != mset.closed_caption_channel) { // mset.closed_caption_channel = c; // if (proc->isRunning()) restartPlay(); // } //} /* void Core::nextClosedCaptionChannel() { int c = mset.closed_caption_channel; c++; if (c > 4) c = 0; changeClosedCaptionChannel(c); } void Core::prevClosedCaptionChannel() { int c = mset.closed_caption_channel; c--; if (c < 0) c = 4; changeClosedCaptionChannel(c); } */ //#if DVDNAV_SUPPORT //// dvdnav buttons //void Core::dvdnavUp() { // qDebug("Core::dvdnavUp"); // proc->discButtonPressed("up"); //} //void Core::dvdnavDown() { // qDebug("Core::dvdnavDown"); // proc->discButtonPressed("down"); //} //void Core::dvdnavLeft() { // qDebug("Core::dvdnavLeft"); // proc->discButtonPressed("left"); //} //void Core::dvdnavRight() { // qDebug("Core::dvdnavRight"); // proc->discButtonPressed("right"); //} //void Core::dvdnavMenu() { // qDebug("Core::dvdnavMenu"); // proc->discButtonPressed("menu"); //} //void Core::dvdnavSelect() { // qDebug("Core::dvdnavSelect"); // proc->discButtonPressed("select"); //} //void Core::dvdnavPrev() { // qDebug("Core::dvdnavPrev"); // proc->discButtonPressed("prev"); //} //void Core::dvdnavMouse() { // qDebug("Core::dvdnavMouse"); // if ((state() == Playing) && (mdat.filename.startsWith("dvdnav:"))) { // proc->discButtonPressed("mouse"); // } //} //#endif void Core::displayMessage(QString text) { // qDebug("Core::displayMessage"); emit showMessage(text); if ((pref->fullscreen) && (state() != Paused)) { displayTextOnOSD( text ); } } void Core::displayScreenshotName(QString filename) { // qDebug("Core::displayScreenshotName: %s", filename.toUtf8().constData()); QFileInfo fi(filename); QString text = tr("Screenshot saved as %1").arg(fi.fileName()); //QString text = QString("Screenshot saved as %1").arg(fi.fileName()); // if (MplayerVersion::isMplayer2()) { // displayTextOnOSD(text, 3000, 1, ""); // } // else // if (MplayerVersion::isMplayerAtLeast(27665)) { // displayTextOnOSD(text, 3000, 1, "pausing_keep_force"); // } // else if (state() != Paused) { // Dont' show the message on OSD while in pause, otherwise // the video goes forward a frame. // qDebug() << "AAAA text=" << text; displayTextOnOSD(text, 3000, 1, "pausing_keep"); } // qDebug() << "BBBB text=" << text; emit showMessage(text); } void Core::displayUpdatingFontCache() { qDebug("Core::displayUpdatingFontCache"); emit showMessage( tr("Updating the font cache. This may take some seconds...") ); } void Core::displayBuffering() { emit showMessage(tr("Buffering...")); } void Core::displayPlaying() { qDebug("Core::displayPlaying"); emit showMessage(tr("Starting...")); } void Core::gotWindowResolution(int w, int h) { // qDebug("Core::gotWindowResolution: %d, %d", w, h); //double aspect = (double) w/h; // if (pref->use_mplayer_window) { // emit noVideo(); // } else { // if ((pref->resize_method==Preferences::Afterload) && (we_are_restarting)) { // // Do nothing // } else { emit needResize(w,h); // } // } // emit needResize(w,h); mset.win_width = w; mset.win_height = h; //Override aspect ratio, is this ok? //mdat.video_aspect = mset.win_aspect(); mplayerwindow->setResolution( w, h ); mplayerwindow->setAspect( mset.win_aspect() ); } void Core::gotNoVideo() { // File has no video (a sound file) // Reduce size of window /* mset.win_width = mplayerwindow->size().width(); mset.win_height = 0; mplayerwindow->setResolution( mset.win_width, mset.win_height ); emit needResize( mset.win_width, mset.win_height ); */ //mplayerwindow->showLogo(true); emit noVideo(); } void Core::gotVO(QString vo) { // qDebug("Core::gotVO: '%s'", vo.toUtf8().data() ); if ( pref->vo.isEmpty()) { // qDebug("Core::gotVO: saving vo"); pref->vo = vo; } } void Core::gotAO(QString ao) { // qDebug("Core::gotAO: '%s'", ao.toUtf8().data() ); if ( pref->ao.isEmpty()) { // qDebug("Core::gotAO: saving ao"); pref->ao = ao; } } void Core::streamTitleChanged(QString title) { mdat.stream_title = title; emit mediaInfoChanged(); } void Core::streamTitleAndUrlChanged(QString title, QString url) { mdat.stream_title = title; mdat.stream_url = url; emit mediaInfoChanged(); } void Core::sendMediaInfo() { // qDebug("Core::sendMediaInfo"); emit mediaPlaying(mdat.filename, mdat.displayName(pref->show_tag_in_window_title)); } //! Called when the state changes void Core::watchState(Core::State state) { //#ifdef SCREENSAVER_OFF // #if 0 // qDebug("Core::watchState: %d", state); // //qDebug("Core::watchState: has video: %d", !mdat.novideo); // if ((state == Playing) /* && (!mdat.novideo) */) { // disableScreensaver(); // } else { // enableScreensaver(); // } // #endif //#endif if ((proc->isMPlayer()) && (state == Playing) && (change_volume_after_unpause)) { // Delayed volume change qDebug("Core::watchState: delayed volume change"); int volume = (pref->global_volume ? pref->volume : mset.volume); proc->setVolume(volume); change_volume_after_unpause = false; } } void Core::checkIfVideoIsHD() { qDebug("Core::checkIfVideoIsHD"); // Check if the video is in HD and uses ffh264 codec. if ((mdat.video_codec=="ffh264") && (mset.win_height >= pref->HD_height)) { qDebug("Core::checkIfVideoIsHD: video == ffh264 and height >= %d", pref->HD_height); if (!mset.is264andHD) { mset.is264andHD = true; // if (pref->h264_skip_loop_filter == Preferences::LoopDisabledOnHD) { // qDebug("Core::checkIfVideoIsHD: we're about to restart the video"); // restartPlay(); // } } } else { mset.is264andHD = false; // FIXME: if the video was previously marked as HD, and now it's not // then the video should restart too. } } #if DELAYED_AUDIO_SETUP_ON_STARTUP && NOTIFY_AUDIO_CHANGES #error "DELAYED_AUDIO_SETUP_ON_STARTUP and NOTIFY_AUDIO_CHANGES can't be both defined" #endif #if DELAYED_AUDIO_SETUP_ON_STARTUP void Core::initAudioTrack() { // qDebug("Core::initAudioTrack"); // First audio if none selected if ( (mset.current_audio_id == MediaSettings::NoneSelected) && (mdat.audios.numItems() > 0) ) { // Don't set mset.current_audio_id here! changeAudio will do. // Otherwise changeAudio will do nothing. int audio = mdat.audios.itemAt(0).ID(); // First one if (mdat.audios.existsItemAt(0)) {//pref->initial_audio_track-1 audio = mdat.audios.itemAt(0).ID();//pref->initial_audio_track-1 } // Check if one of the audio tracks is the user preferred. // if (!pref->audio_lang.isEmpty()) { // int res = mdat.audios.findLang( pref->audio_lang ); // if (res != -1) audio = res; // } // changeAudio( audio ); } } #endif #if NOTIFY_VIDEO_CHANGES void Core::initVideoTrack(const Tracks & videos) { qDebug("Core::initVideoTrack"); mdat.videos = videos; updateWidgets(); } #endif //#if NOTIFY_AUDIO_CHANGES void Core::initAudioTrack(const Tracks & audios) { // qDebug("Core::initAudioTrack++++++++"); // qDebug("Core::initAudioTrack: num_items: %d", mdat.audios.numItems()); bool restore_audio = ((mdat.audios.numItems() > 0) || (mset.current_audio_id != MediaSettings::NoneSelected)); mdat.audios = audios; // qDebug("Core::initAudioTrack: list of audios:"); mdat.audios.list(); if (!restore_audio) { // Select initial track // qDebug("Core::initAudioTrack: selecting initial track"); int audio = mdat.audios.itemAt(0).ID(); // First one if (mdat.audios.existsItemAt(0)) {//pref->initial_audio_track-1 audio = mdat.audios.itemAt(0).ID();//pref->initial_audio_track-1 } // Check if one of the audio tracks is the user preferred. // if (!pref->audio_lang.isEmpty()) { // int res = mdat.audios.findLang( pref->audio_lang ); // if (res != -1) audio = res; // } // changeAudio( audio ); } else { // Try to restore previous audio track // qDebug("Core::initAudioTrack: restoring audio"); // Nothing to do, the audio is already set with -aid } updateWidgets(); emit audioTracksChanged(); } //#endif #if NOTIFY_SUB_CHANGES void Core::initSubtitleTrack(const SubTracks & subs) { qDebug("Core::initSubtitleTrack"); qDebug("Core::initSubtitleTrack: num_items: %d", mdat.subs.numItems()); bool restore_subs = ((mdat.subs.numItems() > 0) || (mset.current_sub_id != MediaSettings::NoneSelected)); // Save current sub SubData::Type previous_sub_type = SubData::Sub; int previous_sub_id = -1; if (mdat.subs.numItems() > 0) { if ((mset.current_sub_id != MediaSettings::SubNone) && (mset.current_sub_id != MediaSettings::NoneSelected)) { previous_sub_type = mdat.subs.itemAt(mset.current_sub_id).type(); previous_sub_id = mdat.subs.itemAt(mset.current_sub_id).ID(); } } qDebug("Core::initSubtitleTrack: previous subtitle: type: %d id: %d", previous_sub_type, previous_sub_id); mdat.subs = subs; qDebug("Core::initSubtitleTrack: list of subtitles:"); mdat.subs.list(); if (just_unloaded_external_subs) { qDebug("Core::initSubtitleTrack: just_unloaded_external_subs: true"); restore_subs = false; just_unloaded_external_subs = false; } if (just_loaded_external_subs) { qDebug("Core::initSubtitleTrack: just_loaded_external_subs: true"); restore_subs = false; just_loaded_external_subs = false; QFileInfo fi(mset.external_subtitles); bool is_idx = (fi.suffix().toLower() == "idx"); if (proc->isMPV()) is_idx = false; // Hack to ignore the idx extension with mpv if (!is_idx) { // The loaded subtitle file is the last one, so // try to select that one. if (mdat.subs.numItems() > 0) { int selected_subtitle = mdat.subs.numItems()-1; // If everything fails, use the last one // Try to find the subtitle file in the list for (int n = 0; n < mdat.subs.numItems(); n++) { SubData sub = mdat.subs.itemAt(n); if ((sub.type() == SubData::File) && (sub.filename() == mset.external_subtitles)) { selected_subtitle = n; qDebug("Core::initSubtitleTrack: external subtitle found: #%d", n); break; } } changeSubtitle( selected_subtitle ); goto end; } } } if (!restore_subs) { // Select initial track qDebug("Core::initSubtitleTrack: selecting initial track"); // if (!pref->autoload_sub) { // changeSubtitle( MediaSettings::SubNone ); // } else { //Select first subtitle int sub = mdat.subs.selectOne(/*pref->subtitle_lang, */"", 0/*pref->initial_subtitle_track-1 */); changeSubtitle( sub ); // } } else { // Try to restore previous subtitle track qDebug("Core::initSubtitleTrack: restoring subtitle"); if (mset.current_sub_id == MediaSettings::SubNone) { changeSubtitle( MediaSettings::SubNone ); } else if (mset.current_sub_id != MediaSettings::NoneSelected) { // Try to find old subtitle int item = mset.current_sub_id; if (previous_sub_id != -1) { int sub_item = mdat.subs.find(previous_sub_type, previous_sub_id); if (sub_item > -1) { item = sub_item; qDebug("Core::initSubtitleTrack: previous subtitle found: %d", sub_item); } } if (item > -1) { changeSubtitle(item ); } else { qDebug("Core::initSubtitleTrack: previous subtitle not found!"); } } } end: updateWidgets(); } void Core::setSubtitleTrackAgain(const SubTracks &) { qDebug("Core::setSubtitleTrackAgain"); changeSubtitle( mset.current_sub_id ); } #endif QString Core::pausing_prefix() { qDebug("Core::pausing_prefix"); // if (MplayerVersion::isMplayer2()) { // return QString::null; // } // else // if (pref->use_pausing_keep_force) if ((pref->use_pausing_keep_force) && (MplayerVersion::isMplayerAtLeast(27665))) {//kobe return "pausing_keep_force"; } else { return "pausing_keep"; } } //#include "moc_core.cpp" kylin-video/src/smplayer/timedialog.cpp0000664000175000017500000001373613233751662017221 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "timedialog.h" #include #include #include #include TimeDialog::TimeDialog( QWidget* parent, Qt::WindowFlags f ) : QDialog(parent, f) , drag_state(NOT_TDDRAGGING) , start_drag(QPoint(0,0)) { setupUi(this); this->setWindowFlags(Qt::FramelessWindowHint); this->setFixedSize(380, 170); this->setStyleSheet("QDialog{border: 1px solid #121212;border-radius:1px;background-color:#1f1f1f;}"); this->setWindowIcon(QIcon(":/res/kylin-video.png"));//setWindowIcon( Images::icon("logo", 64) ); this->setAutoFillBackground(true); this->setMouseTracking(true); installEventFilter(this); time_edit->setObjectName("seekTime"); time_edit->setDisplayFormat("H:mm:ss"); title_label->setStyleSheet("QLabel{background:transparent;font-size:14px;color:#999999;font-family:方正黑体_GBK;}");//font-weight:bold; time_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}");//font-weight:bold; closeBtn->setFocusPolicy(Qt::NoFocus); closeBtn->setStyleSheet("QPushButton{background-image:url(':/res/close_normal.png');border:0px;}QPushButton:hover{background:url(':/res/close_hover.png');}QPushButton:pressed{background:url(':/res/close_press.png');}"); okBtn->setFixedSize(91, 25); okBtn->setText(tr("OK")); okBtn->setFocusPolicy(Qt::NoFocus); okBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); cancelBtn->setFixedSize(91, 25); cancelBtn->setText(tr("Cancel")); cancelBtn->setFocusPolicy(Qt::NoFocus); cancelBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #000000;color:#999999;}QPushButton:hover{background-color:#1f1f1f;border:1px solid #0f0f0f;color:#ffffff;} QPushButton:pressed{background-color:#0d0d0d;border:1px solid #000000;color:#ffffff;}"); this->initConnect(); } TimeDialog::~TimeDialog() { } void TimeDialog::setTime(int seconds) { QTime t(0,0); time_edit->setTime(t.addSecs(seconds)); } int TimeDialog::time() { QTime t(0,0); return t.secsTo(time_edit->time()); } void TimeDialog::setMaximumTime( int seconds ) { QTime t(0,0); time_edit->setMaximumTime(t.addSecs(seconds)); } int TimeDialog::maximumTime() { QTime t(0,0); return t.secsTo(time_edit->maximumTime()); } void TimeDialog::setLabel(const QString & label) { time_label->setText(label); } QString TimeDialog::label() { return time_label->text(); } void TimeDialog::initConnect() { connect(okBtn, SIGNAL(clicked()), this, SLOT(accept())); connect(cancelBtn, SIGNAL(clicked()), this, SLOT(close())); connect(closeBtn, SIGNAL(clicked()), this, SLOT(close())); } void TimeDialog::moveDialog(QPoint diff) { #if QT_VERSION >= 0x050000 // Move the window with some delay. // Seems to work better with Qt 5 static QPoint d; static int count = 0; d += diff; count++; if (count > 3) { QPoint new_pos = pos() + d; if (new_pos.y() < 0) new_pos.setY(0); if (new_pos.x() < 0) new_pos.setX(0); move(new_pos); count = 0; d = QPoint(0,0); } #else move(pos() + diff); #endif } bool TimeDialog::eventFilter( QObject * object, QEvent * event ) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { drag_state = NOT_TDDRAGGING; return false; } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_TDDRAGGING; return false; } drag_state = START_TDDRAGGING; start_drag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (drag_state != TDDRAGGING || mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_TDDRAGGING; return false; } // Stop dragging and eat event drag_state = NOT_TDDRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (drag_state == NOT_TDDRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { drag_state = NOT_TDDRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - start_drag; if (drag_state == START_TDDRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; drag_state = TDDRAGGING; } this->moveDialog(diff); start_drag = pos; event->accept(); return true; } //#include "moc_timedialog.cpp" kylin-video/src/smplayer/inforeadermplayer.h0000664000175000017500000000355613233751662020257 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef INFOREADER_MPLAYER_H #define INFOREADER_MPLAYER_H #include "inforeader.h" #include #include class QProcess; class InfoReaderMplayer : QObject { Q_OBJECT public: InfoReaderMplayer( QString mplayer_bin, QObject * parent = 0); ~InfoReaderMplayer(); void getInfo(); InfoList voList() { return vo_list; }; InfoList aoList() { return ao_list; }; InfoList demuxerList() { return demuxer_list; }; InfoList vcList() { return vc_list; }; InfoList acList() { return ac_list; }; int mplayerSVN() { return mplayer_svn; }; // QString mplayer2Version() { return mplayer2_version; }; // bool isMplayer2() { return is_mplayer2; }; protected slots: virtual void readLine(QByteArray); protected: bool run(QString options); void list(); protected: QProcess * proc; QString mplayerbin; InfoList vo_list; InfoList ao_list; InfoList demuxer_list; InfoList vc_list; InfoList ac_list; int mplayer_svn; // QString mplayer2_version; // bool is_mplayer2; private: bool waiting_for_key; int reading_type; }; #endif kylin-video/src/smplayer/subtracks.h0000664000175000017500000000540713233751662016545 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _SUBTRACKS_H_ #define _SUBTRACKS_H_ #include #include #include class SubData { public: enum Type { None = -1, Vob = 0, Sub = 1, File = 2 }; SubData() { _ID=-1; _lang=""; _name=""; _filename=""; _type = None; }; ~SubData() {}; void setType( Type t ) { _type = t; }; void setID(int id) { _ID = id; }; void setLang(QString lang) { _lang = lang; }; void setName(QString name) { _name = name; }; void setFilename(QString f) { _filename = f; }; Type type() { return _type; }; int ID() { return _ID; }; QString lang() { return _lang; }; QString name() { return _name; }; QString filename() { return _filename; }; QString displayName() { QString dname=""; if (!_name.isEmpty()) { dname = _name; if (!_lang.isEmpty()) { dname += " ["+ _lang + "]"; } } else if (!_lang.isEmpty()) { dname = _lang; } else if (!_filename.isEmpty()) { QFileInfo f(_filename); dname = f.fileName(); } else dname = QString::number(_ID); return dname; }; protected: Type _type; int _ID; QString _lang; QString _name; QString _filename; }; typedef QList SubList; class SubTracks { public: enum ParseResult { SubtitleUnchanged = 0, SubtitleAdded = 1, SubtitleChanged = 2 }; SubTracks(); ~SubTracks(); void clear(); int find( SubData::Type t, int ID ); void add( SubData::Type t, int ID ); bool changeLang( SubData::Type t, int ID, QString lang ); bool changeName( SubData::Type t, int ID, QString name ); bool changeFilename( SubData::Type t, int ID, QString filename ); int numItems(); bool existsItemAt(int n); SubData itemAt(int n); SubData findItem( SubData::Type t, int ID ); int findLang(QString expr); int selectOne(QString preferred_lang, int default_sub=0); //! Parses a line from mplayer output with subtitle info ParseResult parse(QString text); void list(); void listNames(); /* void test(); */ protected: SubList subs; int index; }; #endif kylin-video/src/smplayer/actionseditor.cpp0000664000175000017500000005430113233751662017743 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ /* This is based on qq14-actioneditor-code.zip from Qt */ #include "actionseditor.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "images.h" #include "filedialog.h" #include "paths.h" #include "shortcutgetter.h" #include "global.h" using namespace Global; /* #include #include class MyDelegate : public QItemDelegate { public: MyDelegate(QObject *parent = 0); QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; virtual void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index ) const; }; MyDelegate::MyDelegate(QObject *parent) : QItemDelegate(parent) { } static QString old_accel_text; QWidget * MyDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem & option, const QModelIndex & index) const { qDebug("MyDelegate::createEditor"); old_accel_text = index.model()->data(index, Qt::DisplayRole).toString(); //qDebug( "text: %s", old_accel_text.toUtf8().data()); return QItemDelegate::createEditor(parent, option, index); } void MyDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QLineEdit *line_edit = static_cast(editor); QString accelText = QKeySequence(line_edit->text()).toString(); if (accelText.isEmpty() && !line_edit->text().isEmpty()) { model->setData(index, old_accel_text); } else { model->setData(index, accelText); } } */ QString ActionsEditor::shortcutsToString(QList shortcuts_list) { QString accelText = ""; // qDebug() << "===========shortcutsToString============="; for (int n=0; n < shortcuts_list.count(); n++) { accelText += shortcuts_list[n].toString(QKeySequence::PortableText); if (n < (shortcuts_list.count()-1)) accelText += ", "; } //qDebug("ActionsEditor::shortcutsToString: accelText: '%s'", accelText.toUtf8().constData()); return accelText; } QList ActionsEditor::stringToShortcuts(QString shortcuts) { QList shortcuts_list; // qDebug() << "===========stringToShortcuts============="; QStringList l = shortcuts.split(", "); for (int n=0; n < l.count(); n++) { //qDebug("%s", l[n].toUtf8().data()); #if QT_VERSION >= 0x040300 // Qt 4.3 and 4.4 (at least on linux) seems to have a problem when using Traditional Chinese // QKeysequence deletes the arrow key names from the shortcut // so this is a work-around. QString s = l[n].simplified(); #else QString s = QKeySequence( l[n].simplified() ); #endif //Work-around for Simplified-Chinese s.replace( QString::fromUtf8("左"), "Left"); s.replace( QString::fromUtf8("下"), "Down"); s.replace( QString::fromUtf8("右"), "Right"); s.replace( QString::fromUtf8("上"), "Up"); shortcuts_list.append( s ); //qDebug("ActionsEditor::stringToShortcuts: shortcut %d: '%s'", n, s.toUtf8().data()); } return shortcuts_list; } #define COL_CONFLICTS 0 #define COL_SHORTCUT 1 #define COL_DESC 2 #define COL_NAME 3 ActionsEditor::ActionsEditor(QWidget * parent, Qt::WindowFlags f) : QWidget(parent, f) { latest_dir = Paths::shortcutsPath(); actionsTable = new QTableWidget(0, COL_NAME +1, this); actionsTable->setSelectionMode(QAbstractItemView::SingleSelection ); actionsTable->verticalHeader()->hide(); // QPalette pal = actionsTable->palette(); // pal.setBrush(this->backgroundRole(),QBrush(QPixmap("images/background.png")) ); // actionsTable->setPalette(pal); #if QT_VERSION >= 0x050000 actionsTable->horizontalHeader()->setSectionResizeMode(COL_DESC, QHeaderView::Stretch); actionsTable->horizontalHeader()->setSectionResizeMode(COL_NAME, QHeaderView::Stretch); #else actionsTable->horizontalHeader()->setResizeMode(COL_DESC, QHeaderView::Stretch); actionsTable->horizontalHeader()->setResizeMode(COL_NAME, QHeaderView::Stretch); #endif // background-color:#0f0f0f; // border:1px solid #0a9ff5; actionsTable->horizontalHeader()->setHighlightSections(false);//点击表时不对表头行光亮(获取焦点) actionsTable->setAlternatingRowColors(true); actionsTable->setStyleSheet("font-family:方正黑体_GBK;font-size:12px;color:#999999;selection-background-color:red;alternate-background-color: #2e2e2e; background:transparent;"); actionsTable->horizontalHeader()->setStyleSheet("QHeaderView::section{font-family:方正黑体_GBK;font-size:13px;color:#999999;background:transparent;}"); //设置表头背景色 actionsTable->horizontalScrollBar()->setStyleSheet("QScrollBar{background:transparent; height:10px;}" "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}" "QScrollBar::handle:hover{background:gray;}" "QScrollBar::sub-line{background:transparent;}" "QScrollBar::add-line{background:transparent;}"); actionsTable->verticalScrollBar()->setStyleSheet("QScrollBar{background:transparent; width: 10px;}" "QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}" "QScrollBar::handle:hover{background:gray;}" "QScrollBar::sub-line{background:transparent;}" "QScrollBar::add-line{background:transparent;}"); actionsTable->setSelectionBehavior(QAbstractItemView::SelectRows); actionsTable->setSelectionMode(QAbstractItemView::ExtendedSelection); connect(actionsTable, SIGNAL(itemActivated(QTableWidgetItem *)), this, SLOT(editShortcut())); // saveButton = new QPushButton(this); // loadButton = new QPushButton(this); // connect(saveButton, SIGNAL(clicked()), this, SLOT(saveActionsTable())); // connect(loadButton, SIGNAL(clicked()), this, SLOT(loadActionsTable())); // editButton = new QPushButton(this); // connect( editButton, SIGNAL(clicked()), this, SLOT(editShortcut()) ); // QHBoxLayout *buttonLayout = new QHBoxLayout; // buttonLayout->setSpacing(8); // buttonLayout->addWidget(editButton); // buttonLayout->addStretch(1); // buttonLayout->addWidget(loadButton); // buttonLayout->addWidget(saveButton); QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->setMargin(8); mainLayout->setSpacing(8); mainLayout->addWidget(actionsTable); // mainLayout->addLayout(buttonLayout); retranslateStrings(); } ActionsEditor::~ActionsEditor() { } void ActionsEditor::retranslateStrings() { actionsTable->setHorizontalHeaderLabels(QStringList() << "" << tr("Shortcut") << tr("Description") << tr("Name") ); // QTableWidgetItem *columnHeaderItem = actionsTable->horizontalHeaderItem(1); // columnHeaderItem->setFont(QFont("Helvetica"));//设置字体 // columnHeaderItem->setBackgroundColor(QColor(0,60,10));//设置单元格背景颜色 // columnHeaderItem->setTextColor(QColor(200,111,30));//设置文字颜色 // saveButton->setText(tr("&Save")); // saveButton->setIcon(Images::icon("save")); // loadButton->setText(tr("&Load")); // loadButton->setIcon(Images::icon("open")); // editButton->setText(tr("&Change shortcut...")); } bool ActionsEditor::isEmpty() { return actionsList.isEmpty()/* && btnActionsList.isEmpty()*/; } void ActionsEditor::clear() { actionsList.clear(); // btnActionsList.clear(); } void ActionsEditor::addCurrentActions(QWidget *widget) { QAction *action; QList actions = widget->findChildren(); for (int n=0; n < actions.count(); n++) { action = static_cast (actions[n]); /* if (!action->objectName().isEmpty()) { qDebug("ActionsEditor::addCurrentActions: action # %d: '%s' menu: %d", n, action->objectName().toUtf8().constData(), action->menu()!=0); } */ if (!action->objectName().isEmpty() && action->objectName() != "pl_play" && action->objectName() != "pl_remove_selected" && action->objectName() != "pl_delete_from_disk" /*&& !action->inherits("QWidgetAction")*/ && (action->menu()==0) ) actionsList.append(action); } // QPushButton *btn_action; // QList btn_actions = widget->findChildren(); // for (int m=0; m < btn_actions.count(); m++) { // btn_action = static_cast (btn_actions[m]); // QString actionName = btn_action->objectName(); // if (!actionName.isEmpty()) { // if (actionName == "PlayListBtn" || actionName == "play_next") { // btnActionsList.append(btn_action); // } // } // } updateView(); } void ActionsEditor::updateView() { actionsTable->setRowCount(actionsList.count()/* + btnActionsList.count()*/); QAction *action; // QPushButton *btn_action; QString accelText; //actionsTable->setSortingEnabled(false); int action_count = actionsList.count(); for (int n=0; n < action_count; n++) { action = static_cast (actionsList[n]); accelText = shortcutsToString(action->shortcuts() ); // Conflict column QTableWidgetItem * i_conf = new QTableWidgetItem(); // Name column QTableWidgetItem * i_name = new QTableWidgetItem(action->objectName()); // Desc column QTableWidgetItem * i_desc = new QTableWidgetItem(action->text().replace("&","")); i_desc->setIcon( action->icon() ); // Shortcut column QTableWidgetItem * i_shortcut = new QTableWidgetItem(accelText); // Set flags i_conf->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); i_name->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); i_desc->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); i_shortcut->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); // Add items to table actionsTable->setItem(n, COL_CONFLICTS, i_conf ); actionsTable->setItem(n, COL_NAME, i_name ); actionsTable->setItem(n, COL_DESC, i_desc ); actionsTable->setItem(n, COL_SHORTCUT, i_shortcut ); } // for (int m=0; m < btnActionsList.count(); m++) { // btn_action = static_cast (btnActionsList[m]); // accelText = btn_action->shortcut().toString();//shortcutsToString(btn_action->shortcut()); // // Conflict column // QTableWidgetItem * i_conf = new QTableWidgetItem(); // // Name column // QTableWidgetItem * i_name = new QTableWidgetItem(btn_action->objectName()); // // Desc column // QTableWidgetItem * i_desc = new QTableWidgetItem(btn_action->text().replace("&","")); // i_desc->setIcon( action->icon() ); // // Shortcut column // QTableWidgetItem * i_shortcut = new QTableWidgetItem(accelText); // // Set flags // i_conf->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); // i_name->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); // i_desc->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); // i_shortcut->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); // // Add items to table // actionsTable->setItem(m + action_count, COL_CONFLICTS, i_conf ); // actionsTable->setItem(m + action_count, COL_NAME, i_name ); // actionsTable->setItem(m + action_count, COL_DESC, i_desc ); // actionsTable->setItem(m + action_count, COL_SHORTCUT, i_shortcut ); // } hasConflicts(); // Check for conflicts actionsTable->resizeColumnsToContents(); actionsTable->setCurrentCell(0, COL_SHORTCUT); //actionsTable->setSortingEnabled(true); } void ActionsEditor::applyChanges() { qDebug("ActionsEditor::applyChanges"); int action_count = (int)actionsList.size(); //QAction可以设置多个快捷键,QPushButton只能设置一个快捷键 for (int row = 0; row < action_count; ++row) { QAction *action = actionsList[row]; QTableWidgetItem *i = actionsTable->item(row, COL_SHORTCUT); action->setShortcuts(stringToShortcuts(i->text()) );//action->setShortcut( QKeySequence(i->text()) ); } // for (int m=0; m < (int)btnActionsList.size(); m++) { // QPushButton *btn = btnActionsList[m]; // QTableWidgetItem *i = actionsTable->item(m + action_count, COL_SHORTCUT); // btn->setShortcut(i->text()); // } } void ActionsEditor::editShortcut() { QTableWidgetItem * i = actionsTable->item( actionsTable->currentRow(), COL_SHORTCUT ); if (i) { // bool isbtn = false; QTableWidgetItem * j = actionsTable->item( actionsTable->currentRow(), COL_NAME ); // if (j) { // if (j->text() == "PlayListBtn" || j->text() == "play_next") { // isbtn = true; // } // } ShortcutGetter d/*(this)*/; QString result = d.exec( i->text() ); if (!result.isNull()) { qDebug("ActionsEditor::editShortcut: result: '%s'", result.toUtf8().constData()); QString accelText = QKeySequence(result).toString(QKeySequence::PortableText); i->setText(accelText); // qDebug() << "accelText="<beep();//使用默认的音量和铃声,发出铃声 } } } int ActionsEditor::findActionName(const QString & name) { for (int row=0; row < actionsTable->rowCount(); row++) { if (actionsTable->item(row, COL_NAME)->text() == name) return row; } return -1; } bool ActionsEditor::containsShortcut(const QString & accel, const QString & shortcut) { QStringList shortcut_list = accel.split(", "); QString s; foreach(s, shortcut_list) { s = s.trimmed(); //qDebug("ActionsEditor::containsShortcut: comparing '%s' with '%s'", s.toUtf8().constData(), shortcut.toUtf8().constData()); if (s == shortcut) return true; } return false; } int ActionsEditor::findActionAccel(const QString & accel, int ignoreRow) { QStringList shortcuts = accel.split(", "); QString shortcut; for (int row = 0; row < actionsTable->rowCount(); row++) { QTableWidgetItem * i = actionsTable->item(row, COL_SHORTCUT); if (i && row != ignoreRow) { if (!i->text().isEmpty()) { foreach(shortcut, shortcuts) { if (containsShortcut(i->text(), shortcut.trimmed())) { return row; } } } } } return -1; } bool ActionsEditor::hasConflicts() { int found; bool conflict = false; QString accelText; QTableWidgetItem *i; for (int n = 0; n < actionsTable->rowCount(); n++) { //actionsTable->setText( n, COL_CONFLICTS, " "); i = actionsTable->item( n, COL_CONFLICTS ); if (i) i->setIcon( QPixmap() ); i = actionsTable->item(n, COL_SHORTCUT ); if (i) { accelText = i->text(); if (!accelText.isEmpty()) { found = findActionAccel( accelText, n ); if ( (found != -1) /*&& (found != n)*/ ) { conflict = true; //actionsTable->setText( n, COL_CONFLICTS, "!"); actionsTable->item( n, COL_CONFLICTS )->setIcon( Images::icon("conflict") ); } } } } //if (conflict) qApp->beep(); return conflict; } /*void ActionsEditor::saveActionsTable() { QString s = MyFileDialog::getSaveFileName( this, tr("Choose a filename"), latest_dir, tr("Key files") +" (*.keys)" ); if (!s.isEmpty()) { // If filename has no extension, add it if (QFileInfo(s).suffix().isEmpty()) { s = s + ".keys"; } if (QFileInfo(s).exists()) { int res = QMessageBox::question( this, tr("Confirm overwrite?"), tr("The file %1 already exists.\n" "Do you want to overwrite?").arg(s), QMessageBox::Yes, QMessageBox::No, Qt::NoButton); if (res == QMessageBox::No ) { return; } } latest_dir = QFileInfo(s).absolutePath(); bool r = saveActionsTable(s); if (!r) { QMessageBox::warning(this, tr("Error"), tr("The file couldn't be saved"), QMessageBox::Ok, Qt::NoButton); } } } bool ActionsEditor::saveActionsTable(const QString & filename) { qDebug("ActionsEditor::saveActions: '%s'", filename.toUtf8().data()); QFile f( filename ); if ( f.open( QIODevice::WriteOnly ) ) { QTextStream stream( &f ); stream.setCodec("UTF-8"); for (int row=0; row < actionsTable->rowCount(); row++) { stream << actionsTable->item(row, COL_NAME)->text() << "\t" << actionsTable->item(row, COL_SHORTCUT)->text() << "\n"; } f.close(); return true; } return false; } void ActionsEditor::loadActionsTable() { QString s = MyFileDialog::getOpenFileName( this, tr("Choose a file"), latest_dir, tr("Key files") +" (*.keys)" ); if (!s.isEmpty()) { latest_dir = QFileInfo(s).absolutePath(); bool r = loadActionsTable(s); if (!r) { QMessageBox::warning(this, tr("Error"), tr("The file couldn't be loaded"), QMessageBox::Ok, Qt::NoButton); } } } bool ActionsEditor::loadActionsTable(const QString & filename) { qDebug("ActionsEditor::loadActions: '%s'", filename.toUtf8().data()); QRegExp rx("^(.*)\\t(.*)"); int row; QFile f( filename ); if ( f.open( QIODevice::ReadOnly ) ) { QTextStream stream( &f ); stream.setCodec("UTF-8"); QString line; while ( !stream.atEnd() ) { line = stream.readLine(); qDebug("line: '%s'", line.toUtf8().data()); if (rx.indexIn(line) > -1) { QString name = rx.cap(1); QString accelText = rx.cap(2); qDebug(" name: '%s' accel: '%s'", name.toUtf8().data(), accelText.toUtf8().data()); row = findActionName(name); if (row > -1) { qDebug("Action found!"); actionsTable->item(row, COL_SHORTCUT)->setText(accelText); } } else { qDebug(" wrong line"); } } f.close(); hasConflicts(); // Check for conflicts return true; } else { return false; } }*/ // Static functions void ActionsEditor::saveToConfig(QObject *o, QSettings *set) { qDebug("ActionsEditor::saveToConfig"); set->beginGroup("actions"); QAction *action; QList actions = o->findChildren(); for (int n=0; n < actions.count(); n++) { action = static_cast (actions[n]); if (!action->objectName().isEmpty()/* && !action->inherits("QWidgetAction")*/) { QString accelText = shortcutsToString(action->shortcuts());//QString accelText = action->shortcut().toString(); set->setValue(action->objectName(), accelText); } } // QPushButton *btn_action; // QList btn_actions = o->findChildren(); // for (int m=0; m < btn_actions.count(); m++) { // btn_action = static_cast (btn_actions[m]); // if (!btn_action->objectName().isEmpty()) { // if (btn_action->objectName() == "PlayListBtn" || btn_action->objectName() == "play_next") { // QString accelText = btn_action->shortcut().toString(); // set->setValue(btn_action->objectName(), accelText); // } // } // } set->endGroup(); } void ActionsEditor::loadFromConfig(QObject *o, QSettings *set) { set->beginGroup("actions"); QAction *action; QString accelText; QList actions = o->findChildren(); // qDebug() << "ActionsEditor::loadFromConfig actions count="< (actions[n]); if (!action->objectName().isEmpty()/* && !action->inherits("QWidgetAction")*/) { QString current = shortcutsToString(action->shortcuts()); accelText = set->value(action->objectName(), current).toString(); action->setShortcuts(stringToShortcuts(accelText)); // qDebug() << "ActionsEditor::loadFromConfig action->objectName()="<objectName()<<",accelText="< btn_actions = o->findChildren(); for (int m=0; m < btn_actions.count(); m++) { btn_action = static_cast (btn_actions[m]); if (!btn_action->objectName().isEmpty()) { QList cur_shortcuts_list; cur_shortcuts_list.append(btn_action->shortcut()); QString current = shortcutsToString(cur_shortcuts_list); accelText = set->value(btn_action->objectName(), current).toString(); QList shortcuts_list = stringToShortcuts(accelText); if (shortcuts_list.count() > 0) { btn_action->setShortcut(shortcuts_list.at(0)); } } } set->endGroup(); } QAction * ActionsEditor::findAction(QObject *o, const QString & name) { QAction *action; QList actions = o->findChildren(); for (int n=0; n < actions.count(); n++) { action = static_cast (actions[n]); qDebug("ActionsEditor::findAction: %s", action->objectName().toLatin1().constData()); if (name == action->objectName()) return action; } return 0; } QStringList ActionsEditor::actionsNames(QObject *o) { QStringList l; QAction *action; QList actions = o->findChildren(); for (int n=0; n < actions.count(); n++) { action = static_cast (actions[n]); //qDebug("action name: '%s'", action->objectName().toUtf8().data()); //qDebug("action name: '%s'", action->text().toUtf8().data()); if (!action->objectName().isEmpty()) l.append( action->objectName() ); } return l; } // Language change stuff void ActionsEditor::changeEvent(QEvent *e) { if (e->type() == QEvent::LanguageChange) { retranslateStrings(); } else { QWidget::changeEvent(e); } } //#include "moc_actionseditor.cpp" kylin-video/src/smplayer/mpvprocess.cpp0000664000175000017500000005004413233751662017275 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "mpvprocess.h" #include #include #include #include #include "global.h" #include "preferences.h" #include "mplayerversion.h" #include "colorutils.h" using namespace Global; static QRegExp mpv_screenshot("Screenshot: '(.*)'"); MPVProcess::MPVProcess(QObject * parent) : PlayerProcess(parent) , notified_mplayer_is_running(false) , notified_pause(false) , received_end_of_file(false) , last_sub_id(-1) , mplayer_svn(-1) // Not found yet , verbose(false) #if NOTIFY_SUB_CHANGES , subtitle_info_received(false) , subtitle_info_changed(false) #endif #if NOTIFY_AUDIO_CHANGES , audio_info_changed(false) #endif #if NOTIFY_VIDEO_CHANGES , video_info_changed(false) #endif , dvd_current_title(-1) , br_current_title(-1) { player_id = PlayerID::MPV; connect( this, SIGNAL(lineAvailable(QByteArray)), this, SLOT(parseLine(QByteArray)) ); connect( this, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished(int,QProcess::ExitStatus)) ); connect( this, SIGNAL(error(QProcess::ProcessError)), this, SLOT(gotError(QProcess::ProcessError)) ); /* int svn = MplayerVersion::mplayerVersion("mpv unknown version (C)"); */ } MPVProcess::~MPVProcess() { } bool MPVProcess::start() { md.reset(); notified_mplayer_is_running = false; notified_pause = false; last_sub_id = -1; mplayer_svn = -1; // Not found yet received_end_of_file = false; #if NOTIFY_SUB_CHANGES subs.clear(); subtitle_info_received = false; subtitle_info_changed = false; #endif #if NOTIFY_AUDIO_CHANGES audios.clear(); audio_info_changed = false; #endif #if NOTIFY_VIDEO_CHANGES videos.clear(); video_info_changed = false; #endif dvd_current_title = -1; br_current_title = -1; MyProcess::start(); return waitForStarted(); } static QRegExp rx_mpv_av("^STATUS: ([0-9\\.-]+) / ([0-9\\.-]+) P: (yes|no) B: (yes|no) I: (yes|no)"); static QRegExp rx_mpv_dsize("^INFO_VIDEO_DSIZE=(\\d+)x(\\d+)"); static QRegExp rx_mpv_vo("^VO: \\[(.*)\\]"); static QRegExp rx_mpv_ao("^AO: \\[(.*)\\]"); static QRegExp rx_mpv_paused("^\\(Paused\\)"); static QRegExp rx_mpv_endoffile("^Exiting... \\(End of file\\)"); //static QRegExp rx_mpv_audio("^\\[stream\\] Audio .* --aid=(\\d+)( --alang=([a-z]+)|)([ \\(\\)\\*]+)('(.*)'|)"); static QRegExp rx_mpv_audio("^.* Audio\\s+--aid=(\\d+)( --alang=([a-z]+)|)([ \\(\\)\\*]+)('(.*)'|)"); //static QRegExp rx_mpv_subs("^\\[stream\\] Subs .* --sid=(\\d+)( --slang=([a-z]+)|)([ \\(\\)\\*]+)('(.*)'|)"); static QRegExp rx_mpv_subs("^.* Subs\\s+--sid=(\\d+)( --slang=([a-z]+)|)([ \\(\\)\\*]+)('(.*)'|)"); #if !NOTIFY_VIDEO_CHANGES //static QRegExp rx_mpv_video("^\\[stream\\] Video .* --vid=(\\d+)([ \\(\\)\\*]+)('(.*)'|)"); static QRegExp rx_mpv_video("^.* Video\\s+--vid=(\\d+)([ \\(\\)\\*]+)('(.*)'|)"); #endif #if 0 static QRegExp rx_mpv_subs2("^Sub:( >|) \\((\\d+)\\) '(.*)'"); #endif static QRegExp rx_mpv_chaptername("^INFO_CHAPTER_(\\d+)_NAME=(.*)"); static QRegExp rx_mpv_trackinfo("^INFO_TRACK_(\\d+): (audio|video|sub) (\\d+) '(.*)' '(.*)' (yes|no)"); #if 0 static QRegExp rx_mpv_videoinfo("^\\[vd\\] VIDEO: .* (\\d+)x(\\d+) .* ([0-9.]+) fps"); // [vd] VIDEO: 624x352 25.000 fps 1018.5 kbps (127.3 kB/s) #endif static QRegExp rx_mpv_videocodec("^INFO_VIDEO_CODEC=(.*) \\[(.*)\\]"); static QRegExp rx_mpv_audiocodec("^INFO_AUDIO_CODEC=(.*) \\[(.*)\\]"); static QRegExp rx_mpv_forbidden("HTTP error 403 Forbidden"); //#if DVDNAV_SUPPORT //static QRegExp rx_mpv_switch_title("^\\[dvdnav\\] DVDNAV, switched to title: (\\d+)"); //#endif static QRegExp rx_mpv_playing("^Playing:.*|^\\[ytdl_hook\\].*"); //static QRegExp rx_mpv_generic("^(.*)=(.*)"); static QRegExp rx_mpv_generic("^([A-Z_]+)=(.*)"); static QRegExp rx_stream_title("icy-title: (.*)"); void MPVProcess::parseLine(QByteArray ba) { //qDebug("MPVProcess::parseLine: '%s'", ba.data() ); if (ba.isEmpty()) return; QString tag; QString value; #if COLOR_OUTPUT_SUPPORT QString line = ColorUtils::stripColorsTags(QString::fromLocal8Bit(ba)); #else QString line = QString::fromLocal8Bit(ba); #endif if (verbose) { line = line.replace("[statusline] ", ""); line = line.replace("[cplayer] ", ""); } // Parse A: V: line //qDebug("MPVProcess::parseLine: %s", line.toUtf8().data()); if (rx_mpv_av.indexIn(line) > -1) { double sec = rx_mpv_av.cap(1).toDouble(); double length = rx_mpv_av.cap(2).toDouble(); bool paused = (rx_mpv_av.cap(3) == "yes"); bool buffering = (rx_mpv_av.cap(4) == "yes"); bool idle = (rx_mpv_av.cap(5) == "yes"); if (length != md.duration) { md.duration = length; // #if DVDNAV_SUPPORT // emit receivedDuration(length); // #endif } if (paused && notified_pause) return; if (paused) { notified_pause = true; qDebug("MPVProcess::parseLine: paused"); receivedPause(); return; } else if (buffering) { qDebug("MPVProcess::parseLine: buffering"); receivedBuffering(); return; } else if (idle) { qDebug("MPVProcess::parseLine: idle"); receivedBuffering(); return; } notified_pause = false; #if NOTIFY_SUB_CHANGES if (notified_mplayer_is_running) { if (subtitle_info_changed) { qDebug("MPVProcess::parseLine: subtitle_info_changed"); subtitle_info_changed = false; subtitle_info_received = false; emit subtitleInfoChanged(subs); } if (subtitle_info_received) { qDebug("MPVProcess::parseLine: subtitle_info_received"); subtitle_info_received = false; emit subtitleInfoReceivedAgain(subs); } } #endif #if NOTIFY_AUDIO_CHANGES if (notified_mplayer_is_running) { if (audio_info_changed) { qDebug("MPVProcess::parseLine: audio_info_changed"); audio_info_changed = false; emit audioInfoChanged(audios); } } #endif #if NOTIFY_VIDEO_CHANGES if (notified_mplayer_is_running) { if (video_info_changed) { qDebug("MPVProcess::parseLine: video_info_changed"); video_info_changed = false; emit videoInfoChanged(videos); } } #endif if (!notified_mplayer_is_running) { qDebug("MPVProcess::parseLine: starting sec: %f", sec); if (md.video_width == 0 || md.video_height == 0) { md.novideo = true; emit receivedNoVideo(); } emit receivedStartingTime(sec); emit mplayerFullyLoaded(); emit receivedCurrentFrame(0); // Ugly hack: set the frame counter to 0 notified_mplayer_is_running = true; // Wait some secs to ask for bitrate QTimer::singleShot(12000, this, SLOT(requestBitrateInfo())); } emit receivedCurrentSec( sec ); } else { emit lineAvailable(line); // qDebug("AAA:%s", line.toUtf8().data());//Screenshot: '/home/lixiang/图片/kylin_video_screenshots/cap_血战钢j岭_00:23:25_01.jpg' // Parse other things // qDebug("MPVProcess::parseLine: 'kobe test:%s'", line.toUtf8().data());//'kobe test:Screenshot: '/home/lixiang/图片/kylin_video_screenshots/mpv-shot0001.jpg'' // Debug: MPVProcess::parseLine: 'kobe test:Playing: /home/lixiang/血战钢j岭.mp4' // Debug: MPVProcess::parseLine: 'kobe test:Screenshot: '/home/lixiang/图片/smplayer_screenshots/cap_血战钢j岭_00:01:41_01.jpg'' //kobe 20170706 20170722 // pref->screenshot_template cap_东成西就_00:00:12_01 cap_%F_%p_%02n if (mpv_screenshot.indexIn(line) > -1) {//20170722 QString shot = mpv_screenshot.cap(1); // qDebug() << "shot="< -1) { qDebug("MVPProcess::parseLine: detected end of file"); if (!received_end_of_file) { // In case of playing VCDs or DVDs, maybe the first title // is not playable, so the GUI doesn't get the info about // available titles. So if we received the end of file // first let's pretend the file has started so the GUI can have // the data. if ( !notified_mplayer_is_running) { emit mplayerFullyLoaded(); } // Send signal once the process is finished, not now! received_end_of_file = true; } } else // Window resolution if (rx_mpv_dsize.indexIn(line) > -1) { int w = rx_mpv_dsize.cap(1).toInt(); int h = rx_mpv_dsize.cap(2).toInt(); emit receivedWindowResolution( w, h ); } else // VO if (rx_mpv_vo.indexIn(line) > -1) { emit receivedVO( rx_mpv_vo.cap(1) ); // Ask for window resolution // qDebug() << "kobe call writeToStdin111"; writeToStdin("print_text INFO_VIDEO_DSIZE=${=dwidth}x${=dheight}"); } else // AO if (rx_mpv_ao.indexIn(line) > -1) { emit receivedAO( rx_mpv_ao.cap(1) ); } else // Audio if (rx_mpv_audio.indexIn(line) > -1) { int ID = rx_mpv_audio.cap(1).toInt(); QString lang = rx_mpv_audio.cap(3); QString title = rx_mpv_audio.cap(6); // qDebug("MPVProcess::parseLine: audio id: %d, lang: '%s', name: '%s'", ID, lang.toUtf8().constData(), title.toUtf8().constData()); #if NOTIFY_AUDIO_CHANGES updateAudioTrack(ID, title, lang); #else if (md.audios.find(ID) == -1) { md.audios.addID(ID); md.audios.addName(ID, title); md.audios.addLang(ID, lang); } #endif } else if (rx_stream_title.indexIn(line) > -1) { QString s = rx_stream_title.cap(1); // qDebug("MPVProcess::parseLine: stream_title: '%s'", s.toUtf8().data()); md.stream_title = s; emit receivedStreamTitle(s); } else // Subtitles if (rx_mpv_subs.indexIn(line) > -1) { int ID = rx_mpv_subs.cap(1).toInt(); QString lang = rx_mpv_subs.cap(3); QString title = rx_mpv_subs.cap(6); // qDebug("MPVProcess::parseLine: sub id: %d, lang: '%s', name: '%s'", ID, lang.toUtf8().constData(), title.toUtf8().constData()); #if NOTIFY_SUB_CHANGES updateSubtitleTrack(ID, title, lang); #else if (md.subs.find(SubData::Sub, ID) == -1) { md.subs.add(SubData::Sub, ID); md.subs.changeName(SubData::Sub, ID, title); md.subs.changeLang(SubData::Sub, ID, lang); } #endif } else #if 0 if (rx_mpv_subs2.indexIn(line) > -1) { bool selected = (rx_mpv_subs2.cap(1) == " >"); int ID = rx_mpv_subs2.cap(2).toInt(); QString title = rx_mpv_subs2.cap(3); // qDebug("MPVProcess::parseLine: sub id: %d title: '%s' selected: %d", ID, title.toUtf8().constData(), selected); if (md.subs.find(SubData::Sub, ID) == -1) { md.subs.add(SubData::Sub, ID); md.subs.changeName(SubData::Sub, ID, title); } } else #endif #if !NOTIFY_VIDEO_CHANGES // Video if (rx_mpv_video.indexIn(line) > -1) { int ID = rx_mpv_video.cap(1).toInt(); QString title = rx_mpv_video.cap(4); // qDebug("MPVProcess::parseLine: video id: %d, name: '%s'", ID, title.toUtf8().constData()); //md.videos.addID(ID); md.videos.addName(ID, title); } else #endif #if NOTIFY_VIDEO_CHANGES || NOTIFY_AUDIO_CHANGES || NOTIFY_SUB_CHANGES // Track info if (rx_mpv_trackinfo.indexIn(line) > -1) { int ID = rx_mpv_trackinfo.cap(3).toInt(); QString type = rx_mpv_trackinfo.cap(2); QString name = rx_mpv_trackinfo.cap(5); QString lang = rx_mpv_trackinfo.cap(4); QString selected = rx_mpv_trackinfo.cap(6); // qDebug("MPVProcess::parseLine: ID: %d type: %s name: %s lang: %s selected: %s", ID, type.toUtf8().constData(), // name.toUtf8().constData(), lang.toUtf8().constData(), selected.toUtf8().constData()); /* if (lang == "(unavailable)") lang = ""; if (name == "(unavailable)") name = ""; */ if (type == "video") { #if NOTIFY_VIDEO_CHANGES int idx = videos.find(ID); if (idx == -1) { video_info_changed = true; videos.addName(ID, name); videos.addLang(ID, lang); } else { // Track already existed if (videos.itemAt(idx).name() != name) { video_info_changed = true; videos.addName(ID, name); } if (videos.itemAt(idx).lang() != lang) { video_info_changed = true; videos.addLang(ID, lang); } } #endif } else if (type == "audio") { #if NOTIFY_AUDIO_CHANGES updateAudioTrack(ID, name, lang); #endif } else if (type == "sub") { #if NOTIFY_SUB_CHANGES updateSubtitleTrack(ID, name, lang); #endif } } else #endif //#if DVDNAV_SUPPORT // if (rx_mpv_switch_title.indexIn(line) > -1) { // int title = rx_mpv_switch_title.cap(1).toInt(); // qDebug("MPVProcess::parseLine: title changed to %d", title); // // Ask for track info // // Wait 10 secs. because it can take a while until the title start to play // QTimer::singleShot(10000, this, SLOT(requestChapterInfo())); // } // else //#endif //Playing if (rx_mpv_playing.indexIn(line) > -1) { emit receivedPlaying(); } else if (rx_mpv_videocodec.indexIn(line) > -1) { md.video_codec = rx_mpv_videocodec.cap(2); // qDebug("MPVProcess::parseLine: md.video_codec '%s'", md.video_codec.toUtf8().constData()); } else if (rx_mpv_audiocodec.indexIn(line) > -1) { md.audio_codec = rx_mpv_audiocodec.cap(2); // qDebug("MPVProcess::parseLine: md.audio_codec '%s'", md.audio_codec.toUtf8().constData()); } else if (rx_mpv_forbidden.indexIn(line) > -1) { qDebug("MVPProcess::parseLine: 403 forbidden"); emit receivedForbiddenText(); } //Generic things if (rx_mpv_generic.indexIn(line) > -1) { tag = rx_mpv_generic.cap(1); value = rx_mpv_generic.cap(2); //qDebug("MPVProcess::parseLine: tag: %s", tag.toUtf8().constData()); //qDebug("MPVProcess::parseLine: value: %s", value.toUtf8().constData()); if (tag == "INFO_VIDEO_WIDTH") { md.video_width = value.toInt(); // qDebug("MPVProcess::parseLine: md.video_width set to %d", md.video_width); } else if (tag == "INFO_VIDEO_HEIGHT") { md.video_height = value.toInt(); // qDebug("MPVProcess::parseLine: md.video_height set to %d", md.video_height); } else if (tag == "INFO_VIDEO_ASPECT") { md.video_aspect = value.toDouble(); if ( md.video_aspect == 0.0 ) { // I hope width & height are already set. md.video_aspect = (double) md.video_width / md.video_height; } // qDebug("MPVProcess::parseLine: md.video_aspect set to %f", md.video_aspect); } if (tag == "INFO_VIDEO_BITRATE") { int bitrate = value.toInt(); emit receivedVideoBitrate(bitrate); } else if (tag == "INFO_LENGTH") { md.duration = value.toDouble(); // qDebug("MPVProcess::parseLine: md.duration set to %f", md.duration); } else if (tag == "INFO_DEMUXER") { md.demuxer = value; } else if (tag == "INFO_VIDEO_FORMAT") { md.video_format = value; } if (tag == "INFO_VIDEO_FPS") { md.video_fps = value; } else /* if (tag == "INFO_VIDEO_CODEC") { md.video_codec = value; } else if (tag == "INFO_AUDIO_CODEC") { md.audio_codec = value; } else */ if (tag == "INFO_AUDIO_BITRATE") { int bitrate = value.toInt(); emit receivedAudioBitrate(bitrate); } else if (tag == "INFO_AUDIO_RATE") { md.audio_rate = value.toInt(); } else if (tag == "INFO_AUDIO_NCH") { md.audio_nch = value.toInt(); } else if (tag == "INFO_AUDIO_FORMAT") { md.audio_format = value; } else if (tag == "INFO_CHAPTERS") { md.n_chapters = value.toInt(); // #ifdef TOO_CHAPTERS_WORKAROUND if (md.n_chapters > 1000) { qDebug("MPVProcess::parseLine: warning too many chapters: %d", md.n_chapters); qDebug(" chapters will be ignored"); md.n_chapters = 0; } // #endif // for (int n = 0; n < md.n_chapters; n++) { // qDebug() << "kobe call writeToStdin222"; // writeToStdin(QString("print_text INFO_CHAPTER_%1_NAME=${chapter-list/%1/title}").arg(n)); // } } else if (tag == "INFO_TITLES") { int n_titles = value.toInt(); for (int ID = 0; ID < n_titles; ID++) { md.titles.addName(ID, QString::number(ID+1)); } } else if (tag == "METADATA_TITLE") { if (!value.isEmpty()) md.clip_name = value; } else if (tag == "METADATA_ARTIST") { if (!value.isEmpty()) md.clip_artist = value; } else if (tag == "METADATA_DATE") { if (!value.isEmpty()) md.clip_date = value; } else if (tag == "METADATA_ALBUM") { if (!value.isEmpty()) md.clip_album = value; } else if (tag == "METADATA_COPYRIGHT") { if (!value.isEmpty()) md.clip_copyright = value; } else if (tag == "METADATA_TRACK") { if (!value.isEmpty()) md.clip_track = value; } else if (tag == "METADATA_GENRE") { if (!value.isEmpty()) md.clip_genre = value; } else if (tag == "INFO_MEDIA_TITLE") { if (!value.isEmpty() && value != "mp4" && !value.startsWith("mp4&") /*&& md.clip_name.isEmpty()*/) { md.clip_name = value; } } else if (tag == "MPV_VERSION") { mpv_version = value; //qDebug("MPVProcess::parseLine: mpv version: %s", mpv_version.toUtf8().constData()); } #if NOTIFY_VIDEO_CHANGES || NOTIFY_AUDIO_CHANGES || NOTIFY_SUB_CHANGES else if (tag == "INFO_TRACKS_COUNT") { int tracks = value.toInt(); for (int n = 0; n < tracks; n++) { // qDebug() << "kobe call writeToStdin333"; writeToStdin(QString("print_text \"INFO_TRACK_%1: " "${track-list/%1/type} " "${track-list/%1/id} " "'${track-list/%1/lang:}' " "'${track-list/%1/title:}' " "${track-list/%1/selected}\"").arg(n)); } } #endif } } } void MPVProcess::requestChapterInfo() { // qDebug() << "kobe call writeToStdin444"; writeToStdin("print_text \"INFO_CHAPTERS=${=chapters}\""); } void MPVProcess::requestBitrateInfo() { // qDebug() << "kobe call writeToStdin555"; writeToStdin("print_text INFO_VIDEO_BITRATE=${=video-bitrate}"); writeToStdin("print_text INFO_AUDIO_BITRATE=${=audio-bitrate}"); } #if NOTIFY_AUDIO_CHANGES void MPVProcess::updateAudioTrack(int ID, const QString & name, const QString & lang) { qDebug("MPVProcess::updateAudioTrack: ID: %d", ID); int idx = audios.find(ID); if (idx == -1) { audio_info_changed = true; audios.addName(ID, name); audios.addLang(ID, lang); } else { // Track already existed if (audios.itemAt(idx).name() != name) { audio_info_changed = true; audios.addName(ID, name); } if (audios.itemAt(idx).lang() != lang) { audio_info_changed = true; audios.addLang(ID, lang); } } } #endif #if NOTIFY_SUB_CHANGES void MPVProcess::updateSubtitleTrack(int ID, const QString & name, const QString & lang) { qDebug("MPVProcess::updateSubtitleTrack: ID: %d", ID); int idx = subs.find(SubData::Sub, ID); if (idx == -1) { subtitle_info_changed = true; subs.add(SubData::Sub, ID); subs.changeName(SubData::Sub, ID, name); subs.changeLang(SubData::Sub, ID, lang); } else { // Track already existed if (subs.itemAt(idx).name() != name) { subtitle_info_changed = true; subs.changeName(SubData::Sub, ID, name); } if (subs.itemAt(idx).lang() != lang) { subtitle_info_changed = true; subs.changeLang(SubData::Sub, ID, lang); } } } #endif // Called when the process is finished void MPVProcess::processFinished(int exitCode, QProcess::ExitStatus exitStatus) { qDebug("MPVProcess::processFinished: exitCode: %d, status: %d", exitCode, (int) exitStatus); // Send this signal before the endoffile one, otherwise // the playlist will start to play next file before all // objects are notified that the process has exited. emit processExited(); if (received_end_of_file) emit receivedEndOfFile(); } void MPVProcess::gotError(QProcess::ProcessError error) { qDebug("MPVProcess::gotError: %d", (int) error); } #include "mpvoptions.cpp" //#include "moc_mpvprocess.cpp" kylin-video/src/smplayer/reminderdialog.h0000664000175000017500000000252413233751662017526 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef REMINDERDIALOG_H #define REMINDERDIALOG_H #include "ui_reminderdialog.h" class QPushButton; class ReminderDialog : public QDialog, public Ui::ReminderDialog { Q_OBJECT public: enum Button { Donate = 1, Share = 2, Close = 0 }; ReminderDialog( QWidget* parent = 0, Qt::WindowFlags f = 0 ); ~ReminderDialog(); bool isRemindChecked(); protected slots: void button_clicked(QAbstractButton *); private: QPushButton * donate_button; QPushButton * facebook_button; QPushButton * close_button; }; #endif kylin-video/src/smplayer/desktopinfo.h0000664000175000017500000000220613233751662017063 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _DESKTOPINFO_H_ #define _DESKTOPINFO_H_ #include class QWidget; class DesktopInfo { public: static QSize desktop_size(QWidget *w); static double desktop_aspectRatio(QWidget *w); //! Returns true if the widget is inside the current screen static bool isInsideScreen(QWidget *w); }; #endif kylin-video/src/smplayer/images.cpp0000664000175000017500000000417513233751662016345 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "images.h" #include #include #include #include "global.h" #include "preferences.h" #include "paths.h" using namespace Global; QString Images::current_theme; QString Images::themes_path; QString Images::last_resource_loaded; bool Images::has_rcc = false; QString Images::resourceFilename() { QString filename = QString::null; if ((!themes_path.isEmpty()) && (!current_theme.isEmpty())) { filename = themes_path +"/"+ current_theme +"/"+ current_theme +".rcc"; } qDebug() << "Images::resourceFilename:" << filename; return filename; } QString Images::file(const QString & name) { QString icon_name; icon_name = ":/res/" + name + ".png"; return icon_name; } QPixmap Images::icon(QString name, int size) { QString icon_name = file(name); QPixmap p(icon_name); if (!p.isNull()) { if (size != -1) { p = resize(&p, size); } } return p; } QPixmap Images::resize(QPixmap *p, int size) { return QPixmap::fromImage( (*p).toImage().scaled(size,size,Qt::IgnoreAspectRatio,Qt::SmoothTransformation) ); } QPixmap Images::flip(QPixmap *p) { return QPixmap::fromImage( (*p).toImage().mirrored(true, false) ); } QPixmap Images::flippedIcon(QString name, int size) { QPixmap p = icon(name, size); p = flip(&p); return p; } kylin-video/src/smplayer/prefwidget.h0000664000175000017500000000354413233751662016704 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _PREFWIDGET_H_ #define _PREFWIDGET_H_ #include #include #include #define TEST_AND_SET( Pref, Dialog ) \ if ( Pref != Dialog ) { Pref = Dialog; requires_restart = true; } class QEvent; class PrefWidget : public QWidget { public: PrefWidget(QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~PrefWidget(); // Return the name of the section virtual QString sectionName(); virtual QPixmap sectionIcon(); // Return true if the changes made require to restart the mplayer // process. Should be call just after the changes have been applied. virtual bool requiresRestart() { return requires_restart; }; virtual QString help() { return help_message; }; protected: virtual void retranslateStrings(); virtual void changeEvent ( QEvent * event ) ; // Help void addSectionTitle(const QString & title); void setWhatsThis( QWidget *w, const QString & title, const QString & text); void clearHelp(); virtual void createHelp(); bool requires_restart; private: QString help_message; }; #endif kylin-video/src/smplayer/version.cpp0000664000175000017500000000223013247436775016565 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "version.h" #include #define USE_SVN_VERSIONS 0 //#define VERSION "1.1.2" QString Version::printable() { //return QString(VERSION); return QString(qApp->applicationVersion()); } QString Version::stable() { //return QString(VERSION); return QString(qApp->applicationVersion()); } kylin-video/src/smplayer/paths.cpp0000664000175000017500000000353113233751662016212 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "paths.h" #include #include #include #include #include #include QString Paths::app_path; QString Paths::config_path; void Paths::setAppPath(QString path) { app_path = path; } QString Paths::appPath() { return app_path; } QString Paths::translationPath() { QString path; if (QDir("/usr/share/kylin-video/translations").exists()) { path = "/usr/share/kylin-video/translations"; return path; } else { return appPath() + "/translations"; } } QString Paths::shortcutsPath() { return appPath() + "/shortcuts"; } QString Paths::qtTranslationPath() { return QLibraryInfo::location(QLibraryInfo::TranslationsPath); } void Paths::setConfigPath(QString path) { config_path = path; } QString Paths::configPath() { //kobe if (!config_path.isEmpty()) { return config_path; } else { return QDir::homePath() + "/.config/kylin-video"; } } QString Paths::iniPath() { return configPath(); } kylin-video/src/smplayer/mpvprocess.h0000664000175000017500000001177213233751662016747 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef MPVPROCESS_H #define MPVPROCESS_H #include #include "playerprocess.h" #include "config.h" class QStringList; class MPVProcess : public PlayerProcess { Q_OBJECT public: MPVProcess(QObject * parent = 0); ~MPVProcess(); bool start(); // Command line options // void addArgument(const QString & a);//kobe 20170705 void setMedia(const QString & media, bool is_playlist = false); void disableInput(); void setFixedOptions(); void setOption(const QString & option_name, const QVariant & value = QVariant()); void addUserOption(const QString & option); void addVF(const QString & filter_name, const QVariant & value = QVariant()); void addAF(const QString & filter_name, const QVariant & value = QVariant()); void addStereo3DFilter(const QString & in, const QString & out); // void setSubStyles(const AssStyles & styles, const QString & assStylesFile = QString::null); // Slave commands void quit(); void setVolume(int v); void setOSD(int o); void setAudio(int ID); void setVideo(int ID); void setSubtitle(int type, int ID); void disableSubtitles(); void setSecondarySubtitle(int ID); void disableSecondarySubtitles(); void setSubtitlesVisibility(bool b); void seek(double secs, int mode, bool precise); void mute(bool b); void setPause(bool b); void frameStep(); void frameBackStep(); void showOSDText(const QString & text, int duration, int level); void showFilenameOnOSD(); void showTimeOnOSD(); void setContrast(int value); void setBrightness(int value); void setHue(int value); void setSaturation(int value); void setGamma(int value); void setChapter(int ID); void setExternalSubtitleFile(const QString & filename); void setSubPos(int pos); void setSubScale(double value); void setSubStep(int value); // void seekSub(int value);//kobe 20170705 void setSubForcedOnly(bool b); void setSpeed(double value); //#ifdef MPLAYER_SUPPORT void enableKaraoke(bool b); void enableExtrastereo(bool b); //#endif void enableVolnorm(bool b, const QString & option); void setAudioEqualizer(const QString & values); void setAudioDelay(double delay); void setSubDelay(double delay); void setLoop(int v); void takeScreenshot(ScreenshotType t, bool include_subtitles = false); //#ifdef CAPTURE_STREAM // void switchCapturing(); //#endif void setTitle(int ID); void changeVF(const QString & filter, bool enable, const QVariant & option = QVariant()); void changeStereo3DFilter(bool enable, const QString & in, const QString & out); //#if DVDNAV_SUPPORT // void discSetMousePos(int x, int y); // void discButtonPressed(const QString & button_name); //#endif void setAspect(double aspect); void setFullscreen(bool b); //#if PROGRAM_SWITCH // void setTSProgram(int ID); //#endif void toggleDeinterlace(); void askForLength(); void setOSDScale(double value); void setChannelsFile(const QString &); QString mpvVersion() { return mpv_version; }; protected: bool isOptionAvailable(const QString & option); void addVFIfAvailable(const QString & vf, const QString & value = QString::null); void messageFilterNotSupported(const QString & filter_name); protected slots: void parseLine(QByteArray ba); void processFinished(int exitCode, QProcess::ExitStatus exitStatus); void gotError(QProcess::ProcessError); void requestChapterInfo(); void requestBitrateInfo(); signals: void receivedScreenshot(QString);//20170722 protected: #if NOTIFY_AUDIO_CHANGES void updateAudioTrack(int ID, const QString & name, const QString & lang); #endif #if NOTIFY_SUB_CHANGES void updateSubtitleTrack(int ID, const QString & name, const QString & lang); #endif private: bool notified_mplayer_is_running; bool notified_pause; bool received_end_of_file; int last_sub_id; int mplayer_svn; QString mpv_version; bool verbose; #if NOTIFY_SUB_CHANGES SubTracks subs; bool subtitle_info_received; bool subtitle_info_changed; #endif #if NOTIFY_AUDIO_CHANGES Tracks audios; bool audio_info_changed; #endif #if NOTIFY_VIDEO_CHANGES Tracks videos; bool video_info_changed; #endif //#if NOTIFY_CHAPTER_CHANGES // Chapters chapters; // bool chapter_info_changed; //#endif int dvd_current_title; int br_current_title; QString previous_eq; //#ifdef CAPTURE_STREAM // bool capturing; //#endif }; #endif kylin-video/src/smplayer/reminderdialog.cpp0000664000175000017500000000442413233751662020062 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "reminderdialog.h" #include "images.h" #include ReminderDialog::ReminderDialog( QWidget* parent, Qt::WindowFlags f ) : QDialog(parent, f) { setupUi(this); setMinimumSize(QSize(500, 100)); icon_label->setPixmap(Images::icon("donate_big")); text_label->setText( tr("If you like SMPlayer and want to support its development, you can send a donation. " "Even the smallest one is highly appreciated.") + "

"+ tr("Or you maybe you want to share SMPlayer with your friends in Facebook.") + "

" + tr("What would you like to do?") ); donate_button = buttonBox->addButton(tr("&Donate"), QDialogButtonBox::ActionRole); facebook_button = buttonBox->addButton(tr("&Share with my friends"), QDialogButtonBox::ActionRole); close_button = buttonBox->button(QDialogButtonBox::Close); donate_button->setDefault(true); donate_button->setFocus(); adjustSize(); //layout()->setSizeConstraint(QLayout::SetFixedSize); connect(buttonBox, SIGNAL(clicked(QAbstractButton *)), this, SLOT(button_clicked(QAbstractButton *))); } ReminderDialog::~ReminderDialog() { } void ReminderDialog::button_clicked(QAbstractButton * button) { int res = Close; if (button == donate_button) res = Donate; else if (button == facebook_button) res = Share; qDebug("ReminderDialog::button_clicked: res: %d", res); done(res); } bool ReminderDialog::isRemindChecked() { return remind_check->isChecked(); } #include "moc_reminderdialog.cpp" kylin-video/src/smplayer/screensaver.cpp0000664000175000017500000000743213233751662017417 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 #include #include "screensaver.h" #ifndef Q_OS_OS2 #include #endif WinScreenSaver::WinScreenSaver() { #ifndef Q_OS_OS2 lowpower = poweroff = screensaver = 0; #else SSaver = new QLibrary("SSCORE"); SSaver->load(); SSCore_TempDisable = SSCore_TempEnable = NULL; if (SSaver->isLoaded()) { SSCore_TempDisable = (FuncPtr) SSaver->resolve("SSCore_TempDisable"); SSCore_TempEnable = (FuncPtr) SSaver->resolve("SSCore_TempEnable"); } #endif state_saved = false; modified = false; retrieveState(); } WinScreenSaver::~WinScreenSaver() { restoreState(); #ifdef Q_OS_OS2 unload(); #endif } void WinScreenSaver::retrieveState() { qDebug("WinScreenSaver::retrieveState"); if (!state_saved) { #ifndef Q_OS_OS2 if (QSysInfo::WindowsVersion < QSysInfo::WV_VISTA) { // Not supported on Windows Vista SystemParametersInfo(SPI_GETLOWPOWERTIMEOUT, 0, &lowpower, 0); SystemParametersInfo(SPI_GETPOWEROFFTIMEOUT, 0, &poweroff, 0); } SystemParametersInfo(SPI_GETSCREENSAVETIMEOUT, 0, &screensaver, 0); state_saved = true; qDebug("WinScreenSaver::retrieveState: lowpower: %d, poweroff: %d, screensaver: %d", lowpower, poweroff, screensaver); #else state_saved = true; qDebug("WinScreensaver::retrieveState: init done %s", SSCore_TempDisable ?"succesfully":"failed"); #endif } else { qDebug("WinScreenSaver::retrieveState: state already saved previously, doing nothing"); } } void WinScreenSaver::restoreState() { if (!modified) { qDebug("WinScreenSaver::restoreState: state did not change, doing nothing"); return; } if (state_saved) { #ifndef Q_OS_OS2 if (QSysInfo::WindowsVersion < QSysInfo::WV_VISTA) { // Not supported on Windows Vista SystemParametersInfo(SPI_SETLOWPOWERTIMEOUT, lowpower, NULL, 0); SystemParametersInfo(SPI_SETPOWEROFFTIMEOUT, poweroff, NULL, 0); } SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, screensaver, NULL, 0); SetThreadExecutionState(ES_CONTINUOUS); qDebug("WinScreenSaver::restoreState: lowpower: %d, poweroff: %d, screensaver: %d", lowpower, poweroff, screensaver); #else if (SSCore_TempEnable) { SSCore_TempEnable(); } qDebug("WinScreenSaver::restoreState done"); #endif } else { qWarning("WinScreenSaver::restoreState: no data, doing nothing"); } } #ifdef Q_OS_OS2 void WinScreenSaver::unload() { if (SSaver->isLoaded()) { SSaver->unload(); delete SSaver; } } #endif void WinScreenSaver::disable() { qDebug("WinScreenSaver::disable"); #ifndef Q_OS_OS2 if (QSysInfo::WindowsVersion < QSysInfo::WV_VISTA) { // Not supported on Windows Vista SystemParametersInfo(SPI_SETLOWPOWERTIMEOUT, 0, NULL, 0); SystemParametersInfo(SPI_SETPOWEROFFTIMEOUT, 0, NULL, 0); } SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, 0, NULL, 0); SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED); #else if (SSCore_TempDisable) { SSCore_TempDisable(); } #endif modified = true; } void WinScreenSaver::enable() { qDebug("WinScreenSaver::enable"); restoreState(); } kylin-video/src/smplayer/mediadata.h0000664000175000017500000000452013233751662016450 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _MEDIADATA_H_ #define _MEDIADATA_H_ /* Here we store some volatile info about the file we need to remember */ #include "tracks.h" #include "subtracks.h" #include "titletracks.h" #include "config.h" #include #include // Types of media #define TYPE_UNKNOWN -1 #define TYPE_FILE 0 #define TYPE_DVD 1 #define TYPE_STREAM 2 #define TYPE_VCD 3 #define TYPE_AUDIO_CD 4 #define TYPE_TV 5 class MediaData { public: MediaData(); virtual ~MediaData(); virtual void reset(); QString filename; double duration; //Resolution of the video int video_width; int video_height; double video_aspect; int type; // file, dvd... QString dvd_id; bool novideo; // Only audio bool initialized; void list(); //#if PROGRAM_SWITCH // Tracks programs; //#endif Tracks videos; Tracks audios; TitleTracks titles; // for DVDs SubTracks subs; int n_chapters; // Clip info QString clip_name; QString clip_artist; QString clip_author; QString clip_album; QString clip_genre; QString clip_date; QString clip_track; QString clip_copyright; QString clip_comment; QString clip_software; QString stream_title; QString stream_url; // Other data not really useful for us, // just to show info to the user. QString demuxer; QString video_format; QString audio_format; int video_bitrate; QString video_fps; int audio_bitrate; int audio_rate; int audio_nch; // channels? QString video_codec; QString audio_codec; /*QString info();*/ QString displayName(bool show_tag = true); }; #endif kylin-video/src/smplayer/filedialog.h0000664000175000017500000000413613233751662016641 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _FILEDIALOG_H #define _FILEDIALOG_H #include #include #include class QWidget; class MyFileDialog { public: static QString getOpenFileName( QWidget * parent = 0, const QString & caption = QString(), const QString & dir = QString(), const QString & filter = QString(), QString * selectedFilter = 0, QFileDialog::Options options = QFileDialog::DontResolveSymlinks ) ; static QString getExistingDirectory ( QWidget * parent = 0, const QString & caption = QString(), const QString & dir = QString(), QFileDialog::Options options = QFileDialog::ShowDirsOnly ); static QString getSaveFileName ( QWidget * parent = 0, const QString & caption = QString(), const QString & dir = QString(), const QString & filter = QString(), QString * selectedFilter = 0, QFileDialog::Options options = QFileDialog::DontResolveSymlinks | QFileDialog::DontConfirmOverwrite ); static QStringList getOpenFileNames ( QWidget * parent = 0, const QString & caption = QString(), const QString & dir = QString(), const QString & filter = QString(), QString * selectedFilter = 0, QFileDialog::Options options = QFileDialog::DontResolveSymlinks ); }; #endif kylin-video/src/smplayer/main.cpp0000664000175000017500000000352313247436775016032 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "myapplication.h" #include "kylinvideo.h" #include #include #include int main( int argc, char ** argv ) { MyApplication a("kylin-video", argc, argv ); a.setQuitOnLastWindowClosed(false); a.setOrganizationName("kylin"); a.setApplicationName("kylin-video"); a.setApplicationVersion("1.1.4"); #if QT_VERSION >= 0x040400 // Enable icons in menus QCoreApplication::setAttribute(Qt::AA_DontShowIconsInMenus, false); #endif QStringList args = a.arguments(); QFile qss(":/qss/res/style.qss"); qss.open(QFile::ReadOnly); qApp->setStyleSheet(qss.readAll()); qss.close(); QString arch = ""; #ifdef __x86_64__ arch = "x86_64"; #elif __i386__ arch = "i386"; #elif __aarch64__ arch = "aarch64"; #endif KylinVideo *player = new KylinVideo(arch); KylinVideo::ExitCode c = player->processArgs(args); if (c != KylinVideo::NoExit) { return c; } player->start(); int r = a.exec(); delete player; return r; } kylin-video/src/smplayer/titletracks.cpp0000664000175000017500000000415213233751662017424 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 "titletracks.h" TitleTracks::TitleTracks() { clear(); } TitleTracks::~TitleTracks() { } void TitleTracks::clear() { tm.clear(); } void TitleTracks::addName(int ID, QString name) { tm[ID].setName(name); tm[ID].setID(ID); } void TitleTracks::addDuration(int ID, double duration) { tm[ID].setDuration(duration); tm[ID].setID(ID); } void TitleTracks::addChapters(int ID, int n) { tm[ID].setChapters(n); tm[ID].setID(ID); } void TitleTracks::addAngles(int ID, int n) { tm[ID].setAngles(n); tm[ID].setID(ID); } void TitleTracks::addID(int ID) { tm[ID].setID(ID); } int TitleTracks::numItems() { return tm.count(); } bool TitleTracks::existsItemAt(int n) { return ((n > 0) && (n < numItems())); } TitleData TitleTracks::itemAt(int n) { return tm.values()[n]; } TitleData TitleTracks::item(int ID) { return tm[ID]; } int TitleTracks::find(int ID) { for (int n=0; n < numItems(); n++) { if (itemAt(n).ID() == ID) return n; } return -1; } void TitleTracks::list() { QMapIterator i(tm); while (i.hasNext()) { i.next(); TitleData d = i.value(); qDebug("TitleTracks::list: item %d: ID: %d name: '%s' duration %f chapters: %d angles: %d", i.key(), d.ID(), d.name().toUtf8().constData(), d.duration(), d.chapters(), d.angles() ); } } kylin-video/src/smplayer/recents.h0000664000175000017500000000260413233751662016203 0ustar fengfeng/* smplayer, GUI front-end for mplayer. Copyright (C) 2006-2015 Ricardo Villalba 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 */ #ifndef _RECENTS_H_ #define _RECENTS_H_ #include class Recents { public: Recents(); virtual ~Recents(); virtual void clear(); virtual void addItem(QString s); virtual void addItem(QString s, QString title); virtual QString item(int n); virtual QString title(int n); virtual int count(); virtual void setMaxItems(int n_items); virtual int maxItems() { return max_items; }; virtual void fromStringList(QStringList list); virtual QStringList toStringList(); virtual void list(); protected: int max_items; QStringList l; }; #endif kylin-video/src/translations/0000775000175000017500000000000013261115402015235 5ustar fengfengkylin-video/src/translations/kylin-video_zh_CN.ts0000664000175000017500000143531613227635337021155 0ustar fengfeng AboutDialog Kylin Video is a graphical interface for MPlayer and MPV. 麒麟影音是MPlayer和MPV的图形化前端。 Kylin Video is developed on the basis of SMPlayer, is a graphical interface for MPlayer and MPV. 麒麟影音基于SMPlayer进行开发,是MPlayer和MPV的图形化前端。 Version: %1 版本: %1 Kylin Video 麒麟影音 Playback engine: 播放引擎: Links: 链接: Official website: 官方网站: Support forum: 支持论坛: Kylin Video is a graphical interface for %1. 麒麟影音是 %1 的图形化前端 Click here to know the translators from the transifex teams 点击这里查看 transifex 翻译团队的成员 Many people contributed with translations. 许多人贡献了翻译。 You can also help to translate SMPlayer into your own language. 你也可以帮助翻译视频播放器 Visit %1 and join a translation team. 访问 %1 并加入翻译团队 Using %1 使用 %1 SMPlayer is a graphical interface for %1 and %2. 视频播放器是 %1 和 %2 的图形化前端 Subtitles service powered by %1 字幕服务由 %1 提供 <b>%1</b> (%2) <b>%1</b> (%2) About SMPlayer 关于视频播放器 About Kylin Video 关于 麒麟影音 Page 佩奇 &Info 信息(&I) icon 图标 &Contributions 贡献(&C) &Translators 翻译(&T) &License 许可证(&L) Portable Edition 便携版 Using Qt %1 (compiled with Qt %2) 正在使用 Qt %1 (用 Qt %2 编译) SMPlayer logo by %1 视频播放器标志由 %1 设计 Read the entire license 阅读整个许可证 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. 这是自由软件,你可以在自由软件基金会发布的GNU通用公共许可证的诸条款之下,重新发布和(或者)修改它。许可证为第二版或者任何之后的版本。 Read a translation 阅读翻译 OK 确定 Kylin Video logo by %1 麒麟影音标志由 %1 设计 Packages for Windows created by %1 适用于 Windows 的软件包由 %1 创建 Many other people contributed with patches. See the Changelog for details. 还有许多人贡献了补丁。有关详细信息,请参阅变更日志(Changelog)。 You can also help to translate Kylin Video into your own language. 你也可以帮助翻译麒麟影音。 About 关于 Contributor 贡献者 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> ActionsEditor Name 名称 Description 描述 Shortcut 快捷键 &Save 保存(&S) &Load 加载(&L) Key files 键文件 Choose a filename 选择一个文件名 Confirm overwrite? 确认是否覆盖? The file %1 already exists. Do you want to overwrite? 文件 %1 已存在。 您想要覆盖吗? Choose a file 选择一个文件 Error 错误 The file couldn't be saved 无法保存该文件 The file couldn't be loaded 无法加载该文件 &Change shortcut... 更改快捷键(&C)... AudioDelayDialog Audio delay 音频延迟 OK 确定 Cancel 取消 Audio delay (in milliseconds): 音频延迟(毫秒): AudioEqualizer Audio Equalizer 音频均衡器 %1 Hz %1 Hz %1 kHz %1 kHz &Preset 当前(&P) &Apply 应用(&A) &Reset 重置(&R) &Set as default values 设置为默认值(&S) Flat 平坦 Classical 古典 Club 俱乐部 Dance 舞曲 Full bass 重低音 Full bass and treble 超重低音 Full treble 超高音 Headphones 耳机 Large hall 大厅 Live 现场 Party 派对 Pop 流行 Reggae 雷盖舞曲 Rock 摇滚 Ska 斯卡 Soft 轻柔 Soft rock 轻摇滚 Techno 电子舞曲 Custom 自定义 Use the current values as default values for new videos. 使用当前的值作为新视频的默认值。 Set all controls to zero. 将所有的控制都设置为零。 Information 信息 The current values have been stored to be used as default. 当前的值已被储存作为默认值使用。 BaseGui &Open 打开(&O) SMPlayer 视频播放器 - SMPlayer - 视频播放器 &Play 播放(&P) &Video 视频(&V) &Audio 音频(&A) &Subtitles 字幕(&S) &Browse 浏览(&B) Op&tions 选项(&T) &Help 帮助(&H) &File... 文件(&F)... D&irectory... 目录(&i)... &Playlist... 播放列表(&P)... &DVD from drive DVD 驱动器(&D) D&VD from folder... DVD 文件夹(&V)... &URL... 网址(&U)... &Clear 清除(&C) &Recent files 最近的文件(&R) P&lay 播放(&L) &Pause 暂停(&P) &Stop 停止(&S) &Frame step 逐帧步进(&F) &Normal speed 正常速度(&N) &Double speed 双倍速度(&D) Speed &-10% 速度-10%(&-) Speed &+10% 速度+10%(&+) &Off closed captions menu 关(&O) Sp&eed 速度(&E) &Repeat 重复(&R) &Fullscreen 全屏(&F) &Compact mode 简洁模式(&C) Si&ze 大小(&Z) &Aspect ratio 宽高比(&A) &None 无(&N) &Lowpass5 Lowpass5(&L) Linear &Blend 线性混合(&B) &Deinterlace 去交错(&D) &Postprocessing 后期处理(&P) &Autodetect phase 自动检测相位(&A) &Deblock 去块(&D) De&ring 去环(&R) Add n&oise 增噪(&O) F&ilters 过滤器(&I) &Equalizer 均衡器(&E) &Screenshot 屏幕截图(&S) S&tay on top 置顶(&T) &Extrastereo 附加立体声(&E) &Karaoke 卡拉 OK(&K) &Filters 过滤器(&F) &Stereo 立体声(&S) &4.0 Surround 4.0 环绕声(&4) &5.1 Surround 5.1 环绕声(&5) &Channels 声道(&C) &Left channel 左声道(&L) &Right channel 右声道(&R) &Stereo mode 立体声模式(&S) &Mute 静音(&M) Volume &- 音量 &- Volume &+ 音量 &+ &Delay - 延迟-(&D) D&elay + 延迟+(&E) &Select 选择(&S) &Load... 加载(&L)... Delay &- 延迟 &- Delay &+ 延迟 &+ &Up 向上(&U) &Down 向下(&D) &Title 标题(&T) &Chapter 章节(&C) &Angle 角度(&A) &Playlist 播放列表(&P) &Disabled 禁用(&D) &OSD 屏幕显示(&O) &View logs 查看日志(&V) P&references 首选项(&R) About &SMPlayer 关于视频播放器(&S) <empty> <空> Confirm deletion - Kylin Video 确认删除 - 麒麟影音 Video 视频 Audio 音频 Open 打开 Open &File... 打开文件(&F)... Play control 播放控制 Forward and rewind 快进快退 Play Speed 播放速度 Playlists 播放列表 All files 所有文件 Choose a file 选择一个文件 &YouTube%1 browser YouTube%1 浏览器(&Y) &Donate / Share with your friends 捐赠 / 分享给您的朋友 (&D) SMPlayer - Information 视频播放器 - 信息 The CDROM / DVD drives are not configured yet. The configuration dialog will be shown now, so you can do it. CDROM/DVD 驱动器尚未配置。 现在将显示配置对话框,以便您可以配置它。 Select the Blu-ray folder 选择Blu-ray文件夹 Choose a directory 选择一个目录 Subtitles 字幕 Kylin Video - Seek 麒麟影音 - 定位 Kylin Video - Audio delay 麒麟影音 - 音频延迟 Kylin Video - Subtitle delay 麒麟影音 - 字幕延迟 Error detected 检测到错误 Unfortunately this video can't be played. 抱歉此视频不能播放 Playing %1 正在播放 %1 Pause 暂停 Stop 停止 Play / Pause 播放/暂停 Pause / Frame step 暂停/逐帧步进 U&nload 卸载外部文件(&N) V&CD VCD(&C) C&lose 关闭(&L) View &info and properties... 媒体信息(&I)... Zoom &- 缩放 &- Kylin Video 麒麟影音 Directory... 目录... Recent files 最近的文件 Play 播放 Speed 速度 Normal speed 正常速度 Half speed 半速 Double speed 双倍速度 Speed -10% 速度-10% Speed +10% 速度+10% Speed -4% 速度-4% Speed +4% 速度+4% Speed -1% 速度-1% Speed +1% 速度+1% Next 下一个 Previous 上一个 Frame rotation 画面旋转 Shortcuts 快捷键 Order play 顺序播放 Random play 随机播放 List loop play 列表循环播放 Play order 播放顺序 Help 帮助 The screenshot folder does not exist! 截图文件夹不存在! Zoom &+ 缩放 &+ &Reset 重置(&R) Move &left 向左移动(&L) Move &right 向右移动(&R) Move &up 向上移动(&U) Move &down 向下移动(&d) Zoom 缩放 Aspect ratio 画面比例 Postprocessing 后期处理质量 Autodetect phase 自动检测相位 Deblock 去块 Dering 去环 Debanding (gradfun) 去带(Gradfun) Add noise 增噪 Add black borders 添加黑边 Software scaling 软件缩放 Filters 过滤器 Denoise 降噪 Blur/Sharp 模糊/锐化 Volume - 音量 - Volume + 音量 + Delay - 延迟 - Delay + 延迟 + Load... 加载... Preferences 设置 About &Kylin Video 关于 麒麟影音 Quit 退出 &Previous line in subtitles 上一行字幕(&P) N&ext line in subtitles 下一行字幕(&e) %1 log %1 日志 SMPlayer log 视频播放器日志 -%1 -%1 +%1 +%1 Dec volume (2) 降低音量(2) &Blu-ray from drive 从驱动器播放 &Blu-ray (&B) Blu-&ray from folder... 从文件夹播放 Blu-ray(&B)... Fra&me back step 返回上一帧(&m) &Half speed 半速(&H) Thumb&nail Generator... 缩略图生成器…(&n) Stereo &3D filter Stereo &3D 滤镜 Debanding (&gradfun) 去带(Gradfun)(&g) Seek to next subtitle 使用下个字幕 Seek to previous subtitle 使用上个字幕 Use custo&m style 使用自定义风格 (&m) Find subtitles at &OpenSubtitles.org... 在 OpenSubtitles.org 上查找字幕(&O)... &Default subfps menu 默认(&D) First Steps &Guide 第一步指南(&G) Update &Youtube code 更新Youtube代码(&Y) &Open configuration folder 打开配置文件夹(&O) Size &+ 大小 &+ Size &- 大小 &- Inc volume (2) 增加音量(2) Exit fullscreen 退出全屏 OSD - Next level 屏幕显示 - 下一层 Dec contrast 降低对比度 Inc contrast 增加对比度 Dec brightness 降低亮度 Inc brightness 增加亮度 Dec hue 降低色调 Inc hue 增加色调 Dec saturation 降低饱和度 Dec gamma 降低伽玛 Next audio 下一个音轨 Next subtitle 下一个字幕 Next chapter 下一个章节 Previous chapter 上一个章节 Show playback time on OSD 在 OSD 上显示播放时间 De&noise 降噪(&n) Blur/S&harp 模糊/锐化(&h) &Off denoise menu 关(&O) &Normal denoise menu 标准(&N) &Soft denoise menu 柔和(&S) &None unsharp menu 无(&N) &Blur unsharp menu 模糊(&B) &Sharpen unsharp menu 锐化(&S) &6.1 Surround 6.1 环绕声(&6) &7.1 Surround 7.1 环绕声(&7) &Mono 单声道(&M) Re&verse 反相(&v) Secondary trac&k 第二轨道(&k) F&rames per second 每秒帧数(&R) Connection failed 连接失败 The video you requested needs to open a HTTPS connection. 您请求的视频需要使用HTTPS连接。 Unfortunately the OpenSSL component, required for it, is not available in your system. 很不幸,此功能需要openssl组件,而您的系统中没有。 Please, visit %1 to know how to fix this problem. 请访问 %1 查看如何解决此问题。 this link 此链接 Unfortunately due to changes in the Youtube page, this video can't be played. 抱歉因 Youtube页面的变化,此视频不能播放 Problems with Youtube Youtube的问题 %1 Error %1 错误 %1 was not found! %1 没有被找到! %1 has finished unexpectedly. %1 已意外结束。 %1 failed to start. %1 启动失败。 Please check the %1 path in preferences. 请检查首选项中的 %1 路径。 %1 has crashed. %1 已崩溃。 The YouTube Browser is not installed. YouTube 浏览器未安装。 Visit %1 to get it. 请访问 %1 获取。 Unfortunately due to changes in the Youtube page, the video '%1' can't be played. 抱歉因 Youtube变化,视频 '%1' 不能播放 Do you want to update the Youtube code? This may fix the problem. 你想更新Youtube代码吗?这样或许能解决问题。 Maybe updating SMPlayer could fix the problem. 或许更新视频播放器能解决这问题。 S&hare SMPlayer with your friends 和朋友分享视频播放器(&h) Information 信息 You need to restart SMPlayer to use the new GUI. 您需要重新启动视频播放器以使用新的 GUI。 Confirm deletion - SMPlayer 确认删除 - 视频播放器 Delete the list of recent files? 要删除最近的文件列表吗? The current values have been stored to be used as default. 当前的值已被储存作为默认值使用。 Inc saturation 增加饱和度 Inc gamma 增加伽玛 &Load external file... 加载外部文件(&L)... &Kerndeint Kerndeint(&K) &Yadif (normal) Yadif (标准)(&Y) Y&adif (double framerate) Yadif (双倍帧率)(&A) &Next 下一个(&N) Pre&vious 上一个(&V) Volume &normalization 音量标准化(&N) &Audio CD 音频 CD(&A) &Toggle double size 切换双倍大小(&T) S&ize - 大小-(&I) Si&ze + 大小+(&Z) Add &black borders 添加黑边(&B) Soft&ware scaling 软件缩放(&W) &FAQ FAQ(&F) &Command line options 命令行选项(&C) SMPlayer command line options 视频播放器命令行选项 &Forced subtitles only 仅强制字幕(&F) Reset video equalizer 重置视频均衡器 The server returned '%1' 服务器返回'%1' '%1' was not found! '%1' 没有被找到! Exit code: %1 退出代码: %1 See the log for more info. 更多信息请参阅日志。 &Rotate 旋转(&R) &Off 关(&O) &Rotate by 90 degrees clockwise and flip 顺时针旋转90度并翻转(&R) Rotate by 90 degrees &clockwise 顺时针旋转90度(&C) Rotate by 90 degrees counterclock&wise 逆时针旋转90度(&W) Rotate by 90 degrees counterclockwise and &flip 逆时针旋转90度并翻转(&F) &Jump to... 跳转到(&J)... Show context menu 显示上下文菜单 Multimedia 多媒体 E&qualizer 均衡器(&Q) Reset audio equalizer 重置音频均衡器 Upload su&btitles to OpenSubtitles.org... 上传字幕到 OpenSubtitles.org(&B)... &Auto 自动(&A) Speed -&4% 速度-4%(&4) &Speed +4% 速度+4%(&S) Speed -&1% 速度-1%(&1) S&peed +1% 速度+1%(&P) Scree&n 屏幕(&N) &Default 默认(&D) Mirr&or image 镜像图像(&O) Next video 下一个视轨 &Track video 视轨(&T) &Track audio 音轨(&T) Warning - Using old MPlayer 警告 - 正在使用过时的 MPlayer The version of MPlayer (%1) installed on your system is obsolete. SMPlayer can't work well with it: some options won't work, subtitle selection may fail... 您的系统上安装的 MPlayer(%1)版本已过时。视频播放器无法正常运行它: 有些选项无法正常工作,字幕选择可能会失效... Please, update your MPlayer. 请更新您的 MPlayer。 (This warning won't be displayed anymore) (此警告将不再显示) Next aspect ratio 下一个纵横比 &Auto zoom 自动缩放(&A) Zoom for &16:9 缩放为 16:9(&1) Zoom for &2.35:1 缩放为 2.35:1(&2) &Always 始终(&A) &Never 从不(&N) While &playing 当播放时(&P) DVD &menu DVD 菜单(&M) DVD &previous menu 上一级 DVD 菜单(&P) DVD menu, move up DVD 菜单,上移 DVD menu, move down DVD 菜单,下移 DVD menu, move left DVD 菜单,左移 DVD menu, move right DVD 菜单,右移 DVD menu, select option DVD 菜单,选择选项 DVD menu, mouse click DVD 菜单,鼠标单击 Set dela&y... 设置延迟(&Y)... Se&t delay... 设置延迟(&T)... &Jump to: 跳转到(&J): SMPlayer - Seek 视频播放器 - 定位 SMPlayer - Audio delay 视频播放器 - 音频延迟 Audio delay (in milliseconds): 音频延迟(毫秒): SMPlayer - Subtitle delay 视频播放器 - 字幕延迟 Subtitle delay (in milliseconds): 字幕延迟(毫秒): Toggle stay on top 切换保持在最前端 Jump to %1 跳转到 %1 Start/stop takin&g screenshots 开始/停止屏幕截图(&G) Subtitle &visibility 字幕可见性(&V) Next wheel function 下一个滚轮功能 P&rogram program 程序(&R) &TV 电视(&T) Radi&o 广播(&O) Subtitles onl&y 仅字幕(&Y) Volume + &Seek 音量+定位(&S) Volume + Seek + &Timer 音量+定位+计时器(&T) Volume + Seek + Timer + T&otal time 音量+定位+计时器+总时间(&O) Video filters are disabled when using vdpau 使用 VDPAU 时将禁用视频过滤器 Fli&p image 翻转图像(&P) Zoo&m 缩放(&M) Show filename on OSD 在"屏幕显示"上显示文件名 Set &A marker 设置 A 标记(&A) Set &B marker 设置 B 标记(&B) &Clear A-B markers 清除 A-B 标记(&C) &A-B section A-B 区间(&A) Toggle deinterlacing 切换去交错 &Closed captions 闭路字幕(&C) &Disc 光盘(&D) F&avorites 收藏夹(&A) Check for &updates 检查更新(&U) BaseGuiPlus SMPlayer is still running here 视频播放器仍在运行 S&how icon in system tray 在系统托盘上显示图标(&H) &Hide 隐藏(&H) &Restore 还原(&R) &Quit 退出(&Q) Playlist 播放列表 BookmarkDialog Name 名称 BottomWidget Previous 上一个 Next 下一个 Play/Pause 播放/暂停 FullScreen 全屏 Open 打开 Playlist 播放列表 Stop 停止 Prev 上一个 Play / Pause 播放/暂停 Mute 静音 Open File 打开文件 Play List 播放列表 CodeDownloader Downloading... 下载中… Connecting to %1 正在连接到 1% The Youtube code has been updated successfully. Youtube代码已成功更新 Installed version: %1 已安装版本: %1 Success Success Error Error An error happened writing %1 An error happened writing %1 An error happened while downloading the file:<br>%1 An error happened while downloading the file:<br>%1 Core Brightness: %1 亮度: %1 Contrast: %1 对比度: %1 Gamma: %1 伽玛: %1 Hue: %1 色调: %1 Saturation: %1 饱和度: %1 Volume: %1 音量: %1 Zoom: %1 缩放: %1 Buffering... 缓冲中... Font scale: %1 字体缩放: %1 Aspect ratio: %1 纵横比: %1 Updating the font cache. This may take some seconds... 正在更新字体缓存。这可能需要几秒钟... Subtitle delay: %1 ms 字幕延迟: %1毫秒 Audio delay: %1 ms 音频延迟: %1毫秒 Speed: %1 速度: %1 Unable to retrieve the Youtube page 无法取回Youtube页面 Unable to locate the URL of the video 无法定位视频的URL Subtitles on 字幕开启 Subtitles off 字幕关闭 Mouse wheel seeks now 鼠标滚轮定位 Mouse wheel changes volume now 鼠标滚轮更改音量 Mouse wheel changes zoom level now 鼠标滚轮更改缩放等级 Mouse wheel changes speed now 鼠标滚轮更改速度 Screenshot saved as %1 截图保存为 %1 Starting... 正在开始... Screenshot NOT taken, folder not configured 无法进行屏幕截图,没有配置文件夹 Screenshots NOT taken, folder not configured 无法进行屏幕截图,没有配置文件夹 "A" marker set to %1 "A"标记设置到 %1 "B" marker set to %1 "B"标记设置到 %1 A-B markers cleared A-B 标记已清除 Connecting to %1 正在连接到 1% DefaultGui Audio 音频 Subtitle 字幕 &Main toolbar 主工具栏(&M) &Language toolbar 语言工具栏(&L) &Toolbars 工具栏(&T) Ready 准备好 A:%1 A:%1 B:%1 B:%1 Status&bar 状态栏(&B) &Video info 视频信息(&V) &Frame counter 帧计数器(&F) Edit main &toolbar 编辑主工具栏(&T) Edit &control bar 编辑控制条(&C) Edit m&ini control bar 编译迷你控制条(&I) Edit &floating control 编辑浮动控制条(&F) %1x%2 %3 fps width + height + fps %1x%2 %3帧/秒 EqSlider icon icon ErrorDialog Hide log 隐藏日志 Show log 显示日志 MPlayer Error MPlayer 错误 OK 确定 icon icon Oops, something wrong happened 额..出错了 Error 错误 EscTip Press ESC to exit full screen mode 请按 ESC 键退出全屏 FavoriteEditor Icon 图标 Name 名称 Media 媒体 Favorite editor 收藏夹编辑器 Favorite list 收藏夹列表 You can edit, delete, sort or add new items. Double click on a cell to edit its contents. 您可以编辑、删除、排序或添加新的项目。双击一个单元格可以编辑其内容。 Select an icon file 选择一个图标文件 Images 图像 icon icon D&elete 删除(&E) Delete &all 删除全部(&A) &Up 向上(&U) &Down 向下(&D) &New item 新建项目(&N) New &submenu 新建子菜单(&S) Favorites Jump to item 跳转到项目 Enter the number of the item in the list to jump: 输入在列表中要跳转的项目编号: &Edit... 编辑(&E)... &Jump... 跳转(&J)... &Next 下一个(&N) &Previous 上一个(&P) &Add current media 添加当前媒体(&A) FileChooser Click to select a file or folder 单击以选择一个文件或文件夹 FileDownloader Downloading... 正在下载... Connecting to %1 正在连接到 1% FilePropertiesDialog SMPlayer - File properties 视频播放器 - 文件属性 &Information 信息(&I) &Demuxer 解复用器(&D) Kylin Video - Preferences 麒麟影音 - 设置 Kylin Video - Properties 麒麟影音 - 属性 Kylin video - Properties 麒麟影音 - 属性 Properties 属性 &Select the demuxer that will be used for this file: 选择将用于此文件的解复用器(&S): &Reset 重置(&R) Reset 重置 &Video codec 视频编解码器(&V) &Select the video codec: 选择视频编解码器(&S): A&udio codec 音频编解码器(&U) &Select the audio codec: 选择音频编解码器(&S): You can also pass additional video filters. Separate them with ",". Do not use spaces! Example: scale=512:-2,mirror 您还可以传送额外的视频过滤器。 请用" , "隔开它们。不要使用空格! 示例: scale=512:-2,mirror And finally audio filters. Same rule as for video filters. Example: extrastereo,karaoke 最后是音频过滤器。和视频过滤器的规则相同。 示例: extrastereo,karaoke &Options: 选项(&O): V&ideo filters: 视频过滤器(&I): Audio &filters: 音频过滤器(&F): Information 信息 Demuxer 解复用器 Video codec 视频编解码器 Audio codec 音频编解码器 OK 确定 Cancel 取消 Apply 应用 O&ptions for %1 %1 的参数项 (&p) Additional Options for %1 %1 的额外参数项 Here you can pass extra options to %1. 你可以在这里为 %1 设置额外的参数。 Write them separated by spaces. 在这里输入,使用空格隔开。 Example: 示例: FindSubtitlesConfigDialog HTTP HTTP SOCKS5 SOCKS5 Enable/disable the use of the proxy. 启用/禁用使用代理。 The host name of the proxy. 代理的主机名。 The port of the proxy. 代理的端口。 If the proxy requires authentication, this sets the username. 如果代理需要身份验证,请在这里设置用户名。 The password for the proxy. <b>Warning:</b> the password will be saved as plain text in the configuration file. 代理的密码。<b>警告:</b> 密码将被作为纯文本保存在配置文件中。 Select the proxy type to be used. 选择要使用的代理类型。 Options 选项 Server 服务器 &OpenSubtitles server: OpenSubtitles 服务器(&O): Proxy 代理 &Enable proxy 启用代理(&E) &Host: 主机(&H): &Port: 端口(&P): &Username: 用户名(&U): Pa&ssword: 密码(&S): &Type: 类型(&T): Misc Misc A&ppend language code to the subtitle filename 将语言代码附加到字幕文件名中(&p) Number of &retries: 条目数(&r): FindSubtitlesWindow Language 语言 Name 名称 Format 格式 Files 文件 Date 日期 Uploaded by 上传者 Portuguese - Brasil 葡萄牙语-巴西 All 全部 Close 关闭 Login to opensubtitles.org has failed 登陆到opensubtitles.org失败 Search has failed 搜索失败 %n subtitle(s) extracted 已提取%n个字幕 Error fixing the subtitle lines 修复字幕行时出错 &Download 下载(&D) &Copy link to clipboard 复制链接到剪贴板(&C) Error 错误 Download failed: %1. 下载失败: %1。 Connecting to %1... 正在连接到 %1... Downloading... 正在下载... Done. 完成。 %1 files available %1个文件可用 Failed to parse the received data. 无法分析接收到的数据。 Find Subtitles 查找字幕 &Subtitles for 字幕用于(&S) &Language: 语言(&L): &Refresh 刷新(&R) Subtitle saved as %1 字幕已保存为 %1 Overwrite? 是否覆盖? The file %1 already exits, overwrite? 文件 %1 已存在,是否覆盖? Error saving file 保存文件时出错 It wasn't possible to save the downloaded file in folder %1 Please check the permissions of that folder. 无法在文件夹 %1 中保存下载的文件 请检查该文件夹的权限。 Download failed 下载失败 Temporary file %1 临时文件 %1 &Options 选项(&O) FontCacheDialog SMPlayer is initializing 视频播放器正在初始化 Creating a font cache... 正在创建字体缓存... HelpDialog Kylin Video - Preferences 麒麟影音 - 设置 Kylin Video - Help 麒麟影音 - 帮助 Help 帮助 OK 确定 Supported formats 支持的格式 Supported shortcuts 支持的快捷键 InfoFile General 常规 Size 大小 %1 KB (%2 MB) %1 KB (%2 MB) URL URL Length 长度 Demuxer 解复用器 Name 名称 Artist 艺术家 Author 作者 Album 专辑 Genre 流派 Date 日期 Track 轨道 Copyright 版权 Comment 注释 Software 软件 Clip info 剪辑信息 Video 视频 Resolution 分辨率 Aspect ratio 纵横比 Format 格式 Bitrate 比特率 %1 kbps %1kbps Frames per second 每秒帧数 Selected codec 已选编解码器 Initial Audio Stream 初始音频流 Rate 采样率 %1 Hz %1 Hz Channels 声道 Audio Streams 音频流 Language 语言 empty Subtitles 字幕 Type 类型 ID Info for translators: this is a identification code ID # Info for translators: this is a abbreviation for number # Stream title 流标题 Stream URL 流 URL File 文件 InputDVDDirectory Choose a directory 选择一个目录 SMPlayer - Play a DVD from a folder 视频播放器 - 从文件夹播放 DVD You can play a DVD from your hard disc. Just select the folder which contains the VIDEO_TS and AUDIO_TS directories. 你可以从播放硬盘中的DVD。选择包含 VIDEO_TS 和 AUDIO_TS 的文件夹即可。 Choose a directory... 选择目录... InputMplayerVersion SMPlayer - Enter the MPlayer version 视频播放器 - 输入 MPlayer 版本 SMPlayer couldn't identify the MPlayer version you're using. 视频播放器无法识别您正在使用的 MPlayer 版本。 Version reported by MPlayer: MPlayer 报告的版本: Please, &select the correct version: 请选择正确的版本(&S): 1.0rc1 or older 1.0rc1 或更旧 1.0rc2 1.0rc2 1.0rc3 or newer 1.0rc3 或更新 InputURL SMPlayer - Enter URL 视频播放器 - 输入 URL Kylin Video - Enter URL 麒麟影音 - 输入 URL &URL: URL(&U): OK 确定 Enter URL 输入网址 Cancel 取消 URL: 网址: Languages Afar 阿法尔语 Abkhazian 阿布哈西亚语 Afrikaans 南非荷兰语 Amharic 阿姆哈拉语 Arabic 阿拉伯语 Assamese 阿萨姆语 Aymara 艾马拉语 Azerbaijani 阿塞拜疆语 Bashkir 巴什基尔语 Bulgarian 保加利亚语 Bihari 比哈尔语 Bislama 比斯拉马语 Bengali 孟加拉语 Tibetan 藏语 Breton 布列塔尼语 Catalan 加泰罗尼亚语 Corsican 科西嘉语 Czech 捷克语 Welsh 威尔士语 Danish 丹麦语 German 德语 Greek 希腊语 English 英语 Esperanto 世界语 Spanish 西班牙语 Estonian 爱沙尼亚语 Basque 巴斯克语 Persian 波斯语 Finnish 芬兰语 Faroese 法罗语 French 法语 Frisian 弗里西亚语 Irish 爱尔兰语 Galician 加利西亚语 Guarani 瓜拉尼语 Gujarati 古吉拉特语 Hausa 豪萨语 Hebrew 希伯来语 Hindi 印地语 Croatian 克罗地亚语 Hungarian 匈牙利语 Armenian 亚美尼亚语 Interlingua 国际语A Indonesian 印度尼西亚语 Interlingue 国际语E Icelandic 冰岛语 Italian 意大利语 Inuktitut 因纽特语 Japanese 日语 Javanese 爪哇语 Georgian 格鲁吉亚语 Kazakh 哈萨克语 Greenlandic 格陵兰语 Kannada 卡纳达语 Korean 韩国语 Kashmiri 克什米尔语 Kurdish 库尔德语 Kirghiz 吉尔吉斯语 Latin 拉丁语 Lingala 林加拉语 Lithuanian 立陶宛语 Latvian 拉脱维亚语 Malagasy 马达加斯加语 Maori 毛利语 Macedonian 马其顿语 Malayalam 马拉雅拉姆语 Mongolian 蒙古语 Moldavian 摩尔达维亚语 Marathi 马拉地语 Malay 马来语 Maltese 马耳他语 Burmese 缅甸语 Nauru 瑙鲁语 Nepali 尼泊尔语 Dutch 荷兰语 Norwegian Nynorsk 耐诺斯克挪威语 Norwegian 挪威语 Occitan 欧西坦语 Oriya 奥里亚语 Polish 波兰语 Portuguese 葡萄牙语 Quechua 克丘亚语 Romanian 罗马尼亚语 Russian 俄语 Kinyarwanda 基尼亚卢旺达语 Sanskrit 梵语 Sindhi 信德语 Slovak 斯洛伐克语 Samoan 萨摩亚语 Shona 绍纳语 Somali 索马里语 Albanian 阿尔巴尼亚语 Serbian 塞尔维亚语 Sundanese 巽他语 Swedish 瑞典语 Swahili 斯瓦希里语 Tamil 泰米尔语 Telugu 泰卢固语 Tajik 塔吉克语 Thai 泰语 Tigrinya 提格利尼亚语 Turkmen 土库曼语 Tagalog 塔加洛语 Tonga 汤加语 Turkish 土耳其语 Tsonga 聪加语 Tatar 鞑靼语 Twi 契维语 Uighur 维吾尔语 Ukrainian 乌克兰语 Urdu 乌尔都语 Uzbek 乌兹别克语 Vietnamese 越南语 Wolof 沃洛夫语 Xhosa 科萨语 Yiddish 意第绪语 Yoruba 约鲁巴语 Zhuang 壮语 Chinese 汉语 Zulu 祖鲁语 Arabic - Syria 阿拉伯语 - 叙利亚 Unicode Unicode UTF-8 UTF-8 Western European Languages 西欧 Western European Languages with Euro 西欧(欧盟) Slavic/Central European Languages 斯拉夫语/中欧 Esperanto, Galician, Maltese, Turkish 世界语,加利西亚,马耳他,土耳其 Old Baltic charset 旧波罗的海字符集 Cyrillic 西里尔文 Modern Greek 现代希腊语 Baltic 波罗的海语 Celtic 凯尔特语 South-Eastern European 东南欧洲 Hebrew charsets 希伯来语字符集 Ukrainian, Belarusian 乌克兰语,白俄罗斯 Simplified Chinese charset 简体中文字符集 Traditional Chinese charset 繁体中文字符集 Japanese charsets 日语字符集 Korean charset 朝鲜语字符集 Thai charset 泰语字符集 Cyrillic Windows 西里尔文 Windows Slavic/Central European Windows 斯拉夫语/中欧 Windows Arabic Windows 阿拉伯语 Windows Avestan 阿维斯陀语 Akan 阿坎语 Aragonese 阿拉贡语 Avaric 阿瓦尔语 Belarusian 白俄罗斯语 Bambara 班巴拉语 Bosnian 波斯尼亚语 Chechen 车臣语 Cree 克里语 Church 古教会斯拉夫语 Chuvash 楚瓦什语 Divehi 迪维希语 Dzongkha 宗卡语 Ewe 埃维语 Fulah 富拉语 Fijian 斐济语 Gaelic 盖尔语 Manx 马恩岛语 Hiri 希里莫图语 Haitian 海地克里奥尔语 Herero 赫雷罗语 Chamorro 查莫罗语 Igbo 伊博语 Sichuan 四川彝语 Inupiaq 依努庇克语 Ido 伊多语 Kongo 刚果语 Kikuyu 基库尤语 Kuanyama 宽亚玛语 Khmer 高棉语 Kanuri 卡努里语 Komi 科米语 Cornish 康沃尔语 Luxembourgish 卢森堡语 Ganda 干达语 Limburgan 林堡语 Lao 老挝语 Luba-Katanga 卢巴-加丹加语 Marshallese 马绍尔语 Bokmål 博克马尔语 Ndebele 北恩德贝勒语 Ndonga 恩敦加语 Navajo 纳瓦霍语 Chichewa 齐切瓦语 Ojibwa 奥吉布瓦语 Oromo 奥罗莫语 Ossetian 奥塞梯语 Panjabi 旁遮普语 Pali 巴利语 Pushto 普什图语 Romansh 罗曼什语 Rundi 基隆迪语 Sardinian 萨丁尼亚语 Sami 北萨米语 Sango 桑戈语 Sinhala 僧加罗语 Slovene 斯洛文尼亚语 Swati 斯瓦特语 Sotho 南索托语 Tswana 茨瓦纳语 Tahitian 塔希提语 Venda 文达语 Volapük 沃拉普克语 Walloon 瓦龙语 Modern Greek Windows 现代希腊语 Windows LineEditWithIcon Change 更改 LogWindow Choose a filename to save under 选择一个要保存在下面的文件名 Confirm overwrite? 确认是否覆盖? The file already exists. Do you want to overwrite? 该文件已存在。 您想要覆盖吗? Error saving file 保存文件时出错 The log couldn't be saved 无法保存日志 Logs 日志 LogWindowBase Save 保存 Copy to clipboard 复制到剪贴板 &Close 关闭(&C) Close 关闭 MPVProcess the '%1' filter is not supported by mpv mpv不支持 '%1' 过滤器 MediaBarPanel Form 表格 MediaPanel Shuffle playlist 乱序播放列表 Repeat playlist 重复播放列表 MediaPanelClass MediaPanel 媒体面板 MessageDialog OK 确定 Ok 确定 Cancel 取消 Yes No MiniGui Control bar 控制条 Edit &control bar 编辑控制条(&C) Edit &floating control 编辑浮动控制条(&F) MpcGui Control bar 控制条 Seek bar 定位栏 -%1 -%1 +%1 +%1 MplayerProcess This option is not supported by MPlayer MPlayer不支持该选项 MultilineInputDialog Enter URL(s) 输入网址(s) Enter the URL(s) to be added to the playlist. One per line. 输入要添加到播放列表的网址(s)。每行一个。 PlayControl Rewind 后退 Forward 前进 Play / Pause 播放/暂停 Stop 停止 Record 录制 Next file in playlist 播放列表中的下一个文件 Previous file in playlist 播放列表中的上一个文件 PlayListView Play 播放 Delete 删除 Playlist Name 名称 Length 长度 &Play 播放(&P) &Edit 编辑(&E) Playlists 播放列表 Choose a file 选择一个文件 Choose a filename 选择一个文件名 Confirm overwrite? 确认是否覆盖? The file %1 already exists. Do you want to overwrite? 文件 %1 已存在。 您想要覆盖吗? All files 所有文件 Select one or more files to open 选择一个或多个要打开的文件 Playlist is empty 播放列表为空 PlayList 播放列表 Clear 清除 Add File 增加文件 Add 添加 Play 播放 Reached the end of the playlist 已经到达播放列表底部 Choose a directory 选择一个目录 Edit name 编辑名称 Type the name that will be displayed in the playlist for this file: 键入该文件将显示在播放列表中的名称: &Load 加载(&L) &Save 保存(&S) &Next 下一个(&N) Pre&vious 上一个(&V) Move &up 向上移动(&U) Move &down 向下移动(&D) &Repeat 重复(&R) S&huffle 乱序(&H) Add &current file 添加当前文件(&C) Add &file(s) 添加文件(&F) Add &directory 添加目录(&D) Add &URL(s) 添加网址(s) (U) Remove &selected 删除选定(&S) Remove &all 删除全部(&A) &Delete file from disk 从硬盘删除(&D) SMPlayer - Playlist 视频播放器 - 播放列表 Confirm remove 确认移除 You're about to remove the file '%1' from the playlist. 将从播放列表中移除文件 '%1'。 Are you sure you want to proceed? 你确定要继续? Confirm deletion 确认删除 You're about to DELETE the file '%1' from your drive. 将从您的硬盘删除文件 '%1' This action cannot be undone. Are you sure you want to proceed? 此操作不可撤销。你确定要继续? Deletion failed 删除失败 It wasn't possible to delete '%1' 无法删除 '%1' Error deleting the file 删除文件出错 It's not possible to delete '%1' from the filesystem. 无法从文件系统删除 '%1' Add... 添加... Remove... 删除... Playlist modified 播放列表己修改 There are unsaved changes, do you want to save the playlist? 有未保存的更改,您想要保存该播放列表吗? Multimedia 多媒体 PrefAdvanced Advanced 高级 Auto 自动 &Advanced 高级(&A) Log SMPlayer output 记录视频播放器输出 This option is mainly intended for debugging the application. 此选项主要用于调试应用程序。 Checking this option may reduce flickering, but it also might produce that the video won't be displayed properly. 勾选此选项可减少闪烁,但也可能会造成视频无法正确显示。 Filter for SMPlayer logs 视频播放器日志筛选器 &Monitor aspect: 显示器纵横比(&M): Use the la&vf demuxer by default 默认使用lavf 分流器(&v) &Options: 选项(&O): V&ideo filters: 视频过滤器(&I): Audio &filters: 音频过滤器(&F): &Colorkey: 色键(&C): You can also pass additional video filters. Separate them with ",". Do not use spaces! Example: scale=512:-2,mirror 您还可以传送额外的视频过滤器。 请用" , "隔开它们。不要使用空格! 示例: scale=512:-2,mirror And finally audio filters. Same rule as for video filters. Example: extrastereo,karaoke 最后是音频过滤器。和视频过滤器的规则相同。 示例: extrastereo,karaoke SMPlayer 视频播放器 Log &SMPlayer output 记录视频播放器输出(&S) &Filter for SMPlayer logs: 视频播放器日志筛选器(&F): C&hange... 更改(&H)... Logs 日志 Monitor aspect 显示器纵横比 Select the aspect ratio of your monitor. 选择您的显示器纵横比。 Use the lavf demuxer by default 默认使用lavf 分流器 If this option is checked, the lavf demuxer will be used for all formats. 如果勾选此项,lavf分流器将会被用于所有格式的文件。 Colorkey 色键 If you see parts of the video over any other window, you can change the colorkey to fix it. Try to select a color close to black. 如果您在任何其他窗口上看到了部分视频,您可以通过更改色键来修复它。请尽量选择接近黑色的颜色。 Options 选项 Video filters 视频过滤器 Audio filters 音频过滤器 Repaint the background of the video window 重绘视频窗口背景 Repaint the backgroun&d of the video window 重绘视频窗口背景(&D) IPv4 IPv4 Use IPv4 on network connections. Falls back on IPv6 automatically. 使用 IPv4 网络连接。失败自动返回 IPv6。 IPv6 IPv6 Use IPv6 on network connections. Falls back on IPv4 automatically. 使用 IPv6 网络连接。失败自动返回 IPv4。 Network Connection 网络连接 IPv&4 IPv4(&4) IPv&6 IPv6(&6) Lo&gs 日志(&G) Rebuild index if needed 需要时重建索引 Rebuild &index if needed 需要时重建索引(&I) If this option is checked, SMPlayer will store the debugging messages that SMPlayer outputs (you can see the log in <b>Options -> View logs -> SMPlayer</b>). This information can be very useful for the developer in case you find a bug. 如果勾选此选项,视频播放器将存储其输出的调试信息(在 <b>选项 -> 查看日志 -> 视频播放器</b> 中您可以看到该日志)。在您发现 Bug 时,此信息可能对开发者非常有用。 Log %1 output 记录 %1 输出 If checked, SMPlayer will store the output of %1 (you can see it in <b>Options -> View logs -> %1</b>). In case of problems this log can contain important information, so it's recommended to keep this option checked. 如果勾选,视频播放器将存储 %1 的输出(在 <b>选项 -> 查看日志 -> %1 </b>中可以看到它)。出现问题时,该日志会记录重要的信息,因此建议保持勾选此选项。 Autosave %1 log 自动保存 %1 日志 If this option is checked, the %1 log will be saved to the specified file every time a new file starts to play. It's intended for external applications, so they can get info about the file you're playing. 如果勾选此选项,每次有新文件开始播放时,%1 日志将被保存到指定的文件。这样做有便于外部应用程序获取当前播放文件的信息。 Autosave %1 log filename 自动保存 %1 日志的文件名 Enter here the path and filename that will be used to save the %1 log. 在这里输入保存 %1 日志的路径及文件名。 This option allows you to filter the SMPlayer messages that will be stored in the log. Here you can write any regular expression.<br>For instance: <i>^Core::.*</i> will display only the lines starting with <i>Core::</i> 此选项允许筛选将被存储在日志中的视频播放器消息。在这里您可以编写任何正则表达式。<br>例如: <i>^Core::..*</i> 将只显示以 <i>Core::</i> 开始的行 Correct pts 校正 PTS &Run %1 in its own window 让 %1 在其自己的窗口中运行(&R) &Pass short filenames (8+3) to %1 传送短文件名(8+3)到 %1 (&P) R&eport %1 crashes 报告 %1 崩溃 (&e) O&ptions for %1 %1 的参数项 (&p) Here you can pass extra options to %1. 你可以在此处输入 %1 的额外参数。 Write them separated by spaces. 使用空格分隔。 Log %1 &output 记录 %1 输出(&o) A&utosave %1 log to file 自动保存 %1 日志到文件(&u) Run %1 in its own window 让 %1 在其自己的窗口中运行 If you check this option, the %1 video window won't be embedded in SMPlayer's main window but instead it will use its own window. Note that mouse and keyboard events will be handled directly by %1, that means key shortcuts and mouse clicks probably won't work as expected when the %1 window has the focus. 如果勾选此选项,%1 的视频窗口将不会被嵌入到视频播放器的主窗口中,而它将使用其自己的窗口。需要注意的是,键盘和鼠标事件将由 %1 直接处理,这意味着当焦点在 %1 窗口时,快捷键和鼠标点击很可能无法按预期工作。 Pass short filenames (8+3) to %1 传送短文件名(8+3)到 %1 If this option is checked, SMPlayer will pass to %1 the short version of the filenames. 如果勾选此选项,视频播放器将会将短文件名传送给 %1。 Report %1 crashes 报告 %1 崩溃 If this option is checked, a window will appear to inform about %1 crashes. Otherwise those failures will be silently ignored. 如果勾选此选项,将会出现一个窗口通知 %1 崩溃。否则这些故障将被忽略。 Switches %1 to an experimental mode where timestamps for video frames are calculated differently and video filters which add new frames or modify timestamps of existing ones are supported. The more accurate timestamps can be visible for example when playing subtitles timed to scene changes with the SSA/ASS library enabled. Without correct pts the subtitle timing will typically be off by some frames. This option does not work correctly with some demuxers and codecs. 切换 %1 到试验模式,其中视频帧时间戳的计算方式不同,且支持视频过滤器添加新的帧或修改现有的时间戳。例如当正在播放的字幕同步到场景变化时(已启用 SSA/ASS 库),可得到更精确的时间戳。如果没有校正 PTS,字幕同步通常会被某些帧关闭。此选项不能与某些解复用器和编解码器一起正常工作。 Actions list 动作列表 Here you can specify a list of <i>actions</i> which will be run every time a file is opened. You'll find all available actions in the key shortcut editor in the <b>Keyboard and mouse</b> section. The actions must be separated by spaces. Checkable actions can be followed by <i>true</i> or <i>false</i> to enable or disable the action. 在这里您可以指定一个每次打开文件时将运行的 <i>动作</i> 列表。在 <b>键盘和鼠标</b> 部分的快捷键编辑器中您会发现所有的可用动作。动作之间必须由空格隔开。可选动作可以在后面用 <i>true</i> 或 <i>false</i> 来启用或禁用它。 Limitation: the actions are run only when a file is opened and not when the mplayer process is restarted (e.g. you select an audio or video filter). 局限: 只有当某个文件被打开,而且 MPlayer 进程没有被重启(例如您选择音频或视频过滤器)时动作才会运行。 Options for %1 %1 选项 Here you can type options for %1. 你可以在这里输入 %1 的参数。 Here you can add video filters for %1. 你可以为 %1 添加视频过滤器。 Write them separated by commas. Don't use spaces! 请使用逗号分隔每个参数。不要使用空格! Here you can add audio filters for %1. 你可以在这里为 %1 添加音频过滤器。 Network 网络 R&un the following actions every time a file is opened. The actions must be separated with spaces: 每次打开文件时运行下列动作。动作之间必须由空格隔开(&U): &Network 网络(&N) Example: 示例: Rebuilds index of files if no index was found, allowing seeking. Useful with broken/incomplete downloads, or badly created files. This option only works if the underlying media supports seeking (i.e. not with stdin, pipe, etc).<br> <b>Note:</b> the creation of the index may take some time. 在没有找到索引的情况下重建文件索引,从而允许定位。这对于损坏/未完成下载或制作低劣的文件很有用。此选项仅适用原本支持定位的媒体(即不能是 stdin、pipe 等)。<br><b>注意:</b> 创建索引可能需要一些时间。 C&orrect PTS: 校正 PTS(&O): &Verbose 详细信息(&V) Save SMPlayer log to file 保存视频播放器日志到文件 If this option is checked, the SMPlayer log wil be recorded to %1 如果勾选此选项,视频播放器日志将被记录到 %1 Sa&ve SMPlayer log to a file 保存视频播放器日志到文件(&V) Show tag info in window title 在窗口标题上显示标签信息 If this option is enabled, information from tags will be shown in window title. Otherwise only the filename will be shown. 如果启用此选项,标签中的信息将显示在窗口标题上。否则将只显示文件名。 Show tag in&fo in window title 在窗口标题上显示标签信息(&F) PrefAssociations Warning 警告 Not all files could be associated. Please check your security permissions and retry. 并非所有文件都被关联。请检查您的安全权限,然后重试。 File Types 文件类型 Select all 选择全部 Check all file types in the list 勾选列表中的所有文件类型 Uncheck all file types in the list 取消勾选列表中的所有文件类型 List of file types 文件类型列表 Note: 注意: Restoration doesn't work on Windows Vista. Windows Vista 下不支持重置。 File types 文件类型 Media files handled by SMPlayer: 由视频播放器处理的媒体文件: Select All 选择全部 Select None 取消选择 Check the media file extensions you would like SMPlayer to handle. When you click Apply, the checked files will be associated with SMPlayer. If you uncheck a media type, the file association will be restored. 勾选您想使用视频播放器处理的媒体文件扩展名。当您单击"应用"时,勾选的文件将被关联到视频播放器。如果您取消勾选一种媒体类型,该文件关联将被恢复。 Select none 取消选择 PrefAudio A&udio 音频(&U) Ou&tput driver: 输出驱动(&T): C&hannels by default: 默认声道(&H): Volume 音量 Use software volume control 使用软件音量控制 Max. Amplification: 最大放大率: Audio/video auto synchronization 音频/视频自动同步 Factor: 因子: Output driver: 输出驱动: Channels by default: 默认声道: Glo&bal volume 全局音量(&B) Use s&oftware volume control 使用软件音量控制(&O) Ma&x. Amplification: 最大放大率(&X): Volume &normalization by default 默认音量标准化(&N) Synchronization 同步 Audio/video auto &synchronization 音频/视频自动同步(&S) &Factor: 因子(&F): 2 (Stereo) 2 (立体声) 4 (4.0 Surround) 4 (4.0 环绕声) 6 (5.1 Surround) 6 (5.1 环绕声) 7 (6.1 Surround) 7 (6.1 环绕声) 8 (7.1 Surround) 8 (7.1 环绕声) Default 默认 Audio output driver 音频输出驱动 Select the audio output driver. 选择音频输出驱动。 %1 is the recommended one. Try to avoid %2 and %3, they are slow and can have an impact on performance. 推荐使用 %1。尽量避免 %2 和 %3,它们速度很慢,且会影响性能。 Channels by default 默认声道 Requests the number of playback channels. MPlayer asks the decoder to decode the audio into as many channels as specified. Then it is up to the decoder to fulfill the requirement. This is usually only important when playing videos with AC3 audio (like DVDs). In that case liba52 does the decoding by default and correctly downmixes the audio into the requested number of channels. <b>Note</b>: This option is honored by codecs (AC3 only), filters (surround) and audio output drivers (OSS at least). 指定播放声道的数量。MPlayer 告诉解码器需要将音频解码成多少声道,再由解码器来实现此需求。通常只有在播放带有 AC3 音频(比如 DVD)的视频时才有用。在该情况下将默认使用 liba52 解码并把音频正确地混合成需要的声道数量。<b>注意</b>: 此选项需要 编码(仅 AC3)、过滤器(环绕声)和音频输出驱动(OSS或更高级)三者都满足。 Gradually adjusts the A/V sync based on audio delay measurements. 基于音频延迟的测量值逐步调整 A/V 同步。 Global volume 全局音量 If this option is checked, the same volume will be used for all files you play. If the option is not checked each file uses its own volume. 如果勾选此选项,您播放的所有文件都将使用相同的音量。如果此选项未被勾选,每个文件将使用其自己的音量。 This option also applies for the mute control. 此选项也适用于静音控制。 Software volume control 使用软件音量控制 Check this option to use the software mixer, instead of using the sound card mixer. 勾选此选项以使用软件混音器,而不使用声卡混音器。 Max. Amplification 最大放大率 Sets the maximum amplification level in percent (default: 110). A value of 200 will allow you to adjust the volume up to a maximum of double the current level. With values below 100 the initial volume (which is 100%) will be above the maximum, which e.g. the OSD cannot display correctly. 设置最大放大级别的百分比(默认值: 110)。该值为 200 时允许您调整的最大音量为目前级别的两倍。该值低于 100 时,初始音量(为100%)将高于可调整的最大值,这时例如 OSD (屏幕显示)将不能正确显示。 Volume normalization by default 默认音量标准化 Maximizes the volume without distorting the sound. 声音没有失真的最大音量。 PrefDrives Drives 驱动器 CD device 选择您的 CD 驱动器 Choose your CDROM device. It will be used to play VCDs and Audio CDs. 选择您的 CDROM 驱动器。它将用于播放 VCD 和音频 CD。 DVD device 选择您的 DVD 驱动器 Choose your DVD device. It will be used to play DVDs. 选择您的 DVD 驱动器。它将用于播放 DVD。 If this option is checked, SMPlayer will play DVDs using dvdnav. Requires a recent version of MPlayer compiled with dvdnav support. 如果勾选此项,视频播放器会使用 dvdnav 播放 DVD。需要启用了 dvdnav 支持的较新版 MPlayer Select your &CD device: 选择您的 CD 驱动器(&C): Select your &DVD device: 选择您的 DVD 驱动器(&D): Select your &Blu-ray device: 选择您的 Blu-ray 驱动器(&B): SMPlayer does not choose any CDROM or DVD devices by default. So before you can actually play a CD or DVD you have to select the devices you want to use (they can be the same). 视频播放器默认不会选择任何 CDROM 或 DVD 驱动器。因此在您实际播放 CD 或 DVD 之前,您必须选择您想要使用的驱动器(它们可以是相同的)。 Blu-ray device Blu-ray驱动器 Choose your Blu-ray device. It will be used to play Blu-ray discs. 选择您的 Blu-ray 驱动器。它将用于播放蓝光光盘。 Enable DVD menus 启用 DVD 菜单 <b>Note 1</b>: cache will be disabled, this can affect performance. <b>注意 1</b>: 缓存将被禁用,这会影响性能。 <b>Note 2</b>: you may want to assign the action "activate option in DVD menus" to one of the mouse buttons. <b>注意 2</b>: 您可能需要指派"激活 DVD 菜单中的选项"动作到某一鼠标按钮。 <b>Note 3</b>: this feature is under development, expect a lot of issues with it. <b>注意 3</b>: 此功能正在开发中,估计它的问题很多。 &Enable DVD menus (experimental) 启用 DVD 菜单(试验)(&E) &Scan for CD/DVD drives 扫描 CD/DVD 驱动器(&S) PrefGeneral General 常规 &General 常规(&G) Media settings 媒体设置 Start videos in fullscreen 以全屏开始视频 Disable screensaver 禁用屏幕保护程序 Select the mplayer executable 选择 MPlayer 可执行文件 7 (6.1 Surround) 7 (6.1 环绕声) 8 (7.1 Surround) 8 (7.1 环绕声) Executables 可执行文件 All files 所有文件 Select a directory 选择一个目录 %1 &executable: %1 可执行文件(&e): Default 默认 %1 executable %1 可执行文件 Here you must specify the %1 executable that SMPlayer will use. 你必须在这里指定 %1 可执行文件的位置。 Screenshots folder 屏幕截图文件夹 Here you can specify a folder where the screenshots taken by Kylin Video will be stored. If the folder is not valid the screenshot feature will be disabled. 在这里您可以指定一个麒麟影音将用来存储屏幕截图的文件夹。如果文件夹是无效的,屏幕截图功能将被禁用。 Template for screenshots 屏幕截图模板 For example %1 would save the screenshot as 'moviename_0001.png'. 例如,%1 将会将截图保存为 ‘moviename_0001.png’ 。 %1 specifies the filename of the video without the extension, %2 adds a 4 digit number padded with zeros. %1 指定视频的文件名(不含扩展名), %2 在之后添加 4位数,不够的用0填充。 Format for screenshots 截屏样式 This option allows you to choose the image file type used for saving screenshots. 此选项让您选择视频截图的格式。 If this option is enabled, the computer will shut down just after SMPlayer is closed. 如果启用此选项,视频播放器关闭后电脑会跟着关闭 Video output driver 视频输出驱动 Audio output driver 音频输出驱动 Select the audio output driver. 选择音频输出驱动。 Remember settings 记住所有文件的设置 Preferred audio language 首选音频语言 Preferred subtitle language 首选字幕语言 Software video equalizer 使用软件视频均衡器 This option specifies the filename template used to save screenshots. 此选项定义保存视频截屏时使用的文件名模板。 For a full list of the template specifiers visit this link: 完整模板说明符列表请访问此链接: This option only works with mpv. 此选项仅适用于mpv。 Shut down computer 关机 You can check this option if video equalizer is not supported by your graphic card or the selected video output driver.<br><b>Note:</b> this option can be incompatible with some video output drivers. 如果您的显示卡或所选的视频输出驱动不支持视频均衡器,您可以勾选此选项。<br><b>注意:</b> 此选项可能与某些视频输出驱动不兼容。 If this option is checked, all videos will start to play in fullscreen mode. 如果勾选此选项,所有视频都将以全屏模式开始播放。 Global audio equalizer 全局音频均衡器 If this option is checked, all media files share the audio equalizer. 如果勾选此项,所有媒体文件使用相同的均衡器 If it's not checked, the audio equalizer values are saved along each file and loaded back when the file is played later. 如果不勾选,音频均衡设置会和文件关联保存,当文件再次播放时使用这个设置 Software volume control 使用软件音量控制 Check this option to use the software mixer, instead of using the sound card mixer. 勾选此选项以使用软件混音器,而不使用声卡混音器。 Postprocessing quality 后期处理质量 Dynamically changes the level of postprocessing depending on the available spare CPU time. The number you specify will be the maximum level used. Usually you can use some big number. 根据可用的 CPU 空闲时间动态更改后期处理的级别。您指定的数字将被作为最高级别使用。通常您可以使用大一些的数字。 &Audio: 音频(&A): &Remember settings for all files (audio track, subtitles...) 记住所有文件的设置(音轨、字幕...)(&R) Su&btitles: 字幕(&B): &Quality: 质量(&Q): Temp&late: 模板(&l): F&ormat: 格式(&o) : S&hut down computer 关机(&S) Start videos in &fullscreen 以全屏开始视频(&F) Disable &screensaver 禁用屏幕保护程序(&S) Global audio e&qualizer 全局音频均衡器(&e) Use s&oftware volume control 使用软件音量控制(&O) Ma&x. Amplification: 最大放大率(&X): &AC3/DTS pass-through S/PDIF AC3/DTS 直通 S/PDIF(&A) Direct rendering 直接渲染 Double buffering 双缓冲 D&irect rendering 直接渲染(&I) Dou&ble buffering 双缓冲(&B) Double buffering fixes flicker by storing two frames in memory, and displaying one while decoding another. If disabled it can affect OSD negatively, but often removes OSD flickering. 通过在内存中存储两帧,在显示一帧的同时解码另一帧的双缓冲来修复闪烁问题。如果禁用它会对 OSD (屏幕显示)产生负面影响,但常常能去除 OSD (屏幕显示)的闪烁。 &Enable postprocessing by default 默认启用后期处理(&E) Volume &normalization by default 默认音量标准化(&N) Close when finished 结束播放时关闭 If this option is checked, the main window will be automatically closed when the current file/playlist finishes. 如果勾选此选项,当前的文件/播放列表结束时,主窗口将自动关闭。 2 (Stereo) 2 (立体声) 4 (4.0 Surround) 4 (4.0 环绕声) 6 (5.1 Surround) 6 (5.1 环绕声) C&hannels by default: 默认声道(&H): &Pause when minimized 最小化时暂停(&P) Pause when minimized 最小化时暂停 MPlayer MPlayer MPV MPV Playback engine: 播放引擎: Preview when video is playing 视频播放时进行预览 Enable postprocessing by default 默认启用后期处理 Max. Amplification 最大放大率 AC3/DTS pass-through S/PDIF AC3/DTS 直通 S/PDIF Volume normalization by default 默认音量标准化 Maximizes the volume without distorting the sound. 声音没有失真的最大音量。 Channels by default 默认声道 Sets the maximum amplification level in percent (default: 110). A value of 200 will allow you to adjust the volume up to a maximum of double the current level. With values below 100 the initial volume (which is 100%) will be above the maximum, which e.g. the OSD cannot display correctly. 设置最大放大级别的百分比(默认值: 110)。该值为 200 时允许您调整的最大音量为目前级别的两倍。该值低于 100 时,初始音量(为100%)将高于可调整的最大值,这时例如 OSD (屏幕显示)将不能正确显示。 Postprocessing will be used by default on new opened files. 默认在新打开的文件上使用后期处理。 Audio track 音频轨道 Specifies the default audio track which will be used when playing new files. If the track doesn't exist, the first one will be used. <br><b>Note:</b> the <i>"preferred audio language"</i> has preference over this option. 指定播放新文件时将使用的默认音轨。如果所选轨道不存在,将使用第一个轨道。<br><b>注意:</b> <i>"首选音频语言"</i> 优先于此选项。 Subtitle track 字幕轨道 Specifies the default subtitle track which will be used when playing new files. If the track doesn't exist, the first one will be used. <br><b>Note:</b> the <i>"preferred subtitle language"</i> has preference over this option. 指定播放新文件时将使用的默认字幕轨道。如果所选轨道不存在,将使用第一个轨道。<br><b>注意:</b> <i>"首选字幕语言"</i> 优先于此选项。 Or choose a track number: 或选择一个轨道号: Audi&o: 音频(&O): Preferred language: 首选语言: Preferre&d audio and subtitles 首选音频和字幕(&D) &Subtitle: 字幕(&S): Here you can type your preferred language for the audio and subtitle streams. When a media with multiple audio or subtitle streams is found, SMPlayer will try to use your preferred language. This only will work with media that offer info about the language of audio and subtitle streams, like DVDs or mkv files.<br>These fields accept regular expressions. Example: <b>es|esp|spa</b> will select the track if it matches with <i>es</i>, <i>esp</i> or <i>spa</i>. 在这里您可以键入您的音频和字幕流的首选语言。当发现媒体具有多个音频或字幕流时,视频播放器将尝试使用您的首选语言。这仅工作于提供音频和字幕流语言信息的媒体,比如 DVD 或 MKV 文件。<br>这些字段接受正则表达式。示例: <b>es|esp|spa</b> 将选择匹配 <i>es</i>、<i>esp</i> 或 <i>spa</i> 的轨道。 High speed &playback without altering pitch 高速播放而不改变音调(&P) High speed playback without altering pitch 高速播放而不改变音调 Allows you to change the playback speed without altering pitch. Requires at least MPlayer dev-SVN-r24924. 允许更改播放速度而不改变音调。至少需要 MPlayer dev-SVN-r24924。 &Video 视频(&V) Use s&oftware video equalizer 使用软件视频均衡器(&O) A&udio 音频(&U) Volume 音量 Video 视频 Audio 音频 Preferred audio and subtitles 首选音频和字幕 None Lowpass5 Lowpass5 Yadif (normal) Yadif (标准) Yadif (double framerate) Yadif (双倍帧率) Linear Blend 线性混合 Kerndeint Kerndeint Deinterlace by default 默认去交错 Select the deinterlace filter that you want to be used for new videos opened. 选择您想在打开新视频时使用的去交错过滤器。 Remember time position 记住时间位置 Remember &time position 记住时间位置(&T) Enable the audio equalizer 启用音频均衡器 Check this option if you want to use the audio equalizer. 如果您想使用音频均衡器,请勾选此选项。 &Enable the audio equalizer 启用音频均衡器(&E) Draw video using slices 使用切片方式绘制视频 Enable/disable drawing video by 16-pixel height slices/bands. If disabled, the whole frame is drawn in a single run. May be faster or slower, depending on video card and available cache. It has effect only with libmpeg2 and libavcodec codecs. 启用/禁用以 16-像素高的片/带方式绘制视频。如果禁用,将一次运行绘制整个帧。可能更快或更慢,这取决于显卡和可用的缓存。它只对 libmpeg2 和 libavcodec 编解码器有效果。 Dra&w video using slices 使用切片方式绘制视频(&W) &Close when finished playback 结束播放时关闭(&C) fast 快速 slow 慢速 fast - ATI cards 快速 - ATI 卡 User defined... 用户定义... Default zoom 默认缩放 This option sets the default zoom which will be used for new videos. 此选项可设置将用于新视频的默认缩放级别。 Default &zoom: 默认缩放(&Z): If this setting is wrong, SMPlayer won't be able to play anything! 如果此设置是错误的,视频播放器将无法播放任何东西! Select the video output driver. %1 provides the best performance. 选择视频输出驱动。%1 可提供最佳性能。 %1 is the recommended one. Try to avoid %2 and %3, they are slow and can have an impact on performance. 推荐使用 %1。尽量避免 %2 和 %3,它们速度很慢,且会影响性能。 Usually SMPlayer will remember the settings for each file you play (audio track selected, volume, filters...). Disable this option if you don't like this feature. 通常视频播放器将记住您所播放的每个文件的设置(音轨选择、音量、过滤器...)。如果您不喜欢这个功能,请禁用此选项。 If this option is enabled, the file will be paused when the main window is hidden. When the window is restored, playback will be resumed. 如果启用此选项,主窗口处于隐藏状态时,文件将被暂停。窗口还原时,将恢复播放。 Preview when the video is playing 视频播放时进行预览 If this option is enabled, the video preview will be displayed when the mouse is placed on the progress bar. 如果此选项打开,则当鼠标放置在进度条上时,会显示视频预览图。 Select MPlayer as playback engine 选择 MPlayer 作为播放引擎 If you change the playback engine to MPlayer, please restart Kylin Video. 如果你切换播放引擎为MPlayer,请重启麒麟影音。 Select MPV as playback engine 选择 MPV 作为播放引擎 If you change the playback engine to MPV, please restart Kylin Video. 如果你切换播放引擎为MPV,请重启麒麟影音。 Check this option to disable the screensaver while playing.<br>The screensaver will enabled again when play finishes. 勾选此选项可在播放时禁用屏幕保护程序。<br>播放结束时屏幕保护程序将再次启用。 Here you can type your preferred language for the audio streams. When a media with multiple audio streams is found, SMPlayer will try to use your preferred language.<br>This only will work with media that offer info about the language of the audio streams, like DVDs or mkv files.<br>This field accepts regular expressions. Example: <b>es|esp|spa</b> will select the audio track if it matches with <i>es</i>, <i>esp</i> or <i>spa</i>. 在这里您可以键入您的音频流首选语言。当发现媒体具有多个音频流时,视频播放器将尝试使用您的首选语言。<br>这仅工作于提供音频流语言信息的媒体,比如 DVD 或 MKV 文件。<br>这些字段接受正则表达式。示例: <b>es|esp|spa</b> 将选择匹配 <i>es</i>、<i>esp</i> 或 <i>spa</i> 的音轨。 Here you can type your preferred language for the subtitle stream. When a media with multiple subtitle streams is found, SMPlayer will try to use your preferred language.<br>This only will work with media that offer info about the language of the subtitle streams, like DVDs or mkv files.<br>This field accepts regular expressions. Example: <b>es|esp|spa</b> will select the subtitle stream if it matches with <i>es</i>, <i>esp</i> or <i>spa</i>. 在这里您可以键入您的字幕流首选语言。当发现媒体具有多个字幕流时,视频播放器将尝试使用您的首选语言。<br>这仅工作于提供字幕流语言信息的媒体,比如 DVD 或 MKV 文件。<br>这些字段接受正则表达式。示例: <b>es|esp|spa</b> 将选择匹配 <i>es</i>、<i>esp</i> 或 <i>spa</i> 的字幕流。 Ou&tput driver: 输出驱动(&T): Add black borders on fullscreen 全屏时添加黑边 If this option is enabled, black borders will be added to the image in fullscreen mode. This allows subtitles to be displayed on the black borders. 如果启用此选项,则会在全屏模式的图像上添加黑色边框。这将允许字幕显示在黑色边框上。 &Add black borders on fullscreen 全屏时添加黑边(&A) one ini file 一个 ini 文件 multiple ini files 多个 ini 文件 Method to store the file settings 存储文件设置的方法 This option allows you to change the way the file settings would be stored. The following options are available: 此选项允许更改存储文件设置的方式。可使用以下选项: <b>one ini file</b>: the settings for all played files will be saved in a single ini file (%1) <b>一个 ini 文件</b>: 所有播放过的文件的设置将被保存于单个 ini 文件(%1)中 The latter method could be faster if there is info for a lot of files. 如果有大量的文件信息,后一种方法可能会更快。 &Store settings in 存储设置于(&S) <b>multiple ini files</b>: one ini file will be used for each played file. Those ini files will be saved in the folder %1 <b>多个 ini 文件</b>: 每个播放过的文件都将使用其自己的 ini 文件。这些 ini 文件将被保存于文件夹 %1 中 If you check this option, SMPlayer will remember the last position of the file when you open it again. This option works only with regular files (not with DVDs, CDs, URLs...). 如果您勾选此选项,视频播放器将记住文件的最后播放位置,当您再次打开它时可由该位置开始播放。此选项仅适用于常规文件(不包括 DVD、CD、URL...)。 If checked, turns on direct rendering (not supported by all codecs and video outputs)<br><b>Warning:</b> May cause OSD/SUB corruption! 如果勾选,将打开直接渲染(还不被所有的编解码器和视频输出支持)<br><b>警告:</b> 可能会导致 OSD (屏幕显示)/SUB 的讹误! Requests the number of playback channels. MPlayer asks the decoder to decode the audio into as many channels as specified. Then it is up to the decoder to fulfill the requirement. This is usually only important when playing videos with AC3 audio (like DVDs). In that case liba52 does the decoding by default and correctly downmixes the audio into the requested number of channels. <b>Note</b>: This option is honored by codecs (AC3 only), filters (surround) and audio output drivers (OSS at least). 指定播放声道的数量。MPlayer 告诉解码器需要将音频解码成多少声道,再由解码器来实现此需求。通常只有在播放带有 AC3 音频(比如 DVD)的视频时才有用。在该情况下将默认使用 liba52 解码并把音频正确地混合成需要的声道数量。<b>注意</b>: 此选项需要 编码(仅 AC3)、过滤器(环绕声)和音频输出驱动(OSS或更高级)三者都满足。 Enable screenshots 启用屏幕截图 You can use this option to enable or disable the possibility to take screenshots. 您可以使用此选项启用或禁用是否可以进行屏幕截图。 Here you can specify a folder where the screenshots taken by SMPlayer will be stored. If the folder is not valid the screenshot feature will be disabled. 在这里您可以指定一个视频播放器将用来存储屏幕截图的文件夹。如果文件夹是无效的,屏幕截图功能将被禁用。 Screenshots 屏幕截图 &Enable screenshots 启用屏幕截图(&E) &Folder: 文件夹(&F): Global volume 全局音量 If this option is checked, the same volume will be used for all files you play. If the option is not checked each file uses its own volume. 如果勾选此选项,您播放的所有文件都将使用相同的音量。如果此选项未被勾选,每个文件将使用其自己的音量。 This option also applies for the mute control. 此选项也适用于静音控制。 Glo&bal volume 全局音量(&B) Switch screensaver off 切换关闭屏幕保护程序 This option switches the screensaver off just before starting to play a file and switches it on when playback finishes. If this option is enabled, the screensaver won't appear even if playing audio files or when a file is paused. 此选项仅在开始播放文件之前切换关闭屏幕保护程序,当播放结束时将切换开启屏幕保护程序。如果启用此选项,即使是播放音频文件或文件暂停时,屏幕保护程序也不会出现。 Avoid screensaver 避免屏幕保护程序 When this option is checked, SMPlayer will try to prevent the screensaver to be shown when playing a video file. The screensaver will be allowed to be shown if playing an audio file or in pause mode. This option only works if the SMPlayer window is in the foreground. 勾选此选项时,视频播放器将尝试阻止在播放视频文件时显示屏幕保护程序。如果是播放音频文件或处于暂停模式,屏幕保护程序将被允许显示。此选项仅适用于视频播放器窗口位于前台时。 Screensaver 屏幕保护程序 Swit&ch screensaver off 切换关闭屏幕保护程序(&C) Avoid &screensaver 避免屏幕保护程序(&S) Audio/video auto synchronization 音频/视频自动同步 Gradually adjusts the A/V sync based on audio delay measurements. 基于音频延迟的测量值逐步调整 A/V 同步。 A-V sync correction A-V 同步修正 Maximum A-V sync correction per frame (in seconds) 每帧的最大 A-V 同步修正(以秒为单位) Synchronization 同步 Audio/video auto &synchronization 音频/视频自动同步(&S) &Factor: 因子(&F): A-V sync &correction A-V 同步修正(&C) &Max. correction: 最大修正(&M): <b>Note:</b> This option won't be used for TV channels. <b>注意:</b> 此选项不会用于电视频道。 Dei&nterlace by default (except for TV): 默认去交错(不包括电视)(&N): Uses hardware AC3 passthrough. 使用硬件 AC3 直通输出。 <b>Note:</b> none of the audio filters will be used when this option is enabled. <b>注意:</b> 启用此选项时将不会使用音频过滤器。 snap mode Snap 模式 slower dive mode 较慢的 DIVE 模式 uniaud mode UniAud 模式 dart mode DART 模式 %1 is the recommended one. %2 is only available on older MPlayer (before version %3) 推荐使用 %1。%2 仅适用于较旧的 MPlayer (%3 之前的版本) Configu&re... 配置(&R)... PrefInput Keyboard and mouse 键盘和鼠标 &Keyboard 键盘(&K) &Mouse 鼠标(&M) Button functions: 按钮功能: Don't &trigger the left click action with a double click 不要用双击来触发左击(&t) Media seeking 媒体定位 Volume control 音量控制 Zoom video 缩放视频 None Here you can change any key shortcut. To do it double click or press enter over a shortcut cell. Optionally you can also save the list to share it with other people or load it in another computer. 在这里您可以更改任何快捷键。要做到这一点,请在一个快捷键单元格上双击或按回车。您也可以选择保存该列表以与其他人分享,或在另一台计算机上加载。 Here you can change any key shortcut. To do it double click or start typing over a shortcut cell. Optionally you can also save the list to share it with other people or load it in another computer. 在这里您可以更改任何快捷键。要做到这一点,请在一个快捷键单元格上双击以开始键入。您也可以选择保存该列表以与其他人分享,或在另一台计算机上加载。 &Left click 左键单击(&L) &Double click 双击(&D) &Wheel function: 滚轮功能(&W): Shortcut editor 快捷键编辑器 This table allows you to change the key shortcuts of most available actions. Double click or press enter on a item, or press the <b>Change shortcut</b> button to enter in the <i>Modify shortcut</i> dialog. There are two ways to change a shortcut: if the <b>Capture</b> button is on then just press the new key or combination of keys that you want to assign for the action (unfortunately this doesn't work for all keys). If the <b>Capture</b> button is off then you could enter the full name of the key. 此表格允许您更改大多数现有动作的快捷键。在一个项目上双击或按回车,或按 <b>更改快捷键</b> 按钮可进入 <i>修改快捷键</i> 对话框。有两种方法来更改快捷键: 如果 <b>捕捉</b> 按钮已启用,那么只需按下您想要指派给此动作的新按键或组合键(很遗憾这并不适用于所有的按键)。如果 <b>捕捉</b> 按钮已关闭,那么您可以输入按键的完整名称。 Left click 左键单击 Select the action for left click on the mouse. 选择单击鼠标左键的动作。 Double click 双击 Select the action for double click on the mouse. 选择双击鼠标的动作。 Wheel function 滚轮功能 Select the action for the mouse wheel. 选择鼠标滚轮的动作。 Play 播放 Pause 暂停 Stop 停止 Fullscreen 全屏 Compact 简洁模式 Screenshot 屏幕截图 Mute 静音 Frame counter 帧计数器 Reset zoom 重置缩放 Exit fullscreen 退出全屏 Double size 双倍大小 Play / Pause 播放/暂停 Pause / Frame step 暂停/逐帧步进 Playlist 播放列表 Preferences 首选项 No function 无功能 Change speed 更改速度 Normal speed 正常速度 Keyboard 键盘 Mouse 鼠标 Middle click 中键单击 Select the action for middle click on the mouse. 选择单击鼠标中键的动作。 M&iddle click 中键单击(&I) X Button &1 X 按钮 1(&1) X Button &2 X 按钮 2(&2) Go backward (short) 后退(短) Go backward (medium) 后退(中) Go backward (long) 后退(长) Go forward (short) 前进(短) Go forward (medium) 前进(中) Go forward (long) 前进(长) OSD - Next level 屏幕显示 - 下一层 Show context menu 显示上下文菜单 &Right click 右键单击(&R) Increase volume 增加音量 Decrease volume 降低音量 X Button 1 X 按钮 1 Select the action for the X button 1. 选择 X 按钮 1 的动作。 X Button 2 X 按钮 2 Select the action for the X button 2. 选择 X 按钮 2 的动作。 Show video equalizer 显示视频均衡器 Show audio equalizer 显示音频均衡器 Always on top 始终在最前端 Never on top 从不在最前端 On top while playing 当播放时在最前端 Next chapter 下一个章节 Previous chapter 上一个章节 Activate option under mouse in DVD menus 激活 DVD 菜单中的选项 Return to main DVD menu 返回 DVD 主菜单 Return to previous menu in DVD menus 返回上一级 DVD 菜单 Move cursor up in DVD menus DVD 菜单中向上移动光标 Move cursor down in DVD menus DVD 菜单中向下移动光标 Move cursor left in DVD menus DVD 菜单中向左移动光标 Move cursor right in DVD menus DVD 菜单中向右移动光标 Activate highlighted option in DVD menus 激活 DVD 菜单中高亮显示的选项 Don't trigger the left click function with a double click 不要用双击来触发左击(&t) If this option is enabled when you double click on the video area only the double click function will be triggered. The left click action won't be activated. 如果开启此选项,当你在视频区域双击时,只会触发双击行为。左键行为不会被启动 By enabling this option the left click is delayed %1 milliseconds because it's necessary to wait that time to know if there's a double click or not. 启用此项,左击后会先有个%1毫秒的延迟,再执行单击操作,如果此延迟内再次单击,则是双击操作。 Change function of wheel 更改滚轮功能 Media &seeking 媒体定位(&S) &Zoom video 缩放视频(&Z) &Volume control 音量控制(&V) &Change speed 更改速度(&C) Mouse wheel functions 鼠标滚轮功能 Check it to enable seeking as one function. 勾选它以启用"定位"作为一个功能。 Check it to enable changing volume as one function. 勾选它以启用"更改音量"作为一个功能。 Check it to enable zooming as one function. 勾选它以启用"缩放"作为一个功能。 Check it to enable changing speed as one function. 勾选它以启用"更改速度"作为一个功能。 M&ouse wheel functions 鼠标滚轮功能(&O) Select the actions that should be cycled through when using the "Change function of wheel" option. 选择使用"更改滚轮功能"选项时应循环的动作。 Reverse mouse wheel seeking 反向滚轮媒体定位 Check it to seek in the opposite direction. 勾选它以启用"反向定位"。 R&everse wheel media seeking 反向滚轮媒体定位(&E) PrefInterface Interface 界面 <Autodetect> <自动检测> Default 默认 &Interface 界面(&I) Never 从不 Whenever it's needed 当需要时 Only after loading a new video 仅在加载新视频后 Privac&y 隐私(&Y) Recent files 最近的文件 Language 语言 Here you can change the language of the application. 在这里您可以更改应用程序的语言。 &Short jump 短跳转(&S) &Medium jump 中等跳转(&M) &Long jump 长跳转(&L) Mouse &wheel jump 鼠标滚轮跳转(&W) &Use only one running instance of SMPlayer 仅使用一个正在运行的视频播放器实例(&U) Ma&x. items 最大项目数(&X) St&yle: 样式(&Y): Ico&n set: 图标集(&N): L&anguage: 语言(&A): Main window 主窗口 Auto&resize: 自动调整大小(&R): Center &window 居中窗口(&w) R&emember position and size 记住位置和大小(&E) &Move the window when the video area is dragged 拖动视频区域时移动窗口(&M) S&kin: 皮肤(K): Default font: 默认字体: &Change... 更改(&C)... &Behaviour of time slider: 时间滑块行为(&B): Seek to position while dragging 定位到拖动时的位置 Seek to position when released 定位到放开时的位置 Pressi&ng the stop button once resets the time position 按下停止按钮会重置时间位置(&N) The floating control appears in fullscreen mode when the mouse is moved. 全屏模式下当鼠标移动时浮动控制将会出现。 Show only when moving the mouse to the &bottom of the screen 仅在鼠标移动到屏幕底部时出现(&b) Tim&e (in milliseconds) to hide the control: 隐藏控制条的时间(毫秒): URLs URL &Max. items 最大项目数(&M) &Remember last directory 记住上次的目录(&R) TextLabel 文本标签 &Seeking 定位(&S) &Absolute seeking 绝对定位(&A) &Relative seeking 相对定位(&R) Ins&tances 实例(&T) Autoresize 自动调整大小 The main window can be resized automatically. Select the option you prefer. 主窗口可以自动调整大小。请选择您喜欢的选项。 Remember position and size 记住位置和大小 If you check this option, the position and size of the main window will be saved and restored when you run SMPlayer again. 如果您勾选此选项,主窗口的位置和大小将被保存,当您再次运行视频播放器时将恢复它们。 Select the graphic interface you prefer for the application. 选择您喜欢的程序外观。 The <b>Basic GUI</b> provides the traditional interface, with the toolbar and control bar. <b>基础 GUI</b> 提供传统的界面,拥有工具栏和控制栏 The <b>Mini GUI</b> provides a more simple interface, without toolbar and a control bar with few buttons. <b>迷你 GUI</b> 提供一个更为简洁的界面,没有工具栏,有一个拥有很少按钮的控制栏 The <b>Skinnable GUI</b> provides an interface where several skins are available. <b>可换肤 GUI</b>提供一个支持皮肤的界面 The <b>Mpc GUI</b> looks like the interface in Media Player Classic. <b>Mpc GUI</b> 界面和 Media Player Classic 长得很像 Privacy 隐私 Select the maximum number of items that will be shown in the <b>Open->Recent files</b> submenu. If you set it to 0 that menu won't be shown at all. 选择将显示在 <b>打开 -> 最近的文件</b> 子菜单中的最大项目数。如果您将它设置为 0,将不会显示此菜单。 Icon set 图标集 Basic GUI 基础GUI Skinnable GUI 可换肤 GUI Center window 居中窗口 When this option is enabled, the main window will be centered on the desktop. 如果启用此选项,主窗口将会显示在桌面的正中央。 Move the window when the video area is dragged 拖动视频区域时移动窗口 If this option is checked, the main window will be moved if you drag the mouse over the video area. 如果此选项打开,如果用鼠标拖动视频区域时主窗口会跟着移动 Select the icon set you prefer for the application. 选择您喜欢的应用程序图标集。 Skin 皮肤 Select the skin you prefer for the application. Only available with the skinnable GUI. 选择您喜欢的应用程序皮肤。仅适用于"可换肤 GUI"。 Style 样式 Select the style you prefer for the application. 选择您喜欢的应用程序样式。 Default font 默认字体 You can change here the application's font. 您可以在这里更改应用程序的字体。 Seeking 定位 Short jump 短跳转 Select the time that should be go forward or backward when you choose the %1 action. 选择当您选定"%1"动作时应前进或后退的时间。 short jump 短跳转 Medium jump 中等跳转 medium jump 中等跳转 Long jump 长跳转 long jump 长跳转 Mouse wheel jump 鼠标滚轮跳转 Select the time that should be go forward or backward when you move the mouse wheel. 选择当您滚动鼠标滚轮时应前进或后退的时间。 Behaviour of time slider 时间滑块行为 Select what to do when dragging the time slider. 选择拖动时间滑块时该做什么。 Pressing the stop button once resets the time position 按下停止按钮会重置时间位置 By default when the stop button is pressed the time position is remembered so if you press play button the media will resume at the same point. You need to press the stop button twice to reset the time position, but if this option is checked the time position will be set to 0 with only once press of the stop button. 默认情况下,按下停止按钮后会记录时间位置再停止播放,下次按了播放键后会继续播放。你必须按两下停止按钮才能重置时间,如果勾选此项,只需按一下停止键就能将时间重置为0 Show only when moving the mouse to the bottom of the screen 仅在鼠标移动到屏幕底部时出现 If this option is checked, the floating control will only be displayed when the mouse is moved to the bottom of the screen. Otherwise the control will appear whenever the mouse is moved, no matter its position. 如果勾选此项,浮动控制条仅会在鼠标移动到屏幕底部时显示。否则浮动控制框只要在鼠标移动时就显示 If this option is enabled, the floating control will appear in compact mode too. 如果启用此选项,浮动控制条将出现在简洁模式中。 This option only works with the basic GUI. 此选项仅适用于基础GUI <b>Warning:</b> the floating control has not been designed for compact mode and it might not work properly. <b>警告:</b> 浮动控制条并不是为简洁模式而设计的,它可能无法正常工作。 Time to hide the control 隐藏控制条的时间 Sets the time (in milliseconds) to hide the control after the mouse went away from the control. 设置鼠标离开控制条后,控制条隐藏的时间(毫秒) Max. URLs URL Select the maximum number of items that the <b>Open->URL</b> dialog will remember. Set it to 0 if you don't want any URL to be stored. 选择 <b>打开 -> URL</b> 对话框将记住的最大项目数。如果您不想存储任何 URL,请将它设置为 0。 Remember last directory 记住上次的目录 If this option is checked, SMPlayer will remember the last folder you use to open a file. 如果勾选此选项,视频播放器将记住上次您用来打开文件时的文件夹。 Seeking method 定位方法 Sets the method to be used when seeking with the slider. Absolute seeking may be a little bit more accurate, while relative seeking may work better with files with a wrong length. 设置用滑块定位时所使用的方法。绝对定位可能更精确一点,而相对定位可以在文件有错误长度时更好地工作。 Instances 实例 Use only one running instance of SMPlayer 仅使用一个正在运行的视频播放器实例 Check this option if you want to use an already running instance of SMPlayer when opening other files. 如果您想要在打开其他文件时使用一个已经运行的视频播放器实例,请勾选此选项。 Mini GUI 迷你 GUI GUI GUI &GUI GUI(&G) Floating control 浮动控制条 Animated 动画 If this option is enabled, the floating control will appear with an animation. 如果启用此选项,浮动控制条将以动画形式出现。 Width 宽度 Specifies the width of the control (as a percentage). 指定浮动控制条的宽度(以百分比表示)。 Margin 边距 This option sets the number of pixels that the floating control will be away from the bottom of the screen. Useful when the screen is a TV, as the overscan might prevent the control to be visible. 此选项可设置浮动控制框与屏幕底部距离的像素数。当屏幕是电视时有用,因为过扫描可能会阻碍浮动控制的可见性。 Display in compact mode too 在简洁模式中显示 &Floating control 浮动控制条(&F) &Animated 动画(&A) &Width: 宽度(&W): 0 0 &Margin: 边距(&M): Display in &compact mode too 在简洁模式中显示(&C) Mpc GUI MPC GUI Hide video window when playing audio files 播放音频文件时隐藏视频窗口 If this option is enabled the video window will be hidden when playing audio files. 如果启用此选项,播放音频文件时视频窗口将被隐藏。 &Hide video window when playing audio files 播放音频文件时隐藏视频窗口(&H) Precise seeking 精确定位 If this option is enabled, seeks are more accurate but they can be a little bit slower. May not work with some video formats. 如果启用此选项,定位会更精确,但它稍有点慢。可能无法同一些视频格式正常工作。 Note: this option only works with MPlayer2 注意: 此选项仅适用于 MPlayer2 &Precise seeking 精确定位(&P) PrefNetwork &Youtube (and other sites) &Youtube (以及其他网站) &Enable Youtube internal support 启用 Youtube 内部支持 (&E) Playback &quality 播放质量 (&q) &User agent 用户代理 (&U) Enable &MPV's support for streaming sites 启用 &MPV 流媒体网站支持 &Proxy 代理(&P) &Enable proxy 启用代理(&E) &Host: 主机(&H): &Port: 端口(&P): &Username: 用户名(&U): Pa&ssword: 密码(&s): &Type: 类型(&T): HTTP HTTP SOCKS5 SOCKS5 Network 网络 Youtube Youtube Enable Youtube internal support 启用 Youtube 内部支持 If this option is checked, SMPlayer will try to play videos from Youtube URLs. 如果勾选此项,视频播放器将尝试从 Youtube 链接播放视频。 Youtube quality Youtube 质量 Select the preferred quality for youtube videos. 选择 Youtube 视频优先选用的画质质量。 User agent 用户代理 Set the user agent that SMPlayer will use when connecting to Youtube. 设置连接 Youtube 时使用的代理。 Enable MPV's support for streaming sites 启用 MPV 流媒体网站支持 If this option is checked, SMPlayer will try to play videos from streaming sites like Youtube, Dailymotion, Vimeo, Vevo, etc. 如果勾选此项,视频播放器将会尝试从 Youtube,DailyMotion,Vimeo,Vevo等流媒体网站播放视频。 Requires mpv and youtube-dl. 需要安装mpv和youtube-dl。 Proxy 代理 Enable proxy 启用代理 Enable/disable the use of the proxy. 启用/禁用代理功能。 Host 主机 The host name of the proxy. 代理服务器主机名。 Port 端口 The port of the proxy. 代理服务器端口号。 Username 用户名 If the proxy requires authentication, this sets the username. 如果代理需要认证,请在这里设置用户名。 Password 密码 The password for the proxy. <b>Warning:</b> the password will be saved as plain text in the configuration file. 代理服务器密码。<b>注意:</b>密码会以明文形式保存在配置文件中。 Type 类型 Select the proxy type to be used. 选择要使用的代理类型 PrefPerformance Performance 性能 &Performance 性能(&P) Priority 优先级 Select the priority for the MPlayer process. 选择 MPlayer 进程的优先级。 realtime 实时 high abovenormal 高于普通 normal 普通 belownormal 低于普通 idle 空闲 Decoding 解码中 Hardware &decoding 硬解 (&d) Cache for local files: 本地文件缓存: KB KB Cache for streams: 流缓存: Decode 解码 Threads for decoding (MPEG-1/2 and H.264 only): 解码线程(仅 MPEG-1/2 和 H.264): Form 表格 Setting a cache may improve performance on slow media 设置缓存可能会提高慢速媒体的性能 Allow frame drop 允许丢帧 Skip displaying some frames to maintain A/V sync on slow systems. 跳过显示一些帧从而在缓慢的系统上保持 A/V 同步。 Allow hard frame drop 允许严重丢帧 More intense frame dropping (breaks decoding). Leads to image distortion! 更加强烈的丢帧(中断解码过程)。将导致图像失真! Priorit&y: 优先级(&Y): &Allow frame drop 允许丢帧(&A) Allow &hard frame drop (can lead to image distortion) 允许严重丢帧(可导致图像失真)(&H) &Fast audio track switching 快速切换音轨(&F) Fast &seek to chapters in dvds 快速定位到 DVD 章节(&S) Fast audio track switching 快速切换音轨 Fast seek to chapters in dvds 快速定位到 DVD 章节 If checked, it will try the fastest method to seek to chapters but it might not work with some discs. 如果勾选,它将尝试以最快的方法定位到章节,但它可能无法工作于某些光盘。 Skip loop filter 跳过环路过滤器 H.264 H.264 Possible values:<br> <b>Yes</b>: it will try the fastest method to switch the audio track (it might not work with some formats).<br> <b>No</b>: the MPlayer process will be restarted whenever you change the audio track.<br> <b>Auto</b>: SMPlayer will decide what to do according to the MPlayer version. 可允许的值:<br> <b>是</b>: 它将尝试以最快的方法来切换音轨(它可能无法工作于某些格式)。<br> <b>否</b>: 每当您更改音轨,MPlayer 进程将重新启动。<br> <b>自动</b>: 视频播放器将根据 MPlayer 版本来决定如何做。 Cache for files 本地文件缓存 This option specifies how much memory (in kBytes) to use when precaching a file. 此选项可指定预缓存文件时要使用多少内存(以 KB 为单位)。 Cache for streams 流缓存 This option specifies how much memory (in kBytes) to use when precaching a URL. 此选项可指定预缓存 URL 时要使用多少内存(以 KB 为单位)。 Cache for DVDs DVD 缓存 This option specifies how much memory (in kBytes) to use when precaching a DVD.<br><b>Warning:</b> Seeking might not work properly (including chapter switching) when using a cache for DVDs. 此选项可指定预缓存 DVD 时要使用多少内存(以 KB 为单位)。<br><b>警告:</b> 使用 DVD 缓存时定位可能无法正常工作(包括章节切换)。 &Cache 缓存(&C) Cache for &DVDs: DVD 缓存(&D): Cache for &local files: 本地文件缓存(&L): Cache for &streams: 流缓存(&S): Enabled 启用 Skip (always) 跳过(始终) Skip only on HD videos 仅跳过高清视频 Loop &filter 环路过滤器(&F) Try to use non-free CoreAVC codec when no other codec is specified and non-VDPAU video output selected. Requires MPlayer build with CoreAVC support. 没有指定其他编解码器和选择了非 VDPAU 视频输出时,将尝试使用非自由的 CoreAVC 编解码器。需要 MPlayer 构建有 CoreAVC 支持。 This option allows you to skips the loop filter (AKA deblocking) during H.264 decoding. Since the filtered frame is supposed to be used as reference for decoding dependent frames this has a worse effect on quality than not doing deblocking on e.g. MPEG-2 video. But at least for high bitrate HDTV this provides a big speedup with no visible quality loss. 此选项允许在 H.264 解码期间跳过环路过滤器(也叫做"去块")。因为经过过滤的帧会被当作解码依赖帧引用,而在质量上这比不对视频(例如 MPEG-2)进行去块的效果更差。但是去块至少对高比特率的 HDTV 提供了不损失视觉品质的大幅加速。 None Auto 自动 Hardware decoding 硬件解码 Sets the hardware video decoding API. If hardware decoding is not possible, software decoding will be used instead. 设置硬件解码 API。如果无法使用硬解,则会使用软解。 Available options: 可用选项: None: only software decoding will be used. 无:仅用软解。 Auto: it tries to automatically enable hardware decoding using the first available method. 自动:自动尝试使用第一种可用的硬解方式。 vdpau: for the vdpau and opengl video outputs. vdpau:用于 vdpau 以及 opengl 显示输出。 vaapi: for the opengl and vaapi video outputs. For Intel GPUs only. vaapi:用于 opengl 以及 vaapi 视频输出。仅支持 Intel GPU。 vaapi-copy: it copies video back into system RAM. For Intel GPUs only. vaapi-copy:将视频拷贝回系统内存中。仅支持 Intel GPU。 dxva2-copy: it copies video back to system RAM. Experimental. dxva2-copy:将视频拷贝回系统内存中。试验性功能。 This option only works with mpv. 此选项仅支持 mpv。 Possible values: 可允许的值: <b>Enabled</b>: the loop filter is not skipped <b>启用</b>: 不跳过环路过滤器 <b>Skip (always)</b>: the loop filter is skipped no matter the resolution of the video <b>跳过(始终)</b>: 跳过环路过滤器,不论视频的分辨率 <b>Skip only on HD videos</b>: the loop filter will be skipped only on videos which height is %1 or greater. <b>仅跳过高清视频</b>: 仅在视频高度是 %1 或更高时环路过滤器将被跳过。 Cache 缓存 Cache for audio CDs 音频 CD 缓存 This option specifies how much memory (in kBytes) to use when precaching an audio CD. 此选项可指定预缓存音频 CD 时要使用多少内存(以 KB 为单位)。 Cache for &audio CDs: 音频 CD 缓存(&A): Cache for VCDs VCD 缓存 This option specifies how much memory (in kBytes) to use when precaching a VCD. 此选项可指定预缓存 VCD 时要使用多少内存(以 KB 为单位)。 Cache for &VCDs: VCD 缓存(&V): Threads for decoding 解码线程 Sets the number of threads to use for decoding. Only for MPEG-1/2 and H.264 设置要用于解码的线程数。仅适用于 MPEG-1/2 和 H.264 &Threads for decoding (MPEG-1/2 and H.264 only): 解码线程(仅 MPEG-1/2 和 H.264)(&T): Set process priority for mplayer according to the predefined priorities available under Windows.<br><b>Warning:</b> Using realtime priority can cause system lockup. 根据 Windows 下可用的预定义优先级设置 MPlayer 进程的优先级。<br><b>警告:</b> 使用实时优先级会导致系统锁死。 Use CoreAVC if no other codec specified 没有指定其他编解码器时使用 CoreAVC &Use CoreAVC if no other codec specified 没有指定其他编解码器时使用 CoreAVC(&U) Cache for &TV: 电视缓存(&T): PrefPlaylist Playlist 播放列表 Automatically add files to playlist 自动将文件添加到播放列表 If this option is enabled, every time a file is opened, SMPlayer will first clear the playlist and then add the file to it. In case of DVDs, CDs and VCDs, all titles in the disc will be added to the playlist. 如果启用此选项,每当打开一个文件时,视频播放器将先清除播放列表,然后再将该文件添加到其中。若是 DVD、CD 和 VCD,光盘中的所有标题都将被添加到播放列表。 None Video files 视频文件 Audio files 音频 Video and audio files 视频和音频文件 Consecutive files 连续的文件 Add files from folder 从文件夹添加 This option allows you to add files automatically to the playlist: 此选项允许自动添加文件到列表 <b>None</b>: no files will be added <b>空</b>: 不会添加任何文件 <b>Video files</b>: all video files found in the folder will be added <b>视频文件</b>: 文件夹中所有视频文件都会被添加 <b>Audio files</b>: all audio files found in the folder will be added <b>音频文件</b>: 文件夹中所有音频文件都会被添加 <b>Video and audio files</b>: all video and audio files found in the folder will be added <b>视频和音频文件</b>: 文件夹中所有视频和音频文件都会被添加 <b>Consecutive files</b>: consecutive files (like video_1.avi, video_2.avi) will be added <b>连续文件</b>: 连续文件(如 video_1.avi, video_2.avi)会被添加 Play files from start 从开头播放文件 If this option is enabled, all files from the playlist will start to play from the beginning instead of resuming from a previous playback. 如果打开此选项,所有播放列表里的文件都会从开始播放而不是从上次播放停止位置开始。 Get info automatically about files added 自动获取新添加文件的信息 Save copy of playlist on exit 退出时保存播放列表的副本 If this option is checked, a copy of the playlist will be saved in the smplayer configuration when smplayer is closed, and it will reloaded automatically when smplayer is run again. 如果勾选此项,当smplayer关闭时,一个播放列表的副本会被保存在smplayer配置文件夹下,在下次smplayer运行时重新载入此文件。 Play next file even if the previous file failed 上个文件播放失败时继续播放下个文件 If this option is enabled, the playlist will ignore playback errors from a previous file and will play the next file in the list. 如果启用此项,播放列表将会忽略此错误并继续播放下个文件。 &Playlist 播放列表(&P) &Automatically add files to playlist 自动将文件添加到播放列表(&A) Add files in directories recursively 添加子目录中的文件 Check this option if you want that adding a directory will also add the files in subdirectories recursively. Otherwise only the files in the selected directory will be added. 如果您想在添加一个目录时也递归添加子目录中的文件,请勾选此选项。否则将只添加所选目录中的文件。 Check this option to inquire the files to be added to the playlist for some info. That allows you to show the title name (if available) and length of the files. Otherwise this info won't be available until the file is actually played. Beware: this option can be slow, specially if you add many files. 勾选此选项可以查询文件添加到播放列表中的一些信息。这将允许显示文件的标题名称(如果可用)和长度。否则在文件被实际播放之前这些信息将不可用。注意: 这个选项可能会很慢,特别是当您添加的文件过多时。 Add files from &folder: 从文件夹添加(&f) P&lay files from start 从开始处播放文件(&L) Add files in directories &recursively 添加子目录中的文件(&R) Get &info automatically about files added (slow) 自动获取文件的信息(较慢)(&I) &Save copy of playlist on exit 退出时保存播放列表的副本(&S) Play &next file even if the previous file failed 上个文件播放失败时继续播放下个文件 (&n) PrefScreenShot &ScreenShot 屏幕截图(&S) Screenshots 屏幕截图 Folder: 文件夹: Template: 模板: Format: 格式: &Enable screenshots 启用屏幕截图(&E) &Folder: 文件夹(&F): Temp&late: 模板(&l): F&ormat: 格式(&o) : Select a directory 选择一个目录 Enable screenshots 启用屏幕截图 You can use this option to enable or disable the possibility to take screenshots. 您可以使用此选项启用或禁用是否可以进行屏幕截图。 Screenshots folder 屏幕截图文件夹 Here you can specify a folder where the screenshots taken by Kylin Video will be stored. If the folder is not valid the screenshot feature will be disabled. 在这里您可以指定一个麒麟影音将用来存储屏幕截图的文件夹。如果文件夹是无效的,屏幕截图功能将被禁用。 Template for screenshots 屏幕截图模板 This option specifies the filename template used to save screenshots. 此选项定义保存视频截屏时使用的文件名模板。 For example %1 would save the screenshot as 'moviename_0001.png'. 例如,%1 将会将截图保存为 ‘moviename_0001.png’ 。 %1 specifies the filename of the video without the extension, %2 adds a 4 digit number padded with zeros. %1 指定视频的文件名(不含扩展名), %2 在之后添加 4位数,不够的用0填充。 For a full list of the template specifiers visit this link: 完整模板说明符列表请访问此链接: This option only works with mpv. 此选项仅适用于mpv。 Format for screenshots 截屏样式 This option allows you to choose the image file type used for saving screenshots. 此选项让您选择视频截图的格式。 PrefShortCut Here you can change any key shortcut. To do it double click or press enter over a shortcut cell. 在这里您可以更改任何快捷键。要做到这一点,请在一个快捷键单元格上双击或按回车。 ShortCut 快捷键 Here you can change any key shortcut. To do it double click or start typing over a shortcut cell. 在这里您可以更改任何快捷键。要做到这一点,请在一个快捷键单元格上双击或按回车。 Shortcut Key 快捷键 Shortcut editor 快捷键编辑器 This table allows you to change the key shortcuts of most available actions. Double click or press enter on a item, or press the <b>Change shortcut</b> button to enter in the <i>Modify shortcut</i> dialog. There are two ways to change a shortcut: if the <b>Capture</b> button is on then just press the new key or combination of keys that you want to assign for the action (unfortunately this doesn't work for all keys). If the <b>Capture</b> button is off then you could enter the full name of the key. 此表格允许您更改大多数现有动作的快捷键。在一个项目上双击或按回车,或按 <b>更改快捷键</b> 按钮可进入 <i>修改快捷键</i> 对话框。有两种方法来更改快捷键: 如果 <b>捕捉</b> 按钮已启用,那么只需按下您想要指派给此动作的新按键或组合键(很遗憾这并不适用于所有的按键)。如果 <b>捕捉</b> 按钮已关闭,那么您可以输入按键的完整名称。 PrefSubtitles Subtitles 字幕 &Subtitles 字幕(&S) Autoload 自动加载字幕文件 Autoload subtitles files (*.srt, *.sub...): 自动加载字幕文件(*.srt、*.sub...): Same name as movie 与影片的名称相同 All subs containing movie name 所有包含影片名称的字幕 All subs in directory 目录中的所有字幕 Default subtitle encoding: 默认字幕编码: Try to autodetect for this language: 尝试自动检测此语言: Use the &ASS library 使用 ASS 库(&A) Enable &Windows fonts 启用 Windows 字体(&W) Font 字体 Size 大小 Au&toload subtitles files (*.srt, *.sub...): 自动加载字幕文件(*.srt、*.sub...)(&T): S&elect first available subtitle 选择首个可用的字幕(&E) &Default subtitle encoding: 默认字幕编码(&D): &Include subtitles on screenshots 屏幕截图时包含字幕(&I) Select first available subtitle 选择首个可用的字幕 Default subtitle encoding 默认字幕编码 Include subtitles on screenshots 屏幕截图时包含字幕 Text color 文本颜色 Select the color for the text of the subtitles. 选择字幕的文本颜色。 Border color 边框颜色 Select the color for the border of the subtitles. 选择字幕的边框颜色。 Select the subtitle autoload method. 选择字幕的自动加载方法。 If there are one or more subtitle tracks available, one of them will be automatically selected, usually the first one, although if one of them matches the user's preferred language that one will be used instead. 如果有一个或多个字幕轨道可用,其中一个将被自动选择,通常是第一个,但如果其中一个匹配用户的首选语言,将会改为使用该字幕。 Select the encoding which will be used for subtitle files by default. 选择将用于字幕文件的默认编码。 Try to autodetect for this language 尝试自动检测此语言 When this option is on, the encoding of the subtitles will be tried to be autodetected for the given language. It will fall back to the default encoding if the autodetection fails. This option requires a MPlayer compiled with ENCA support. 开启此选项时,将尝试自动检测指定语言的字幕编码。如果自动检测失败,它将退回到默认的编码。此选项需要 MPlayer 编译有 ENCA 支持。 Subtitle language 字幕语言 Select the language for which you want the encoding to be guessed automatically. 选择您想要用于自动推测编码的语言。 Encoding 编码 Try to a&utodetect for this language: 尝试自动检测此语言(&U): Outline 轮廓 Select the font for the subtitles. 选择字幕的字体。 Use the ASS library 使用 ASS 库 This option enables the ASS library, which allows you to display subtitles with multiple colors, fonts... 此选项会启用 ASS 库,这允许字幕以多种颜色,字体显示... You should normally not disable this option. Do it only if your MPlayer is compiled without freetype support. <b>Disabling this option could make subtitles not to work at all!</b> 您通常不应禁用该选项。除非您的 MPlayer 编译时没有启用 FreeType 支持。<b>禁用该选项可能导致字幕无法工作!</b> Enable Windows fonts 启用 Windows 字体 If this option is enabled the Windows system fonts will be available for subtitles. There's an inconvenience: a font cache have to be created which can take some time. 如果启用此项那么Windows 系统字体将会用于字幕显示。不过有个不便:需要花时间创建字体缓存。 If this option is not checked then only a few fonts bundled with SMPlayer can be used, but this is faster. 如果不勾选此项,那只有视频播放器内置的字体可用,但是更快。 The size in pixels. 以像素为单位的大小。 Bold 粗体 If checked, the text will be displayed in <b>bold</b>. 如果勾选,将以 <b>粗体</b> 显示文本。 Italic 斜体 If checked, the text will be displayed in <i>italic</i>. 如果勾选,将以 <i>斜体</i> 显示文本。 Left margin 左边距 Specifies the left margin in pixels. 以像素为单位指定左边距。 Right margin 右边距 Specifies the right margin in pixels. 以像素为单位指定右边距。 Vertical margin 垂直边距 Specifies the vertical margin in pixels. 以像素为单位指定垂直边距。 Horizontal alignment 水平对齐 Specifies the horizontal alignment. Possible values are left, centered and right. 指定水平对齐方式。可允许的值有 左、居中和右。 Vertical alignment 垂直对齐 Specifies the vertical alignment. Possible values: bottom, middle and top. 指定垂直对齐方式。可允许的值: 底部、中部和顶部。 Border style 边框样式 Specifies the border style. Possible values: outline and opaque box. 指定边框样式。可允许的值: 轮廓和不透明框。 Shadow 阴影 Apply style to ASS files too 将风格也应用到 ASS 文件 Si&ze: 大小(&Z): Bol&d 粗体(&D) &Italic 斜体(&I) Colors 颜色 &Text: 文本(&T): &Border: 边框(&B): Margins 边距 L&eft: 左(&E): &Right: 右(&R): Verti&cal: 垂直(&C): Alignment 对齐方式 &Horizontal: 水平(&H): &Vertical: 垂直(&V): Border st&yle: 边框样式(&Y): &Outline: 轮廓(&O): Shado&w: 阴影(&W): A&pply style to ASS files too 将风格也应用到 ASS 文件(&p) Use custo&m style 使用自定义风格 (&m) The following options allows you to define the style to be used for non-styled subtitles (srt, sub...). 下面的选项允许您定义用于无样式字幕(srt、sub...)的样式。 Left horizontal alignment Centered horizontal alignment 居中 Right horizontal alignment Bottom vertical alignment 底部 Middle vertical alignment 中部 Top vertical alignment 顶部 Outline border style 轮廓 Opaque box border style 不透明框 If border style is set to <i>outline</i>, this option specifies the width of the outline around the text in pixels. 如果边框样式设置为 <i>轮廓</i>,此选项将以像素为单位指定文本周围轮廓的宽度。 If border style is set to <i>outline</i>, this option specifies the depth of the drop shadow behind the text in pixels. 如果边框样式设置为 <i>轮廓</i>,此选项将以像素为单位指定文本后面阴影效果的深度。 This option does NOT change the size of the subtitles in the current video. To do so, use the options <i>Size+</i> and <i>Size-</i> in the subtitles menu. 此选项不会更改当前视频的字幕大小。要执行此操作,请使用字幕菜单中的 <i>大小+</i> 和 <i>大小-</i> 选项。 Default scale 默认缩放 This option specifies the default font scale for SSA/ASS subtitles which will be used for new opened files. 此选项可为新打开的文件指定用于 SSA/ASS 字幕的默认字体缩放。 Line spacing 行距 This specifies the spacing that will be used to separate multiple lines. It can have negative values. 指定将用于分隔多行的间距。它可以是负值。 &Font and colors 字体和颜色(&F) Defa&ult scale: 默认缩放(&U): &Line spacing: 行距(&L): Freetype support FreeType 支持 Freet&ype support FreeType 支持(&Y) If this option is checked, the subtitles will appear in the screenshots. <b>Note:</b> it may cause some troubles sometimes. 如果勾选此选项,字幕将出现在屏幕截图中。<b>注意:</b> 它有时可能会引起一些故障。 Customize SSA/ASS style 自定义 SSA/ASS 样式 Here you can enter your customized SSA/ASS style. 在这里您可以输入您的自定义 SSA/ASS 样式。 Clear the edit line to disable the customized style. 清除编辑行以禁用自定义样式。 SSA/ASS style SSA/ASS 样式 Shadow color 阴影颜色 This color will be used for the shadow of the subtitles. 此颜色将用于字幕的阴影。 Shadow: 阴影: Custo&mize... 自定义(&M)... If this option is checked, the style defined above will be applied to ass subtitles too. 如果勾选此选项,上面定义的样式将被应用到 ASS 字幕。 PrefTV TV and radio 电视和广播 None Lowpass5 Lowpass5 Yadif (normal) Yadif (标准) Yadif (double framerate) Yadif (双倍帧率) Linear Blend 线性混合 Kerndeint Kerndeint Deinterlace by default for TV 默认电视去交错 Select the deinterlace filter that you want to be used for TV channels. 选择您想要用于电视频道的去交错过滤器。 Rescan ~/.mplayer/channels.conf on startup 启动时重新扫描 ~/.mplayer/channels.conf &TV and radio 电视和广播(&T) Dei&nterlace by default for TV: 默认电视去交错(&N): If this option is enabled, SMPlayer will look for new TV and radio channels on ~/.mplayer/channels.conf.ter or ~/.mplayer/channels.conf. 如果启用此选项,视频播放器将在 ~/.mplayer/channels.conf.ter 或 ~/.mplayer/channels.conf 中寻找新的电视和广播频道。 &Check for new channels on startup 启动时检查新频道(&C) PrefUpdates U&pdates 更新(U) Check for &updates 检查更新(&U) Check interval (in &days) 检查间隔(天) &Open an informative page after an upgrade 更新后打开介绍信息页面(&O) Updates 更新 Check for updates 检查更新 If this option is enabled, SMPlayer will check for updates and display a notification if a new version is available. 如果此项开启,视频播放器会检查并提示有更新 Check interval 检查间隔 You can enter here the interval (in days) for the update checks. 你可以输入检查更新的间隔(单位:天) Open an informative page after an upgrade 更新后打开介绍信息页面 If this option is enabled, an informative page about SMPlayer will be opened after an upgrade. 如果启用此项,在更新后会打开一个关于视频播放器的信息页面。 PrefVideo &Video 视频(&V) Ou&tput driver: 输出驱动(&T): &Enable postprocessing by default 默认启用后期处理(&E) Use s&oftware video equalizer 使用软件视频均衡器(&O) D&irect rendering 直接渲染(&I) Dou&ble buffering 双缓冲(&B) Dra&w video using slices 使用切片方式绘制视频(&W) Default 默认 slow 慢速 Video output driver 视频输出驱动 Select the video output driver. %1 provides the best performance. 选择视频输出驱动。%1 可提供最佳性能。 Enable postprocessing by default 默认启用后期处理 Use software video equalizer 使用软件视频均衡器 Output driver: 输出驱动: Postprocessing will be used by default on new opened files. 默认在新打开的文件上使用后期处理。 Software video equalizer 使用软件视频均衡器 You can check this option if video equalizer is not supported by your graphic card or the selected video output driver.<br><b>Note:</b> this option can be incompatible with some video output drivers. 如果您的显示卡或所选的视频输出驱动不支持视频均衡器,您可以勾选此选项。<br><b>注意:</b> 此选项可能与某些视频输出驱动不兼容。 Direct rendering 直接渲染 If checked, turns on direct rendering (not supported by all codecs and video outputs)<br><b>Warning:</b> May cause OSD/SUB corruption! 如果勾选,将打开直接渲染(还不被所有的编解码器和视频输出支持)<br><b>警告:</b> 可能会导致 OSD (屏幕显示)/SUB 的讹误! Double buffering 双缓冲 Double buffering fixes flicker by storing two frames in memory, and displaying one while decoding another. If disabled it can affect OSD negatively, but often removes OSD flickering. 通过在内存中存储两帧,在显示一帧的同时解码另一帧的双缓冲来修复闪烁问题。如果禁用它会对 OSD (屏幕显示)产生负面影响,但常常能去除 OSD (屏幕显示)的闪烁。 Draw video using slices 使用切片方式绘制视频 Enable/disable drawing video by 16-pixel height slices/bands. If disabled, the whole frame is drawn in a single run. May be faster or slower, depending on video card and available cache. It has effect only with libmpeg2 and libavcodec codecs. 启用/禁用以 16-像素高的片/带方式绘制视频。如果禁用,将一次运行绘制整个帧。可能更快或更慢,这取决于显卡和可用的缓存。它只对 libmpeg2 和 libavcodec 编解码器有效果。 PreferencesDialog SMPlayer - Help 视频播放器 - 帮助 General 常规 Video 视频 Audio 音频 Performance 性能 Subtitles 字幕 ScreenShot 屏幕截图 Shortcut Key 快捷键 Cache 缓存 OK 确定 Cancel 取消 Preference 设置 Apply 应用 Help 帮助 SMPlayer - Preferences 视频播放器 - 首选项 Kylin Video - Preferences 麒麟影音 - 设置 Kylin Video - Preference 麒麟影音 - 设置 QObject will show this message and then will exit. 将显示此消息,然后将退出。 the main window will be closed when the file/playlist finishes. 文件/播放列表结束时,主窗口将被关闭。 This is SMPlayer v. %1 running on %2 这是运行在 %2 上的视频播放器 v. %1 tries to make a connection to another running instance and send to it the specified action. Example: -send-action pause The rest of options (if any) will be ignored and the application will exit. It will return 0 on success or -1 on failure. 尝试连接到另一个正在运行的实例,然后向它发送指定的动作。示例: -send-action pause 其余的选项(如果有的话)将被忽略,应用程序将退出。它将在成功时返回 0,失败时返回 -1。 action_list is a list of actions separated by spaces. The actions will be executed just after loading the file (if any) in the same order you entered. For checkable actions you can pass true or false as parameter. Example: -actions "fullscreen compact true". Quotes are necessary in case you pass more than one action. "动作列表"是个由空格隔开的动作列表。动作将仅在加载文件(如果有的话)后按您输入的顺序执行。对于可选的动作,您可以传送 true 或 false 参数。示例: -actions "fullscreen compact true"。在您传送多个动作时必须要用引号。 media 媒体 if there's another instance running, the media will be added to that instance's playlist. If there's no other instance, this option will be ignored and the files will be opened in a new instance. 如果有另外一个实例正在运行,媒体将被添加到该实例的播放列表中。如果没有其他实例,此选项将被忽略,文件将被在一个新实例中打开。 the main window won't be closed when the file/playlist finishes. 文件/播放列表结束时,主窗口将不会被关闭。 the video will be played in fullscreen mode. 视频将在全屏模式下播放。 the video will be played in window mode. 视频将在窗口模式下播放。 Enqueue in SMPlayer 添加到视频播放器队列 opens the mini gui instead of the default one. 打开"迷你 GUI",而不是默认的。 Restores the old associations and cleans up the registry. 恢复原来的关联,然后清理注册表。 Usage: 用法: directory 目录 action_name 动作名称 action_list 动作列表 opens the default gui. 打开"默认 GUI" subtitle_file 字幕文件 specifies the subtitle file to be loaded for the first video. 指定将被首个视频加载的字幕文件。 %n second(s) %n秒 %n minute(s) %n分 %1 and %2 %1 和 %2 specifies the directory where smplayer will store its configuration files (smplayer.ini, smplayer_files.ini...) 指定视频播放器将存储其配置文件(smplayer.ini、smplayer_files.ini...)的目录位置 disabled aspect_ratio 禁用 auto aspect_ratio 自动 unknown aspect_ratio 未知 opens the mpc gui. 打开"MPC GUI" width 宽度 height 高度 opens the gui with support for skins. 打开可换肤 GUI sets the stay on top option to always. 设置为总是置顶。 sets the stay on top option to never. 设置永不置顶。 sets the media title for the first video. 为第一个视频设置媒体标题。 specifies the coordinates where the main window will be displayed. 指定将显示主窗口的坐标位置。 specifies the size of the main window. 指定主窗口的大小。 'media' is any kind of file that SMPlayer can open. It can be a local file, a DVD (e.g. dvd://1), an Internet stream (e.g. mms://....) or a local playlist in format m3u or pls. "媒体"是视频播放器可以打开的任何类型的文件。它可以是本地文件、DVD (例如 dvd://1)、网络流(例如 mms://....)或 m3u/pls 格式的本地播放列表。 SMPlayer is my favorite media player for my PC. Check it out! This text is to be published on twitter and the translation should not be more than 99 characters long 视频播放器是我最喜欢的多媒体播放器。快来看看! This is Kylin Vedio v. %1 running on %2 这是运行在 %2 上的麒麟影音 v. %1 ShareDialog Support SMPlayer 支持视频播放器 &Remind me later 稍后提醒我(&R) Donate with PayPal 使用 PayPal 捐赠 You can support SMPlayer by sending a donation or sharing it with your friends. 你可以通过捐赠或帮助宣传来支持视频播放器 ShareWidget Donate with PayPal 使用 PayPal 捐赠 Share SMPlayer in Facebook 将视频播放器分享到 Facebook Share SMPlayer in Twitter 将视频播放器分享到 Twitter Support SMPlayer 支持视频播放器 Donate / Share SMPlayer with your friends 将视频播放器分享给朋友/捐赠 ShortcutGetter Modify shortcut 修改快捷键 Clear 清除 Press the key combination you want to assign 按下您想要分配的组合键 Add shortcut 添加快捷键 Remove shortcut 移除快捷键 OK 确定 Cancel 取消 Capture 捕捉 Capture keystrokes 捕捉按键 ShortcutsWidget Kylin Video - Shortcuts 麒麟影音 - 快捷键 Forward %1 快进 %1 Rewind %1 快退 %1 Play control 播放控制 Other control 其他控制 Close 关闭 Play/Pause 播放/暂停 Previous 上一个 Next 下一个 Jump to... 跳转到... Mute 静音 Volume + 音量 + Volume - 音量 - Set audio delay 设置音频延迟 Increase or decrease audio delay 增加或减少音频延迟 Playlist 播放列表 About 关于 Quit 退出 FullScreen/Cancel fullScreen 全屏/取消全屏 Audio delay +/-/= 音频延迟 +/-/= Open File 打开文件 Screenshot 屏幕截图 Preferences 设置 View info and properties... 媒体信息... ShutdownDialog Shutting down computer 电脑关机中 Playback has finished. SMPlayer is about to exit. 已播放完毕,视频播放器即将退出。 The computer will shut down in %1 seconds. 电脑将会在 %1 秒内关机 Press <b>Cancel</b> to abort shutdown. 按<b>取消</b>键取消关机 SkinGui &Toolbars 工具栏(&T) Status&bar 状态栏(&B) &Main toolbar 主工具栏(&M) Edit main &toolbar 编辑主工具栏(&T) Edit &floating control 编辑浮动控制条(&F) &Video info 视频信息(&V) &Scroll title 滚屏标题(&S) Playing %1 正在播放 %1 Pause 暂停 Stop 停止 Stereo3dDialog Stereo 3D filter Stereo 3D 滤镜 &3D format of the video: 视频的 3D 格式(&3): &Output format: 输出格式(&O): Side by side parallel (left eye left, right eye right) 左右式(左眼在左,右眼在右) Side by side crosseye (right eye left, left eye right) 左右交叉式(右眼在左,左眼在右) Side by side with half width resolution (left eye left, right eye right) 左右格式半宽分辨率(左眼在左,右眼在右) Side by side with half width resolution (right eye left, left eye right) 左右交叉式半宽分辨率(右眼在左,左眼在右) Above-below (left eye above, right eye below) 上下式3D(左眼在上,右眼在下) Above-below (right eye above, left eye below) 上下式3D(右眼在上,左眼在下) Above-below with half height resolution (left eye above, right eye below) 上下式3D,半分辨率(左眼在上,右眼在下) Above-below with half height resolution (right eye above, left eye below) 上下式3D,半分辨率(右眼在上,左眼在下) Anaglyph red/cyan gray Anaglyph 红/青 灰色 Anaglyph red/cyan half colored Anaglyph 红/青半彩色 Anaglyph red/cyan color Anaglyph 红/青全彩色 Anaglyph red/cyan color optimized with the least-squares projection of Dubois Anaglyph 红/青全色(使用Dubois的小方格投射优化) Anaglyph green/magenta gray Anaglyph 绿/洋红 灰色 Anaglyph green/magenta half colored Anaglyph 绿/洋红半彩色 Anaglyph green/magenta colored Anaglyph 绿/洋红全彩色 Anaglyph yellow/blue gray Anaglyph 黄/蓝 灰色 Anaglyph yellow/blue half colored Anaglyph 黄/蓝半彩色 Anaglyph yellow/blue colored Anaglyph 黄/蓝全彩色 Interleaved rows (left eye has top row, right eye starts on next row) 插入排(左眼在最上一排,然后是右眼) Interleaved rows (right eye has top row, left eye starts on next row) 插入排(右眼在最上一排,然后是左眼) Mono output (left eye only) 单频道输出(仅左眼) Mono output (right eye only) 单频道输出(仅输出右眼) None Auto 自动 SubChooserDialog Subtitle selection 字幕选择 This archive contains more than one subtitle file. Please choose the ones you want to extract. 此存档包含多个字幕文件。请选择您想要提取的。 Select All 选择全部 Select None 取消选择 SupportFormats Video formats 视频格式 Audio formats 音频格式 Subtitles formats 字幕格式 Some video formats do not support preview and seek by dragging, e.g. the swf. 一些视频格式不支持预览和鼠标拖动定位,比如swf。 SupportShortcuts Play control shortcuts 播放控制快捷键 Other control shortcuts 其他控制快捷键 Play/Pause: Space 播放/暂停: Space Previous: Ctrl + < 上一个: Ctrl + < Next: Ctrl + < 下一个: Ctrl + > Forward %1: Right(→) 快进 %1: Right(→) Forward %1: Up(↑) 快进 %1: Up(↑) Forward %1: PgUp 快进 %1: PgUp Rewind %1: Left(←) 快退 %1: Left(←) Rewind %1: Down(↓) 快退 %1: Down(↓) Rewind %1: PgDn 快退 %1: PgDn Jump to...: Ctrl + J 跳转到...: Ctrl + J Mute: M 静音: M Volume +: 9 增加音量: 9 Volume -: 0 降低音量: 0 Set audio delay: Y 设置音频延迟: Y Increase or decrease audio delay: + / - / = 增加或减少音频延迟: + / - / = Playlist: F3 播放列表: F3 Open File: Ctrl + F 打开文件: Ctrl + F Screenshot: S 屏幕截图: S Preferences: Ctrl + P 设置: Ctrl + P View info and properties...: Ctrl + I 媒体信息...: Ctrl + I About: Ctrl + A 关于: Ctrl + A Quit: Ctrl + Q 退出:Ctrl + Q FullScreen/Cancel fullScreen: Ctrl + Enter 全屏/取消全屏: Ctrl + Enter SystemTray Kylin Video 麒麟影音 Open Homepage 打开主界面 Open screenshots folder 打开截图文件夹 Preferences 设置 Help 帮助 About 关于 Information 提示 Show 显示 View &info and properties... 查看信息和属性(&I)... P&references 设置(&R) About &Kylin Video 关于 麒麟影音 About &SMPlayer 关于视频播放器(&S) Quit 退出 TVList Channel editor 频道编辑器 TV/Radio list 电视/广播列表 TimeDialog &Jump to: 跳转到(&J): OK 确定 Seek 定位 Cancel 取消 Jump to: 跳转到: TitleWidget Kylin Video 麒麟影音 ToolbarEditor Toolbar Editor 工具栏编辑器 &Available actions: 可用动作(&A): &Left 向左(&L) &Right 向右(&R) &Down 向下(&D) &Up 向上(&U) Curre&nt actions: 当前动作(&N): &Icon size: 图标大小(&I): Add &separator 添加分隔符(&S) Time slider 时间滑块 Volume slider 音量滑块 Display time 显示时间 3 in 1 rewind 3合1后退 3 in 1 forward 3合1前进 TristateCombo Auto 自动 Yes No UpdateChecker Failed to get the latest version number 获取最新版的版本号失败 New version available 有新版本 A new version of SMPlayer is available. 新版视频播放器出来啦。 Installed version: %1 已安装版本:%1 Available version: %1 可更新版本:%1 Would you like to know more about this new version? 想更加详细地了解新版本? Checking for updates 检查更新中 Congratulations, SMPlayer is up to date. 恭喜,视频播放器已是最新。 Error 错误 An error happened while trying to retrieve information about the latest version available. 或许最新版信息时出错。 Error code: %1 错误代码:%1 VDPAUProperties VDPAU Properties VDPAU 属性 Select the vdpau codecs to use. Not all of them may work. 选择要使用的 VDPAU 编解码器。它们并非都能工作。 ffh&264vdpau ffh264vdpau(&2) ff&mpeg12vdpau ffmpeg12vdpau(&M) ff&wmv3vdpau ffwmv3vdpau(&W) ff&vc1vdpau ffvc1vdpau(&V) ffodiv&xvdpau ffodivxvdpau(&X) &Disable software video filters 禁用软件视频过滤器(&D) VideoEqualizer Video Equalizer 视频均衡器 &Contrast 对比度(&C) &Brightness 亮度(&B) &Hue 色调(&H) &Saturation 饱和度(&S) &Gamma &Gamma Software &equalizer 软件均衡器(&e) Set as &default values 设为默认值(&d) &Reset 重置(&R) Use the current values as default values for new videos. 使用当前的值作为新视频的默认值。 Set all controls to zero. 将全部设置清零。 VideoPreview Video preview 视频预览 Cancel 取消 Thumbnail Generator 缩略图生成器 Generated by SMPlayer 由视频播放器生成 Creating thumbnails... 正在创建缩略图... Size: %1 MB 大小: %1 MB Length: %1 长度: %1 Save file 保存文件 Error saving file 保存文件时出错 The file couldn't be saved 无法保存该文件 Error 错误 The following error has occurred while creating the thumbnails: 创建缩略图时发生以下错误: The temporary directory (%1) can't be created 无法创建临时目录(%1) The mplayer process didn't run MPlayer 进程没有运行 Resolution: %1x%2 分辨率: %1x%2 Video format: %1 视频格式: %1 Frames per second: %1 每秒帧数: %1 Aspect ratio: %1 纵横比: %1 The file %1 can't be loaded 无法加载文件 %1 No filename 没有文件名 The mplayer process didn't start while trying to get info about the video 试图获取视频信息时,MPlayer 进程没有启动 The length of the video is 0 视频的长度是 0 The file %1 doesn't exist 文件 %1 不存在 Images 图像 No info 无信息 %1 kbps %1kbps %1 Hz %1 Hz Video bitrate: %1 视频比特率: %1 Audio bitrate: %1 音频比特率: %1 Audio rate: %1 音频采样率: %1 VideoPreviewConfigDialog Default 默认 Thumbnail Generator 缩略图生成器 &File: 文件(&F): &Columns: 列(&C): &Rows: 行(&R): &Aspect ratio: 纵横比(&A): &Maximum width: 最大宽度(&M): The preview will be created for the video you specify here. 将为您在这里指定的视频创建预览。 The thumbnails will be arranged on a table. 缩略图将被排列在一个表格中。 This option specifies the number of columns of the table. 此选项可指定表格的列数。 This option specifies the number of rows of the table. 此选项可指定表格的行数。 If you check this option, the playing time will be displayed at the bottom of each thumbnail. 如果您勾选此选项,播放时间将显示在每个缩略图的底部。 If the aspect ratio of the video is wrong, you can specify a different one here. 如果视频的纵横比是错误的,您可以在这里指定一个不同的。 Usually the first frames are black, so it's a good idea to skip some seconds at the beginning of the video. This option allows you to specify how many seconds will be skipped. 通常情况下第一帧都是黑色的,因此视频开始时跳过几秒钟是个好主意。此选项允许指定多少秒将被跳过。 This option specifies the maximum width in pixels that the generated preview image will have. 此选项可指定生成预览图像的最大宽度(以像素为单位)。 Some frames will be extracted from the video in order to create the preview. Here you can choose the image format for the extracted frames. PNG may give better quality. 某些帧将被从视频中提取以创建预览。在这里您可以选择被提取帧的图像格式。PNG 的质量可能会更好。 Add playing &time to thumbnails 添加播放时间到缩略图(&T) &Seconds to skip at the beginning: 开始时跳过的秒数(&S): &Extract frames as 提取帧为(&E) Enter here the DVD device or a folder with a DVD image. 在这里输入 DVD 驱动器或 DVD 镜像文件夹。 &DVD device: DVD 驱动器(&D): Remember folder used to &save the preview 记住用来保存预览的文件夹(&S) VolumeControlPanel Playlist 播放列表 Fullscreen on/off 全屏开/关 Video equalizer 视频均衡器 VolumeSliderAction Volume 音量 kylin-video/src/translations/.tx/0000775000175000017500000000000013214347337015762 5ustar fengfengkylin-video/src/translations/.tx/config0000664000175000017500000000043613214347337017155 0ustar fengfeng[main] host = https://www.transifex.com [smplayer.english] type = QT file_filter = smplayer_.ts source_lang = en source_file = smplayer_en_US.ts trans.he = smplayer_he_IL.ts trans.vi = smplayer_vi_VN.ts trans.ru = smplayer_ru_RU.ts trans.uk = smplayer_uk_UA.ts minimum_perc = 50 kylin-video/src/translations/kylin-video_zh_CN.qm0000664000175000017500000014271213261115402021116 0ustar fengfeng Q?Rd@RASCESCTE_VGBV?GmX&&YJYĩIVYAJZjLZNzZNZQ!ZNZةM[dO[-^\o=\ġRx\\-\]RK]ØS*^cVS^T gzlG-xӮRN`N6C6=d%Xy^/.>5X59Ù>Q^.l }"l;""$6s&XR`0aFd!7YY|G> |]JXϦi7H.|\~jS(Xg#Z@2  x &e&# ,wBVRNrm~xvNK/n1n.A5Y1Cn5dDS+KI'"{ jȰAB͢Pؘvƾ3c fT_ _(OfqB5o2+rC~E3C`:ЩWLQNWq^kCD!~A\^KUjZ8 $Ҕ ~#{Q 2tXMO$*Ս+K4S71Pc1S~p[=Qd~eQfjPmnnrJ~:1x/2P(1 b) 281gIwI$I.IUoIII^3EO[:4OTȘ5+{RgUMmP6-uEr+'7Bx*p~8֓*}9!)I=XI_ 7`đ cRWrY*eJG5C `7mT 5~t5~LI7ɟ.H֣%R}㞳DEsFE룃'aaD; Y. e !W#Q/5FgEGZc0GZ_xcfb~ RWSU0QNL)'ݙC/97 17S(/>/N+Um$K Z.J)hI>boq5Nx/|~(^Qz1B2!^2|E?J.5:JS)Hi2I>q^̪>18ZρQ?o# b'O 1/ ] Q.r (q3 )4 %4 h> jO>3e jn q=J u={ >4 c# . 5 s s-4 s s ZA ȏ.J <3 ʟ.I xttF ۊF= G#zZ 꽺q 4 L5 v .J 5] ` qKy l> n *G7 6L| C,O d<) dUV hPM@ iP5 }N # 80 d G % l  ]I <j $G K8> ŷn #" t`2 tF I. ‹k  ‹m ; <.@ ΂$ ΂*, ҂U- yM ۰M .O Z^|j 1  Y {K Tj ! Vt ,S 2~sy 3i <' CUR E9~ F Q F W _4 gBf gJz h sBr t9 z͢> z, 4*  A E~b s . I'' ȟ ;   xB t tU7 ( U  Hp ` ) P #P ̛: \  ^}  >) E I: ! "6 " &#%l &#C (c< +[= = t B) BR: B:) C, FOK I N07 OQ RVC hۮ: v z`[ |9v m \8 \ 11 Z % s0 /   \ b 1bQ Q,  P8 y| qM EW *7 6M&; 74<B 74< :n4 ZtN^ bz i8:|: ko 6R q+  HY >9= q { }S /, <* < #6k:A))w } +> 2DN;^`ƞYaDcda>l lW sbt[Mxa~m\>;'m4{P)^b@;Fj] :7h dZA4Ho !*1+ߞ[3gKXY8iY8iac@ix!iT{iTuwzk4NuQw ZqjBH KL >k P:QOT3ixQsNAbout AboutDialog!s. Contributor AboutDialog_q Kylin Video AboutDialogL_qWNSMPlayerۈL_S f/MPlayerTMPVvV_bSRMz0`Kylin Video is developed on the basis of SMPlayer, is a graphical interface for MPlayer and MPV. AboutDialogxn[OK AboutDialog de>_dPlayback engine: AboutDialog.kcW(Ou( Qt %1 (u( Qt %2 )!Using Qt %1 (compiled with Qt %2) AboutDialog rHg,: %1 Version: %1 AboutDialogcϏ Description ActionsEditorT yName ActionsEditor_cw.Shortcut ActionsEditor^ Audio delayAudioDelayDialog^(ky):Audio delay (in milliseconds):AudioDelayDialogSmCancelAudioDelayDialogxn[OKAudioDelayDialog %1 %1 ErrorBaseGui%1 T/RY1%0%1 failed to start.BaseGui%1 ]])n0%1 has crashed.BaseGui%1 ]aY~g_0%1 has finished unexpectedly.BaseGui4.0 s~X(&4) &4.0 SurroundBaseGui5.1 s~X(&5) &5.1 SurroundBaseGui6.1 s~X(&6) &6.1 SurroundBaseGui7.1 s~X(&7) &7.1 SurroundBaseGui Y~(&A)&AlwaysBaseGui R(&A)&AutoBaseGui XS(&C) &ChannelsBaseGui nd(&C)&ClearBaseGui yu((&D) &DisabledBaseGuieN(&F)...&File...BaseGuilR0(&J)... &Jump to...BaseGuilR0(&J): &Jump to:BaseGui]XS(&L) &Left channelBaseGuiSUXS(&M)&MonoBaseGui Y(&M)&MuteBaseGui NN (&N)&NeverBaseGui Qs(&O)&OffBaseGuiSXS(&R)&Right channelBaseGui eˏl(&R)&RotateBaseGuizeeˏl90^^vl(&R)(&Rotate by 90 degrees clockwise and flipBaseGui\O^Ub*V(&S) &ScreenshotBaseGuizOSX(&S)&StereoBaseGuizOSXj!_(&S) &Stereo modeBaseGuiQW@(&U)...&URL...BaseGui'%1' lg b~R0'%1' was not found!BaseGui+%1+%1BaseGui-%1-%1BaseGuiBaseGuiQsN _qAbout &Kylin VideoBaseGuib@g eN All filesBaseGuiu;bkO Aspect ratioBaseGuiAudioBaseGui bNN*v_UChoose a directoryBaseGui bNN*eN Choose a fileBaseGuixnR d - _qConfirm deletion - Kylin VideoBaseGui^ +Delay +BaseGui^ -Delay -BaseGuiR dgveNRhT? Delete the list of recent files?BaseGui v_U... Directory...BaseGuiSP ^ Double speedBaseGui hmKR0Error detectedBaseGuiQNx: %1 Exit code: %1BaseGuilVP(&P) Fli&p imageBaseGui__Forward and rewindBaseGuiu;beˏlFrame rotationBaseGuiSJ Half speedBaseGui^.RHelpBaseGui lR0 %1 Jump to %1BaseGui_q Kylin VideoBaseGui_q - [OMKylin Video - SeekBaseGui_q - [W^U^Kylin Video - Subtitle delayBaseGui Rh_sde>List loop playBaseGui R}...Load...BaseGui\PVP(&O) Mirr&or imageBaseGuiYZOS MultimediaBaseGuiN NN*NextBaseGuikc^8^ Normal speedBaseGuibS_OpenBaseGuibS_eN(&F)... Open &File...BaseGuiz^de> Order playBaseGuide>^ Play SpeedBaseGuide>cR6 Play controlBaseGuide>z^ Play orderBaseGuide>Rh PlaylistsBaseGuihg噖 yN-v %1 _0(Please check the %1 path in preferences.BaseGuin PreferencesBaseGuiN NN*PreviousBaseGuiQQuitBaseGuig:de> Random playBaseGui Sv(&v)Re&verseBaseGui gveN Recent filesBaseGuizeeˏl90^(&C)Rotate by 90 degrees &clockwiseBaseGuieeˏl90^(&W)&Rotate by 90 degrees counterclock&wiseBaseGuieeˏl90^^vl(&F)/Rotate by 90 degrees counterclockwise and &flipBaseGui nv(&T) S&tay on topBaseGuifYO`oS–e_0See the log for more info.BaseGuin^(&Y)... Set dela&y...BaseGui_cw. ShortcutsBaseGui ^+1% Speed +1%BaseGui ^+10% Speed +10%BaseGui ^+4% Speed +4%BaseGui ^-1% Speed -1%BaseGui ^-10% Speed -10%BaseGui ^-4% Speed -4%BaseGui[W^US`'(&V)Subtitle &visibilityBaseGui[W^U^(ky):!Subtitle delay (in milliseconds):BaseGui[W^U SubtitlesBaseGuib*VeNY9N [XW(%The screenshot folder does not exist!BaseGuig RVhV'%1'The server returned '%1'BaseGuibkIkdƘN de>)Unfortunately this video can't be played.BaseGuiƘVideoBaseGui$Ou( VDPAU e\yu(ƘnVh+Video filters are disabled when using vdpauBaseGuiZOSO`o(&I)...View &info and properties...BaseGui +Volume +BaseGui -Volume -BaseGui_Sde>e(&P)While &playingBaseGuiYMute BottomWidgetN NN*Next BottomWidget de>/fP\ Play / Pause BottomWidgetde>Rh Play List BottomWidgetN NN*Prev BottomWidgetP\kbStop BottomWidget"A"hnR0 %1"A" marker set to %1Core"B"hnR0 %1"B" marker set to %1CoreA-B h]ndA-B markers clearedCore~j*k: %1Aspect ratio: %1Core^: %1kyAudio delay: %1 msCore N^: %1Brightness: %1Core QN-... Buffering...Core[k^: %1 Contrast: %1Core O=s: %1 Gamma: %1Core r: %1Hue: %1Core hnڏnfe9^Mouse wheel changes speed nowCore hnڏnfe9Mouse wheel changes volume nowCore hnڏnfe9)e>{I~"Mouse wheel changes zoom level nowCore hnڏn[OMMouse wheel seeks nowCoreqT^: %1Saturation: %1Core elՏۈL\O^Ub*V lg MneNY9+Screenshot NOT taken, folder not configuredCoreb*VO[XN: %1Screenshot saved as %1Core elՏۈL\O^Ub*V lg MneNY9,Screenshots NOT taken, folder not configuredCore ^: %1 Speed: %1CorekcW(_Y... Starting...Core[W^U^: %1kySubtitle delay: %1 msCore[W^UQs Subtitles offCore[W^U_T/ Subtitles onCore(kcW(fe[WOS[X0SQyҔ...6Updating the font cache. This may take some seconds...Core : %1 Volume: %1Core )e>: %1Zoom: %1CoreError ErrorDialoge_Hide log ErrorDialogMPlayer  MPlayer Error ErrorDialogxn[OK ErrorDialog ..QNOops, something wrong happened ErrorDialogf>y:e_Show log ErrorDialogiconicon ErrorDialogc ESC .QQh\O"Press ESC to exit full screen modeEscTipSUQN bNN*eNbeNY9 Click to select a file or folder FileChooser n(&R)&ResetFilePropertiesDialog bxVh(&S):&Select the audio codec:FilePropertiesDialog$ b\u(NkdeNvY u(Vh(&S):4&Select the demuxer that will be used for this file:FilePropertiesDialog bƘxVh(&S):&Select the video codec:FilePropertiesDialog^u(ApplyFilePropertiesDialog xVh Audio codecFilePropertiesDialogSmCancelFilePropertiesDialogY u(VhDemuxerFilePropertiesDialogO`o InformationFilePropertiesDialog_q - nKylin Video - PreferencesFilePropertiesDialogxn[OKFilePropertiesDialog\^`' PropertiesFilePropertiesDialognResetFilePropertiesDialog ƘxVh Video codecFilePropertiesDialog^.RHelp HelpDialog_q - ^.RKylin Video - Help HelpDialogxn[OK HelpDialog e/cvh<_Supported formats HelpDialog e/cv_cw.Supported shortcuts HelpDialog##InfoFile %1 Hz%1 HzInfoFile%1 KB (%2 MB) %1 KB (%2 MB)InfoFile %1kbps%1 kbpsInfoFileNAlbumInfoFilezg/[ArtistInfoFile~j*k Aspect ratioInfoFilemA Audio StreamsInfoFileO\AuthorInfoFilekrysBitrateInfoFileXSChannelsInfoFileRjO`o Clip infoInfoFilelCommentInfoFilerHgC CopyrightInfoFileegDateInfoFileY u(VhDemuxerInfoFileeNFileInfoFileh<_FormatInfoFileky^'epFrames per secondInfoFile^8GeneralInfoFilemAm>GenreInfoFileIDIDInfoFile RY˗mAInitial Audio StreamInfoFileLanguageInfoFile^LengthInfoFileT yNameInfoFileh7sRateInfoFileRs ResolutionInfoFile ] xVhSelected codecInfoFileY'\SizeInfoFileoNSoftwareInfoFile mA URL Stream URLInfoFilemAh Stream titleInfoFile[W^U SubtitlesInfoFilehSTrackInfoFile|{WTypeInfoFileURLURLInfoFileƘVideoInfoFilezzemptyInfoFileSmCancelInputURLQeQW@ Enter URLInputURLxn[OKInputURLQW@:URL:InputURL ?^TȉN Abkhazian Languages?l\Afar Languages SW^wQp Afrikaans Languages?WNAkan Languages ?\]\\Uighur LanguagesNLQKQp Ukrainian LanguagesNLQKQp v}OWeUkrainian, Belarusian LanguagesUnicodeUnicode LanguagesNL\Urdu Languages NLQyR+QKUzbek LanguageseVenda LanguagesSW Vietnamese Languages lbfnQKVolapük Languagest柙Walloon LanguagesZ\XWelsh Languagesk'Western European Languages Languages k'(k'v)$Western European Languages with Euro LanguageslmY+Wolof Languagesyф(Xhosa Languagesa{,~Yiddish Languages~]Yoruba LanguagesXZhuang LanguagesyVZulu Languagesfe9ChangeLineEditWithIconmpvN e/c '%1' nVh'the '%1' filter is not supported by mpv MPVProcessSmCancel MessageDialogT&No MessageDialogxn[Ok MessageDialogf/Yes MessageDialogMPlayerN e/c y'This option is not supported by MPlayerMplayerProcessNxlvR d(&D)&Delete file from diskPlaylistmRAddPlaylistXReNAdd FilePlaylistb@g eN All filesPlaylistO`xn[~~!Are you sure you want to proceed?Playlist bNN*v_UChoose a directoryPlaylistndClearPlaylistxnR dConfirm deletionPlaylistxnydConfirm removePlaylistR dY1%Deletion failedPlaylist R deNQError deleting the filePlaylistelR d '%1'!It wasn't possible to delete '%1'PlaylistelNeN|~R d '%1'5It's not possible to delete '%1' from the filesystem.PlaylistYZOS MultimediaPlaylistde>PlayPlaylistde>RhPlayListPlaylist de>RhN:zzPlaylist is emptyPlaylist]~R0de>Rh^Reached the end of the playlistPlaylistR d [(&S)Remove &selectedPlaylist bNN*bYN*bS_veN Select one or more files to openPlaylistkddO\N Sd0O`xn[~~?This action cannot be undone. Are you sure you want to proceed?Playlist \N`vxlvR deN '%1' 5You're about to DELETE the file '%1' from your drive.Playlist"\Nde>RhN-ydeN '%1'07You're about to remove the file '%1' from the playlist.PlaylistFcPOu( %10\=ϐQM %2 T %3 [N^_ab NO_qT`'0g%1 is the recommended one. Try to avoid %2 and %3, they are slow and can have an impact on performance. PrefAudio2 (zOSX) 2 (Stereo) PrefAudio4 (4.0 s~X)4 (4.0 Surround) PrefAudio6 (5.1 s~X)6 (5.1 Surround) PrefAudio7 (6.1 s~X)7 (6.1 Surround) PrefAudio8 (7.1 s~X)8 (7.1 Surround) PrefAudio 󘑏QqRAudio output driver PrefAudio/ƘRT ke Audio/video auto synchronization PrefAudio؋XSChannels by default PrefAudio ؋XS:Channels by default: PrefAudio0R kd yNOu(oNmVh N Ou(XSamVh0SCheck this option to use the software mixer, instead of using the sound card mixer. PrefAudio؋Default PrefAudioV[P:Factor: PrefAudioQh\@ Global volume PrefAudio,WN^vmKP<keet A/V T ke0AGradually adjusts the A/V sync based on audio delay measurements. PrefAudiodYgR kd y `de>vb@g eN\Ou(vT v0Ygkd yg*R kN*eN\Ou(Qv]v0If this option is checked, the same volume will be used for all files you play. If the option is not checked each file uses its own volume. PrefAudio gY'e>Y'sMax. Amplification PrefAudio gY'e>Y's:Max. Amplification: PrefAudioXlg Y1wvgY'02Maximizes the volume without distorting the sound. PrefAudio QqR:Output driver: PrefAudio^c[de>XSvep0MPlayer TJɉxVh\󘑉xbY\XS Qu1xVhge[skdlB0^8Sg W(de>^&g AC3 (kY DVD)vƘebMg u(0W(`QN \؋Ou( liba52 x^vbkcxnW0mTbvXSep0<b>la</b>: kd y x(N AC3)0nVh(s~X)T󘑏QqR(OSSbf~)N n፳0Requests the number of playback channels. MPlayer asks the decoder to decode the audio into as many channels as specified. Then it is up to the decoder to fulfill the requirement. This is usually only important when playing videos with AC3 audio (like DVDs). In that case liba52 does the decoding by default and correctly downmixes the audio into the requested number of channels. Note: This option is honored by codecs (AC3 only), filters (surround) and audio output drivers (OSS at least). PrefAudio b󘑏QqR0Select the audio output driver. PrefAudio֋ngY'e>Y'~R+vv~Rk(؋P<: 110)0Py:)\N kcxnf>y:0 Sets the maximum amplification level in percent (default: 110). A value of 200 will allow you to adjust the volume up to a maximum of double the current level. With values below 100 the initial volume (which is 100%) will be above the maximum, which e.g. the OSD cannot display correctly. PrefAudioOu(oNcR6Software volume control PrefAudioT keSynchronization PrefAudiokd yN_u(NYcR60.This option also applies for the mute control. PrefAudioOu(oNcR6Use software volume control PrefAudioVolume PrefAudio؋hQSVolume normalization by default PrefAudioLYgT/u(kd y N;zSYNr`e eN\fP\0zSSe \`bY de>0If this option is enabled, the file will be paused when the main window is hidden. When the window is restored, playback will be resumed. PrefGeneralnW(^gaN e Of>y:ƘV0lIf this option is enabled, the video preview will be displayed when the mouse is placed on the progress bar. PrefGeneral,YgO`Rcbde>_dN:MPV T/_q0EIf you change the playback engine to MPV, please restart Kylin Video. PrefGeneral4YgO`Rcbde>_dN:MPlayer T/_q0IIf you change the playback engine to MPlayer, please restart Kylin Video. PrefGeneralMPVMPV PrefGeneralMPlayerMPlayer PrefGeneral g\SefP\Pause when minimized PrefGeneral de>_dPlayback engine: PrefGeneralƘde>eۈL!Preview when the video is playing PrefGeneralƘde>eۈLPreview when video is playing PrefGeneral b MPV O\N:de>_dSelect MPV as playback engine PrefGeneral" b MPlayer O\N:de>_d!Select MPlayer as playback engine PrefGeneralRAutoPrefPerformance(RR\Ou({,NySu(vxle_0ZAuto: it tries to automatically enable hardware decoding using the first available method.PrefPerformance Su( yAvailable options:PrefPerformance[XCachePrefPerformance g,W0eN[XCache for filesPrefPerformanceg,W0eN[X:Cache for local files:PrefPerformancemA[XCache for streamsPrefPerformancemA[X:Cache for streams:PrefPerformancexDecodePrefPerformancexlNxHardware decodingPrefPerformanceKBKBPrefPerformanceeNonePrefPerformanceeNu(o0*None: only software decoding will be used.PrefPerformance`' PerformancePrefPerformance6nxlNx API0YgelOu(xl ROOu(o0sSets the hardware video decoding API. If hardware decoding is not possible, software decoding will be used instead.PrefPerformanceBnu(Nxv~z ep0NŐu(N MPEG-1/2 T H.264KSets the number of threads to use for decoding. Only for MPEG-1/2 and H.264PrefPerformancekd yNe/c mpv0 This option only works with mpv.PrefPerformanceBkd ySc[[X URL eOu(Y\Q[X(N KB N:SUOM)0OThis option specifies how much memory (in kBytes) to use when precaching a URL.PrefPerformancey:Q0.vdpau: for the vdpau and opengl video outputs.PrefPerformanceR%1 c[ƘveNT N T+bi\UT %2 W(NKTmR 4OMep N Yvu(0XkQE0i%1 specifies the filename of the video without the extension, %2 adds a 4 digit number padded with zeros.PrefScreenShot T/u(\O^Ub*VEnable screenshotsPrefScreenShoteNY9:Folder:PrefScreenShot [etj!gf{&Rhkdc;For a full list of the template specifiers visit this link:PrefScreenShotJOY %1 \O\b*VO[XN: moviename_0001.png  0AFor example %1 would save the screenshot as 'moviename_0001.png'.PrefScreenShotb*\Oh7_Format for screenshotsPrefScreenShoth<_:Format:PrefScreenShotbW(ّ`SNc[NN*_q\u(ge[XP\O^Ub*VveNY90YgeNY9f/eeHv \O^Ub*VR\yu(0Here you can specify a folder where the screenshots taken by Kylin Video will be stored. If the folder is not valid the screenshot feature will be disabled.PrefScreenShot\O^Ub*V ScreenshotsPrefScreenShot\O^Ub*VeNY9Screenshots folderPrefScreenShot bNN*v_USelect a directoryPrefScreenShot \O^Ub*Vj!gTemplate for screenshotsPrefScreenShotj!g Template:PrefScreenShotkd y` bƘb*Vvh<_0MThis option allows to choose the image file type used for saving screenshots.PrefScreenShotkd yNŐu(Nmpv0 This option only works with mpv.PrefScreenShot*kd y[NIO[XƘb*\OeOu(veNT j!g0EThis option specifies the filename template used to save screenshots.PrefScreenShot0`SNOu(kd yT/u(byu(f/T&SNۈL\O^Ub*V0QYou can use this option to enable or disable the possibility to take screenshots.PrefScreenShotNW(ّ`SNfe9NOU_cw.0PZR0Np W(NN*_cw.SUQChfe9_cw.</b> c SQe <i>Oe9_cw.</i> [hF0g N$yelgefe9_cw.: Yg <b>cUcI</b> c ]T/u( NHSc N ``cm>~kdRO\vec .b~T.(_Wa^vN u(Nb@g vc .)0Yg <b>cUcI</b> c ]Qs NH`SN叓Qec .v[etT y0This table allows you to change the key shortcuts of most available actions. Double click or press enter on a item, or press the Change shortcut button to enter in the Modify shortcut dialog. There are two ways to change a shortcut: if the Capture button is on then just press the new key or combination of keys that you want to assign for the action (unfortunately this doesn't work for all keys). If the Capture button is off then you could enter the full name of the key. PrefShortCutb@g ST+_qrGT yv[W^UAll subs containing movie name PrefSubtitlesv_UN-vb@g [W^UAll subs in directory PrefSubtitlesRR}[W^UeNAutoload PrefSubtitles2RR}[W^UeN(*.srt0*.sub...):+Autoload subtitles files (*.srt, *.sub...): PrefSubtitles ؋[W^UxDefault subtitle encoding PrefSubtitles؋[W^Ux:Default subtitle encoding: PrefSubtitlesxEncoding PrefSubtitles[WOSFont PrefSubtitlesN_qrGvT yvT Same name as movie PrefSubtitles b\u(N[W^UeNv؋x0ESelect the encoding which will be used for subtitle files by default. PrefSubtitles" b``u(NRcmKxv0PSelect the language for which you want the encoding to be guessed automatically. PrefSubtitles b[W^UvRR}el0$Select the subtitle autoload method. PrefSubtitles[W^USubtitle language PrefSubtitles[W^U Subtitles PrefSubtitles\ՁRhmKkd#Try to autodetect for this language PrefSubtitles\ՁRhmKkd:$Try to autodetect for this language: PrefSubtitles_T/kd ye \\ՁRhmKc[v[W^Ux0YgRhmKY1% [\VR0؋vx0kd y MPlayer g ENCA e/c0When this option is on, the encoding of the subtitles will be tried to be autodetected for the given language. It will fall back to the default encoding if the autodetection fails. This option requires a MPlayer compiled with ENCA support. PrefSubtitles؋Default PrefVideovcn2gDirect rendering PrefVideoSQDouble buffering PrefVideoW(Q[XN-[XPN$^' W(f>y:N^'vT exSN^'vSQgeOY p0Ygyu([O[ OSD (\O^Uf>y:)Nub_qT OF^8^8Sd OSD (\O^Uf>y:)vp0Double buffering fixes flicker by storing two frames in memory, and displaying one while decoding another. If disabled it can affect OSD negatively, but often removes OSD flickering. PrefVideoOu(RrGe_~R6ƘDraw video using slices PrefVideo؋T/u(TgYt Enable postprocessing by default PrefVideoT/u(/yu(N 16-P} vrG/^&e_~R6Ƙ0Ygyu( \Nk!ЈL~R6etN*^'0Sf_bfab SQNf>SaTSu(v[X0[S[ libmpeg2 T libavcodec xVhg eHg0Enable/disable drawing video by 16-pixel height slices/bands. If disabled, the whole frame is drawn in a single run. May be faster or slower, depending on video card and available cache. It has effect only with libmpeg2 and libavcodec codecs. PrefVideoYgR \bS_vcn2g(N b@g vxVhTƘQe/c)<br><b>fTJ:</b> SO[ OSD (\O^Uf>y:)/SUB v!If checked, turns on direct rendering (not supported by all codecs and video outputs)
Warning: May cause OSD/SUB corruption! PrefVideo QqR:Output driver: PrefVideo"؋W(ebS_veNN Ou(TgYt0;Postprocessing will be used by default on new opened files. PrefVideo( bƘQqR0%1 ScOgOs`'0ASelect the video output driver. %1 provides the best performance. PrefVideoOu(oNƘWGaVhSoftware video equalizer PrefVideoOu(oNƘWGaVhUse software video equalizer PrefVideo ƘQqRVideo output driver PrefVideoYg`vf>y:Sabb@ vƘQqRN e/cƘWGaVh `SNR kd y0<br><b>la:</b> kd ySNgNƘQqRN Q|[0You can check this option if video equalizer is not supported by your graphic card or the selected video output driver.
Note: this option can be incompatible with some video output drivers. PrefVideoabslow PrefVideo^u(ApplyPreferencesDialogAudioPreferencesDialogSmCancelPreferencesDialog^8GeneralPreferencesDialog_q - nKylin Video - PreferencesPreferencesDialogxn[OKPreferencesDialog`' PerformancePreferencesDialogn PreferencePreferencesDialog\O^Ub*V ScreenShotPreferencesDialog_cw. Shortcut KeyPreferencesDialog[W^U SubtitlesPreferencesDialogƘVideoPreferencesDialog%1 T %2 %1 and %2QObject%nR %n minute(s)QObject%ny %n second(s)QObject*f/ЈLW( %2 N v_q v. %1'This is Kylin Vedio v. %1 running on %2QObjectRautoQObjectyu(disabledQObjectg*wunknownQObject mR_cw. Add shortcutShortcutGetterSmCancelShortcutGettercUcICaptureShortcutGettercUcIc .Capture keystrokesShortcutGetterndClearShortcutGetter Oe9_cw.Modify shortcutShortcutGetterxn[OKShortcutGetterc N ``RMv~T.,Press the key combination you want to assignShortcutGetter yd_cw.Remove shortcutShortcutGetterQsNAboutShortcutsWidgetQsCloseShortcutsWidget _ %1 Forward %1ShortcutsWidgetQh\O/SmQh\OFullScreen/Cancel fullScreenShortcutsWidgetXRbQ\^ Increase or decrease audio delayShortcutsWidget lR0... Jump to...ShortcutsWidget_q - _cw.Kylin Video - ShortcutsShortcutsWidgetYMuteShortcutsWidgetN NN*NextShortcutsWidgetbS_eN Open FileShortcutsWidgetQvNcR6 Other controlShortcutsWidgetde>cR6 Play controlShortcutsWidget de>/fP\ Play/PauseShortcutsWidgetde>RhPlaylistShortcutsWidgetn PreferencesShortcutsWidgetN NN*PreviousShortcutsWidgetQQuitShortcutsWidget _ %1 Rewind %1ShortcutsWidget\O^Ub*V ScreenshotShortcutsWidget n^Set audio delayShortcutsWidgetZOSO`o...View info and properties...ShortcutsWidget +Volume +ShortcutsWidget -Volume -ShortcutsWidgeth<_ Audio formatsSupportFormats2NNƘh<_N e/cT hbR[OM kYswf0MSome video formats do not support preview and seek by dragging, e.g. the swf.SupportFormats[W^Uh<_Subtitles formatsSupportFormatsƘh<_ Video formatsSupportFormatsQsN Ctrl + AAbout: Ctrl + ASupportShortcuts_ %1 PgUpForward %1: PgUpSupportShortcuts$_ %1 Right(!)Forward %1: Right(→)SupportShortcuts_ %1 Up(!)Forward %1: Up(↑)SupportShortcuts0Qh\O/SmQh\O Ctrl + Enter,FullScreen/Cancel fullScreen: Ctrl + EnterSupportShortcuts.XRbQ\^ + / - / =/Increase or decrease audio delay: + / - / =SupportShortcuts&lR0... Ctrl + JJump to...: Ctrl + JSupportShortcutsY M Mute: MSupportShortcuts N NN* Ctrl + >Next: Ctrl + <SupportShortcuts"bS_eN Ctrl + &Open File: Ctrl + FSupportShortcutsQvNcR6_cw.Other control shortcutsSupportShortcutsde>cR6_cw.Play control shortcutsSupportShortcutsde>/fP\ SpacePlay/Pause: SpaceSupportShortcutsde>Rh F3Playlist: F3SupportShortcutsn Ctrl + PPreferences: Ctrl + PSupportShortcuts N NN* Ctrl + <Previous: Ctrl + <SupportShortcutsQCtrl + QQuit: Ctrl + QSupportShortcuts"_ %1 Down(!)Rewind %1: Down(↓)SupportShortcuts"_ %1 Left(!)Rewind %1: Left(←)SupportShortcuts_ %1 PgDnRewind %1: PgDnSupportShortcuts\O^Ub*V SScreenshot: SSupportShortcutsn^ YSet audio delay: YSupportShortcuts(ZOSO`o... Ctrl + I)View info and properties...: Ctrl + ISupportShortcutsXR 9Volume +: 9SupportShortcutsMON 0Volume -: 0SupportShortcutsQsNAbout SystemTray^.RHelp SystemTraycy: Information SystemTray_q Kylin Video SystemTray bS_N;uLb Open Homepage SystemTraybS_b*VeNY9Open screenshots folder SystemTrayn Preferences SystemTrayQQuit SystemTraySmCancel TimeDialoglR0:Jump to: TimeDialogxn[OK TimeDialog[OMSeek TimeDialog_q Kylin Video TitleWidgetRAuto TristateComboT&No TristateCombof/Yes TristateCombo lg eNT  No filename VideoPrevieweN %1 N [XW(The file %1 doesn't exist VideoPreviewƘv^f/ 0The length of the video is 0 VideoPreviewMPlayer z lg ЈLThe mplayer process didn't run VideoPreview0VS։ƘO`oe MPlayer z lg T/RIThe mplayer process didn't start while trying to get info about the video VideoPreviewelR^N4ev_U(%1)-The temporary directory (%1) can't be created VideoPreviewkylin-video/src/res/0000775000175000017500000000000013214347337013321 5ustar fengfengkylin-video/src/res/no-video.png0000664000175000017500000000112213214347337015543 0ustar fengfengPNG  IHDRFFq.tEXtSoftwareAdobe ImageReadyqe<IDATx윁m0EbF ` `0Y tݠl@6`6h_UTvO:At:/KfyL ϓ j+GU)(L`F`F`F-aL%87n{:Ci_zrLm0 y8sp/ *Ug  c+ճU|9d 8x=CԳ *_O=S%ax﹬u'SS)f !רf^cGlnj c3/,׆R0~Xk*SٔT{C*Yo2:U%r[6AT*)Q%Yvex -$pTÏRnO9`TVvE'ɘkiqK'o s> %i<ƹLvn IUIENDB`kylin-video/src/res/video_hover_press.png0000664000175000017500000000234513214347337017560 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp ۟UIDATxb3 " @zHdH " Pπ3# 0iUS<@x@s Q A11 ]H|4PWCiC= g=,#y 0`As;@M9btoYwݛBҐ n XA0` U N:>$a; `h3j!H1 >@Ղg*ZEXk@qynpha 03x">pi8I 1B߆ȂQ0I{IENDB`kylin-video/src/res/playlist_close_hover_press.png0000664000175000017500000000255113214347337021477 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp I [!Ƃ@ TXD qI@S 3X%DFr"%:D'&a8<kK$G5@c8 |59d-aMޠ GA%l%@4'!?4<bT64 aXEr&T`YQxW:Ğĕ* B!+5SB кW \7=IENDB`kylin-video/src/res/open_window_normal.png0000664000175000017500000000027613214347337017734 0ustar fengfengPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<`IDATxb`h"\`z( d6^*:  b@ )1k VzhI  ./ *IENDB`kylin-video/src/res/screenshot_normal.png0000664000175000017500000000055613214347337017562 0ustar fengfengPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxڬS @  d:200228䝩K^JWg$IIպ+l,w2@Mg>>???AAACCCDDDEEEFFFGGGHHHJJJMMMQQQVVVYYY\\\^^^```cccfffiiimmmrrrtttvvvwwwxxxyyyzzz{.ntRNSM~bKGDf |dfIDATjQΉ 4BB,t6Zل@lEZ[{+[/kX6B,ܙ= @@\ d21 A9SdT)> aNJedFIY6XE)?̣3ٓb+vN!J̚yUv;l뺶n0if$*s\.7/>/`}%$]WB[ %'Ivd=zo9B'@`ٖdIX{&NU y[fϺۧzM7 Q/^Ab8@p~lxqr[Օ$#!QD@b#sK7 OwqIENDB`kylin-video/src/res/backoff_10_seconds_normal.png0000664000175000017500000000313213214347337021007 0ustar fengfengPNG  IHDR tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp qlIDATxb?h` (҇M$ @ Hb DRDѹ #@8 ;7> ğ`b f#p %0W 9> Ā>Cd1lA 9&[ر' Pg >EBaF;d1"ulbDUXV0_ ДREW)R" DX#̩Ls8S )~tL9p5xF&3ŀ+)ɤPXlTTbZ4" 2(6<@,Td@ 񥜕He;H*&bM,0 1Ȑk8J tuɵ\CD#";huO -{ -Z@3VaV%1f4@E4+r[J"q,AMLh-" ϠZ.f@Cq uIHL$֤t[4bv"NjTex!>uBhb!#E9< r@8DN uZ^1}&" i o҈(uIENDB`kylin-video/src/res/ok.png0000664000175000017500000003456313214347337014453 0ustar fengfengPNG  IHDRa pHYs  8$iTXtXML:com.adobe.xmp Adobe Photoshop CC 2017 (Windows) 2017-06-22T16:14:06+08:00 2017-06-22T16:14:16+08:00 2017-06-22T16:14:16+08:00 image/png 3 xmp.iid:33eaa353-cf74-6f45-9cc4-eeac871f3c63 xmp.did:33eaa353-cf74-6f45-9cc4-eeac871f3c63 xmp.did:33eaa353-cf74-6f45-9cc4-eeac871f3c63 created xmp.iid:33eaa353-cf74-6f45-9cc4-eeac871f3c63 2017-06-22T16:14:06+08:00 Adobe Photoshop CC 2017 (Windows) 1 720000/10000 720000/10000 2 65535 16 16 3e cHRMz%u0`:o_FIDATxԓQ @Dߑ @Bq@@PpXup%%_&3U!`H^@!18LA9P4SI])<@m//``9~@a[[tB =5Qkp*qLbnт8u"[/mYcm>k`UQIENDB`kylin-video/src/res/volume_low_normal.png0000664000175000017500000000042713214347337017572 0ustar fengfengPNG  IHDRw=tEXtSoftwareAdobe ImageReadyqe<IDATxb`֠a>f00<&P8-n a pwR,jf$Bm>SP%b "?M,`8(x.*EFZ A=|PF dIDATxbtpp`& ~efcc3T @@ %%P0# `DW D =jjjؕK_+\Ά mf`dzH#Or+>"B52`z|-S#$aor_X6d!䘠sWd 6=?͞#( "@qpC?<%9C/)m5oBٞ]5&gT(:,=!}ÍHT<IENDB`kylin-video/src/res/option_hover.png0000664000175000017500000000235313214347337016545 0ustar fengfengPNG  IHDR$$e?YtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp 풸#IDATxb: 01RĈlϏn ʩA8Ĉ -5EXQh t9W!$}9Hp>dM$ L,B؋>Ƨ h5fd6ۀW&Hdj!Hjc!#AbO@Eɂl8o-l6~Cvbp'e#3wՍ ^ˀR%Nre 9K"6U#F|(8zq6jH AIuIENDB`kylin-video/src/res/delete_normal.png0000664000175000017500000000060513214347337016642 0ustar fengfengPNG  IHDR Vu\gAMA a cHRMz&u0`:pQ< pHYs  IDAT(jP{R:D:e ;9dwTcBtv $o▭{g)dʖ&P~?I=|jt]7'i3J~DĽ{:u]/۶}N#&>&F@EѶ( `^A }Kˀ<;h#nDGgv*ϲl-VD'رG8kZ+.IiYLIw?7ʮ~tIENDB`kylin-video/src/res/progress_pointer_press.png0000664000175000017500000003667613214347337020671 0ustar fengfengPNG  IHDRp n pHYs  9iTXtXML:com.adobe.xmp xmp.did:24776fe3-5e39-7846-8bf7-7165f60dca4a xmp.did:5B0A2F11524211E785EEB6DD3C6AA44E xmp.iid:247c9624-d7cb-c049-80be-5cac164ea0b6 xmp.iid:2a7af3b8-43b0-6745-a0f2-048f0ea0e907 adobe:docid:photoshop:772c815a-4f1d-11e7-a29c-ee28c792f004 saved xmp.iid:247c9624-d7cb-c049-80be-5cac164ea0b6 2017-07-12T13:45:03+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-07-12T13:44:21+08:00 2017-07-12T13:45:03+08:00 2017-07-12T13:45:03+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 24 24 JT cHRMz%u0`:o_FIDATx =D2@6lܩ6L,! Cu뷉SI6]I.)kei ```He``Pb@R. vTα @PEaNB 7 DU/&<@ )_ѠŁ=GL "" 2JT_t;AQčĕQB3Gg1ښ#9ܿޏ2 #yRw s,G[Xb)"c{i/ ^aT DRVhFnїo:օ0 8mTj WP[P)% 6z JDRK*6a3Gs9w_6*cUM@oֱsGSҹMnW"$t/\Us6=jSSKD?s&va]XL4>FksR_R ^+#{q++ ڴŸtf^\p ܦ [~߼ K)VQ\kS(膃(~k{Xq̵FJ. w`0o >TCUU<`udW@{$q̢U`eRme/8!8I`L>B+/&4Qк\gHRRKW_x#ֳT|?x8&ӑIENDB`kylin-video/src/res/forward_10_seconds_hover_press.png0000664000175000017500000000350013214347337022126 0ustar fengfengPNG  IHDR tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp e4{RIDATxbm53B0Ai!!\ F~(\: 2ML? H$#7L $ ? @ NU@rO@Hq(T7 ~h,< G@.Pp& yRШ$@ `!y CO@@Š@N"ty01󀚧 ffb gB Y47SD*݃FgS13K 51K"yŏR@,fH4PH AM!XB;K )<^@K[6ub#.0dg7#ǵK|Fߋ'~gxf{蔜YAO(& hNZ@譼%x4J?w\y +SdjVs#Ԕ).q7x1 zcwq9rd8f"KEorn2-5#`Ha0_ uס58&)>aaJQPC$RA A@m@)AhD"(9Qhܹ@|hAy u~5b! Pa-4(@ ×h`A@P--R3 ` &A5=M Ϡl p] U|yX ىnA@Y d7/>Ձ -%ױf! -se  d *vڊxEð ظE^-/[|[MNY r %V^o%c.?IENDB`kylin-video/src/res/volume_mute_hover_press.png0000664000175000017500000000260113214347337021006 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp IDATxb? 0q/!(H ѕ1`(b5 ?A @ PlD,Pq" 0AdOp@&q@D0`{>&F4$=(!Iq",7t#9IJ7d ӁN@8a Yk!pLHC"~` Hfa1 $"%UA|@{ɠ8q=-  5&X,K!tAhKJHiI)A 6@1-1zcIr46aa@!`AKe HI$mF,6@@h6 w ^q?;YBPχfh6e5bJa\r(<# ]-R1RĔ_H6. ͵86$) a!{94mZ4U {q]IENDB`kylin-video/src/res/pause_hover_press.png0000664000175000017500000000231613214347337017565 0ustar fengfengPNG  IHDR==ieQtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp IDATxb9À01)ИV0R bs8` D8p 7tH5 @ 4`N-U#㫩G}nحca!o\n0N`0!xhǎM@8A6G0 :6)d{>? :*-@fUŞIENDB`kylin-video/src/res/prefs_hover_press.png0000664000175000017500000000251513214347337017570 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp  }M_IDATxb?01@@1L E0%3\ 0!C$P!g@<PK@$@0[/T#+ˠ& ~ 0@ 5=T d<@@01b_X(G \x;>9jBs!d_< /^(9/:`n `a. N įK@ŗbjTຐlG(ɽr(M4(4 JOX\Hrˁx34>e Y( Br a#|N=es@ܑrL#3IENDB`kylin-video/src/res/spin_top_arrow_hover.png0000664000175000017500000000233213214347337020277 0ustar fengfengPNG  IHDR |@~tEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp IDATxbtpp`&  F | @@/#\H H#H+, "@ es/n9$ PF,Xu@=O|ځB}+l3f<0KJJ)/ |8 p@ dCILVŵdT<|yML4 ?p= *~hЅUon~zQN=_bIENDB`kylin-video/src/res/checkbox_disable.png0000664000175000017500000000233613214347337017304 0ustar fengfengPNG  IHDRhOGtEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp 3IDATxbL &Č @DZd@p=0YRFiL@=HTQQѐ H”0E0H}H SihJ"V_%T<,0{Au!Hyd<r:P>l 4h(t gYU tč@W`MPM@=SO+`Ѡ JR 4P@/$8ZM%H@GV}1oߞIENDB`kylin-video/src/res/volume_high_hover_press.png0000664000175000017500000000277313214347337020765 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp kIDATxb&p10 o@ ѕq>)  U b;% M@p@Pf|($D B}'H pADU ;D0ERȌ 5̇:(q>H!Ա݄<?.`b@Neۣk`D DX 6@mi:BlQ @5@=r!{Lh xa@gGbq}k0ġPhr,Qa, 85l!nKz$$AXZai X` "kN:  ;) lE#bPҰ >@ʪa. A%  H@  + f 8r<+4~zwョqG r6<|~f ȓ !B$%AE-9$3ԇ k ;xÒıJ,ݍ#%p:a\M.$ީaS*9"6I'{ D‰Jځ E'UZ9 h#Gofy(vnai&;F/Gg VW(RnIENDB`kylin-video/src/res/max_normal.png0000664000175000017500000000220413214347337016162 0ustar fengfengPNG  IHDR$$tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp .IDATxb?:`b( Ftj#,@\Osh p)O5ip"*0f۠6?]B H5q@&Q( 77IDATxb? s@1( l@CCZ0~& Ť<d72`3 'DI3U@ :88h?P xmp.did:24776fe3-5e39-7846-8bf7-7165f60dca4a xmp.did:A792F0EC524511E78266808D4B6162B4 xmp.iid:1aabfc52-2e34-d449-bafa-250edc218ba0 xmp.iid:2a7af3b8-43b0-6745-a0f2-048f0ea0e907 adobe:docid:photoshop:772c815a-4f1d-11e7-a29c-ee28c792f004 saved xmp.iid:1aabfc52-2e34-d449-bafa-250edc218ba0 2017-06-16T12:25:38+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-06-16T11:40:14+08:00 2017-06-16T12:25:38+08:00 2017-06-16T12:25:38+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 24 24 w- cHRMz%u0`:o_FIDATxb? 0000466e``Pb 000bAQȈb?L*𪡡ALB ٘wl1 0@OPDL SҹcЀ5tuܨ xtϱ @P#e H)S05cd*v  z*"'ͷ%^ l1ʇdĂZz1g욀○w\p' MҾm6LE8U pGh4&̂&fA61Y{ A AZ&,wrq $[2`>,~h*pS#>RƯ+@ mHV^X5Qȡ0)\F6 PAjթfq-:PSOj٣4DQ` ll,m\`)(jEF1d>!V6XYQq n ^r33;St:Gkz!L]n3` DfI`5zQ;I9ZJ6DeNPov<#<ܩWi+M$O1ct,HrZG蝫{bO%1jOm>Ǖ#U} Q;>Gm4Bc_zRJc)Av7=?%=3IENDB`kylin-video/src/res/radiobutton_checked.png0000664000175000017500000000256013214347337020032 0ustar fengfengPNG  IHDRhOGtEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp a辰IDATxbd L b}b9UL@a@ @&_ـx"4 b +z2@H&W H `z@U1% 20 ~ A2FX< "@Հ `{@| d PdC,[S /(2AIB'{(v `}@Ij3"A!% J/ F3TNlpIENDB`kylin-video/src/res/option_normal.png0000664000175000017500000000226413214347337016713 0ustar fengfengPNG  IHDR$$tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp O$IDATxb?:`bC1v,HlF -benY  Fl'7h!$Ft7n" cS3ښQI`t'' F!"@9 "*5k\X(_aD0k`T+!F4bBJBTw6(?lЕCih4 ԣu=kIENDB`kylin-video/src/res/spin_top_arrow_disable.png0000664000175000017500000000231013214347337020553 0ustar fengfengPNG  IHDR |@~tEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp 2`IIDATxbtpp`& ~ F ;;; f ϟ?R$@ACRRRLpD8\'! PF,XmB1M : Ç.}5Bϟ@?~@1h S\%P\$''${SHZZΝ;***_~})N//ޛ7onݺ? dEʨUIENDB`kylin-video/src/res/warn.png0000664000175000017500000000742113214347337015002 0ustar fengfengPNG  IHDR<::o pHYs   MiCCPPhotoshop ICC profilexڝSwX>eVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/%ҟ3 cHRMz%u0`:o_F>IDATx[q@}ɿ܁/>T` L: L `;w>*T{,OvF}{\‰Jͱ.uep|Rlv{>aȂ5ʑ'}LMܴeZoI-Pc/2_]s5 |<"?1FW]& A@d36!1X`t;`L$f`L5+t3`j! .9mrVf4h.x˃0^*v#&/eu* cyd x@² r;(^.wlvYSaa@[3, =KXc~Y  kO\-r.q/r ݟêUuKKs 4ZYiBO]n\ Vj?[|b_ăEzb-b^iKPH uacjXJQ}h(!ҏxf ɝ}7H)g~ %CAҤS\>tᝧMY:}UD?)UZm{o#7PP *UԱZ۳崧%ִ.BŒ#Qw/c]sI+h֘vdŁz:vsϥn4zKC!Yn.=_@fC6(?j-d)k?rx'>۲gF%~!S3xގo3W#~hP 8P^t IENDB`kylin-video/src/res/unmax_normal.png0000664000175000017500000000227313214347337016533 0ustar fengfengPNG  IHDR$$tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp S*IDATxb?:`bcdī -b"h+abz|C;E4݄Kb1mΠT`q\ÈO! @#>#e~ 5tDgj%٨F4X OZez4 WQ0* O(0l?Q ;|.6KzIENDB`kylin-video/src/res/style.qss0000664000175000017500000010330013214347337015206 0ustar fengfengQLabel#BtmSeperatorLine { background-color: rgba(0, 0, 0, .1); } QLabel#TopSeperatorLine { background-color: rgba(0, 0, 0, 0.1); } QFrame { border:none; } QToolButton#MenuButton{ background:transparent; font-family:"方正黑体_GBK"; /*font-weight:bold;*/ font-size:16px; color:#48494c; border:none; /*background-color:#e9eef1;*/ } /*QToolButton#MenuButton:hover{ background-color:#ddf3f6; border:1px solid #abd3e2; border-radius:3px; }*/ QWidget#SoundVolume { qproperty-background: rgba(255,255,255, 100%); qproperty-borderColor: rgba(0,0,0,20%); qproperty-radius: 4.0; } /*-------------------QMenu-------------------*/ QMenu{ background: #2e2e2e; border:1px solid #121212; margin:1px; } QMenu::icon { position: absolute; left: 21px; } /*QMenu::icon:checked { background: red; border: 1px inset gray; position: absolute; top: 1px; right: 1px; bottom: 1px; left: 21px; }*/ QMenu::item { padding:0px 0px 0px 45px;/*item的文字距离item的上右下左的距离: top right bottom left*/ margin-left: 0px; border:1px solid #2e2e2e; height:25px; color: #999999; font-size:12px; font-family:方正黑体_GBK; background-color: transparent; border: 1px solid transparent; } /*当用户使用鼠标活着键盘进行选择的时候选择项的颜色*/ /*QMenu::item:selected { background-color: #0da4f6; }*/ /*item不可点击时 color:文字的颜色*/ /*QMenu::item:disabled { color: #4f4f4f; }*/ QMenu::item:selected:enabled{ background: #0da4f6; color: #ffffff; } QMenu::item:selected:!enabled{ background:transparent; } /*分割线*/ QMenu::separator{ height:1px; background: #3b3b3b; margin:2px 0px 2px 0px; } QMenu::indicator:exclusive:checked { image: url(:/res/menu_selected.png); } QMenu::indicator:non-exclusive:checked{ image:url(:/res/ok.png); } /*QMenu::indicator { width: 65px; height: 13px; }*/ /* exclusive:这個条目是一個互斥的条目组中的一個。比如,在一個互斥的QActionGroup 中的一個菜单条目。 non-exclusive:这個条目是某個非互斥的条目组中的一個。比如,在某個非互斥的 QActionGroup 中的一個菜单条目 */ /*QMenu::indicator:non-exclusive:unchecked{ image:url(:/res/ok.png); } QMenu::indicator:non-exclusive:unchecked:selected{ image:url(:/res/open.png); } QMenu::indicator:non-exclusive:checked{ image: url(:/res/music.png); } QMenu::indicator:non-exclusive:checked:selected{ image: url(:/res/logo.png); } QMenu::indicator:exclusive:unchecked{ image:url(:/res/playlist.png); } QMenu::indicator:exclusive:unchecked:selected{ image:url(:/res/prefs.png); } QMenu::indicator:exclusive:checked{ image:url(:/res/quit_normal.png); } QMenu::indicator:exclusive:checked:selected{ image:url(:/res/speed.png); }*/ QPushButton#TrayButton { border: none; background: transparent; } QPushButton#TrayButton:hover { background: rgb(233, 237, 252); color: rgb(42, 120, 192); } QSlider#PlayingProgress1::groove:horizontal { /*background: transparent; position: absolute; left: 0px; right: 0px;*/ border-radius:2px;height:3px; /*height: 6px;background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 rgb(124, 124, 124), stop: 1.0 rgb(72, 71, 71));*/ } QSlider#PlayingProgress1::handle:horizontal { /*background:transparent; margin: 5px -5px;*/ background:rgb(255, 255, 160);width:8px;border-radius:4px;margin:-3px 0px -3px 0px; /*width: 1px;background: rgb(0, 160, 230);margin: -6px 0px -6px 0px;border-radius: 9px;*/ } QSlider#PlayingProgress1::add-page:horizontal { background: transparent; background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0 transparent, stop:0.08333 transparent, stop:0.08400 rgba(255, 255, 255, 0.08), stop:0.16666 rgba(255, 255, 255, 0.08), stop:0.17000 rgba(0, 0, 0, 0.0), stop:0.24999 rgba(0, 0, 0, 0.0), stop:0.25000 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0) ); } QSlider#PlayingProgress1::sub-page:horizontal { background: #2ca7f8; background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0 #2ca7f8, stop:0.08333 #2ca7f8, stop:0.08333 #2ca7f8, stop:0.16666 #2ca7f8, stop:0.17000 rgba(0, 0, 0, 0.3), stop:0.24999 rgba(0, 0, 0, 0.3), stop:0.25000 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0) ); } QSlider#processProgress::groove:horizontal { background: transparent; position: absolute; left: 0px; right: 0px; } QSlider#processProgress::handle:horizontal { background:transparent; margin: 5px -5px; } QSlider#processProgress::add-page:horizontal { background: transparent; background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0 #1f1f1f, stop:0.08333 #1f1f1f, stop:0.08400 #1f1f1f, stop:0.16666 #1f1f1f, stop:0.17000 transparent, stop:0.24999 transparent, stop:0.25000 transparent, stop:1 transparent ); } QSlider#processProgress::sub-page:horizontal { background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0 #b35dff, stop:0.08333 #b35dff, stop:0.08333 #2cbdff, stop:0.16666 #2cbdff, stop:0.17000 transparent, stop:0.24999 transparent, stop:0.25000 transparent, stop:1 transparent ); } QSlider#processProgress::groove:horizontal[status="active"] { height:6px; background:#1f1f1f; position: absolute; left: 0px; right: 0px; top: 0px;/*-8px;*/ } QSlider#processProgress::handle:horizontal[status="active"] { border-image:url(:/res/progress_pointer_normal.png); border-radius:7px; width:24px; height:24px; left:4px;right:4px; margin:-9px -9px -9px -9px; } QSlider#processProgress::handle:horizontal:hover[status="active"] { border-image:url(:/res/progress_pointer_hover.png); border-radius:7px; width:24px; height:24px; } QSlider#processProgress::add-page:horizontal[status="active"] { background: transparent; background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0 transparent, stop:0.08333 transparent, stop:0.08400 rgba(255, 255, 255, 0.08), stop:0.16666 rgba(255, 255, 255, 0.08), stop:0.17000 rgba(0, 0, 0, 0.0), stop:0.24999 rgba(0, 0, 0, 0.0), stop:0.25000 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0) ); } QSlider#processProgress::sub-page:horizontal[status="active"] { background-color: qlineargradient(x1:0 y1:0, x2:1 y2:0, stop:0 #b35dff, stop:1 #2cbdff ); } QSlider#PlayingProgress::groove:horizontal[status="active"] { /*border-radius:2px;height:3px;*/ /*height:6px; margin-left:3px; background:#1f1f1f; border-radius:3px;*/ height:6px; background:#1f1f1f; position: absolute; left: 0px; right: 0px; top: 0px;/*-8px;*/ } QSlider#PlayingProgress::handle:horizontal[status="active"] { /*background:rgb(255, 255, 160);width:8px;border-radius:4px;margin:-3px 0px -3px 0px;*/ /*border-image:url(:/res/progress_pointer_normal.png); width:24px; height:24px; border-radius:7px; margin-top:0px; margin-bottom:-4px;*/ /*border-image:url(:/res/progress_pointer_normal.png); border-radius:7px; width:24px; height:24px; left:8px;right:8px; margin:-14px -14px -14px -14px;*/ border-image:url(:/res/progress_pointer_normal.png); border-radius:7px; width:24px; height:24px; left:4px;right:4px; margin:-9px -9px -9px -9px; /*margin-top:-5px; margin-bottom:-5px;*/ } QSlider#PlayingProgress::handle:horizontal:hover[status="active"] { border-image:url(:/res/progress_pointer_hover.png); border-radius:7px; width:24px; height:24px; } /*QSlider#PlayingProgress::handle:horizontal:press[status="active"] { border-image:url(:/res/progress_pointer_press.png); border-radius:7px; width:34px; height:34px; }*/ QSlider#PlayingProgress::add-page:horizontal[status="active"] { background: transparent; background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0 transparent, stop:0.08333 transparent, stop:0.08400 rgba(255, 255, 255, 0.08), stop:0.16666 rgba(255, 255, 255, 0.08), stop:0.17000 rgba(0, 0, 0, 0.0), stop:0.24999 rgba(0, 0, 0, 0.0), stop:0.25000 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0) ); } QSlider#PlayingProgress::sub-page:horizontal[status="active"] { /*background: #2ca7f8; background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0 #2ca7f8, stop:0.08333 #2ca7f8, stop:0.08333 #2ca7f8, stop:0.16666 #2ca7f8, stop:0.17000 rgba(0, 0, 0, 0.3), stop:0.24999 rgba(0, 0, 0, 0.3), stop:0.25000 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0) );*/ background-color: qlineargradient(x1:0 y1:0, x2:1 y2:0, stop:0 #b35dff, stop:1 #2cbdff ); } /*QSlider{ border-color: #cbcbcb; height:18px; background: transparent; }*/ /*槽*/ QSlider#PlayingProgress::groove:horizontal { /*background: transparent;*/ /*height:2px;*/ background:#1f1f1f; position: absolute; left: 0px; right: 0px; } /*滑块*/ QSlider#PlayingProgress::handle:horizontal { /*background:transparent;*/ margin: 5px -5px; } /*未滑过的槽部分*/ QSlider#PlayingProgress::add-page:horizontal { background: transparent; background-color: #1f1f1f; } /*已滑过的槽部分*/ QSlider#PlayingProgress::sub-page:horizontal { /*background-color: qlineargradient(x1:0 y1:0, x2:0 y2:1, stop:0 #b35dff, stop:0.08333 #b35dff, stop:0.08333 #2cbdff, stop:0.16666 #2cbdff, stop:0.17000 rgba(0, 0, 0, 0.3), stop:0.24999 rgba(0, 0, 0, 0.3), stop:0.25000 rgba(0, 0, 0, 0.0), stop:1 rgba(0, 0, 0, 0.0) );*/ background-color: qlineargradient(x1:0 y1:0, x2:1 y2:0, stop:0 #b35dff, stop:1 #2cbdff ); } /*槽*/ QSlider#VolumeProgress::groove:horizontal { height:2px; background:#141414; border-radius:2px; position: absolute; /*left: 0px; right: 0px; top: 0px;*/ } /*滑块*/ QSlider#VolumeProgress::handle:horizontal { background:#ffffff;width:12px;border-radius:6px;margin:-5px 0px -5px 0px; } /*QSlider#VolumeProgress::handle:horizontal:hover { background:#ffffff;width:12px;border-radius:6px;margin:-5px 0px -5px 0px; } QSlider#VolumeProgress::handle:horizontal:press { background:#ffffff;width:12px;border-radius:6px;margin:-5px 0px -5px 0px; }*/ /*未滑过的槽部分*/ QSlider#VolumeProgress::add-page:horizontal { background: transparent; background-color: #141414; } /*已滑过的槽部分*/ QSlider#VolumeProgress::sub-page:horizontal { background:#808080; } QSlider#HoverProgress::groove:horizontal,QSlider::add-page:horizontal{ height:3px; border-radius:3px; background:#18181a; } QSlider#HoverProgress::sub-page:horizontal{ height:8px; border-radius:3px; background:#008aff; } QSlider#HoverProgress::handle:horizontal{ width:12px; margin-top:-5px; margin-bottom:-4px; border-radius:6px; background:qradialgradient(spread:pad,cx:0.5,cy:0.5,radius:0.5,fx:0.5,fy:0.5,stop:0.6 #565656,stop:0.8 #565656); /*bacder-image:url(./res/images/live/GOUGOU.png)*/ } QSlider#HoverProgress::groove:vertical,QSlider::sub-page:vertical{ width:8px; border-radius:3px; background:#D8D8D8; } QSlider#HoverProgress::add-page:vertical{ width:8px; border-radius:3px; background:#008aff; } QSlider#HoverProgress::handle:vertical{ height:12px; margin-left:-5px; margin-right:-4px; border-radius:6px; background:qradialgradient(spread:pad,cx:0.5,cy:0.5,radius:0.5,fx:0.5,fy:0.5,stop:0.6 #565656,stop:0.8 #565656); /*bacder-image:url(./res/images/live/GOUGOU.png)*/ } QPushButton#StopBtn{ border-image: url(:/res/stop_normal.png); } QPushButton#StopBtn:hover{ border-image: url(:/res/stop_hover_press.png); } QPushButton#StopBtn:pressed{ border-image: url(:/res/stop_hover_press.png); } QPushButton#PrevBtn{ border-image: url(:/res/previous_normal.png); } QPushButton#PrevBtn:hover{ border-image: url(:/res/previous_hover_press.png); } QPushButton#PrevBtn:pressed{ border-image: url(:/res/previous_hover_press.png); } QPushButton#PlayBtn{ border-image: url(:/res/play_normal.png); } QPushButton#PlayBtn:hover{ border-image: url(:/res/play_hover_press.png); } QPushButton#PlayBtn:pressed{ border-image: url(:/res/play_hover_press.png); } QPushButton#PlayBtn[playstatus=playing]{ border-image: url(:/res/pause_normal.png); } QPushButton#PlayBtn:hover[playstatus=playing]{ border-image: url(:/res/pause_hover_press.png); } QPushButton#PlayBtn:pressed[playstatus=playing]{ border-image: url(:/res/pause_hover_press.png); } QPushButton#NextBtn{ border-image: url(:/res/next_normal.png); } QPushButton#NextBtn:hover{ border-image: url(:/res/next_hover_press.png); } QPushButton#NextBtn:pressed{ border-image: url(:/res/next_hover_press.png); } QPushButton#SoundBtn[volume="high"]{ border-image: url(:/res/volume_high_normal.png); } QPushButton#SoundBtn:hover[volume="high"]{ border-image: url(:/res/volume_high_hover_press.png); } QPushButton#SoundBtn:pressed[volume="high"]{ border-image: url(:/res/volume_high_hover_press.png); } QPushButton#SoundBtn[volume="mid"]{ border-image: url(:/res/volume_mid_normal.png); } QPushButton#SoundBtn:hover[volume="mid"]{ border-image: url(:/res/volume_mid_hover_press.png); } QPushButton#SoundBtn:pressed[volume="mid"]{ border-image: url(:/res/volume_mid_hover_press.png); } QPushButton#SoundBtn[volume="low"]{ border-image: url(:/res/volume_low_normal.png); } QPushButton#SoundBtn:hover[volume="low"]{ border-image: url(:/res/volume_low_hover_press.png); } QPushButton#SoundBtn:pressed[volume="low"]{ border-image: url(:/res/volume_low_hover_press.png); } QPushButton#SoundBtn[volume="mute"]{ border-image: url(:/res/volume_mute_normal.png); } QPushButton#SoundBtn:hover[volume="mute"]{ border-image: url(:/res/volume_mute_hover_press.png); } QPushButton#SoundBtn:pressed[volume="mute"]{ border-image: url(:/res/volume_mute_hover_press.png); } QPushButton#FullScreenBtn{ border-image: url(:/res/fullscreen_normal.png); } QPushButton#FullScreenBtn:hover{ border-image: url(:/res/fullscreen_hover_press.png); } QPushButton#FullScreenBtn:pressed { border-image: url(:/res/fullscreen_hover_press.png); } QPushButton#FullScreenBtn[fullscreen=true]{ border-image: url(:/res/cancel_fullscreen_normal.png); } QPushButton#FullScreenBtn:hover[fullscreen=true]{ border-image: url(:/res/cancel_fullscreen_hover_press.png); } QPushButton#FullScreenBtn:pressed[fullscreen=true]{ border-image: url(:/res/cancel_fullscreen_hover_press.png); } QPushButton#OpenFileBtn{ border-image: url(:/res/open_file_normal.png); } QPushButton#OpenFileBtn:hover{ border-image: url(:/res/open_file_hover_press.png); } QPushButton#OpenFileBtn:pressed{ border-image: url(:/res/open_file_hover_press.png); } QPushButton#PlayListBtn{ border-image: url(:/res/playlist_open_normal.png); } QPushButton#PlayListBtn:hover{ border-image: url(:/res/playlist_open_hover_press.png); } QPushButton#PlayListBtn:pressed{ border-image: url(:/res/playlist_open_hover_press.png); } QPushButton#PlayListBtn[playliststatus=close]{ border-image: url(:/res/playlist_close_normal.png); } QPushButton#PlayListBtn:hover[playliststatus=close]{ border-image: url(:/res/playlist_close_hover_press.png); } QPushButton#PlayListBtn:pressed[playliststatus=close]{ border-image: url(:/res/playlist_close_hover_press.png); } QPushButton#PlayMaskBtn{ border-image: url(:/res/play_center_normal.png); } QPushButton#PlayMaskBtn:hover{ border-image: url(:/res/play_center_hover_press.png); } QPushButton#PlayMaskBtn:pressed{ border-image: url(:/res/play_center_hover_press.png); } QWidget#TipWidget { qproperty-background: rgba(0,0,0,70%); qproperty-borderColor: rgba(0,0,0,10%); qproperty-radius: 4.0px; } QWidget#EscTip { qproperty-background: rgba(0,0,0,70%); qproperty-borderColor: rgba(0,0,0,10%); qproperty-radius: 4.0px; } QLabel#WhiteTipText { font-size: 12px; color: #ffffff; } QLabel#SplitText { background: #ffffff; } QLabel#VideoText { font-size: 14px; color: #808080; background: transparent; } QLineEdit#PlayListTitle { color: #ffffff; font-size: 12px; background: transparent; border: none; qproperty-alignment: AlignLeft; } QLineEdit#PlayListTitle::hover { color: #0da4f6; font-size: 12px; background: #242424; } QLineEdit#PlayListTitle:enabled { background: #0a0a0a;color:#999999; } QLineEdit#PlayListTitle:enabled:hover, QLineEdit#PlayListTitle:enabled:focus { background: #0a0a0a;color:#ffffff; } QLineEdit#PlayListTitle[status="active"] { color: #009aff; } QLineEdit#PlayListTitle:focus[status="active"] { color: #ffffff; background-color: white; border-radius: 4.0px; border: 1px solid rgba(0, 0, 0, 0.08); } QLabel#PlayListIcon { image: url(:/res/playlist.png); } QLabel#PlayListIcon[iconName="vedio"] { image: url(:/res/video_normal.png); } QLabel#PlayListIcon:hover[iconName="vedio"] { image: url(:/res/video_hover_press.png); } QLabel#PlayListIcon[iconName="music"] { image: url(:/res/music.png); } QPushButton#PlayListDelete { background-image:url(':/res/trash_normal.png'); border:0px; } QPushButton#PlayListDelete:hover { background:url(':/res/trash_hover_press.png'); } QPushButton#PlayListDelete:pressed { background:url(':/res/trash_hover_press.png'); } QPushButton#PlayListDelete[status="active"] { background:url(':/res/trash_hover_press.png'); border:0px; } QFrame#PlayListInterFrame{ border: none; border-bottom: 1px solid rgba(0, 0, 0, 0.05); } QFrame#PlaylistWidget{ /*background: rgba(255, 255, 255, 20%);*/ border: 1px solid rgba(0, 0, 0, 0.1); border-top: none; background-color: #2e2e2e; /*rgba(255, 255, 255, 0.9);*/ } QFrame#PlaylistWidgetAddFrame{ background-color: #121212; } QPushButton#PlaylistAddButton{ color: #0da4f6; font-size: 14px; border-radius: 4px; background-color: #383838; border: 1px solid #808080; } QPushButton#PlaylistAddButton:hover{ color: #0a9ff5; background-color: #404040; border: 1px solid #0a9ff5; } QPushButton#PlaylistAddButton:pressed{ color: #0da4f6; background-color: #333333; border: 1px solid #0da4f6; } QPushButton#PlaylistButton{ color: #ffffff; font-size: 12px; border: none; background: transparent; } QPushButton#PlaylistButton:hover{ color: #0da4f6; font-size: 12px; background-color: transparent; border: none; } QPushButton#PlaylistButton:pressed{ color: #0da4f6; font-size: 12px; background-color: transparent; border: none; } /*QPushButton#PlaylistButton:disabled{ color: grey; background-color: qlineargradient( x1:0 y1:0, x2:0 y2:1, stop:0 #ffffff, stop:1 #fdfdfd); border: 1px solid rgba(0, 0, 0, 0.08); }*/ QListWidget#ListBox{ color: #999999; font-size: 12px; border: 0px solid rgba(255, 0, 0, 0.7); background-color: #171717; outline:none; } QListWidget#ListBox::item{ color: #999999; height: 30px; } QListWidget#ListBox::item:selected:!active { color: #999999; background-color: #171717; } QListWidget#ListBox::item:selected:active { color: #999999; background-color: #0f0f0f; } QListWidget#PlayListView{ color: #009aff; font-size: 12px; border: none; background-color: #2e2e2e; outline:none; } QListWidget#PlayListView::item{ border: none; color: #009aff; height: 56px; } QListWidget#PlayListView::item:hover{ background: #242424; } QListWidget#PlayListView::item:selected{ color: #0da4f6; background-color: qlineargradient(x1:0 y1:0, x2:1 y2:0, stop:0 #0da4f5, stop:0.015 #2aa6f8, stop:0.0155 rgba(42, 166, 248, 20%), stop:1 rgba(42, 166, 248, 20%)); } /*QListWidget#PlayListView::item:selected:active { color: blue; background-color: red; }*/ /*QListWidget#PlayListView::item:selected:!active { color: white; background-color: qlineargradient(x1:0 y1:0, x2:1 y2:0, stop:0 #2aa6f8, stop:0.015 #2aa6f8, stop:0.0155 rgba(42, 166, 248, 20%), stop:1 rgba(42, 166, 248, 20%)); } QListWidget#PlayListView::item:selected:active { color: #0da4f6; background-color: qlineargradient(x1:0 y1:0, x2:1 y2:0, stop:0 #2aa6f8, stop:0.015 #2aa6f8, stop:0.0155 rgba(42, 166, 248, 20%), stop:1 rgba(42, 166, 248, 20%)); }*/ QListWidget#ShortCutList{ color: #009aff; font-size: 12px; border: none; background-color: #2e2e2e; outline:none; } QListWidget#ShortCutList::item{ border: none; color: #009aff; height: 30px; } QListWidget#ShortCutList::item:hover{ background: #242424; } QListWidget#ShortCutList::item:selected{ color: #0da4f6; background: rgba(42, 166, 248, 20%); } /*-------------------QRadioButton-------------------*/ QRadioButton { spacing: 5px; font-size: 12px; color:#999999; font-family: "方正黑体_GBK"; } QRadioButton::indicator { width: 14px; height: 14px } QRadioButton::indicator:checked { image: url(:/res/radiobutton_checked.png); } QRadioButton::indicator:disabled { image: url(:/res/radiobutton_disable.png); } QRadioButton::indicator:unchecked { image: url(:/res/radiobutton_unchecked.png); } QRadioButton::indicator:unchecked:hover { image: url(:/res/radiobutton_unchecked.png); } /*-------------------QCheckBox-------------------*/ QCheckBox{ spacing:5px; background:transparent; font-size:12px; color:#999999; font-family:"方正黑体_GBK"; } QCheckBox::indicator { width:14px; height:14px; } QCheckBox::indicator:unchecked{ image: url(:/res/checkbox_unchecked.png); } QCheckBox::indicator:unchecked:hover { image: url(:/res/checkbox_unchecked.png); } QCheckBox::indicator:unchecked:pressed { image: url(:/res/checkbox_unchecked.png); } QCheckBox::indicator:checked{ image: url(:/res/checkbox_checked.png); } QCheckBox::indicator:checked:hover { image: url(:/res/checkbox_checked.png); } QCheckBox::indicator:checked:pressed { image: url(:/res/checkbox_checked.png); } /*-------------------QComboBox-------------------*/ QComboBox#Combo { width:150px; height: 24px; /*border-radius: 4px;*/ border: 1px solid #000000; background: #0f0f0f; font-family:"方正黑体_GBK"; font-size:12px; color:#999999; } QComboBox#Combo::hover{/*非编辑状态下,鼠标移到控件上的背景色和边框色*/ background-color:#0f0f0f; border:1px solid #0a9ff5; font-family:"方正黑体_GBK"; font-size:12px; color:#999999; } QComboBox#Combo:enabled {/*点卡下拉列表后下拉列表各项的文字颜色*/ color: #999999; } QComboBox#Combo:!enabled { color: #0f0f0f; } QComboBox#Combo:enabled:hover, QComboBox#Combo:enabled:focus { color: #1f1f1f; } QComboBox#Combo::drop-down {/*右侧箭头图标的处理*/ width: 17px; border: none; background: transparent; } QComboBox#Combo::drop-down:hover { background: transparent; } QComboBox#Combo::down-arrow{ image:url(:/res/combobox_arrow_normal.png); } QComboBox#Combo::down-arrow:hover{ image:url(:/res/combobox_arrow_hover.png); } QComboBox#Combo::down-arrow:pressed{ image:url(:/res/combobox_arrow_press.png); } QComboBox#Combo QAbstractItemView {/*下拉列表弹出框*/ border: 1px solid #0a9ff5; background: #1f1f1f; outline: none; /*selection-background-color: yellow;*/ } QComboBox#Combo QAbstractItemView::item {/*貌似无效*/ height: 24px; color: #999999; } QComboBox#Combo QAbstractItemView::item:selected {/*貌似无效*/ background: #0f0f0f; color: #999999; } /*非编辑状态下默认底色和编辑状态下鼠标移到非选中项的底色*/ /*QComboBox:!editable, QComboBox::drop-down:editable { background: #1f1f1f; }*/ /*编辑状态下鼠标移到被勾选项时的底色*/ /*QComboBox:!editable:on, QComboBox::drop-down:editable:on { background: #262626; }*/ QTimeEdit#seekTime{ border: 1px solid #000000; background: #0f0f0f; font-family:"方正黑体_GBK"; font-size:12px; color:#999999; height: 24px; } QTimeEdit#seekTime:hover { background-color:#0f0f0f; border:1px solid #0a9ff5; font-family:"方正黑体_GBK"; font-size:12px; color:#999999; } QTimeEdit#seekTime::up-button { background:transparent; width: 17px; height:12px; } QTimeEdit#seekTime::down-button { background:transparent; width: 17px; height:12px; } QTimeEdit#seekTime::up-arrow { border: none; width: 17px; height: 12px; image: url(:/res/spin_top_arrow_normal.png); } QTimeEdit#seekTime::up-arrow:hover { image: url(:/res/spin_top_arrow_hover.png); } QTimeEdit#seekTime::up-arrow:pressed { image: url(:/res/spin_top_arrow_press.png); } QTimeEdit#seekTime::down-arrow { border: none; width: 17px; height: 12px; image: url(:/res/spin_bottom_arrow_normal.png); } QTimeEdit#seekTime::down-arrow:hover { image: url(:/res/spin_bottom_arrow_hover.png); } QTimeEdit#seekTime::down-arrow:pressed { image: url(:/res/spin_bottom_arrow_press.png); } /**********微调器**********/ QSpinBox#spinBox { /*border-radius: 4px;*/ height: 24px; min-width: 40px; border: 1px solid #000000; background: #0f0f0f; font-family:"方正黑体_GBK"; font-size:12px; color:#999999; } QSpinBox#spinBox:hover { height: 24px; min-width: 40px; background-color:#0f0f0f; border:1px solid #0a9ff5; font-family:"方正黑体_GBK"; font-size:12px; color:#999999; } QSpinBox#spinBox:enabled { color: #999999; } QSpinBox#spinBox:enabled:hover, QSpinBox#spinBox:enabled:focus { color: #999999; } QSpinBox#spinBox:!enabled { color: #383838; background: transparent; } QSpinBox#spinBox::up-button { border: none; /*border-left: 1px solid rgb(111, 156, 207);*/ width: 17px; height: 12px; /*border-top-right-radius: 4px;*/ image: url(:/res/spin_top_arrow_normal.png); } QSpinBox#spinBox::up-button:hover { image: url(:/res/spin_top_arrow_hover.png); } QSpinBox#spinBox::up-button:pressed { image: url(:/res/spin_top_arrow_press.png); } QSpinBox#spinBox::up-button:!enabled { background: transparent; } QSpinBox#spinBox::up-button:enabled:hover { background: rgb(255, 255, 255, 30); } QSpinBox#spinBox::down-button { border: none; /*border-left: 1px solid rgb(111, 156, 207);*/ width: 17px; height: 12px; /*border-bottom-right-radius: 4px;*/ image: url(:/res/spin_bottom_arrow_normal.png); } QSpinBox#spinBox::down-button:hover { image: url(:/res/spin_bottom_arrow_hover.png); } QSpinBox#spinBox::down-button:pressed { image: url(:/res/spin_bottom_arrow_press.png); } QSpinBox#spinBox::down-button:!enabled { background: transparent; } QSpinBox#spinBox::down-button:hover { background: #0f0f0f; } /**********输入框**********/ QLineEdit#lineEdit { /*border-radius: 4px;*/ height: 25px; border: 1px solid #000000; background: #0f0f0f; font-family:"方正黑体_GBK"; font-size:12px; color:#999999; } QLineEdit#lineEdit::hover { border: 1px solid #000000; background: #0a0a0a; font-family:"方正黑体_GBK"; font-size:12px; color:#ffffff; } QLineEdit#lineEdit:enabled { background: #0a0a0a; color:#999999; } QLineEdit#lineEdit:enabled:hover, QLineEdit#lineEdit:enabled:focus { background: #0a0a0a; color:#ffffff; } QLineEdit#lineEdit:!enabled { color: #383838; } /*QTextBrowser{ background: red; font-family: "方正黑体_GBK"; font-size: 50px; color: #999999; }*/ QToolButton#folderToolButton{ padding: 0px; background-color:#323232; border: 1px solid #000000; color:#999999; font-family: "方正黑体_GBK"; font-size: 12px; text-align: center; } QToolButton#folderToolButton:hover{ background-color:#323232; border:1px solid #0a9ff5; color:#0a9ff5; font-family: "方正黑体_GBK"; font-size: 12px; text-align: center; } QToolButton#folderToolButton:pressed{ background-color:#262626; border:1px solid #0a9ff5; color:#0a9ff5; font-family: "方正黑体_GBK"; font-size: 12px; text-align: center; } QToolButton#folderToolButton:!enabled { background-color:#323232; border:1px solid #000000; color:#595959; font-family: "方正黑体_GBK"; font-size: 12px; text-align: center; } /**********滚动条-水平**********/ QScrollBar#hScrollBar:horizontal { height: 8px; background: #141414; margin:0px 0px 0px 0px; border:1px solid #141414; } QScrollBar#hScrollBar::handle:horizontal { height: 8px; min-width: 45px; background: #292929; margin-left: 0px; margin-right: 0px; } QScrollBar#hScrollBar::handle:horizontal:hover { background: #3e3e3e; } QScrollBar#hScrollBar::handle:horizontal:pressed { background: #272727; } QScrollBar#hScrollBar::sub-line:horizontal { width: 6px; background: transparent; subcontrol-position: left; } QScrollBar#hScrollBar::add-line:horizontal { width: 6px; background: transparent; subcontrol-position: right; } QScrollBar#hScrollBar::sub-line:horizontal:hover { background: #292929; } QScrollBar#hScrollBar::add-line:horizontal:hover { background: #292929; } QScrollBar#hScrollBar::add-page:horizontal,QScrollBar#hScrollBar::sub-page:horizontal { background: transparent; } /*QTableWidget { background-color:#0f0f0f; border:1px solid #0a9ff5; font-family:"方正黑体_GBK"; font-size:12px; color:#999999; selection-background-color: red; } QTableView::Item { background-color: #0f0f0f; }*/ QTableWidget QHeaderView::section { background-color:lightblue; color: black; padding-left: 4px; border: 1px solid #6c6c6c; } /*QScrollBar:horizontal { height: 20px; background: transparent; margin-top: 3px; margin-bottom: 3px; } QScrollBar::handle:horizontal { height: 20px; min-width: 30px; background: rgb(170, 200, 230); margin-left: 15px; margin-right: 15px; } QScrollBar::handle:horizontal:hover { background: rgb(165, 195, 225); } QScrollBar::sub-line:horizontal { width: 15px; background: transparent; subcontrol-position: left; } QScrollBar::add-line:horizontal { width: 15px; background: transparent; subcontrol-position: right; } QScrollBar::sub-line:horizontal:hover { background: rgb(170, 200, 230); } QScrollBar::add-line:horizontal:hover { background: rgb(170, 200, 230); } QScrollBar::add-page:horizontal,QScrollBar::sub-page:horizontal { background: transparent; }*/ /**********滚动条-垂直**********/ QScrollBar#vScrollBar:vertical { width: 12px; background: #141414; margin:0px 0px 0px 0px; border:1px solid #141414; } QScrollBar#vScrollBar::handle:vertical { width: 12px; min-height: 45px; background: #292929; margin-left: 0px; margin-right: 0px; } QScrollBar#vScrollBar::handle:vertical:hover { background: #3e3e3e; } QScrollBar#vScrollBar::handle:vertical:pressed { background: #272727; } QScrollBar#vScrollBar::sub-line:vertical { height: 6px; background: transparent; subcontrol-position: top; } QScrollBar#vScrollBar::add-line:vertical { height: 6px; background: transparent; subcontrol-position: bottom; } QScrollBar#vScrollBar::sub-line:vertical:hover { background: #292929; } QScrollBar#vScrollBar::add-line:vertical:hover { background: #292929; } QScrollBar#vScrollBar::add-page:vertical, QScrollBar#vScrollBar::sub-page:vertical { background: transparent; } /*QScrollBar:vertical { width: 17px; background: transparent; margin-left: 3px; margin-right: 3px; } QScrollBar::handle:vertical { width: 17px; min-height: 30px; background: rgb(170, 200, 230); margin-top: 15px; margin-bottom: 15px; } QScrollBar::handle:vertical:hover { background: rgb(165, 195, 225); } QScrollBar::sub-line:vertical { height: 12px; background: transparent; image: url(:/res/spin_top_arrow_normal.png); subcontrol-position: top; } QScrollBar::add-line:vertical { height: 12px; background: transparent; image: url(:/res/spin_bottom_arrow_normal.png); subcontrol-position: bottom; } QScrollBar::sub-line:vertical:hover { background: rgb(170, 200, 230); } QScrollBar::add-line:vertical:hover { background: rgb(170, 200, 230); } QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { background: transparent; }*/ /*QTextEdit { border: 1px solid #000000; color: #999999; background: #0f0f0f; font-family: "方正黑体_GBK"; font-size: 12px; } QFileDialog { border: 1px solid #121212; border-radius:1px; background-color:#1f1f1f; }*/ kylin-video/src/res/progress_pointer_hover.png0000664000175000017500000003667013214347337020652 0ustar fengfengPNG  IHDRp n pHYs  9iTXtXML:com.adobe.xmp xmp.did:24776fe3-5e39-7846-8bf7-7165f60dca4a xmp.did:FAFE9C98524111E78EE6AFF41394CF28 xmp.iid:7735c375-c239-7a4b-be7c-9f9c2616719e xmp.iid:2a7af3b8-43b0-6745-a0f2-048f0ea0e907 adobe:docid:photoshop:772c815a-4f1d-11e7-a29c-ee28c792f004 saved xmp.iid:7735c375-c239-7a4b-be7c-9f9c2616719e 2017-07-12T13:45:08+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-07-12T13:44:21+08:00 2017-07-12T13:45:08+08:00 2017-07-12T13:45:08+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 24 24 -*tn cHRMz%u0`:o_FzIDATx! &{?`Nq`,! } (:i@0mT^I.Dˡ @kuݢ0 K ?^$4T\GDd|xu8'Tͱ `D+FpK0S0!JXR${ɽ] 뿡$qŀ/^KGIL_t=~ǂ *t! agd^I fT<3;ţ 6E2ooc%ЕYd½58a%FUD`h6bkZteiaw5>|-KDaeEMF`X4 ?_—jl3Y55" Ye.\89gf*zKS0ޚ@/;q'25%"ְ_ss,D.>p喑`:Lg[]8WF8ۨ`=sS"3"G 3sC+\>d,&o4`0t0UyE?JP4D).: E]|Wǂ>[)8) ( i]~B jMps?TyENKaNM/iZŽJ3AS90*׬^8>\NPV`/л0gG]ipvAR}augi;1 pi7q0# nvm | G !auT;qk&Nd,j&v={gNb@%`ϕsb'4yV䦋|"px/L=0y*=]/!IENDB`kylin-video/src/res/open_screen_hover.png0000664000175000017500000000201013214347337017523 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp 7*xIDATxb?01@@1b\@ F "Y^6t  aA F )O{+*`ħ !B|60h0?QHq4H c*IENDB`kylin-video/src/res/combobox_arrow_disable.png0000664000175000017500000000233413214347337020536 0ustar fengfengPNG  IHDRtEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp r!IDATxbtpp`& eA D!b[0 JG @ʀXKJRR.gC?$lt޽ϧ P| XidKpqq1lll`d@]>| -- d<}EY,@${,)$HuRg)x/p)c, 03TAcDvbfDXfnl/ƪQub&wMfIENDB`kylin-video/src/res/open_file_normal.png0000664000175000017500000000043013214347337017334 0ustar fengfengPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxb`ޠa>SÌGs?bĦ 9*ftPQZč@.Y/7pH @v"zx)@  @<_qx d8C H *!1H0OBլa`JL@Ibbǐ20/{yA{=IENDB`kylin-video/src/res/close_press.png0000664000175000017500000000270513214347337016354 0ustar fengfengPNG  IHDR$$e?YtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp +DIDATxb|]΀POZvĈlNqsAObl,S!,#$yc/sbj,{"+MpALr %0߿腄w]133c=1X` EkS/ȯM!6d$k r$G?ܑ pIDATxbT[ 01RĈl_"8lX#pZv3\\8 hJv@m r,Ȏ0WCnVr @NtOFhLX"[pjLj4T{ih-gK\pT5 Qpm/ mFfG-)X/0ULdZpAkOA 4Z\Z6j>YIENDB`kylin-video/src/res/open_screen.png0000664000175000017500000000022713214347337016330 0ustar fengfengPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<9IDATxb`򀑐xiL- gd &Jq*BL kIENDB`kylin-video/src/res/option_press.png0000664000175000017500000000235313214347337016556 0ustar fengfengPNG  IHDR$$e?YtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp IDATxbT[ 01RĈl_ I*C8Ĉ XQh t9W!$}9Hp>dM$ L,BS_O+l\26"moH #髍=)$ "iH h_` w*2{8 =X។MW7Z6x-jHG8ɕ=&T6.q,Cr1C!ЋQFe2IENDB`kylin-video/src/res/spin_bottom_arrow_press.png0000664000175000017500000003555313214347337021025 0ustar fengfengPNG  IHDR |@~ pHYs  9iTXtXML:com.adobe.xmp xmp.did:25d3b678-10bc-fe4d-ba41-689616e973fe xmp.did:4DB9AFCA5AD511E785F9EC65476E1141 xmp.iid:6c5d26b0-8a1f-d547-aa9e-7750d603fad1 xmp.iid:51e652ec-356d-ef43-a124-5fe63f3cb50c xmp.did:25d3b678-10bc-fe4d-ba41-689616e973fe saved xmp.iid:6c5d26b0-8a1f-d547-aa9e-7750d603fad1 2017-06-27T09:11:18+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-06-27T09:10:58+08:00 2017-06-27T09:11:18+08:00 2017-06-27T09:11:18+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 17 12  cHRMz%u0`:o_F;IDATxbrppPSSspp`b``^bRSSSSScb`````brppwQSSwqpp"#(1 b VAGl\"9}?0 .bRTyN4TBr먙fJNqG_du|,c8S\%3AsO9w~XBɿ􏓟ߋM6U}àލswi}~ 0C )*?,E ``` `ݕ~IENDB`kylin-video/src/res/playlist_close_normal.png0000664000175000017500000000260113214347337020424 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp kIDATxb? F &Ȉ ACC: de@+2`AV @tEg3B9Hj3`b4#.2@ !n. >4 90`FcjZfĦDO@_C6\nN NdAw %yp V /Q5J0  ,$#Mh>'*-AMe k*w,X iq ПE@P@; 9h"9C*J( `e!ŕ!Nrhnĕj>@28*ٞ|, @>P!h݋ɫvH SށIENDB`kylin-video/src/res/volume_mid_normal.png0000664000175000017500000000055613214347337017545 0ustar fengfengPNG  IHDRw=tEXtSoftwareAdobe ImageReadyqe<IDATxU @Db@ t Vv HBtVv` v l3~89fv7EQs5|+x@jך'y6:i Fıa(P,wK10Qj}M% s'6@=F"vc?dW5H$ 81۳2Xg\jJLXrtE/Hɷi*nLP8w`eA<-wqi\Z,V?Ys+LGIENDB`kylin-video/src/res/about_hover_press.png0000664000175000017500000000225113214347337017560 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp tIDATxb?01@bDa $08J t`" eP`- b>@1 B w@܏ Y P&U;G0q:| (8 5#|ЬDvqxq?̄@$xc`3(H0&,s@Sx=uYh8*%ͭb v*hH6)tpDrR@6WEOp@9', A1' L€oIENDB`kylin-video/src/res/close_normal.png0000664000175000017500000000237113214347337016507 0ustar fengfengPNG  IHDR$$tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp ^c IDATxb?:`boDk L ZOsQdS ںz 1D@G†h|0(f۠26Z\T-mBb_K05 r e;t@!*xDD4GƄFeDιѼ6 0ڨF4 *gוX[-UtP8JVB\ 4Pդ u 1%556h3ڞ7LrC9j`!bF~Au;ΎVm IENDB`kylin-video/src/res/combobox_arrow_hover.png0000664000175000017500000000236213214347337020257 0ustar fengfengPNG  IHDRtEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp !IDATxbtpp`& eA D!b[0 J^r 122® PlGX\UjBp6TNjW3#ӝ @Ć8a* V3lo҆h /Aٿ|y ʡxSʦ'>@̖J?cF0q k0|1 \Q29AҿklxP=aZ-zl?6Y2˙d}n,@Tjd (IENDB`kylin-video/src/res/radiobutton_disable.png0000664000175000017500000000256413214347337020053 0ustar fengfengPNG  IHDRhOGtEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp BwIDATxbd L ir<.  @"M@N ӭȨ2&@| b,PW d,LPH `z@U1% 20 ~ A2FX< "@Հ ^(=$;i8A>{lP7$ˡXC I#4́7@vnb1 fDR$)t ė%y+Pq  0oU vH\|2 @J P`;rj4j9$bؚyA ==H@< C$ dXCdtJR@ )YPE/47rPJngIENDB`kylin-video/src/res/progress_pointer_normal.png0000664000175000017500000003600013214347337021002 0ustar fengfengPNG  IHDRp n pHYs  9iTXtXML:com.adobe.xmp xmp.did:24776fe3-5e39-7846-8bf7-7165f60dca4a xmp.did:F2088D53524111E79321CAE5FEC76BAB xmp.iid:ec89375f-25a4-8948-bd68-b9f5249e6143 xmp.iid:2a7af3b8-43b0-6745-a0f2-048f0ea0e907 adobe:docid:photoshop:772c815a-4f1d-11e7-a29c-ee28c792f004 saved xmp.iid:ec89375f-25a4-8948-bd68-b9f5249e6143 2017-07-12T13:44:56+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-07-12T13:44:21+08:00 2017-07-12T13:44:56+08:00 2017-07-12T13:44:56+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 24 24 k cHRMz%u0`:o_FIDATxb? 31@0bBW&U BV&&e``x` 3B#6300d-Gr@63000*b\P ^4̀ - l05Lz P`Ħt 8H d100\f`` AH : DYK-f x9R5Ŧ?+6% ]b"/"9-````x-}e.=*GQF6 רIENDB`kylin-video/src/res/play_center_normal.png0000664000175000017500000001614713214347337017715 0ustar fengfengPNG  IHDR6wNtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp KyIDATxb` 0 >ľ<",5A7p|4 L(DECQ3QP؆EX6&@FF3a|bxjMTO8FD N`aaq+11Q(á9Jȱ:~7|\'դׯk0Ӹ =͂Ƨk߿՟?ZWP 4D-|O^^ FAA8kggǵ|ry*iDLB49C"&&FlAf(uP Pe%K@gtvІ,x:9D ^$ˣC%sM4كhhhSMe䡉l8JǏPYj&DАc֭J4p((QRQh[,˗/hPC)v,hZS\\ &` lж)1ސ!סձ&HCc1 I;Bs8TT7Lg b.yM:㸊SL$hHXfC ^tPAA$ xݒ htHVz>́,3<>x|_|< plnPgQd/XGio ]h8 ?4 CitOY)"mR9͏~! ,9Sl %pm >i㮅ͮLHѤF3Xwa?Ȓ- WT]aK݀eSzdp8|b^ l%3n4@|4Ǐ{L[c{y)蔄rsfmF-tO1Y& /m6%z71XHΑ U|^RruT'k8**TzV(!AlWRd?Ma^@ X'`h,HTuЗ84{l;Ag(if+ճ&=XjuA՞ȱXLرP&ijX, ~Ϛ^ x⡧űN&`0t:?x?x&􆂖Kdh|?̚.jaR/ R3,4V*ju_"I٢gT-< qD޺B|TP,&'8bx>2e:bít:= 0BxSVP0tűH4 N08Sh{ıp8BZ#ODKn~ZA~ Z7`Axl0wCО2,= WquTs'slBW^"^[-* HhxT02(!Fj0~p"$~bL0$GM #TbPb2ʣPah=-} 1,̩@lX7a\'~xI,c& LFw@,vK mb1^=ŐX5˔M^['ش`cۤKJ qG"~{ 㵅_-VCk WÄTPd^ F(O;&|1,\4D9na/w 9ΪxH" R&+*p{m! pXI| W !qmzuPDMI 6 h;::GY[[BRrR"/퉊+m6ۡX,rLmauf[V[[e1($"aޫ0sssg9 BΖKKKv!cc{ *XXXWrXuKzbP0Eq߰ ? ڂjU'@!)X,CBj:eoo "}!-fbĐ{$|i^*vee$%%%UoRlee%T66 7*P(D kt=E L&YEElyy!n}? 0W.//X3*Օ666uai*b34v䎥yE:;;W v=/+b"W[]]=::H'9UHtKjf dgg;Wm6s#E}tj :1Ď 3 k$ '}sNa:i I*!SS1V;`wrD {2*c eLkc,,KdqQ2EXOM?iVc2H{M+Hn†=1H$dEed {;EX}\R34Q?2ɬiKZ?RV~b4XF*5<9RBcV?#Ч9Me(+砼![X "6XBk v?*\Ltbʰv `r|iz߿66mzzjWV(}㴩u&9ҍ7nlyӟzd2đ#Gpby2aIRzUݡC|w2p`Ҹbm+]}}} SL6ms }̓5T*xvAtQk` l]\.;;:GGGaYYYIIItwwY U+.ǘ3<<ܾ}{7w}sΝåKcqa),airK r܆њAG,\ǽ"+o#̅yy<.. o}"( 䭬(|Fa,&Yttt + xO,(]ussepz@X.jbTWW5ׯLvJQ0U&|6aQ ˧54dzC7iaqߧQXX8@߂YYY]{|>'4~ ,^Μ9l6.//OBZ[G؍f/4Ngggp8uu%%%}/^TH$L׉Ґ;w[b񨷷7l؏lьe˖ٓ>n`ppjլnTCaisy6}~ʕ**QX Zx=zDخ>̎r/3ر-//鄓'Osrrz &GIZš 68 GTRΝ{AZ0ٙ]\+V8\|9tizzz7LPX9w݁VDfGkީ(ƪjԼnlkkeҺҥK|"hxɒ%}ћD_z:{mTd -{ٙ5ed@au>}zݻY,˗/7o~rWRV`BÞ$|AX(pT H1;F(S}"SȣV&);]nnnWM":%ot_N 99مKJr,??_V0;F O3}]jsT {333я#zK/d//(( Q#)//xc_3P#h){id )j~IENDB`kylin-video/src/res/help.png0000664000175000017500000000115213214347337014756 0ustar fengfengPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe< IDATxWq0 dA:a ` &H6 &h[R&1V\z|AI,e0cl6- SM"Rhh&$_BYi ":Edge1 dDO[v7j'] ވm$eYi} gTǶ}ᐏ8*r88"{X-/c|7j#/pT[?+?һ5y#o;⃁ʙ$J+Xޙ[T23xHꈩG5/~7 ^d6"1NR-Pb!Ȩ𣸲cPѾ >@`]x-']1POi'LE~kX5δCR!5 MKneÄ}ZgJ_౥- F-b PFmnvD(8JW4^LM-w4]rj&%0O.w ٩IENDB`kylin-video/src/res/cancel_fullscreen_hover_press.png0000664000175000017500000000254013214347337022116 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp /JrIDATxb? 01 @1 @ʸaGя{7Y @b$qZL 8N 1~~v½@5ktP6xݟ0Tc$8 SpNņ!cθ~B* z70O'Myx@'*Q-h`#4@L@M(^ac•ذ # ? YNĖOXG(#'@&[!0 g,.RDW`:z 9aYyEf b)> x@L'hD򠓂鄚aB κr)oIIENDB`kylin-video/src/res/min.png0000664000175000017500000000244013214347337014612 0ustar fengfengPNG  IHDRl$jZtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp < 2IDATxb?:>̀"x; 5L d! =`ݜH?MĈ-J5DkhZ6j0 b2>1aЅM`! -0bG0xHvw1$#!G'|c u` A _!|A! Ehe+sގ-:((@K2 h@@z܅ܦtJj8)C0 -c/o!m=gQ!ބ$! `&rMIENDB`kylin-video/src/res/list_cycle_normal.png0000664000175000017500000000301413214347337017527 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp IDATxb? s`bDQ$#$%V` X#5Od @t0BURP1s@8 dd"dj!P*hĥ@|Y1݇?ڍI ?>`e@+X(A3 CDP* @B>/8 O`ACDJɯp7D.L"5{ AifPJ zuq.@2@h ҀqK|NB`88RNb/ b~v VfpPzę|DHZd8P_r\ -A2Lĝ Y 3XA-`P3(Sl` F:dLH@c9P j?@ ^ĠBPRz R@  GI# 6s1n\,͋ HnnEIENDB`kylin-video/src/res/info.png0000664000175000017500000000040713214347337014763 0ustar fengfengPNG  IHDR szztEXtSoftwareAdobe ImageReadyqe<IDATxb``CC ͽĎ@s>RȂK9`?gE,R0hRPG$PG, ::ȞOt"R\)1chBa`Q0D8Fh"uX. >8IENDB`kylin-video/src/res/spin_bottom_arrow_hover.png0000664000175000017500000003555313214347337021014 0ustar fengfengPNG  IHDR |@~ pHYs  9iTXtXML:com.adobe.xmp xmp.did:25d3b678-10bc-fe4d-ba41-689616e973fe xmp.did:5F8BEA435AD511E7AD2DFE8D367DFF0E xmp.iid:09066481-876a-7b4e-8c9d-997610446247 xmp.iid:51e652ec-356d-ef43-a124-5fe63f3cb50c xmp.did:25d3b678-10bc-fe4d-ba41-689616e973fe saved xmp.iid:09066481-876a-7b4e-8c9d-997610446247 2017-06-27T09:11:08+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-06-27T09:10:58+08:00 2017-06-27T09:11:08+08:00 2017-06-27T09:11:08+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 17 12  cHRMz%u0`:o_F;IDATxbrpp022rpp`b``xPb222222bb`````brppK122Kqpp"/ ' b VAk"9c3~=6.b2TN:4TBe~У'B_fsr,c8S\%~6Ds7ignXR ދ[/;クv5 pe.w6 u?IDATxbT[ 01(f _};<&&#p*: * `~=>6Ie43hȕCs'BL"`=ȮE1 L# o2X%1` 6̤6! @C;6i^@ Zǧ Xv07rTʨ#ĝL = C" mFfG- G,$2ZVȥ e_ܿo4, !(К}Z4`xx{jx90"#GQFeHvT3mIENDB`kylin-video/src/res/plus.png0000664000175000017500000003513513214347337015021 0ustar fengfengPNG  IHDR 2Ͻ pHYs  9iTXtXML:com.adobe.xmp xmp.did:6DA91737B5A811DF8B4091CFECE95E79 xmp.iid:34579b01-2447-0447-8016-b72990af1cc5 xmp.did:9c6542e1-9f1d-bf45-95d6-dd43ee6c3218 xmp.did:9c6542e1-9f1d-bf45-95d6-dd43ee6c3218 xmp.did:6DA91737B5A811DF8B4091CFECE95E79 saved xmp.iid:34579b01-2447-0447-8016-b72990af1cc5 2010-09-03T15:26:18+08:00 Adobe Photoshop CC (Windows) / Adobe Photoshop CC (Windows) 2010-09-01T17:08:03+08:00 2010-09-03T15:26:18+08:00 2010-09-03T15:26:18+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 10 10 cHRMz%u0`:o_F;IDATxϡ 0BQcsKMOԔCAzpny+ 7d`7#B@[ IENDB`kylin-video/src/res/close.png0000664000175000017500000000412613214347337015137 0ustar fengfengPNG  IHDRl$jZtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp ?4/hIDATxb?:=os001 5&Vmyr#z a4PPl J9d D4 FlP$,J9L|-1_bK @C/`XH-c̎80Hihhϲ/_202ݿo3p3|e 㳌=,pbBe XdGp B3@D#1&&/~=*8l5 =b!hE\‹ _pM +)1UnCs:\xA< #9EgVq)$QbYR߾0s ȳz Ȟ 9S2ǰ- hPU O^SIqcT11615Zg_IQ'cFh;8.B/`SputRHKJd{AR!A "" wf``z!.l@Rq _} 01i+$Gi'3pPe5N Kq#9}1X7IsdIrw@}sdINj%դB裂wcwSл1X8. M|R:1بc_lv[u# փZυ=q*09Uzr3'M(A0,*,Q=úra`HGhߊ*zx4Q`O =I* V&A1w=) r0@h 4nQwra ɿ7oC_QXXāŠK[[Dh!_#Q%As,"Qb%0;vvIf&&SQĬD`("Ƞ l4|gZp(^@@1n`5ej]G.0G5pq1b\\ ?UT:>hB^F|^U? `9vJ|Ka] Y #B.*їҳHnN$CS(G`4F#lF(@+F#lLIENDB`kylin-video/src/res/video_normal.png0000664000175000017500000000053313214347337016506 0ustar fengfengPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxڔS 0d  `C a:lȱ^r!{wk} uOViF E 00W@; E} fu9"^Rb&9Y"S@r k"щt\(Vd@҉)8-kzdpɃa㛴 mŖƱ3.5!A|.beT1M'B$˟[8e"ITE{_c4bܩ IENDB`kylin-video/src/res/kylin-video.png0000664000175000017500000001727213214347337016272 0ustar fengfengPNG  IHDR@@R tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp IDATx7"-3guԊ=sT ~^  Fkwa %Y _'ыdT|vJfP|9}7{IP ggڷ0Ƽ })f@AƋ3lJ7# ?߼~V(qܸv.ma 8Yپ}},g;[Fff?ԣG>|t01 [X/ VߤWϯ5[/+Pk Egi ~b  QP!ZT,TF$x9:3 Lrcc%B}1x.QYݟk>&!1HiA M_ n?嫀Ah0AE(n,odR؁JC0(BҲ"QF_`pl|_@;2BSD~ۃ~Hl H$M 88X;I}Kĩզf@bBhJH-+CeS b\"' !7=yt K㷝nptäMFԷ&1 " 3dJ`AYڸIp;7Mբ?"*HPJ ! ʅ$ m{{?潙;3vc7̝9~} {W*0VTl (lk7 ԪT^x5P%eMZ҂lu(0e4O?*6 |Xi2 SYBLM2:d$EM(5 @!WqƇ yYJddi"OiBk$EDg+>hS"ݭ3/C _kHUb^ Mr޼uŤ/X#Rb_xg hx7RH vS'O}N S0d`+X93)՚/6 yEV4D?/'Sl5eBkL 4>$m{{՛הjs=s(E8.P`h,w=5=0T09,.d1op~Xp6ᄆPӗ_:I[ 0gD;b3qHee+}\97gG `ӆ~/lw4n [q,4k8' %ljb2O< ~=۷)TnPR&\z)srU[f7#g>|/7qF rL_C|d4mm2&ٴ>S$'+ۆhޜsv|80 qw׬\+U{FlYm` RuNP i>䦫+]'wKT24;[9b>=?T(k+4ۯ_p"=:gYcsM=AS?k# CuX ꓻZuĔHLO8 TɆ&Wֹ:oё*Ф.`v>44dk3A8nNV F$T?ݔmܹ1kwhebCcC jDA@#!ZDTB@HD" X"B )4<bx I ?**&U1Z%@yyιwf+?Ng3umȒ+|^`4n &$,l\W \/PSX?5kJa#%ֈa4p(q)uMnsT>;兴-@reY6,GZx<'+{ )kV()&LS+Z˺<"\~6]YC9┤%rfPWFe%8d{\ORJ>ʧ.+Qa05j&mH881;+tO>iN,ĆޥB)߶8$@Q68|z4Jsy[}gV ?5~2EƊjw?]Dn@*~C.@^mGGeAIfՃ/iPXini;Z *UF"cߘWpanfXyx@FީDCNmC~h#tZήS/yݪ=HjʁWETYg)r('B"2W3B,LBlAC1N3 .άQڐ"֨ QL .^ډJhX@^މ V-BI/=tv0 SIݰUİPN=\H/UT55 5Y1{%P7 &Ab-X;|'T x#?Sq$hAk-{qމ/v "nwg|jSFʆ!ӽ`pı5oZ.CL.G>ٖ̥Dbkpx}GkG1t[[7W"e*sw'k! WPoB 4I]sF,ۼkmMlCED_QW]u@%d-mܺқד5_˞~oZN 6݃{D@n_{gip)g}>ԝ0  /8g;3hΜ8ñw$I -BRUutmQ=ơ÷R O"GdM`M[bVo #KڳkZn>dOlhVUfބ_ȉu̒5U PPWɤ ,ɟ-. jegک^("(s"$sN=Mҗ?W~ʀo)N }+ 򈜷 &5F(ZMvNK_* ?^ x Q̌vU6ya[ww/p "k`f7 w>o!g=vN.ZEqѤ4PN,i },4QKRa`KP2ɉZ/ԜF-4eGmu.䧡J-Zm—YI8Vvnv7uk}{.nVFy`2mN Y<ldB6#V4Z3g`e.nkI@.1}1vxgFpoQ7ep㛿Pjl6+3CuqaN*Y@I+>1|amTEpDGp:_ف$ D 1 :t::~~4%1Rs(D2#9?L; , xӌ`_2HB.:ǘc Rcb*Ph7[Y}emWә4[$P45X&P^0x4._<мkBW;h0O[ B$b"(<?lj̀j8DDGX̲=`*WyG"9f~.[mDw0f>(1X i^4m.U@ գ>c"P靲4V{CI*++5cƗVR\|YG aY ݩ`8&(xJ@#3W{li2A5æ=J nĠw&glYa`phϞoe*^k!@O]I.kom,THQT8Qe}a 7ZEFӧMm~Ф#GNcQ*>4K0#2 e~k#C!H$g|>?<ѹm8' ~#SN:aNۚt̾Ǐ:Ag2L!UbuuT?<:mza5oy](D'߷x(3tN8$6'ya6 vB9Hѣ'OӢ>)PD녘e&,Z:{M xgHl9>:k:=d׻QY@]Sv*`(PYטtD Mk2$sQQJyY; Յc{^ٮ/zq)5/ՠW>BP; _E/_gݨɤPZ$\ y|_UU&evJO ĥM͓&Зi::" yne XOpkb05dDBv!CM:f1 ^6\^hlx͸#N1&xg) pR!_[ԕq٤@2xjsm:%w:Lg@_4qeiwƞ s듥ą ]lE._{aM@|1b . 7vJz\ہ{A T eIDATxbtpp`& ~ Fl @@ۯs w#\H#H+, "@ eЀ"c$ PF,Xu@=oC&swM7k@FAM|G Xp@ d{%nG_R"k ߄Nd{v$fsvr_\/,7 dEnSDdhIENDB`kylin-video/src/res/play_center_hover_press.png0000664000175000017500000001557713214347337020772 0ustar fengfengPNG  IHDR6wNtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp .IDATxb WX3x.94J?b fHqif!xR(4"1QPh(6eb £psىv54Rdpb&WHg?A5ȉ1p` 5g}97,|l0iOt|e((<TPj|P26Ð@1YK7q=bBi* Xswbd#7㬕^#S)ݢT/Q yqT3V~0q0Rץ   ah1b Psfgr?QPbɆS12QuH \]&j\R|Cu*RY ҿPð2DlmJJHber2)! &ZS"%1HcH|CC7#6Aq;p σF?(ڝv`#6d{qsLBghp&1 nǮw`VAı庬 B+`"RݱVb 9`v tB 12, 5{aT *3|!O$%C)vٖLS[^, At Vl 1 ujFdP_& nGd0lZo?CMw@Mf)\πXV-fRPQӱ4@Fk>!UPtf?1O@l'I 'P8+asl, ]4Hapw0[`;TV93v X 9rV PԻM!3e^j{dwf"̱2ԁf#T_L ! -wY`R1Ӽ=LQcap`(Ntð_C[P(/agag#?pPczȓA |:Hn]q+X @Rb1l1}-yٽ? @cJ[&NG_e2a2/Y!ز3|ev@m`:TZ!n =s T;C*vݓ> ˭A[09t'TS Ͽgc4S,6: QaxutX|Ma;f`L #a? NhR Yͳk7R ;` Ls]Ͱa,l(ƨ/2E5D!G8g聟p,z& g:FqǏAHvHG)3n>h L->`Ae&l|`Р Xv&h>h샮UP ngF =a.`jEl2LZw<;d[&PAX @ FX!V,aD2c4áH^- PF2ƬGS,2%XHb@@a#9łָҤ7Rl9a bA7-Y [ `Lc8og:JK!1"AKU )&j4F .(L1}h%DLL#ئ*-F-R$nty{*Y:޽w?y )sE(d ntFmͦq󐃊Kβ焑 0.ײ|k.رNe=kG͞/P,B%=_QV;"*{HRqI^TK WtS&Y1;Opln .c$+ 2) t&"X~7(I4u`a?{ ~ Aގ :NH덳./g0ORMQ(-6(lsx^+-X2ayMD` u02.„tRgR]R +ٹЫ 9S2٥s5qP@S!%>4U{TMj0?YF\RmN]GTbOpu^kנF,iݟl#[?׿oʥ EV0}QTʣOn`4hɶsJR<7DjZCxm(Y&`kD_|Y{_,F =Oamީc*1M V}H~bbEhL챲4+|Ěu / EtBFZ/*bakHD A0O"|6nMȈ6߃.<B@vt` 4YM'~a 쳕ExlO1H)Wm`-!dF͢5&-"/}G-`i]dg:r [[ @͞JH)RMOũCluE݁4e:S5bndmc/5q/(Mj d.2=+r"&|K?̗ojo%E>8xË_zAS(VVBU)b鋳=GS#@{gUٶo( E* Rh%(hRA$99<(j0"@HQJ  (G9 rYvwnJ-{UCiwoƈS>h=]Y'if$B7ApM.Ru<9)F-z]UUkі- f,5mW4>D?6GRItIl`إ8 wN@? WaF Eqɨґ&}㒾*K`вI:Րz dRMҷ,`e]]C1GW ,{и;SJgϽ$ fE헿4F0;r-*dX]=tV!F&_lqZ6]#Y Qv[ZV$hyݣt'ښFd -t$ɵ-km/se"m\hl}rDl)5P肥稌9`87WU?Sͮ0`kTM̗ZM-ee8׃A2Mhi\3A""X sL-L%DF#~4 -f[ l<*X9Z Mu,d! (WcwT,_X#ښKɮQjwsMyh tߧC>,TE >O<5dim3`EnzmSH {ϕüޚxV8 iR{ v,CVͳ$޾˝p#F\1,#,Ǿm-fBeKp^ l, N²^x@mHzYVEO uiэbxi:mۡBb~@J)DQj3l9ܛióp[r,l7Al@k5xRu)ACS`n~I t'+]A _' [IO6X#/גQY6UAi \7|s ]5R#sfl#Oozn)Ӯ ª,l"_ie}k<sx90}˜#+`7)gGeI*˃B]خ( ^ :M"WkW`peJp~ ^bwj{+{aVκXUl&8¼vH"P &Evu($1]RwmwbB`۲4Nykba2Con@[O[,|2V{b2.MQ8+2mΐHuzKttE"MczAI&ҁzcF(Mv!eblOxyڄP!6Pak\plyOHѽ%aMF1F߷ft*\PMQ`M@:6:7DJku)l4v z'ksM'h꽭|lQWk|';B)%^0X,XCE AkDETj8 c1)r րV԰6qbk}7>M ^AH8@>ԭnLd?X:ӷY,@M h _p[;F\Ntk;ۡiM|r'aF',ѡ|ӵGT)oj Bl q҆~Z#mC? Oq{U_X!M}5nXX]Y! yk7<F|d AG[i.XW,WN!@E` oN.O][5^i_, q0)czaibͩ6h|CLI=.;U;q(+>G4tV ɡmGXLbUcZfu/e\#:m?Mď$Y(/#m0]\'!b>:0W5T- b]wkEeg:De2]8z"?d)lbϔѕhw\,uw Hq3ZIm7`"*˄ehAXL88M~ )0Fg]`P ;Z`mN >F/[L%Ga$b,/4`P?z|,X&6靦}79, zZѾ1LH,wQ,Xks- I ӜXchte6hV9{?͑i`h A2`N[j13Xᇮ9Цt;vDVE2R3#𺜚IENDB`kylin-video/src/res/background.png0000664000175000017500000042611413214347337016156 0ustar fengfengPNG  IHDR-tEXtSoftwareAdobe ImageReadyqe<niTXtXML:com.adobe.xmp o,6(tIDATx[}fWYޙN?RGۖBE1G,MX $ĐB?$E0i@)jjL (&54RZRV~t;y=syg6х{=$"Xm5VC[]Sb,o3G@zs _awj}ʀHĝa 7=N;pGm3k\.M#Ӱp[`IK=<[v7jlq3=6oE9t;nME*F؇qers-k]GoE͠R$8Yë^+$Hڥ^JN.r Dӂ^ @g6x)2`ƌ͛h;c$R(xu,a|Fio`bhqd7~q֩h84DY摁酕NL1Я>tEc.oZؖU#caFĨU)#Gue. UJz@Y1M`"e@1QallcY/UTP)bf" Qs`29f*1zƧ QdJl X3[} vbn50~tQbqkDC쌀xy>_G<=#uect9|_GPsto4GYڐW! }gLO @#Jz]f@#PV!!eC?m*" 2ctOXgX/ BE iG;i?zmb>Bhcq8x@|NcMxen>|I#2$SE2u6^n۟`G'A f퇹y^Ru։G?{qΏXoL*{ | oZ<oUw3N>?|Ӈ'Yx=zJ[PH.>|L "`)GE[c鉿<¡) f66 Oiӏ|c|Z ?q[\=ϞfĎ{G?tk=~$ s_ࣧe0Л `> l.8Et]J`E21g4 i3#7b0O7  +6A/{,hxn.}#'W=]м_r_rڳ`i: 4DeJ>v _4ju-xf^kkk0x8qk+: [׬2/9c_oTW)F J#z,~L^#`trtA>ɚHj{1($C_dp: TmFK#ac*a6pΜwڅ`>e7Qۼaͭt͓ygoɟ L}ϗ=e#xTBt̏uEcDE  gaNrMl[`%Nհy,eoV.y;cX8x'Ӳ1ڀ vfCbd~3a(?V7ߊEWA|R첍 B Fk)ۨmM'j-;7@֬lc6ҙ^|"웁YWay,:47+,/ů@QTm>etJdI/[!!L\.!mNqԒ@(>=o:ȯ>䬥gyY;,3Mve)1e"uf9 [`XCCgQmqőJqS4)+we \1d,Rck>j#=wr]OAΔ3ThEu# ںZ ʊn4B)ERAe*qccs WMf+ԾʆIC>YQv#v,Tϔ~JR~ ~fX JzN Xq!6S6~xL2 N6dRZ :CiLDͮpv~*^9RϞ0tSQ/do İ`+Zk\!2_$Ӊ 4"EyU5Y *qORcro;,Q-rJ2T099Q7 DԥuHC/ DxR4N7<-I uTUUuq9O)Roȱ)E)HMY_NVz4[F&qcߌN, ڠԶs:68©o/x=Цt ƼdOo(Z>WSzwlEGj}#-m3qvDz&` "K+]^ )R`28Z]bj|oTKpPԲwdmD:gK=FU=ԙ2&sV2۷>Kr)@bd,::| @۹UUq|=3U,!`ZD j?lQ Ш  D 1"L&h!A'I (Kス9gk>g-m&wΙ9k ^`SAeWcw YwZkh9*j\l}5$*'zҖ xC5F>Q3u*~}O"eQ`wˇU.p~РjEY΀bцKVi>O UYR }4ޣ*$ץ _ $nE?L}C34 /Ht$ԧ 3v&w/gh"TӀ0Ieƌk&FS R  ?]}"0t@H̞edcq ʕ/c:+S[P=A1ޙQIftf\H@$b%6Qr#v%)# $*lL?wsjWT׿Qܯ@)mJx*Ȁ`\s쁜av̍!X vZ .8*@~eUdUV.[k@e&9 7%2S`N̓f5|* ڪ4jK1 2j/j_TATXga=A܀e$5(} "@#܍ L.<Fbc߈.B(DչS0ESq֐X^_o zDBJp!8j3PD4 f G4=T6m&f]+9Lz,2) &izԥ?e_hݷ`g\}PaWyk.$_͈0ix!]j\clJs綛lfbp-I~VѕY!E`1ڍ;nF?1Qej"#DxY$ uM&UnfI2Hu  mcAV޶)A hk˛#Nkz{I?Ж(ĺ#Ʋc v8czcY|Zg/"GиyiJض`ف ly)b`A:+r~/i+3t 3qS VN<=4 ?)u*H(x8W{]yFF8.$LP,NXuz*zT0/HtTVXoKML|Ci݊\qafAE^~|96 %+R<"{@h`&zAo e>ȎWqxF'd {Oq tlSz[ ʚu UՑ(]׾27}ܼw `" ;ҿ-`qqOXSp<(1Nˎ%mk9.b:⌮?-|W+<B'3F|:QOqQPu<}r=,]>a~t~.jF &&BQtaaf59m=9pЇ1Gflްq%87nΣcc#ݳe?Df115:hOg g"}ZQxae-b ):jA5 {ұz[7nRT=f ȓr;l9gO[߸TRɳT]o )7FJ|~|CR7< ˼83/6!݅~Âͦn1K0\su6`VWOp }U_<-6bw=Ox|gb8zch{7`+{>m֮5 uM;[lYsdAސ EC6GpJD-,=Pl5,n~ Ѥ!2əqu>|x}MݻtS>xuӇMk~;?h'S.8"KϜw~4l/NOܽϪD}$dM=%Q<@Ã3n ]kR$l وK<`(peh9?@d;&؀h_}"&B{$ӭ)xX gYh"‘"'O@9:H D4<88,v*"@kt(X" s)sHF1m^B1=t؞\N.5aFϒOX07~hlSƭ(REekbnE['=tI$ +SRrѶ>1C#.BRuqv3n{vd6^bd { CC%y0;xHCnбb^Cg7EN:P ΃%$йHf3hKſ>-Q`.lTsFV@ew 7'~ߠQR[DSe7ʝ3`6%H7 ;,B 6Tə憬 vD~.˯mX\WoKp驲>w^5’/5Ӗ81.DJI& '!Dm+ }u" JARAK(AJK6eޚOezH,%)Å GLjvJK=[*^l@'甽!M]˻pv/5{QQe H9!㮅{x<U.5QسR {'wʬVIS AV;+0Ua2E)o{)ThQYd~TGx`_Hk\"7h`5~%m$w.TY)թȯ%>W@MVN Pޯc],@~D15SܥHJHp^= y9>cnD>x߇H ({ÈC[`rA '/P0УJ+-MXf@)acHe lf1%`rHhn ҰflsXN Y0{V*ĥT yGL~Ka<5tI2[&@mH du#@ZUtPKsϖ]m4$EL("1k}NHصHdeNZ/5Ŗ֋yFC 3$ eNDžK'JC3ՐD-&'} 1SE`kxPw!1"8`X3/\b$'/sWdWYܛlPH~IUTRu:JF@ҙ0BKmOZE !DHlݽ~;߹nv7{y=P6A~d1">GCÿb1%eWZ#bo ?.k6s:m Z~$>C]`6Ґ@,>J_)KX ;XA;R%R@lK#-MbGC%J̀ 5 m-fC)߭7y}š+‘\pYJ*L*4e4DiY]pHqG@X i%3xbkAj3vmjPLlfGϴq:avqnzT 6@j:_i}$]Á6j%ZĆ\4k.Sg4xKaAJb(TXQha΄a6DqlpHEebg 5mrŠ;" YiK(RZ)N4,&#V/ҙ^KEX¶N4cn]7V@ S"e)pfiا4@N'ԼEWrŒu [Y0Pwظl eVGdTϷZ7Yb5ـJ*ňn9`G34 F͌G[Ԑ-'L=ʻiÐB;P&'3 Xe@ydXW^$; ^vIGJ"!('9,1Aģc&L? *JhƌvD>J'Gs@Hde)6ߤՖ$UR&;*sٚ\_skWwY9] !9VSxLYP@OR=~yHO\Ȁ= qPh-qmlK4mm#n@\%4Fx!A0-od#KWڕ}ʋt2ˈIN8AyQuJjdl'8Ace ~i9Ф(fN;ɐ@H$і%$),[ vu Z+X @F91{hǭMYtLs7,*Ьr֐aʽIWh1n9 -_a2KaDDE2Z8Y"X؏bRUZ#+,eT,bq s;ݼoWs 9ZW{ e$mS.C@n(Ɇqv0,QrEHC(c]r)B*M)>Bҥ.9OLTL~.蘅pX-h[?$؈dVZ&9U7??8Hh(li +L%Qq~Cc?;Q"D~=JcQFʢKAkA|({W'qT: k%B-bsהb$,*f )^\ RN|_gn){%v!_I[*`DɨcyALGY,=aʡ cL3rl8#) ?Z`xy])IbM\&1TYf5(ծWAbיbIf'/gZ1"F:4Px_o3S~틫'&vG`,Lw͐e(3OSد7t$3Ǜ<6=ry]qqewNFkbaW. ;[`i{ 3XXT'ML{.a :05X(t!C7Ԯ}^iw8 #CtH5DI-+9^tGf2"j!ZJVŕLH|uZX;y8O s&0{36z=_Ex~.8],[#Ny\10p_oDLǯ=ms`u?YV/|UZ;μر7{V0c1} ܛVOhxgz䙷nČ}fYgkE9'zڼ_0z~s_Og6jm9z}KoHB s#mhA64^,EF  z;jKݛ`cUЩLL:N̅~}wQYˮ7q$L;V3S@cGm MHI_ğ-W(jl5pnzϾ<=4sMo;s~r+޳ez mgsCi4rP8{Ftjb)JPi֫]l[cA.mtQWGoһm9#w|kN'OvLu Į -q7G1k;K/]u9sy!l繌;br'7<{I-W7?,??wpSEjxܷ9%z)|'-q|&=z_Zf~K*/rV+DeX41!p:)խܽ''@x]{ǭnk_o;C^L;g/tIKrr \==㝗׶+-ci1q}M73o|θߴ~}7\\M.ǛYwu~OƤ5,٬nm[mcn[`nv5r> a3%.D 4Fa!6E{?zy^||rؚDǞ5 *W= /Uwx,_{!Gdz}X86(l[ ºSF[GL$$DesZNni[!jfFV]ih+&IAK{̦-!A&A5YKϦT KIS0't �0obƋOw[ _֝N *L-yGs[o-c%?33VƋa ՅIPo@9ELvIĨO ~ HJT+fi( GrC 5'7"]58P 5 ɃVQƃyʆsFx۝v*KluxNeyzpomp׉Z;^쓻ɸcY[ݱ1FB$dI yO8{)PX/d%!(}hMѡ4A艣sa㪵Ǹb)tU:xGjM~A`@ǹ Py1^ZXCAJ>zINHe._XxkV9 PrXG8$b ˒Qz=ҤxZ[ŤE= %Aؖ<6?S"&@֜TEƌrOǂ!YAs,:1ېS_u@D3dF?(tvTҐH*&HEgTReSJB~x+I}'.DZXlF,`cW=9 Q"Hi /:z[GQtW`Z#7%Wz.FYΦsk/ cg gjZhg+2BlUI)LYȸ8'H5{7NJ[Y<r^Lz ߬1e@^;_9M\$:Tm<Kj_aBMws%ebオjz+m3Ն"Q?ʦzΐނRs@f aS`h_VXvJ`ae\J"T1֑Þ$ښ[4>e僺Ri1h$ $AMiœcĜ" ].b<~ER`,%fk@!E٩h ֱDw4wP™~52i zȮ+x)4ORNY ,R5jğGA (lC&*"܋H+ QKdR˟Qd8rDj9a!+UUJTS`N"E4 oڽA~jTo*'ׅv+\THUD Iմxy#h,cYRB:b|OQ*b3a˄; Y}r J>zxy ,|sF]Lba.`.RU6ӈ,WIO# mp;huJ#*+{R^;Ob&,f 6m)GULsA|8J_ _ ئ-(5 ƅW=|U0$IIȚJ/U)QZ)-5bf*!(5ѣ3< 02 p燽_CdXB٢\HwK dzpKkzJx2۪db:y3fC(*cdEIlѦ\~-͸q2v<Q6RO^224΃/IINd.L:\,nEӠR:}eqbvok P, hh.8n Vs 1ru -Wc!=p@&"iRyeVudJ'ja?JQ\6qHHoD^o#8u ܂ļR' 5}6py-chglgmb -(KsoOT Znk'U  % !JKՔ`lw-å~ 6~9d*! ~ ! D~6z!Ssa(c[V]\C[h 1bnE P%P{EYܢh ㌙13I\-h("p#.'DQKѐ#M6-/ZUr#i-[nݺye'>#❜Z ]IM;^סGs N]8f(!33%2C[z+ܗ&J+3w .k;ۚ{|πGH6/ZAw ?'vWC$]w_iYkE*m$D:&dc6i+<|PG5O&IZW>ǡ|h:^NJv~xKJH`7[P(`*^b+}O&(ےRrFS:݋ 0wL> 6"'p-H('@{"9v ^PtlZu7 Ǡd xON,ɧD9Jأi`]ɳM*{9]cQRf)J*rTBR*[Ts+6\ABKs lbq8E-4IHgl @(el>vCRͫ.#b-k!Q=kk5-zhT3vݨ6ly'%߃!!Ѓz,}Szo=˵I,]@=R @$b$&[bY_&N{ԅKB>eZ2%)YIo5d9GF2ڷzPHPg\@DDO1 o)T\:e֦7kh\:I]`*0& #lJ٣HDW}5%q013q1Y9 b Brfz{kz.$f"U,$!E_p\ {DТ%@d䘺Yo-5A! c)u0񍀔]y1&(1YuaGBA 5mda0uˆSy-jH:Jk BT&Pg5F)Cn=hc(*[XAyĕ;!%JBV ^2^L6FrI.^WƙioN5%eG;1{+&+avi%k߃(K-1z)l"mOn }jrTr D/ 1"RPT١2CXGWC˽Zlr)AW1g\=YH^͈{X~iK h}\t}X,"sVZ"bGꆫiYN_h5tE^1!鈈¶ N||Qd$GdvEu"$L?;aE)l{Ɣ8{sHatj2ɜ?ܛ2n9 d XAbQi Jkm(d;;Q[}[d%Ts;#=cO b6%!Ȑ\ne #AtsFO!lsռtN*A d> C\ځ̶Aa 1Wދ$o"fJ^hkf=mXS]vB%  @m bI r8$$!8XRZytV8ÁWyPrNB$C)xϡy,xzrx |v ٞCnj^߸4 y:OOU#݄Шp$A컽ё"roVeh@-dGF:{0؂i7 Ǿ'`#ZEװkv 9YA?yքPbG;Y>μxba݊DV&BjyP{׾Hz&V?7D,8Q#tk`c@ _x6P6v\~֦^p%l$E ?߉~dx ff6ʶH af)H-JTrXbIȜvj'*vҲb@wId%$uP/@-nsWJga7 ԴOEUȂu- rAI y鬴'*,.yӓd#;^ gဲ+~٢oIݟ%u:.yn߃_8Vc![{ ٯT1ʌDu/xO>ǤeԦph PEsHh.]ŋYi"}$ >iFVW\:N"fVUkB4J늗N8 Y2`W\z0~Re._CXw_L,Ir0dw% $ro;.f;KuP͎'Ch?`Am >㺵Bbt2l{Z}lyK~d<œSjpSTe 09dG߿ػsGcN;RQI=vc>;ПA)yS:UP+UH&oy^2O~5`#5+a]z gƪOڄ.q:%$00 Z^czޯod!tN#<?fEΊܱ`\IHHJ'%|~ ߪWү>w@3\ڪ <9>8J![.=/'}(qYgf;z8FA9U4Zs!|?SjTGU)]*qtt&5mF6ko]:Y΃YQU5a#dJ #'Fy`*OGK^a~{j%m7}~0$K v)Qy./}QmHVp^XV7h 9u-q1jKbTĝd6ϝ xs^C0~r";˩᜚>j:؆t ?|sؾR? _Sᑏ#u2qs~}̆L/؅U/ZVCIBVJ! $Kg]VQ<~ہHg7R u漏.g&lZlE5ɪiQrq= gw׮U JJOG>~W^U%5{o%|~YNyD8?I%b%;XxcE⩭tTݿZ @;~sQ3Z3UƵş)]B=ӛ"`k@v±jkE4M?mλ{6h͍i ui$lH3NlG߼M=>k7o*GWs׀ 07짝oꩰqm ʞ\8qoم~Iҍϐ U6[?< {nxI4Qvn{י۠Tۻ\鉏3 r`cXadJ[kr~~̓Œ 1d˟76%IalYBoc\c݇W^;J)){}\ iVvx{k~hFrbFLBo݉n[ÒuAvf=ǩo]'4굆w.:zڨj{vJ:E_f,Xþӯ۹o ޷=]s֏kwMo=ϼ"6L+&:wwƻ^!eҠ v\LzMW d|z^F![ӽ/&R~.J5Sh /j0 ǜ҇o0ZI9TT@F>\T?|c{ F xPsF}~ ]5Ah. (q<]m$5i^*6S6/T?@x%]/v絍U3{΅qi]iݵEL8g'K|뷽P^@bAɬ&קnVDW_+ >mKV¨&>7vZQlPGbrUFgT}:B^d*V+0~?z1g*ͮ,lـI.DUY_Ox[Ӷy2 ^v'~;ەl8թ@~Feowlml |IoV}޷aphlf8ud|cZ i~z}UgR SD 4%N}<r@Q9|H!6DjhIUU$aUkF6> k[o!=BQë?n6*j=M$4j*?$2m$#oSIə~'/ myn׺ Zꮿr?sFJ;5Z!P`ځ8 o.KiMv)-TR( em+蘭.Br̽闓vKݤkqoP?5h MEOSSJ5C{W g28nZk Ra$'YƩsyKp}Gw[ϼxӕCUw?V{;[}7ɣKk{rqm[Ug]5 6ZuϽHEjQgrn5,εiSȴ@#GR> isCW?`00Nc?1o~VVi8d9dϱPR㻿cTZ}S͖y8nojn:3{[ R[GNک{a,"w`+r6?qgcƒf`tQGVi~zǘHdjSn) miDMr[9^:٢3-)G6AQ?W&c:yV*JW/ieը=zpDg[+1صoSSao܋oN0 n6 -ƾC޳U xu~2w2Bx,WVlȜ5)S}&|@<UFu )j\XeT([:yHCK[X ܿw/E(۲gʀ/pNK\`aqK+ w~&+mV<{_m[co o~o8osQ϶v'aWdS,{O~7{KzPsزOJ+kYZZ|K/QvzŠꔳꆺvTzpߎ&^_VZG zՌrt HFJ owg,h'P.o_~Bn8p膧r(dd}@u6̝Kǟ?yQb,E;pLYj09&t*cIlT5ԑەyňl^R ɂ>7!8p\OOl߾`pk_F諫1RRos6u@t{%=nLgxSچ6kϻBЅdX9`aچ!QX.#>Qd8DWDIcӡfcXAbط?q34׶I;m}m^U7UZ!6kw08x۞ 9D^oSԓpޅW` nݩb <_k"y#׆= -*kWV] GyKXlˊBdh5(:Ɛ-➾i?UrUPIWiy1bM(Mj<3S}?]z0uppaf{X!XP=s0} 3o;Z||F\*}zz^&0PR5;ծ>:UHNoD9tp w&g!>eUC`]9F+wFOWIJy7PȶШua)5vݷR`$[Y;kk"̪նZU=XT ;x:79C뇑1Lr&);4m ]EGgZe@9TO AG6w;nuK u熓i ]\m C`yix0#xՒȅI/há+z`SZP^Հy+7~5[poi( yoƻN,*Үmb>-E%'=5h*oF1gRsFL% 0J NRI4!'/Ԛb\VY\(R#r9}x9ǤgmA7!=y7Q"1&@vw=$a5#-L1hZPA 1#mL( l7{ -l:Ddi]f{1h,cJJHZFkQ[l!=L-.RTrvґ]Ȉ*26bK XRp^4Z' elD  5u% Y' B7Oc.e9#2!ס.9  t W s&&1-bNy Bن=4}$qbUPunEv,p'}[$ĺ{1A>NiMH.y.!j䭢s؄芲SǤCtէب+GY3"_7;bΥ0aW9$&*j'Hyx">aU2槙Qnh.UQDH*ϑf`ħM+$B$ F̀Z*B/D͙! *|73H0V djb_I(AR3[]хsɘ"@S9iŭ -Q.ɐh;KK$Z/Aő/ja 0.Qs@6H?quX#15+C$.S `#K ϙՔH>'!&N`YӉ\ZH3=1"PNig^uaPFKx1 JPFKHLA\D^"I ZZCgX1 -_+; r @0*c|O=ciۣ|{IBRfՍC[cv9 `R%%%*\Q$)Cj?Kf *3W^j"\ ɷ0wErS>u]䍒 Wr8؜]tx:ǶS+᬴a^qs -s2; 6xH͇Al))F`NttVg /@EPQ֖+$7!dʪZ$5),&W^vZ%&O! nΙKRDғ"i1q12x3v 2uhKͱ sMxn m=YJ k+邭OY(T+^P׸J3Iy6-m?hEbFNmb(p(& Z6:qJu) 6)9!Ys>ߋ]7,ܘrC16F_u(qpV>;lO<>t yS3dgO,Dikꑰ9 N$b&-Y,)%d;xU2M|M\,zX$vq#@0bM?7˅$^D_Ι4@rׂtT\;.2F7^LQ H+#\pe9b* R{DPW9 "՜1J>bQ|>yd-:EaFrƉ ('SoxĜ.YmXtcf1:}ɷwD$2W12%glHƦf; D` j8l{0ov`f>לKaR2q6>fӰ@N8 +A6|Vьa]!y2 c@B!QKa"LrFz<LL`j Jb19wSz͓ޣ1>utks`<o`Fc $ Q(5{[+?9 M#hu|w kWu2fp\AVnbUP{vC9ӚmuSMU̾upRCxu<"8ؒa"!Qچc G0e"9*i4p v7[R)y! PV #,Z~h*EC\NhK2\6.[Aދ]Wa; dbC2Ḃ|[e -N(Jl 릔*3f@tLI*FD?>Rm¬8p[ij29i90", Ҵ1OC D\9-C:J0PiQDIuʀΆxbANiomvv }mxQQF?gCu &0]S.7/B5CJ8Vb-+=H؉k/3 +f AYm$!½́XQ雒 PVVeKUY:zB{%I5bFL2ݿȞlUNA3$]"hh"^,x{ kGFǦ$+,<(j}} Wu9^wk%d˫h` @'q2lf'؀m:$$Ðe0٘vcKwcIV/r9[Uu `{׭?cQc_}؎GS/>\Ӯ;5; ֑G[B[xv/"-k#@"n`8a\OKqzMbhWj,óhOlQt?(gXґaGY,+%fK0ҐEsYiw+8KͲSw3!CH;@l6?&. ~ԓ D\z'x(qq y,b C/vED-a ]Yۆi ~4Q(ihOEpL߮N ̶ b>S'}͐zqFHKК6J|A<k" m'fR#VȌAv/p4Fq7i9 eCbt*lGkvX8{vw,I@Γ#:A{a5u61'UP[ȉؗ2H2ɒBz(M]m",Z$xS͇kx#Z!vvXSVv*&Y`&=6b,J2CDXS{Y&lbh\"=}9r';8U q @9F`E0m.y#Z\>sgRS²W+T KvE?@oب@_#i]2x(E-2;Cm!XBe܋,tABS4qT3d08ZN&GXLl*{_$?].0#5l:LC@WWTX"V*بCh*JBH 1#h%.&;C,AQMQ83Dd2p[4Vu=! g⏋ПDҩ"UˆV(=bMwbVeptl ђc+ v 9`h9&ej4攽įWޞQ~痋u27AZ6w{Jz!Z2 %^,\Ew%%y\eD$q|}7Pfi.Hi}Lb& c%pn`垾Am0 T_j`2LoQ(!(qJe>c8 I.H50ӮD3O;i,o2:%Q- ǐ;4<˵e4~CD#Fm0u$ m"fK+NNAQZ\konBRfyfK385vZ]k#gƍ ~03L-G00𰂧h1C"ta"LlR^>@ ʘ سL0BHҋB<1HPgX ^XIwѳTdeոD~hmd\ ́֓6lBq3Bu(:̴^Llk40;A_k 3쓝bgXp1`~w 834PZa2yk ,N 0^]p&912n ]=QF' :)ꜩS*4*Е9HE ȺE8+V|0 ƍ8ĚA,,Nbg-vhC39C2PG!1T!^fBH8ZSK`md9Ɗ# |M!ԜޓƳeOe (3Ur AT p܂ r e@cP9jO2zIYaV1Wbw5\eh$,]m o\+ILj8< 2FhꡋCUijc;d8GԶv+"PřaFX2 ԜBFR,n2;$L*hg7QIis Oi&'~eksA[: ~zS‚)F0$ C$Xj S&mOI4b"zTLo ^ QyUɄ|#njyT)0; YxW 7dq6G02E.9*T)vf N ɋ A(L 0 C(dӀ#!HI3??<#s$ٴ鸂SO<[ }&oOwLJLQQzNH*܆j]ㅌTg9GӌΓȻIG29Tb) Sh4Ԫa aѬ{b֌tac/Hfh^aLaɖd>'d2!4 ]3qӗbI {7U^\! *Qarv(:4;qfxlXciIJSx/P2Sg8; ZqΛV=Zډ"E)_L¼Q,z".ZM4ШAc&oщy:QB_r!c;"$1V0LZ3d0aDg$a"$ f) Z1 Ɉ–Y{=2&Bf{S&wsЁRlYy̥0,n'#& NX'-@ܛÃ)EA=h|v668{QV:.@43W7vSvY$ CB3?\=q 4O$;$aOɊ5pn;]/"5B(D2z|[rݴ0 $0"H$1iebSlc7z]ٸ"cH3/9~A~VykD5X ֢趠Ԍ-Hdj8b_/$Y6̐0N I&kݳQaHgtdo*U]u|X cSQV0|HGсgʋK8Dڋ쀵`>]Cw.;X9z >'LTQ2Gd[Ivɩ.~zcc$Qo~0hxşC`rcIA' UVPz-NsP LTꕪʧ-ӹ gn\ɖ8sH}OX`lnfw%w)M E( LBuc"X3D1D9M0kt v=yɬtHYF Y|›L$5f Xv䅲B)pgB6,"RhIayʽX6S(T̖ J(Cձ:܃<<Ǚ@PHtavQ']ka~ 4EpV:UBiC[8 {fh6;趜ȫV!Ⱥ^D˙c1Ŏg$7<&'`&&Vkq^l?C:>BecR)$Yx} 5+ c+V9e 2/¬ZlS"r)$#O x#p8(^ထ,zNtuߞ U!ױԣ#n1 DLB5ZYx1Ӊf1⼑aP~Qϖkӕ>*Ս őa8TO c"Weˀ-bdSW^ ~j?V ]4aZ@ὂASsg7}0bMU6瞝 ;Lə`$#L:頼 $AH{4favnɯ󡽀X;d-/,q kaONxa̡pI'A|Q}@9f0Xb$u`vRmkm\@*Ec~f]Tx.t(1FӁLqCG+ $uVǻrw'eA׾JN}답OEB1M%P=zLĸ]q\*QWfSH=b<ff 9v;K%n|p7>?Go $$Ծ5I!9~fF̡2Abllagx)p W䘭#Y U;lox߮$%>wv=[5gmo8厭&Wn* !|v#zS|̣S?ЮQ߾?{_Z_wNr2o8Wv{U|]jt t XqDV붼i07[oT %&4SC]9B<̲ea~~g>J%&5CP]ZکB;),( zAO[RUAW$Ϊ.ry2J O9xS6q$ 8ʟq^er>LNիVɖCceS7vsl,nON,Ms&$d-;N77?y+l9avggz I&g`;t(tx0k fO{-#_- -y{w=^7u=5֬neݬo7mu7Oj72@̭Wout$rƟ>{^a*{'t|pC]u8̿(9ϽkukeQv1lQe6sȣt_A`*IVUnXqO暢pӃ0}7O/`P{!Y !0y8cbSlrP 0_z铮,"8Uo `uᙗ]{xa7$)x93 ?H{o 飽~4عcKs3ָDŏo;pVij0Z" Ev?kvWnxh{w/߫7|M:3 oLtr彏)-{>>_~<;[mo)eo?mo?_ͯ/PL|Ggνs3Z !1l_[^,tU k8뒏݃N t2[yj&v % ;XMJ0̰D~<}?ȗwx3͔;b}ґ~c!98 ˸0GMS\\MTج$WEO0Չl (ל;|!Bm'Iљͽ^{Reσ BW2uկå||h.DUôNϹY|&>[?q@ B3<3NC 1q(֚ˇZY~SސW}oԵK_zm[v#+if.Zɏs) sDon^f"_3.?]~=g~chk}$??:{[[ےk)N |}λ_g0K+ϼ/y?}_'' 5ȗcSPn,qysGrh UY0D&ta5Hƫ(_~Z#Qވrd]uHkMFD(L΅2z6]H bqg3&"'_r9'a ewoI39_SClMp֖Lq:3 /wU|&Ecˎ2X;.}JEhU!h)+?dpc2v;m9y?ڹuOԦ7wTUu}Nc~{q]q7{}/8⧽Ovu[/zGÄ\EnyCnP\vKmz[9#/7'o,et탛O|ڟ^hWs8>J•UoyOdž%:ͥ}knbD*@={WNJ:t_uXtT{NZU *?EE¼$`#fƂ#Slg`‰1Ħ̸y<nVK?7X[?>c=X}fVL}yeY+:7޾sX1')a2O<{gf#r헟fӳȘɳk͊xcrZf~EAu^elpk{AO擄`t'S=/7tBo]UU{,nȯiRjby~r,B‘o#-V=+d'QB4*YLch=MYRdHP2+d7(7Κ?k \X73{aصB'ߜtR3╍s~$ 8̍9ٳdo_ Lhr2iZ40}ˍ0e Ld<=J, g=LHGo/~'}3m;eyy s| {Ncpg|-3Ox$=O"-Wmn\0KO]}vaƿ47vnÎ=37@OǛo;%m~k6/i/v=TI.mb% ]|x~Cp3aS*pXz ĪXwTA~V=rH=5@pa 91$/wP^jS෱Aq|$M53̟sLrHj̫tlTCU.MgX̉O -2pd=88y`llLUcyڵ6w~O[=G]73gQa2L+謒7^~=|ës&xÎϞΊ2'M9]m+N~IS߿}犍_{9w=:,[i|ǖs =i}KN9;YQ^O-DMpG~cd(riN7\p$+ }"6 %qaZE J5:07ΘC0;7 u{́23zawXNkd#S:]]t?i2DeVepͮ+G̶ן?)J~?=}dş۷-\_l2sC.d7s/>ɷsخ8vBdf홙\0̼ VM/mӷ>]{ϿS~-Ws ,V;>[. ~'S%+bDU#(bܥ+]uԊs#\g~Ty2gOFw@{aƠkīܐ7BF.?f2s@p$hr݀.@`i6 﫳O;Pu+!ieBy Ś9gxKu@p=fVBU|מݻ7/CW^ /+ mq`;]uWe<~D}A 94IH3`z6C͖^U7S\i׽dË ?vӥUX۝kO^qeC Wre_Vso8+7~m:뺌X=wrI--tn9ͬ1OTŚx Έo>?7\__@2d'zrCЫ"%c-2'.;w?P]iVLϺτqi>&׾033yԱrԅPV9y8Nt[ *XsSa>=},$gܡD̲lTM"X§m{ɓ[a'׬C&q太'Z'o^y~߯e**"7O<SE\Uƻ6ʸE5k?[Ư_^?һ^l*9f^cS-|g_41|sԟGv~W+7^VN$O|T1 %늿w|sЭBיA )%UhݹgzӖLT`CIk /[aģb"%gHu_gľQxh~Gs9{%6![Q+%釠؜)Vs‡'f:{W@b8nFԿ~$3*sٹyEu}vq_E_z\ftU+&8D,23SijSDd΅s$WvyM X"wH] :8^*RĦY;`٩O¶>?܇IVX|(bk>5.Sz<MD76Y+Q}[-v3lj2=uw{7j4ru.\On\y6&`N3bMWWmv`8kzzOko4+qEPv8|iR,g$%22*Tz&*=dF&]D{2 F1?b|Ps埭|1~ۑ*MwMSfARLbb> ke˛) CHfx(DfˀyRsA]zG0 zy7=p\{`ĚRX SeeXF1PL[u"{?sӅ~{fPd |NuB4S)Y@,\Ɗ9C"гb%HOG{kpTL\&0_Yen *Դ]oX> E Mנ@U\/8kd$)Oۑ}Pje\qȲkMxZ8CT9ЬbUfjID-㲰n{6,`x0s F\^Jޅ ]:OLƍ$?+pS7|}L*4P1ˈAҐؓ !< pc035m_X`byO&ՕIe]Rx-G TȀ:eT~VCTnHju.IF}C/^>,/eYTs `dG ڼUIux,3,wGG&qX֞t&<:/_!x+,}2N ,f 6dT XvL&!,\*yD8m(Dby3&%u 7:U^ _K~kYU 0[t%l׮OZ2h2G a%iUdƺcT!fJh2nzժHX|yqJةlX^6϶[ͫHrsP,mͣf.d8h ϗϐ{w-~ϽYXv\"*Se̔3¶]E)HE n&"=T'.ےG58 Cr5+δhb$:,bJ!J-%}(5J!gdj+AC7jRMLHPVOCTթܻž!3b>*O@^& b$ST!\sjoh1ϲa^iO e= ~e.0P^/1FM;*Cޭ/oR5&0S T/c^6(CPyWsP SA嵾S%X*̀6ٍd{G=ձ%DL$c$nT')-8OMI8YKX[uXEb%DŽLy=7R9ʵ nSH87-:@/SoX@֠E)ڢPҢGΦc37{`tJIR;9C[ ^ryx zK 7qIS^[z0 Sļ(頍%F2N$#܅ NYw <[v*pr9/St۔[+GFguVa_.~0y%]ȻA,>Y;{c񟧣qKP$,z3E0@azx2&9|5FUx0v0rhJYT Vb*VȽ(&* rD0- Df] xMԕ5F3/'kF|8HPs,W:pLBʩ<WOx]}ŌJ@& ޳Q)Y%NF;Vy*$?{)J}G@yb%FX9۳|aX__fu,҈4LlhtcizрQY b~ O],K`JS+FTg6enn7V$rm(ku\N2$WfoySd{ b z[Dyy6 kXwje,n P QAjG܈5:RL1cPXwc=EztǑl<[sB`iiZw?wv80lSeR[s7"Dێܓdo.+ gM~& _>-"ti[w2'3E1)EpM1"|CY+z R-H4Bf#hњ. uXzeNDUh‘9 0;  qn1CӬtg/3'j}K$4*.*>ˇ<ɲuV#S'g^x ƜΆQH g$EuQ9n3OD{}4 +`XՠES2D Qehdn7u`vss٫0qV(eB K(wn:A[cd&ᝮ>"KbHN1$,89d`l@ xH#J,% -.)zq3ڈ̔&Y ZҬ%fcE*7nVTY @jVC~*LݬHѶe1Xr)qmhM`fttm;ZWkZگE56#da9k1R0`m$uj2C1nH+Kx1#rIJjTJ߇ŭ`mfʂ6 HaWNEۤ'Mr&&d{ U%&P724Abl3;2C]/4$r] #݆& =ZX<֕HuExCɤusf z 1EHɴ^R΁Bz pH=Aݻ>(od0;0~cBӺiAs /pnCW!@CNP5 6Xa9Ñ#ey&6f)mS0$.ՄD1lM9= JY^lJspFMPJDb`qe\qM,()2-Fp6aTÔ?Gr}!CW +Vf$Et+Rbfi 1-# Zú#N1\r&{eoYQ:֑iUP_)Fʃ"o,u9LSĉؤ+djAm:WQGv`8p{vd^x&K#Et2(KpG.jku.}bWs y`F j90ʮyyC. Lh 'Pԝa mC}"v1d5VK<"b #d AƬ߱}nsFV ZOh[L"c+lck޷Zv_Ĵ'$6 =oiL.Ww,;09n MF)u3qϪN~l raU٪ PXSA e]"+`T6GN P E,vb_2-6M bO\U ~@gϳRS7GD--(!1UްRјe"'BUǰ]9Nրez {p5| PUahWXئ,J 伣4 X 2ê˳>{j =Q_+lG)Nˬ İly9ViIԬqX$5T%, @aI΃k aW{A8] ڄvF eP!+;80QG X[Fc}hXwVFMmyR$)i.rj+ @$6eb!chW=Uߣu=f-_P+ZYvj>$jv\-|mw^AX 1/IO<sŀΒ`v(K@]痸/J^0BGHxŒ}zn4!'aZif(c[mYt9 ;Ď,-|5E&i4Y7k 2A3*&QTV PWnJw=˪&:Oj;~ZQU[CSdygde1Wv@Ѭ2U8Ϫa-*S+uSQjQ"d [DE׷9&G`ǐ$9W iLB44,Ŏqy5rXzxĚZez; B&( (-UH{ 0n(+`%19ԽDBmmd"Ø(Dj5NlT7Zޚb0DIM0JsW|aQXheڡYp ؾC |a*N*z-&hJWnK!KJ!@Y-]eI#&|Q.,#n;P{"D44AlZ"FniH`lPsg0m6SdGڛ~+ /ma!<$V /46-P@n l^&"e$L1<$DIcQ& PjS NW.glG3Zb>a#Fc׭KMM-Q3JZ,?P>FmSǰ'xp\(^a&e" MDlI zTM]( I{Q 3X]O3`]vP$l $jfQ0G~[! ' {2[1~Øf6k TN l,2;:HNON 508A+8ŋMď4s A}LglY7-WԦe8KM Sd1X[F8ݍH9X6-NJ s4iʩw0rː)*ș-@#EX,|-2dBӰlQFjpU"󃘞hfFLkX QSv57& SQ`An) HQKC?Em.^(Ny9eVަE{ء[$Ùrڅ<:vF_QLh-r5nwc д 49nȂat*ZV(<P4 `=;{(}h@ k1ji -+3ءhHDƈcќnfspx dn>צ(SѤeb.[Ό" z;Q3(A(tVāBυ8ຆH\U<1P\hۭh6o 18&`}ؾlS6y[E8v}N[l8\5Bt YVxst(SYt0ڦFh2gȜ/Z7L Ӣ=P7 6$BYVzdxR 8hIh&uCPXSU=ՋMkz"CiEJA \2Խ 5j`46m~KaZdmv1:tdqJkF5ju:8NFc ILXj.k`} E^HꗨjcKزi&uBb`SK|]bO77lN $X:]L_F j0O.iD #j-TZxK b#*GtD:aF)aTK-`BÂgGB]JʀtVR.,7EѬY+!wYhA LaH 5ؾBѓF˴єm1kNEcj'Kg0tchHtT&6Yl;2lfKw3?;\ƗX(b>/},ʄ;"x T m#@ m!+:*pv ٣36b(ȟsb[ϕh6m60lnle3$C {ZVUk{{6C/(4%$j["J"RTJ#j Fbl)be` ߽g>gs{s-y^~ڷW}HgCV5ˠRXmf^WA=\zgɣЭe֩@_'_cUwKuPPsg+Rs̞;̪N\_8>Yaz8;qb5Ǡ WA?6a'r;L.,P sS`Dҋ$ v Oo]Sy&^2xb>TȴAX4(HԾU {q8$ n 3r漇L:[Й`>{?2T7p;I+u f]$ v 3e&l0l =U-Βcbw e‽ObMseW}P1/\/̜f+8pR aU!0*h2eOir,in|pLnL^9լH:?݀'"W&0J}ڗgEW`3kr,~ԇ}>^,jL N^8!0>MfTfe1̰LM7ۨn3%S9Y 짙]Xmb@Ib%3;73Rf6܏ ]8v/ѱ~_v) jU)=5'q&ϝ{ nA uhve`ƕ:ИurDw]`z5wcoK*{LT}YfE;'wmeqg[klܸ!uio`Ob-|U{:= )A]lN' ք6C3}-etPE-M1&orOLL2þU<I3a r6N]3R=,=boDmE=MX!`3RS 'Tpza/qWۧbwX|c"&s 9,ftg4*kX7;-fr a eu&]M Fnk3څuڑ߮Cƒ9ˈ%J% a5íwd/T7fr/VUE5#Y!uRd٨9(t8Vo!XrpPBOW D wP|8fXa7~mUœ+yDt,3kH t \ U0%qa6ՔlhMNJ%\γdž]*T$iMuIJ5IQ/o2;x36+B΄kTq߮fXseKS"0dNιGi:x5@3K\y0,B]U]ÿPL2~QàLNH}V>Htd @qX~5C_!Xmn&\ Ѻw?E&hz cUdjݻ85aγI#48—k&1@H=̺ud׭n'.` I.*~B )*ɑ0nR1l4{&NM&Q9z"QQ%`A5+Ao]!S:~ ۥײܬn*O(^c՜j_xIj{dzLd* >Nл@Hlݩ_'=QMӻ)#UV]ˊ 0sDmDНjEҊcwt`wu>ԩ`'@uj*kbe'? ަbPJ]o}A S#11E+#O2όܙ:̰oT ڽY@WQsǓP(LpQ*Q:L:m.sKLi11Gg*NV_}5A 0 a]0,j0kXiކ١nCT*w'ꥰUApgв 5sLE1Q`O,@eUފ:RhL7a"c*5YuK;gej*@wQt <T XkZˤZff^ovXfVea~su&9U$X@q*;\.&S|ԀzMNnVs>`=G MACB]w5t04#[ u6kӁ\1uXe!VJ B|PJ:w)J{afK]j<1 `S ̡(CRp,MFopN]8ΒZ"vؿ~;6%v_50HdqrHdu#/+8#=Ɉ 4%V v% yӁhZHd-s/jc#>C^as:9~A]G"QY[8xvX ao1)hǁ|HR~=jG {t A߈~}4MV!Ou DX',nK1,1|٨DrV0Slc;H(R 덻:-)8.;Dw!h>~;"<[(U1U[$7KQKIP@؉H}ªʓ^,YM*gGQwG٘`1 -+$ ō<u TyНLџ-t~26>GV¸;0t ^aJNꨮZu䈱hl E~̶R? cH^cSK Gqac%BFO'퀥<]H]'^lb_ E*m\\zn G0 T!U|$3,fA& 9ˢ볎@XB~OevZFwو]`uKbt% nz&idOFD|[|B=oL+.]E婡HLJD )`H`֡pqspߛ*L2Ө_E3 5p s XXUun+;P$v 2?R[dO8sj6LSra0_ jnBt *B! JB lKp=TڔW%ԀD839G2QԐstwx:FJ18 .1 "[ ]DM'F[Q~}]D=©֢2)̿#9hB৑~BX ٬^>r "(, Hkjiv T~QLrf 9pQ90YFѮ{qNKUv H}jO2 *=k;Me KItg(&gkD|S !I Eg9lGD,Uw%ްP' 榸4Lʎ Y(p$Ln1Z= #,/ I; |m-VaB7wY0 z%lÞj;^=3,L, l. c,,!a! ђo2$@2MLu_.*K&BMK}^ Y1>( @H1g&=ѻ~<v^䉍e3D[îqF[o>IaؿrvKNI+{P-,2?:r6"On(0abӎ6\/ˋ5-$qGTX&Po"'s` cԷW݌/*%t&w#;^ULɞZv2D FÐ XK# *ZCT/$t 3HQAH.v6Y ]䁛 rSk"#$csoMGPl jzžY\FZv%?-Z }R5Uߙ xeX\:-r*{m _ k2C*m.+ !;v"v\!ӋT'*Lɩ"!u[B7w4ې{'6U[mSU1|yVbK9XP%5>t@Ťkyآdk2]ȢNkXmFMDO0j^2~ÚP1SODOȭ8r=a IHv BvP3JDr9j+U0_ߟoMNe X8( d : iQNx^oJThm)O [$_t}9e):~ Uznisz ";烸A`7 xeE2+W׎˶IVZ9Qڱ6afxT< Ig#U0K1OBB}m 2e$ 8&ftKAn#( GM 9%/J)k*nl+TLu~[ߌ/9"/+P Q.Jt2W"G9Sًv5zB^Hd]liT}\0P%^e v te/I~V%7ﵒ1EyI;eX+VvH6Ь]M؇z0E^ r G ]E>A%o b*=:=k %Ue0h2\B%9>+xuWZD+bN1t7<`]vPYn,]'53$,&!,;mDR;b5NjNct!JQ,)ƄFG).&WA9_ykhhwLfh$?9Z:BBy5k;F4r4$ $x  B,ZKIhaW|1, VtO Lj'Uؕ)n)#.\;(GBȠ@e'w so 7*xf}>S7 E-~(zӜr b`.[e7؟ N;eKIL5)IlktDDN j%GBs!.O=Mv)8FWsoRkMڊ6oj0Awr,-$}r"CѲ44k$a=R%5o9 $]TGnS <@,K|J؄$!`r١"- Ie S˒ߐDvA\DR'%0CФ-<[{/Ho";}UU-V<62M(K|Eg9lA mL8Wq5#ao]ގ&<CF#u1(p넠\[dHuEZMr3S0hfg̰ud`6wbVy]|-˵)~z #eb^*ϒ@ f<',Ù28NjbYL^)h+C<Y[bN[K͆Jِ0j`@4rk8b0Em+1dЈ ,HQf`rUCˈ*4ehi[]Rjt>H;16"$0jA+"61SVur#⡩*3p9 2 +s3+l #L5 *3B]vKxcnׯX-R/&8zw֪ih"\kTSl\P)yr.ꑆ#{$7(ɫD zWD apJ3 ;8c2(kue欓%m 38M'XP>[tN-RwR-(iʮ.!/@#(bM:pIvRt1j|D͆eMMM܁}ϰt>0ڎa"YiLFH vdvG;턀udƨʶ[wq){WNǛaj巠`i%bj~ ņPʄ]O}|ILixH[+t' 9ߗYc0[#ӜO&@HAL'>F KʘH&ñ@Mj3_!;ʼnLcQGvsZ ]lc,=c ՜tz ؀@FL l޾oӏ:&&!6'n2-U1I=rZ.Y?FشNwmڏ@LڎYR؟zMEr&RCF߁~@F^\aw2hSsuʺWvB6H(&B=Bjr7P;Ffb8 Hq5[X̦}-OAn W 'g( 1p ^a`brp`s=9 &Lq 4,]HlwжFvA̰06C/L.;;W6:rk)I⚸VyVg !q?1hbr`R̚%c. sZ{{ 9L6@Izq2vڜv0YLJAjW -cQȱo>3&XW]P𤕀w/ ujB4E0c=+~B5kR0(06N?[K8 ~00g`qrWln'`rAIhR+ϑKePLsH܎36BLQdAE2XKG<m.zz ׷Fxm0Qւ`I,m0dLię`h2sӁ ޶_T-J>O65Q^N+ؑi,#gt.>&yf`pϿ3,٭Vb&/X?Vg$084s1bbDi 6?t'7TDg-clNNNnD60q5 t/5oCu E(h .s0Ș d7ݏeJ`h <@`v' FL"7d]ь q7t#K4o妒[6i4*',۵_v;^ `Yga,`Į 9>(F;Q_alx[֋~ [Ƿ X8Jޚ kg.L9Hb#5`vԀFLrT~F\9C Gn&4σEܷPv2OLυy{IDa| Kxo S HDjhz]PGx5Fhr?ݯsHNVBwȵiȉ Pv4HeYUz{X(T,m8Z&ߦIqc)DMwzF*L#]ƹ$[wL-?I>ttJlG6(;Ok/feh[c(6wgvw-ړW[Yw/ng _{L ahp>|>3w. 45 5TH3F~W,ύ;{+}|̗9q2]ڄ̇9ՂeqLﻉy*0Jh y1z: $dbf2oϣd["f6 Dg amj&f#J6Z`Bh f=Ad;!1Cc~A:׳aڷH9+̞thzMI9mYFp^I\0bqi(c#p犡$+792U cG"g@oeN\leOSoR?aXրvR^0ޒݤvN6JQ`c#Eej7Yy!xlUSL]&rWD4wy^~ 3bAP s]tg2Ϝ 55L^AQnۃ7~Ƨ'2Z% 3l'c]E e9 ,j\=ey)&)Clyi6ȀQe|Ȭb&nn_i#Pېϡ0~ E遨<3#phl0 ('Y͂2ɒ3:ɍPAjSQȞ-%t n":c 9}2F|bS=k`)X)LP xM$A[1Sy&3?v}XV$Ǡfs4@FcH gjh`A1i"6S./~1hSb{꽙|H-b4+Cni42V3GuIl[qwj>w&t{)Yv<49 9'>hX P)1$#Q΅ .nOaE1Tf~5-vI+r֢=rFI2 I0 ߃XЂ\3Yˮ9yk:U]Rlbfd t׏[9@YfaCIfry7RemPWQ47ax  nP}?֭-N~biC38^.y!W>ߞbHJb8&Mk7Pw4 QGDEloX V!*th bSDc)b\Ev>yr;NL I 5Spc%4?Oɥk9 o)ېWn{>} 4dlVe34ȝfB"CAPNV-1#D{Jl aH*M@VD &Pis1cv#mtn\PRojnj(P{[ 5. IZ⽏<[-a[ۧ?woݱ ԛ6wd4Pp; ~zi3?reW]:xuZfi+,7%,(VjVe(S-[mܸJ6VLE2/(L1.(j:;^OZnC tKfZdR65 2@4 X+y vxk8:O3}ne)VS}wփG2V9~^x/?}qrT)?NٍP1Ndpt M,4'=PzqM%|@:f֦42Д kʖ] ugyr>D~B>*_a1ٔFyҡf.Jp> ԓ7D @̒H53ǮG?>8pߥs2]f8Oq!21Hʁ8Zxd 4v_G0l.O^g:-Js.ǣ^ٞSTlfmXQt?${AW/{Jփm-̋u,+>t{;Wo֌A..pןzC//,|GOޯ7t޵_v+zտ~upY@ svwv?onqG,;9!!fZ&sVZ>V- c Ji&߶ 젉KE)LQoDvݘCUɲEJ5yu j5foy@E 24~300s4[ι~a\9sF}A4|>I7JK2 Âᩒk~G$y&|-ElХvS-ӯZZ<o;uiAjAk_/Ql<=NVuH cC{ug!m?낇/[ua+竎[v zGzӛyIG/ws/g^{ip+yN2Cpi+_WoI"Y!LYZ"@sTE:y@U2̀Lǽ"Ԓ p@jQP!rm =ZA 4磁]!wh7BMH)5+-Cӭ#A!Tk|j&[01?;(wIĎ`@U*#rQ ͧ<]O7,m7;r3db7Ӝ?)NUl/Òvꩀf@ʿPo#cA}pH * Gߣ^1DOa `O{)?S=aW_v~ |oX0/zʑ3pGz;=.u}X3H謃$?Ef=mg&f~F>JOSy&բ3F],&d9/Si #E+(:\Ze6R1CUl$̘`3]~ M~ɒD_QYԐ3>,&`>o>w.0pWvڒ:}G|kk$hsdZYiP`ىFh B9ˀh, h=87;V Ay&[.KulrY]'%G}pD> L%*bޜ*ƥ<l0v}c1W:6]Ϣ@Xgi6Y=o(RQL^ !K~'.!ï6 {h:-ˆTj#MՋT9x:+Cx"?U:zH|PT=y;=0U7taoی,1u!cqP~/lңVO $Xٟ =ǵIk\_kKy5gB?6}*ëd Zi43ĐMLSiLJkLD441ʀ3va쥖Hx/O...[%k\ n ccpJ"[E0Nӹ}-{Ӗ-CQ@ *Y?'}c_O{k}h Ӗ>?4iasg"Ja5\vRvoɯ/>ۦsA7]ٟ߹+?M׫420\N;uv_9E1@j*iZe7%gw5˯wlg\D$J2BAyJDdtMOOx++HMq].LW{ g~6]a|e꯾c~涑aup8J!xIps'/{{ |7r_y0၂EZ%GGe*E/1f`I@F?Xk^G5pf!'M؆&hW$TF34pqr#mMe Gi2,̭qCYk|ŌsLm۶ «?gaE ;fD̠sk 6ArЭT%Ew(Δy- E1mp~w~nO+3@WS[Xx=Kt*d^'t:M~vA.x|c?KE:K1›rERwv!o:oHl%Y)rOE?% {ŖE 맲YH5"a|_.~%;-rK?Q" `Oд PەuP'DZ\Pn&?yog\|V s hY-꧍6^F] w1*-[?^a0h'3b94HNE$9l5;;]E|Չ G_5:^)9uy7qz|Y312'g/XJ2'^‡}{nt}a[0Ys3G 2Lf!Z#sRx mSh vNZX( @GRaE^: ,_ե"~=H'z╏}K\ l9P-˗v˴S7?.o<߼UWs8 cxEͧ>T%M$[J3T4c|`jHH#E b[ҐaۘEMDٔ܍Z"4 $bs "x% yI\ǘA?a &ʒ;#L#ㅁ30M\N3)6Ŝ֧nMy0%id9 9Sn4Ce}uOeT5b_؇aw>H-['peV#c LtzOOն_?r>&{S/NN(yTl]HV9󿍸kP&MNII40#m#Cҿ_%$օlKo}7oXդ\1;LK8|R%V老C&ѯvEG!mC1ſÕ*DT|daqE *Od~z~f";\HW0W;H($RwcT:LmkPs(D߃֮)yİÉ [ |v_(Ohs2KAȿ=)>41{(*\D)\GH2F~0pC6w^0/T8y̐F/GL SG̶0|NaF)#$V0/EA뽑ti7ByVXi^]&IyCB-qB}&Ӛ| gwC&ʬHe^|{T"&Z}F\. H[8Lǭ)#|ʷ?gxT'6mtImk s3Pԅ s8^^ Cd{b"2oO>20Db,LhõUfj1kYLvipPJd֡"#:"MB@V]FM޹υXV[YUyżiFd&ͭ ր|*Aԉ(SgٟvYyGh0HLSp#)]+:2061XQyQ3/^s?yKSOb9䬱9߇S[snxd֍ 4*;*E Ndț7 k5KKkcj/-Ω/v=[yucchedr:^ Y˫7U#8x{>`Mwpa][ tp*dZi3"a~)TL)WqC`NVZ;} ٝry&2@ Y(z"3F&`;% ʭG%b焹  =/Ќۭ`2,8? 4,"0ZԶ~^?$n_~-AK7,dZ Wr9Hx~_en$>B6@KSU>R)ۺ֌m]ԢM߇h%4w_pg67D):mۅ+Yek7f>ܤ#æB`1gsyd6m 5 q52-'0&%!B/9nrc:jL?PDݎbPl(VRy26 [%UAPlC&bDm*yf6Wy ܒFj|TUK37W@ߖ@Sfڗ$OH5df 5*&sw Cٹa)0 il5,m&fOljVb:aSjM5K`ƞ?G'gھfcFCs`GUM, X:2@MLCfRy]!/ bړ#+Rvpqqa'̙V.%s1}{Z/kS<` rNHIS"HqQEfCt.)R ]"ܻlTz%FSP$3\t]S a)or}tk|&- _6l."ʤ_9C4ڜqn&ǩY~v׻c] ]5a[K͏`d/{3M6j5dok:[p V v1crU3N*Ȋ*|@1$;v{l#JoID˅)i:0" aE'6tԅ(b~$X5Xb3k-C131<,t# yLØ4 dSUDyʹ薀 Am.5@JSt5*{2RUԸ#H@^S  29t !P%='lh' EU'wH}%k66JCg|[}/|΃ǒeXPVc.1x;c7]<%0}5FC3aaԄ> |1Cz` fi6hMnG?J gЗ%vzaǕ$'<8.A)Eȩȇj>д@ݘةW,SE3{/.90<~um~oEf9 ahb8W/| 7O0LVlj1T  ΍u@saLo@ɕ(M4*/ `VwT&r.alf`SV:a&_(X\Ṭ5y/K=@}c6DR%23W[:uΞ k7,C,31# Ph5Y* !/M^록K0On5U=#( Ӱ~C =00Єg>p3~satj&aJ1 ̟&3'2էGal:A/7Q)k,hN ) b}&y>o&X2 TmX&{<+eE?]ຘj)@$Dc(T]֔΃ Nɽw[Hh$QV,sGl>-ȦH, hDG0#q$SHObvSm2Fr1 c?&Vh c8P=Zl܂[0sE0oHo"k =aqJ#a8Ʊ6:E#&㼅0vK91j.T3_0rطhq:$PqnJJ >q$7aSvrpX5 [ O]Dsj9 jčŒF.:0yW}jnO" \aw" ̼z.$ɞ4C=FD]jduueE-9΅,#8q,<ը降01Ac S'Id{ M64'$Y>C%WAwàO> ?eW6\cJNTR?͕ނBY PU<,?^\4<5bD'e/ 4B-FY?Xi6b=I;k6w&,'0qVbvL )f,c3L05F)ekGQݸH^ `-{y{eۚ.%"Nײ0[Ll&Z ;~+H,"lIpZ}N`\9b$dF{Uoi?[juFy4)j(7~sW- a&>5X"#ΝĪ.(s搜JLxD{H>āK)1ElL*y1t$g]1iԯSm)a| OdPP2S4,4 _\Sk~ͅ&wx&kx(B&ser7]4-S3˃F$5*)劝hg.:0vؖ[bKƒj+DJ! 3XfU?향,&#'iҏ\)秴9Q\,P(KYbS;.Eb6Nti= ,1vCv, ?#Al6(WK ŢwAi'V@9U-gMOregB+I5~7+7N!3E/K^Y刉F vHgK9@.v<fxIy(tˉxP<ub?!ŬN- ws%3AIu~ ";9ݶ#Ҭ4#')`^Ifs4yF'$ b,Prf,1~+Y|)"+-{`B:FR/9.lJi%dBe2n8s wfmza&HyU!n|ؽ@CE-xxA0y%-[u2.K$q6"RkzC U2Ź'P@rFE| SwW* ;cyQӌI^C>%?q]'f1okDzQ)+aOZ.#c۩mIϊ o:2cD  P`$00rވHK׭ŃR==p<[&[*'1 xRsƲƆ׌An5,e;Pq*]Ə &JMڈ䇟/sۄg6'9@^2+.|{/1KQܐs$+3LԮۺVr#TardܦGKF|Ϊ<?TK \uRa{ * l驂b`z!6Qd|r$ ,eazG\y> uQI2SQӧ*3j2͝6_DIUB>, vKU!dC7kVg&@?~^d$Uj\gi.O";FI _5~R<]5c%|&Yİ<#;)h!`Sr׵J24unbIʒ_PɆ0+\(0@E7f8pEQ?Viv T{%zs|S,T%,sVFh&g3DJ;4gAT3,7cձ f.1i_׀wi'+YãQ5G=4x-(Dș ]%>cd]Vu|s  #ľCQz-ٟw8!}kc o#8?+eaJ38*}9q`ߡ#0 ffF[W7AG hjk5zkGG[`ZXŠbg V5s9s`irky/)\g| KjSH?ut@ZƼyU6K[$u}J8ka7WL9-#`|KHI¹ƞ#X9,ډ8Eg-`,H]'csSݳeLz]oo~{/FSYRQ.oZI- )>_^-յwM3ow;Qlt€7s󑅊𜌬.8Å %wh (1>(aU֣;7j 'i„:+LaLV^ EYWdhβ7L0d. dz689}ErA^gceLvI-4 Dșoqˢ\c''CYHM>uFv,3%47-u/~*n`_R7h oxk$h׷^Xm".%6c cR&ɃGf`o润ax5"Q/|dVpT[,S#Lz? t֔k<~u2} h&CXh=k]4gpLh/ 6}qA1(+EJp`"`!˳8vV`\k+*'%!̗Êg|{V[fqI1UNȦ1e6/zs OԢO #v"8-,?HyTKB7iJ7|]ץ}~oG;5vY 06 {-/37?Oi+-Y A1lyNJmXȜ(-@5tz,g$o0i\]5gY7ps-ˁNU0/ࡳ btBJΊR~z mɴhuL1G,1ʜOLG<+JeE8*4﫛(^1`ذF0Y\󾱘S G~H=̎^{(+̠J И6vc!\:I^QCWToVӊ s+wҫB&Eݜ**m*VrB<.+ESyiۺϏ#AUƘ), YI%R'dNXr8Nz L"u`NmY]QSՁ~n=RQ[=kfԀ;?B,67ꊈig`jdPn`y3\I͇|{kDneb,yrQ4߾,Gl߿*a؇ t:+kxax|N|\%zVa7/Y=NSݺLW]䩖BiAq[I3{&;N:Sǃ&2Ru#"t(f\gΒ0UK x1ͯZgůk( @^dhT/I x\.,):$~߽ێ3=ͨZUKDgf*w [,-- A.G*]E;2BtőUAcuQ0x·3v*ILGswq[_u8Ț߸tب  !°p,u x~wqWm +]WJ=jV|eg>-ZWpd 9PRLN8 %fmãjt ͡s{8Qt% |sNns^kIaa%uN{[J.;b.xX2߁3BV0)gy }0᧴?V^B\} :Ɗ`(3c &PF+]2a+++"ki%b̬xтڪ8\?A[",{q >%hzb&*19mЍ%Y5T&43oA2)~l ƴ /b'x1{(D^$dm|&NkSVLmVB=9EUڂrM`WH&>#-i-h6<_`!1s%\%4ȇTB1=̆GS?זhJNi{vSYWʹ)szXFD wa2|c{ݔBt#c*BJ$ bR`}F#- ~sR3ڂR%2Єd| m!"pD1oLbU (39#cӞQ^|y" uw.MXŃ CD;F&e mj@UR1s? IV?|`ZK;(z,. s}ћ-w+U|CH Ps^4E* JsNA ,u{ Zz+g[ z׏ߟE "F hj -KzIH =f; zq* v1 eFYL%:3<`+`g-Ngԭj6oAȆ30l[Erɪ\*4Ox=B`c5W&ʂǍ!cH 72a! }CkEsO*$ K0 ؞@%)y+8Էm⾦hQy_ x3n9Yy~;_ke F*Of{ /t9{gJI͙89@e'@P+,((Yeb,ݵXmH)Jt匁wA(fe_ύ-mp!/aE?hsX axf֛J{}"39MHBF,uݡH|{5\6t{U4ݻx@Ԫj6xiO* QݪtQj]CU<3L+󎗸_m64rD M9M^VO&z٪ԓYO@{Oav4[M|7-wn|aH0r8 +pb!>gŸGX6ؠ%k!;[@94̕1i6uO!4moW8Blix6g'%Z݌tdzGꈁWzd >"2^"ٖѬ!Z ŭw2<Q8 N](vA),\M0PdLqtkphp,1ZDڪbѢLn^5Кe=kfg(h1M#ZيiQ%Nkټ9a6)ѱ!1TάzE6zyat<@o$,4>Z C,X%`1gPWD[-,zdx,˄3ΔG vx q:Ƶ9W`㓣wOSӨrswM2ݞEmmU05ZVE;Pݼ9sz=3`Y[D=IvX+xᰛnw %9= 7aJ0/[j,1ˑMiPe:٦?α9z @ B 9DKtƕd1ceA43U *tL fp.GQ5eybwР)BS0c1=X6b}.yR uhDms ;gm\b@tlP 5j鉉{ꂮxcZ0sRX7Z2&a  w%,"{@MgnK!oITŊ م͌rbzl/=+C9%ad>)֜c 2vyͬŎyC+qfkWE{Q V !'pOj*O %91Zd<ݫ5$!c Bk2A`i`CIkup408fT9vTG?o>%\9Fk 8sb= dJUƮA4!Z#+P }D-Ύ4cxs#7ja"X&M}GJ}4tDӉ]ap8RVpvvz[Ws$xCs%\.ƿc`mrr{S{2a2̀|3"GJzb;4b @Z0,:*.F*/]TݡoߞATрQPE`$ ј9jhI4>%l$Q1O PDQ橻Tu;Z{Su--nֿFsY|ɾU` .48"Ի>= oP;[fE_͋clF^Njh^})ɳS$璉s1 dK7f(בV=-f퇹'U|7MJtv.a_!Q/' qќVµ\B\6\M%aI= L.(P}?,8%u1 v! W_+{%8톗c/7G#vZk aMd9ZUhvꥨ&[Rא2hZ -Grך\ r{@p1KA+=үp%z~ KɴpYi}֢{7ܣB9WAk],VsQX!w e]>+ṗrl23IV"EW {Qi9yr_RŴ'Pս+ń\B4|$M0REÏ%ZfϺV i /b^]l|-¬_"O< d8TfpEOcZ\>NKOѱɥ6I@1sKȒO"KgF ~13WA=>J}hG5 K/r?vD3 =l&FhBr᧣;/j_EB@(ֆ,*HAG ؍DYU8Πw1c$:!lURaYwPE#ʹXG(4+#1/5 , 8XЀ>bO4~lt$MWA†W*8\KTR˅)lL)|Do{}3{!}`lPl4uF+]Ɓ@#1ǖ Uu)Hmjvg*H'S][K˿ U^E }Oqfe~đV1 D円@H)&Z5Jִ^{*Z),(̙C-~ԜIbǠ?fpW~|+3؄~<CT4@qDkHѵ^m5Qc^ | MĕRo-e qRH VJH]i[ T!Yp"FVc{ۜc;zZ˂lsޢZq֯INZW r Y.;Eo-~/o!\obF.ru (nH5vˀ#Xe '';A]Sydz}f$Ch\lԾب0z6MCĕjb6Fa/w%e)| q$l ]aRX,8T 6 WK`KڀΕ,'lT_FpY"-m;c&%߆OcCCqtU_8jPJݏG +…hqGQsOC4 0p4YЃ@sR ZdsNU۳/Cd՜A?qdc7TDf۶ePhz֟1Png$^K)ϰaS:2bm^|@!۫A`%"H&b͟ v]#lLF\~HBcAo&0-3eY)$*76[IF@c~:Q8KpD i`Yhti[ )t-+e8us]f, X$FѶ4l=Z2F>Īúͦ8+{[$ɠ>{808 t9йA&`FVyY0^&i Ip%?XbWߙnZVt~IhLJ?!4LKQGM|2!6Y-=b}A4&#'{spl 3Q7M#]p9p@Q>M0 Àp@q%i ڹw;{++DŽK0hD)ZR۾@#+ ,j-<^ ޘHڤOJl :c;hI7fZ$uFkѫ<&(IyWak , hP1!.Iv|CB?KGl2VBJr^CroȌp~wxB/7D8p_! ̑4dEr\O} 勈8JWAVvQ]o-X}apHCܗk02`+?bGY{Z4@sA7>ofF䅖$`D43? 5.$3q*.u4' pC6ZxD.J@] AE9mD/`Ӵ+thi<@b4J)r@thck5GP5Zs5Ro325߿e/Db0? lB8(^G w%*S)S-0WİqW?_p_fhRʑ oDvyep@ oRd&_%kiM˩GCؒxH=E,/vQOP}&A $!/p6c{)E̓M7qD ^>I`3(&K$<o4At@/ cuٮ7~9P0d#!+/YOtG Y t8k'q@p} UܮVqyb 7tB[viΈG2Y4u143~Ƀ De]B^ YeX*Ŗ٪kp2w|r`&5TD-iU27j,'! ) !'ٮƱU{"kHRb8_81Ė6߲ۉqgSˆE9l׈ s1VQ.nh15) E3(q D"}&4xg@4u q+,,Y[gЛ:X!o/(5":P=%fs}$ ,QdLB 2h^{Zoiń} ЅCuE`Y|%t$6S4r^^5op7|/5 -=\wI'풴|M  }c#e&fuP"˿{P=2#K΁%b0^/4ՙJ%aJJشȎ&pWUna ~$n[y@ QU^HfXќiˌ }~(%lFaZY` Xj؇N) ;Cg.v_A.rW$@W(FF(xu P]l"ݱdt RL:6*ˬ dɽCO[go 2(*q$$8`lQ@&A- ME~0y!j .zN|క.#؄< 2 >]&$3t/~dL{,rY9IxGh҈Wb7l4f^5VWTCMIF^r$Iܳgs8kˌ1{$p qh3 [Kϗbw46kcYM-8T642iMAĎ,rK̠ܺiޮE|AOvIæ`]"#. ɂ5FL b oWǓ0(OZ,)2mJNHFӓ/b(n[aIlEQ<"ZuXK큇ڍуEfNT+,eKp"M` 5`<4jpm!tKxҐ@KF{4 >CM YC)ca9 dOMB /~Dn D(YjYlk̍\`.C&6܃liSEw@6UP PiԒY3rQ}$ZΫn֍|,| m IWoCYCQpFb*os,9O!k2Oɥy9.6 |5ČƆ-o_=]2M8h-}u_s&ͷѽqQ|,Tjt͙ Fe$ѣ/Zy.NkEl&-"!=#_"rעh-U),MV >E.:V"&JP!C| zld-aezA B HA- T߻l]>\'Ct@vs3j2-mDFI̐G3#bMGd, >QIc.*Zta ΢9v+0b<͌U87a ޢTiNr}nRr-bnjbgȁ( -0`+@l4\D/3FZ\XB3r'3~ƐB'’ Cs@U p8<9˪52=WAp:YY5Y}Y6~fօi9(jڢȤ6#KN@cCE: qk(QG,!8Z9!Vyqx6898Dȧ (.3(̢bHR}%kS6>evYWk :Hے5p櫣`Q,?76kC=F X[n^q8IQ1}%dR"O35i~#im Bs!x} C5x`܋x%ܒX5 ߖ2ɉMc1w9DAp/X 嚗Tx-?*;P|XJ@H DF>6ڙ3Z7ACeU8\98MrYd Ù8$=|(DL"cRa Kjn1(5RBM.Kh91$ <ˣqmC }2]ur|dd5èk4&8B\iIjLf"xPɲC2zw@f5ts3g$1\}8nd.( e 9{QUvĥf\(ztUMQeQY\lPddc(NF#CR$(1ov=_|[<#jv|4m*"<83?S0{S~/`u^2آzs@jtaH& `4 LƯjR9Oj91ڀXN7%U,^`K-QkG*Y$d>J]]HDr(ivHUjK5;p%2=y]=R9-qs[BZH.͝7b\LdHPbh8J:$BypXLՕ(mug@U !h3HzXW*Jp/`),VHx"m3,r>jD X@$}$mjs1)nFVLk(kbP7R{#s9<+0ĶcE6gCbnם:cQ{Ę%0*_^RY̖=X Cj޷i"g+E6|Z$P1#`5WG"!'"X76ijz(dUZbK#."=LqVwwW?Y)Or!lIcu)2/F ܦ6°Z *L& g\GF 520>`R3i7f7{NH տ$0W)İ 9@Nkt.0 bWjVA%{f_U0p̡O\K~(^B8E )Ejͮ%|0 T#$YѪ6e24]CSpO1u,&+|nE"(`Dsgv]4yt2MaF=m23$)?iј} 2-`Es49đ0Lmk-SyN\LPG>8x60`[.:8l3]"؍RTfV@<ҸG`zPhWA $43o&Xye"n\8cMR6+)fHS`k e;r0~>:Z.ָI>S=/)K 9"ynhbasfYP!2mBZu@D.'62ekQi 2rWy{*Hlʵ]+,PE+~c;pPW %kPwT){sֳP3 ŧ'IVNbi*b~)Rn&K<}Fä-e[3vuFQ6Y(3 JjtئykI>0wcQor&aTPw1 9[ANj}w: u1S̙ǃI>~F}\n:%2N.ahv#Eo2i$pFe"s%Q1 DÐy nޑgs@XFCjSG%0 %.+qph@H2D ?+IQSSBڕ9XսmL*X3ˈ@̨}l(<.e&r:-/\#L~Z h :L64ϫl3IrrpIEF³ٌY`7 ȥ1,E}PQע.`cT%Ar0y^ @F |dC1sFǔ9A5)z\>6+Vy1Dk##HHh1zt4/W9uXMF=9HkBzԩ5۔9fh M}FI6g䷭NC[ a' |ᄊD)u}Sjgv r/yi>`h,@>0A!,ȕ 3tmD"%zp&I3D #Nc B]g 6܈y``L};ۏF9֒o 2p7; Z|ř\BP}KM:UDX"=#pY5Rh8 >oݯ9R8%ѐ!Y%qS]gI@HXKV~%k.K XCaBZ@XdU8(c= nd,{޼ QϾDA>UX ÿ}v1-ZLf@$! PB*`u1AgfzL\Y)pbF~ !ؙ@{tltﲊζϴZV94/4 0;S T$^r^[76ob%,YdڅY?WS p r1;=b1D;owbGԂH9Y&jI]agNu@B TE|,%DBB0,mDC9žtB2f ٩Pswsr-}>a!#!&3cȹ1VB\IR]< 0ş . rRJa!I 0kn=J4+u&bx Y/GYw.qk(ׁpx>ٱ0&"#7~5,m.65GG?`#.rه,^ LhaLo,v5949X$0-dEX] 0 B@ݛkat# F%@plbd Mj92e1S$HqdG& #^exNdey`(EKs&PbK PE f# ԑ"MbQnVk̈́Kú-` yP:G- C3H94[R->rf (&D~).24Y)oeOGbNc`TT?@XTSfz ED8Kf]%LfZeE zq0 1dtt1a;߰i:4sc7oa2\ap?<] Ϻq$?9V,o2`%lE""LJ P"ICZv%4}K`7R`a&T% EnC&H%@Ԁ=P39sɿ l#\%Sc .9 e u~!XpebHg|Ǩʼna͍Z~ SG3 /stU7G1cԧM\>pVUR"@Ub,L*.4z'y߀bQY"͆ci$= sH+݇:əzG84 7ltaE޲F2Y vG'lً hݶ] x+ TmFuL La: +ie;w yi+q,WPaUGaL#a$("ۀ ȱu6)uըjs&Mj3x.HE>ǡ{[N(+fH/6un ,!M495\ MQlv*3C+?@͡} [2-S8sL{ F59}]dF8L6PEd[1R(o<(~cH$jίE.Tzx[yۡ0rnNeە;c &q˰3~eվB )7jTHS_KQz[4y#SD&xhu@CLNJ0j3@Ak]$SD8&q廄&wb4cj|"d'EE11Hphaa$Υpp 3 $1P'~h3 #]&[DFg?i{(bVd)Z EZg"Os9\dnJMK>a!E:~1G5sa}8g-13ƀr#UdJXHb XƩ9y+֑ϻ *\SUPX'VX-"D yZ]K`6u1e />3ܾ\W`HvP[33 L$5QWAb˗}x`W*0Mt]T]yBX܊V *t)T(P:ٰ J6 JP ʒZpHc"9g=熈uGIX,7!jmgnl)ѬOn,w40dk"M O7rf8d,ajIy75_9h3sҼPadJ&l5Uyk_R6tWT3p3 #gU2w&lI(<@6ʆJS`J2QX K)N3"bPMSlܯja"rͮ9G(US2bLN Hr.3L^&Ie7u猀7˹v(\S;ې_#Wꓦ#7B ~*-1+$FLSur#nntU7gGa!⾂!DGkL0@ :hbjr_T]WQ6"yՑZtSKd=~<@".~ ~ɛa=\ g72aUTS>KD^< ro pHB/MnF,bI̹!4PAYxj5<(:W @F!4Rtj+Hl{6 }SDV7)8^D,1cgfqm<>,CE֦|;'!7kbS W2WR޿9k(He@C]::Zϵ6RZdVן4?w"J|bjin3$*MIȲ2X4g? 'qR~k*À 26ؠpȺ=bzpHy|lS 1LZmĴ52PvK[umB9|n|&RE> [%N|L9W @'Pݑ369|\?qHQs}W17D 8v@gu+sA( 05Tk2M5zr BUkI)OBcgHO٪R>_WtPggՈQf(eo9N(kǔ1jNrp`7zV4L u뽝<(nKILTYs[bM(@&Rr,0$7ݡx@9=E'b?"y.mE˔C2D(uP)wiN3 Y>Zn+ʰR4G\1SECt`;|:@zaL&L02TiLƱhwkFW5mW:8?T;Z3gFf>%.:!Wa( (tգIbYMv"&(3]/g|H(ǨN%m^Dy uf!Pxȑif,v .0 +plY^PƢ5̢fhYsz=8WBa ;q4|)n.شAFP7|+puɉz\p؄a ɰ|!]sF̞߸?&?x梕/KLA! Z~r̈T1x8vIQ(>VM [2bQ/Cx@Q]ob4cq, t)E 1[_4Hc2]+6FQ.sv4h'eO15 cu4WFm:]B"*\ \ @}QlDJ˅\U!y5Vm# Gl9NxYp'<,P ={z"j'-DL!5y#6.{LlmF1fR85.dcu& rJLϦ~oq#ijwvǦFݰy6;_130'3+,5͜-9RA5DvCLUHh .d>aq>rZbC R; zfs*v0JNdi5O(B'!*zX蛾 s;#$"5:ްaG ϯyB'{0"ȵ&߳/$}XAlun <h 0%@PiJ nڽN88l"$3Oi"=[*ʺ.Dftԯk'[ȇ<σ`f x20Kߤĩt/2R#ҿEdXL9MErpX)Kga&ꌣ|"Ȏ>>;O_;h,Փ0/:Ӈ Asn,Pra =eH'/ tcEU[άLeI)bO5)Z87mS2+CvGqM\ݩɌފZvi!R65XQzwCTЅJ|.nJS*''|6 19U կH#~"c.k{k_=Nþ=Z;1$[lsrRf1XHFc|ĂmiDy–QݣS/n'fqajVcT&oLI.D\XCg;\v}Й86xg7 *B%T :@$jw\z3.5]F`LZl.:0,#= Iڢ_Q ,JA>!8o\ j# $#t9"dgV')vEc9HT{l AmT; .ԁ%UX*L,S)!tí *5,d@<Ɗ qn9uۨDq#eBض4U&rpݑTBqP3 =͙ч}5, ED`N侹7<6¾ 0a&FArtt*p%:]5]1Xw~_/&r1U/yER~K\rld'B<*z N gj*9giGW˦޵\ddz7fp.eʄs?Q_+c- Rs8eZ(Xڜi`P̈́hAv=} !*-%+ !Zm8ѳͿhBAs`QdJYH5.:XJHPXMc=96kfρ^Df{of_u\:bf RMdLNF0> ߉Ÿq#51caNu -eRmZ0̅ ؜ȑ_v(=f &q$9/ń`WQ+ ڰ֜~zM.c44׶1,C$i16 ː"ݫIf2oѴ6CA'b!o+L@uBۧ%-ёJ?5S 2 ̓BNF%v="~IW W@i&M:A'/τ$up~_ƚnW%M&N@ 61 HU3pY0{EߖH 0r(F Y #\puS4- b:)$  i? J&{0M~GFŽ}{2`be֪>T\\0qԚdBv1RpekYbm-7v-y@oBA;+qf6O ׁN7y%frl:p}롟*%n>L!3 *ݓLjh]Ե5Inr@'?:Oy,|3@t L4i-"1yBhoOxP/FnhDNp( '(_ߦ8X"dFLeJr\E^,4҃]͇{tRH0 άqY ~5$ j|EFS2ڞ瑃J$snHg=D{Rm$* kC4Kըa}ꄒtt @Z<KLho i9r7dmu-;aEF_b֢(DH RiXFL:&(/πP{)~2O@Ӟ8eqٯ s' HJtƧ`O& k {$N@bf π_'u)7$EhjV;;<\7Σ3 9P8O>z DT՝9g8dm߇rHhSU6.gBӡ w&&OE0@)@LbTGہɕd@-g..[c:ARtkmD&(H>reTSӧ3fA U@y#i gq]5ZO)28+mk:̳ -PSw,e˲n܅H< ,klAmSD&bh39&B0E uK{I#j$s"۵}'FX9ߑ2P`e!+<A*=T{xb s8DE>Qۣ IT,DdԟVp&ي?mǀI ?@p.moڤ4 k8MlQo0nq$F-3O| /Mn0\}W/;oK@8u'4T$YLP:ބ鳭I?PM :q *?7-m8/5G 0bB ~+]4PH,v:]^>*ˀSw(HId:z2"O R-M)CR :BDUAnQ ddma'S\\IfU@ R2dZd|Y+Ő)iL `'KHP0V4v䝳Q24Z1P*#Rlph ǑB<- &"Y,(0:G6Z̤{:8bLlarh0ާ!͊b(CIiKܻ~#p 'L G( C/0LH(3L[O}pUX:2lܣ2lŒl$5.gƈbesS斣S)MotaӉy8< c;i$Ow&`⿀hz=$*5ŗƂ9F1K'hg[D :{1R.kLHlO1*悽GpbXBb,dAX@3 b3$4\^ b> =!ĠſJ$,PF@O3g.ǾeGEδH:I$,5#, ,,۾@Q?}6GНBHSsujV?_OdU+ETG)?yX6Q<"ŔVY29)JR;sY4ty=R20(8< }oMp ^P`z.JO~?/630ۖi5cΖ䰗wg+s0keپu˷~.!wdz&_v7};nĩ%-0-m{z5o{a\ZFcWL!IWЂXH0R6kzR%m1Q5H-¹'uJ3Pt VuٰO>MYAԃ{o`z27AǾ~P9ヰS/teO$ ĴVNG_s֧\s/<;hfșfP;4&1lͨڹE?I:[y藿yx@68Kq_/b˅m路[9~>_9 Ff,ڣ_~Kۚf+c/$SNX+Nx/_sDMp.٧_{ cn9p#y\]@< rۓm[kdAM<ˉφx!=Dy$4G8I11f.֕@5Od09" uRF V^,{,zEH_ Nے*шzY#ɩ7HWERK0&h<2 E,}1Y`ҕt`|uW=}p.,G2"}ufrNck,wrl odz7~6MoxT3P5 Gen(W2'9?=8ć/|囗 vkQnƍk9Dy;.ӭRxͤɽܥ%yi1 sXPB6b*(wLNC<}3G< 9ciҁ@?@$tv|Lr}S'I4,]h~rמ}䧛*?!";7]W%U{LX_(mt5"#-5N<^+k^5=3*S_ٻpݚΑ8d** ke;O{zQ[ߣl*y|G7?v/9tޙ;Sl50$͌hf \kH3ǛyM {4"t^sId8&lVegpdgolEf^g#KF !#Hݔ;:(iʄhEIA*DʳtF7XT7jd iMuB/X$Dm&d< WQ6P<8}Gv>pnS+r^Q`Iʹ] \Ybcօ:_<$uQ& w驍Edq~sGbq/7ayn?$\g XD6S}\< p  JL154UsHLZkzυ#N?B\V(\2J1k/|^O|~ \˨ROV{ߝo/}:޾x{ vDuGW[?7_ok/f{Ƨw\i)+{ݽr/Gx~7.h׽阫n߹{dux9g!cON?q—*ʬLiI,?7Y1Ozٖ ݗm{߰q{ny9x0uS_r~yc'QV>ˊ?{o>w~싞Ex>j]?K}PS+zu3[ʾ'oYw\O.zk;;_296z'$ɘs^7'sN;u7{ o~WtT%ZR&zl| k\Y$Ŧ :.y|1pۧݍ†S?Ea9hAhF9H "|<5%Չu?ꥇRx7gV͉_^KwqG5[<W |_{ԣ?|Q*XvSpяPW=Kw] 0^i{ŗ:+5%_c.H?7λ7ڊѱg4M߯?fcFJITi79wIo|_2xOW#fClǮyWu+JMf]j]po&?N|WQɓwZu$MT!Z (_4G~>Fd̑.3MwNctRfS}a1VcF;n$e31&T"k)2L9yٌT1'!Y6'WčEjtb2aۄ!l̨HN*NM)TcR%ͽ܇_&xf@laT99 Gyf)ƪ[6n?O/zrǝpW }Rvv&ǥv;P%Y@Y6DUOՎ=gLJ4v=afX7fwz37&ul``$ždu?e bXZweI3`ҽ[z(r vY$n s<>w-o'l2it#<3\EQm-^Hfخ{?5g#6aou[]z_|{nO'0Mk;FBNl|oyu|}~_P,q %e ~ѧOo{ԇ8׽ߙ|׿lǿ/ےDw_e {Y?9맢pWU<Qh|1ϼa/~{n\"ӼP㪿>';=ܳǭ_go?s~qgO0p:%8*X08: RʦVwTFejT&Ll绗3/fyP3ޗb4*i5 ;@Ā<Z {F{;YAYE!z$nm]3QɀW^a=r^ajȏN@ HpJݤX0dv:[˯j¯6++&KerT0P Vu`kT7aUx[g<sS`fn>ç.ܽkq}Q]FPlDio@Hƹd!SKq\Neq]wgHlY;b*@$u .6΍nRAY~n9;."'wO2*a>* kgI~e굳 ] =_>VlR tPi|jO=n:5<?~zkۿRQV$vq[?77g5w-3,@_1eZm>xC}*_̟=jPٻꯏ=wrnv>qDk2މ`CT CuéXS@lTWfveh*]^,ŷgS#9f芮W!ҠBQNaj^>06 "R,ƤXO# L'<*H\l^̨2I CdA[`yE2*](pN'b&{~i3 ֌ɃTrWUX8x:h%*lUF R-v0-fqaLR*@䮯H쐚 ]TP'$;::B){w6ֿ㚛f?vo߸ĺ!١P֔50 U_&M {❟O|3uMMw7 fƔgy'2Qk$$N|΀4ad p7Y9VHa}ЗXeUH-a&+; XɅBo3=~_"FPUEGa$pY3tXE+b%VD+"v9k*r :椓;j0=M=w(+7GO57\ -c ^2j&lPA,/U>FZceY^tyѣ4p~.N 5?'|:ݿ.o?˥mߘzܔ76I4SK~SM킝4Liufcw:_ uv.(,D &Sq 1m NQ0LlQ?k/y}~ju\}~;R >/o|N0$Q~7^F)֛{y7.+t^A{ǃx e.R34F"ٱE5=;wzMw]p]}$`9m}G_˿y#LNe1fɫ9M$\*zf7js@~ v'T7)؍_/ Zi(Ef6.{wbcT syV }կzzxO5{f.C7Dw}{ 聹{?8 J#z~Lf&L5Oy9ip?H76ul |39#'3{K\osuy=k<_kϹxk >zYaC<*Ld`sKU-k#aڏf7 3X V:% Wy~;6/֮'tIk']7yyʿOzӍfqRyc%zu2$2M|{|棞箙8_vsEw)6fcPw=ݽ $l/r@ 0yfZ<23y:惔l  a)A 2s?D10ڶ6N9ĊC3eLVѵ)WQ]ñ{npfWq4u}M 1?Z4/t'6SpS.e(:Jgլ3S<s*Nfad&z(M.%ҶǨ,~hؒԶ)vl4MMW5 ikwkoh7v.b{U_pI6Λ?7}%o?{?٘O}w_bUG{>_+%!ǟ=HH@b FC^s`buK[ף^u{%o<%OIzBT$BT&3ג?)O]guL'I)KfDnϨP$O0= /8ԑW@3?z{ }Pz7,))_izFP.jyQa} ׻)YdNDq5KYCTFUx ~ڶV (" ǼHɤDԃ4*̷%l,)3|z)]o _o8^oIquf(04F6т1۷=L^edVa*(hu o}2!ZlԿ. Y/Kœwk/x7jdDTeZ05W^(tUqqvܽvޝw(Iz|˖fcٷoL]w׮2Uܷ@$NkI*EPM4>!&A|ڠ h vgU>7' !)(DZZrmE?։uz^+@ED (r@ "DHHB&}3{=gXk={>9s{?{g?/yꡚ#Pkğɋ_C8v}_|.~Kkgx[~;Fsj%ep/~ 4;ZSt6ޡ^O9mpĬJ'A[.:onkG[_{Go<|:ۯ;a3:auug3pWfkP ? ~/]ݗ_yy?/|W JXo)0DU0.`w- īC01|2?&ؐS080?9^9 )|F"K?um`YP$_fBZ"."YITֈ](`qz3uz .dڳ%ߑKþ.F٠nUR .+]( C52 qt)6\6~=Sz;~֝l 2v 9>gxu:ԙux; oG>ؽ{9r'>zW?|O-|o0Oo C^c+2\G"vTx­nnzi;6}p.lM[>7?o课ݿ8u{k>3g^pey~կ{>=I$U{Y1[~'>}]GEQz1p_#_:Sw^f+եy׷CZCqk|h@B`딹! UQnlxr ڪ5A ۿ*A`#nݐȸ0r'XpaW?AF׏@{+@1 ̓]:EKrsϠwąqA|UPowZubp#_v!YtnĬ]v h7Ïe]^ZK:8bdhGlRNmBEW<}x{41Ts8s >u *z)}c؞-016۔!ҝǝiЈCԡbmQlS".*a^\=SϼıH_>Q/ܻ]Ŧ}}0t8+qe85V ],'eX$Y&7X49(*1ARTwANXcIb[)}GT'M4_lf"o=%&$W:|_ ]aiio)hT_Rx1bX_T`lMc]Pm ES\7`-CcEORWw_HCşXhl qʀbVu5,\z] mwx_^D)fyW<::q^yM>#/|̏[;?{> ƹF?"|orZ7*` )6&x@5Fm90^g+U;G1&%2rs=b40i*v}YH0j l")`N׃󠕳םhJGRm 67U_,[g.TV@jI}-ڀ..?|ei9 nٌ`1Ru(Gcǎ7!̵uuNؘ0XSN6텛n,aػ k+wJ Lk {M{d{ybTnB\8~V"-%dgf @Ry?Ww\g?q}kO+0kٛo;6}/kŷUt{_uov<1{^a,oAғ^_wמyK-񖈨Fh{?z/]+Wo=G^[_|%k?pxmlэuNⷼ.Tt+kjq |WO(d9">|ׯzag|ߨ=p£Zu!Xf̏_ۮ3Ͽ;7~ŏ~r!y?vޡwy?^p 7C"4 (Ğm?Jm`El+@=ntYB6 GD #=ލ@A!6"2 شЮb͏ւ*+^%lhE`A{1t֢Zc>j$3;K-a`Γ׵Ӆ@kt fׂBW@.Z`Oe- [%lU@j7=kn8y`x %t ol}w =4l3o7_e"bv>}4}q'>ɛ6}pf~.sr p5k9]a.itPחbKՇ9p}9lWs!oU_dܲ.dvb٨ mO _E?]o?I]=ezs7?9tlo;zn8|퓿lKO9~SL#~.{SmׁÕ{_\?S_{?zrvy5poG<|??9zbvqw_}!o{^p\v|`kw=!|BNWya7| /pT*l8o_/~<-GĿ?2A:ADobU~H=1E6,OB^vxcƐ})b,)-ȧD`-u|^w$^)p*P޵G^ЬႁDwAcÞ{2brD J Cs;}z@bak!8]=VL]^::'[w3_1+ǽg 9~K}a;nK>tK>xꚮ#a-o{_>I,w&*Rw~/z;|-G*m__3W?8y>jp}>??qij8˖W< ^!P~J;xyMl{]%?3ۨĐc~GVWdhЧ_o%ዶxשSZ{-S"(z *>De+GMټ7 z) =H;<\Tm=<"V+{ '"ĜNcmȀ0fܡ>8눯tvb@xσ^ً֖`iWjNq_Gހ׼Uɻ>{T;yV"R8EZ1x}yK.lo X{ӿST@%oooɓ{o7OnC70EtqIE/{ ~lYIee N+5p"V|m̱q2筺͓EL<QA` Ld;`Oz^=bs+Rݶiȗg" \.d|[ob \^#J,l_@nH&f OsO] Eb l[nG|09_R4Q$ ,B)t3߶6+ hY\;<#!/Cee5(; `9rNapAN" J1;{[lP{ b]&qYg2!믃JVz槠4XĒ Esc'CF}%<[YPZEsx/ܿW8Ͱgeo {G,-Չ7؍u=TVyvREN˵îy 7'`scy_| 77ùl4 9l0oCP^1#*~bFn;K_αp^]:4?ID&76?fV{\WdI1\\(֛ ~s}rB^2NC uyq4HD 6䤜`P8xMF!>쑷vT0VK㝫S n> -lvbq֛9>ڲĀ<%_©eFBa HAXlIP~{ 3 =;.<6.fK QF1D [b>wo7b;kaeI4fL9O6:J4(Cp^?Ҧ :{zzT=UhW9 qR7DcsvHnA >f͂Jn1N8x챣<`bذL"7("Wz -XAuN ޽D d F!$_)4A}dֵN ?w@X0dK ~(J '}H ζV  fza P۝+eEQ1tg F ސACASܒ1[CIt"p[%">p su822~]枤2XhW[V c+sK,9˰zrsZ+6ɯz=pxHqY^Yn@=|n(:F"|L+.׽O㰺._PaP-)BQ ŭps^GZ3n>P ]P[ml'p*~?\zյ jgPA&v M׽0mἧhy4a [1{0S;!bBˈ e$iiDEf.IǞD#P^sݔuE{wVfQˠhFs%V.8/6G PJ 1 &_%T$XDe'_: /th6KNo+vY("@c02|,?:ebn@+3Pti#rY1Uy~ձ݀u(_{:ݵ坝I’ A7 K1j71.n?[2DnA2`3N|:P#5 m{7ܼxvDpM(Llv t IC]N|N W6O[?}k_'(̶֕(0:ғu-';{m&g,7vXHe,.G%t_!q4wCi<6p?7p3[݋MX:QvrC>QuC`,PJJfD=mzZꖒ-a'>,HibeQX`6L<^-w͔ 18r D cp0a`'D%WFP|612 %\V(8&$5[ q:/8@Qti x+k˷v`B,CLp sȥ?a':2M=i'iӯX]{˩`T +` ֯'mO={a_aP.]`V&@`I9l_#t,A{B.z9DoV9tXC,[H'4=t>C _ӿ~,l; ӧ W=]I5=?=|(ni6SB T4B0M.[v}¶IJ_n`ƀHCi#ȍzvbdICc?UMs@;hHa/=Uts1<@ O-wF:\}S}mgPhL?p|uBG(}aS`-*A­R({P%oR0RӐ/ =XEXENFEN|[ݏ*sD (m؞+? 'UC-Jvz䝱X]zY1A/ګw ?x>b ^ [0Zg~ӳ{O n5yA g̅ԴOXA wj4s1 py;k4ՍTav v8p+`xȖ-^ߠ#0gnQR6&G0Zs9.H4l41Bk0&K@pw`ID!t!tK1_./)7 N? ++fHZs 8t l0ԯvx Op]kb8Z af1ޘHp"6誊 /MتCpS }k['N‘u;OpfA񩿂qX9u?szGZaC!`6cPdδyBbA !BA"vTdPzK'VF9\/́C^;0 =0IBVS:xAl[/2Jq"fW(Qu͘wtQXɉ?C}}pwb;X+;ߨNFQx#v{l9\ɨ'A0+@=:Ēf'm]Sy 89ݰ@g;./>%' >R"0c cw})r/r>q&l5:f6*t߱uXWŋVai_5o+.x4ß~/ /atp׃nrF_?JBQ"@Xnɣv"9ð~d[*qT wljT@XA3V?Ns/ZcFg1Rzb?~O\7IY 3s݅nƈ{W?xatSL91,k/\QwHdItR dPf 6,*K4zn˞at3;_&ÈLga(wA`f=Ů9DgbhmI TH_0U)$Pd019b @v߷n2>swov{uȹ.T9867aD$V1CUPȽ`K>,pO:Z ً@SD~uqh}X4-<\6{nܧO>?/;{FrTtB;9n!|Ohuy}w-u&¯x*\ʡ58sd٭ T unWae+o2X_s/ً"z]r'"/-M>֦pR7."vk2.0AD QЉaCŕzЕ%V)0gPVyvY"Ĝ'Dslr0%suZlvpȼ΢4z|>R(ai@l$BZ[XC /x `/! *Ȱm54T祝TѬŇNbؿ|`wC.x^>V dA`?iH\s8duy?ʾ^L{Ӧs^)qªIـO8.Zֿ of,s-F,`mAނnfMQpEkys\!;GdmXm` paëFl:!?dƾj/Q%`LO7t0Nwwe`XAG%s33(Vfzb $rր h&J_ȕ d3v!E%; ";J|IKj)rN)E>ÊII;r 0rK%$ZR,=rPEJ__{{W`i.58{@"cJVm8vtKp#mkupyU< ڧ4ZXַ{4ιj8/׀YJ85;sK]8Npt [cbǩ~VxG/U{^Q${cYb@HSE-)`Щd7>AJcO`gc-DBXnDަ@seDj<]ZxGkp"SM?8  o/^LXn"|q9 .)f&W'5ńldY en-1?,ۑKHa( &Nn= E ,-<z%R!Wtq9.XzLEg9R0P"^ vL@f&7EA5߀ jYݸKP|% G.qB5 0`i>՛lZrP؊ TqSS<ʻ?G>^X>tAu+ӆ"D)$\$PڂȳıY]qsGMJG m -(<}j D|yl!*T?S3~5f23B˱z"Ej #IdN ?GMRDQZY+HR7c~-&yBuzwzHI]^8լ-H\r@X \ Y@v:81 C~^FFʖ )TXN_%"DbmȡL'ހ - u>rV8^5p܆:ǯ1WѲZ@Q}-BS0\z.‰ l.͒ Qfe Pnk5YAa?-W pk[zlśO  p΅iڏve"@[?rlSaU׃hk 8scftt$ 10<bA0(!)dkOFl*q6 I -LzHs*4Eg0`XQE~s_v-g\dGW0*V @:3p^# ClH\ k9@HfHt@^31`y٘UGnSE!lR.*P ۙ8Q b>a!tq2szx M%kuypԺlwDg;O@܄]-U3̬kzPvڬ yʶ̬C֥>W 8n̪֟߬̚`< k}6GI1):7/ɳYxصSSc7bm,ք{ϭv^ 'L+Qzh"ҖgC掽: +@؄V{k'0;ao" kХ|4F!q!Z|9Dl̋XDtƐXN/G8Vk /SOgקEsJfs<גnT FM0`i 2Wl۳xw}o=gg /rHQ)nRXC({*PE,NCA/=3sP>@lb{螷t3s ɭPH%`B#{N"\KʍS5w.(dTp \59v oVf}mw}p׺!82 9^f.n~ N`,H!j]|Ayr?~8 (,V=9e.+| %C~t} !AB`œ0h9n#N;3X 6ppl*!X")>Pq^{X8R.(}PM&T'QfR4x29,DN01[, ǣ:h]L ˻W_aKg5$``#u68~Z0\buo {16ֵKCHxM?ũL,wÃ"P RanGGX8oGS 17BfЈ1Nfc`F^uD%G'l`Rg{m& Fc"KƵlx ˣdFݍx9Gs~D0v8 G,E@.m]yd - nriG#RJ)a燓N ((0OQ~xg6{#A3"v$;tg`!S%Q$PcyҘ)(N }b !I^(_cbV9 ,삢#.yuk(1=o@*9-42\;n+9L!.+(%A F+`82LG'q>GlxEK;Zֲ vqR'Yok{y t22ĩ?M4O'q1#2:RwQI⪕13W @)}YFAg-L h#d :Wn!=p4 1`C\z)*ުA8mpdH5֬Dl᳴p?9jlĞ^f$"p>8X{9aiO/=>B\Q[A1W&qRa9 W(#6ΆkvF{•eze ,/!>NRK~-A!1@$JHx\,Wq*5m7{l.~Ӧ5|.3`zEe^+k}u_{Z Mf&, ̋l|Ē(. j%dn;N$a=1U?DCȉjbC Q$lOd wA"$0#ME/=ϖvDaH_"u ѯB Q@G<x}y!ȣQ__2' Anغ>Y;yeZ"z( a2B)e{뾖ZV;>zRC z^"aXKLaEm QFshDjgag|.H3(IL6du8ϭ ³ޞRZ5ˁoBЧ/ (-rY\iHI$iHsK4O1燙qrׯ+M,q[%aCꝜ>گZZnwĥhE{$  \AubE= sN*)Ug{> Lu\ʶczaSٖ"EaK)qbF/#Uc,@ϛwe(&}ʐvAy*a֖@#˔4_#ПdXJ>/ؿZ#X X?̞&2:;Ǥb jX1]dINsտr7 U{&zs!D4aE1=4hG%Vo[/Ĩǡ X~Bd];3pkOTχ6H=V N:s95a\^|z~DD]1!gݴɭ7,;znŊQzvJLB!POS@ZbF1rޕP6)#$n%JQ!S']k1tw$KJv` [,4a./|GhM /eDglG؛uҰT+Ϗ2.xjG$lP?2}o(9p+>KG}L}9X}m!fwUL" EjL4p~.?R}>쳤Zs{j&CϗӏIU*A߱c -$rBcgyjr;Ix WpT1RJ`Z&qnL2)7_@sbI-9 2|!H!2!"0ŀx4!x5HEyɆ[$5t- )~SBFZ 8x4nsUf au3bOu|c8P] rcס 9FtcJ~%`GOڬEwT_RQk ǡv3@O@[DאrV‘Z@ *) cԚ.*h4E"%,B(0ԻrcDyp􀡔NyRQeUX$0gcR_cL8Js~t]^a6|Ljex}@,4.a^CK^I+=VnubPJ樛뜱D#$m ]`Y}=-f2ЂoB0쏤nw}L;z<)SE#qAXNEocAFгa"Yw,Y!'Z*i_v5E퐬v0X8q :[ OL"}|}_MpjCD3 5F"#Vwn{DY}WJwYL I 3HӐ0MOb(=2Ņ: \SǺA5׽}KAR y}*MB&X$kJl.P/$CKN1fO(-[LP8^LbS}ny. J/3-2xhP?QZ$GaR&9.wڢ$.;뱼=| H!g!N:UrqO|QjuJh>_LeuE%6RZ #m R|=Ik-&Ci8zn`y![(:éV& ;f !ia^Ѩ3]pR澞+me&9$W(ysGW4K!H8`pK0o8 qa a09B%{ؚ2,ef,ol l%}r^$35!Z >) 1a^Δ\mπ^ļ}wl9`!:@饋s!. ) Ԑ鑍EDgF 0Ias%?=Rc3bxgq@O=84@`pheF%6Ӛ`^b*dulAHIraZ5igۋjݰWQKƅ+HaI^Dy]WŲ-@8`=A\Ø\cBw_c1G[JLyȺ>a)-}rCe$R^͌;øY$Ѐ$!MFC>VR,G1Bm8e[g5O?|D}L_fY]&qfBmY^hu:h܆h4 au01/{ǃ*ĉ`s,&\g/`InX8؁L I?Rվ%` ]G[qI¹gV6Ҳ)9W&1%2s_6 vy훲USy6RmtJ$;5F؎{2*tXBt?hSt NIwwgr-xq#vS\L^]if]B`Ib(`d]AM M/~4i$?wĔj^b ҭby$| .B֭E3joBF89Je^Rx`d| 7 sZ%)\D72w^jزB ~3z ؤ)E3Rъ)8F/ߨK vZ_bIؐ+QޔՃ- tK5kgѝu: aHl8psJ*'P?儬I]}KKBR-.WydbTojH+m|瓇umŢo0wnX7e']]%uf)8#ʐ̓, uODvN`Mg&%$6so5 tyDep؋yTÐbH-Gr4 8Le.sL,@gZ-.߾Xw+5 1- 4)oUڒTojH5J;f'9 3n MbXD[~ وT#k|&a vn=0DDɖkgEDj:85@WI (^D632 /z4MY|߲48-\,g)Ă1جgD>=.ǒ" s}^$Qͺ>;BNl3S c8J pQ6adtB'asHLpQ9]/^=?;;T&]PvZ,5tCXDZ5Z=1A6:-_h}])+]p_|֒!OAaY'~K)}CDN|’-"yAf̎w;)lWly!rfg{0F `3M!,NT5OHcmzUaE5 cJ6E̽~b9E̦Rubc|Ck5rg\M$Bi2dZ2e ]2I HY9F$6Jj%-OH "|Y =ÀA Y@}Kn4ہ* Mf4*sӉ_A^Q15l n$vpE(h;^p[)!ta܎~FVP4~8/t xYQll eY\枺3{,0)PU_{wх3',l^jf g|b#d <fY1&|2M7d&13HU0,FVrږ8.H0!EZbpLm `=ҋ[= %x3|Ed:/-xBV 'ҳe(eTJir'OBPG2]mnޮU6`B -p^*0IhhZ8)@ڬ<8P#uh n)ℂ]8죰&:8hN7.$fG\d.RBrk4kx+ԅ`wV ;mIan9anYXz$%SqӍe@"UI^q^Ik-s9J$Ndg&H2N35\x=-C)6`c;0'xgOkGȭaXJ炙/77R\G{:!Qr[G&b6Ɠk/r v{J{BLkl C+< 7E3 >ВS<mOl(73r*Can;|F X"V*X zyЛFm_R =Gdi G WsB'Nޗ(ޒW"IC~/͑|e]n%)b Dl^z_vn&/^H2s:? @6뼥ji*' n7an˳s.8( >*A5isґ'>.)KR$aeBHd\ٕs" p-`%.3~lZ" pe;J8W"/sN6ǁ Kb7܎Zܑ°.gיKXt t d~?EHHM:'&1U Qoƹdu3\6w8mj vpt&Xl+Ņ 3f/ Z 3E+q)MboR|.\ /߿`R$vz;E5S22ŅU+9|݈Kl","cz@^8HVAs-@98#|D6;s*Nv^ӏ$wtJ v^LC> Cq!CL6Wv(`9TiL-+>-\-rѝaS`wp0Z j}g;MG+X IR{ڙU%9۟G^1OA]3jF"W<Ӡ]H ]z܁ n6_X}Q;f>Mg4$7l0kbRiK"PUUݢ;w R~@" |MDy+X((P7^k,r9#۳ MCbچfNhzD"m` I&S&" MM0P=8 A~}{N$W.p ^SM5U?3B}^jŵoK;6obَfG5 vk;|%9yte+d6^|<Y6!gGL.mb2xpWyʖ hXh2ϱv|Ş4MhY, 6%كXo,{@r70ڹlAq+e0{(D9Fv8Ywi|`][^H0x@ 6{Ѷ9b72("h+|^ciD_H, I 1qq4HE--\(>2'hSuMb|@2cG&hCHiNh`/-~d7ǔF5 X[H>@oŠi+[=a"\3`А\e>bŻv\ j0 X'?AX,"qR&nw v9[ٽ}aRGdV g S%㦵7^̾fk(eQ#dH )x3MPů0cGڊjlTAeDA)#XK ӔX2(;xm51^ Z>8c ha,$8MˊPV*B- e0A1YQ"8e vm^$γӢ$A?ƏjGGbG)5۽o\\*zq[.ym\_\k#Qdn ]>\A"'" bQ,&x!L.H̹n@q\I"+# ʀʁ)098s2J[50yNÖQD?]' H{{-?F"9؁zRȭ%.,}an;ŀ;?;$HɾՔB|{Y4e$Gp_?zm fΦ~zC&ž"`|0sA?й톛- ِl?Yk_l qysSژ\Z/D" =mjnDBPQ͊%gJ'^!:EEژn/*ǰsK 2&!*=2*6񂮑grlC7v{t/a])A+I3FNs0iyzj^.@53C2@ajÄc(IN.bJڲ)G[e3OC;wAbh<[y(%.ܺhIaj("k<E{z><@+xDӮ)OiOL<8IA$>Zy@kvق(`rNjsj h]tt{6P3ѳC"}'TT%`2S1j-.0ongh),ᤊfY@8 I8w$NeDpǶWkr(#,,4NsC4ފE2tS0|) 켦*gX-fPLE%(L[
    /d:( <:np3D|Ғ-FBJ:0&DƁ_or;! "2-J/|)U;Sj5*Q6@htqhecē 1A$6cBAq,&&.H<|NsPnrNjY8d/it"Jj-җd7)} l9.^"@"5~4/fjg(dKQ4=``1rLYe0,TR;2c 㺥#[lL 8X&A6v6r,VDYE0 r!qXr䠑J"N8.H4AF??<4h^h-el6ԮZWH2n|,Rt_uZGJ8WP4`?qh:pd6q^@9`[%{Eȿb۴1Nڝ5= : 2ȑhc[F"T{i<ȣ6γHF=ژ52$q !^QqsTvy rm'z2_deDk\#e=u_L;s)鹉_J޺m&D1YܜS61L̹jv&c*;^z>='?\ @5(>ɕ0#Jv>.70pnby OJI aÃDPiBplD |wo3n(0m gBA2Te3 tp 6rv~ "b]8>F4}3;K f 'TGD Z=?BڑT)3ڦө1-,\Cu&3<l#u sS#K7-dGE,{;MgP$}2 J" {.L#D}Sb'_DRDXATF&d<-l[ Rmr?MZp 4k j 3x} r9gǦM#i8L-t~xR8ghNYb:*c7v_0PVR,EӬjfz䨬 ;Wb0FaLeW{."NE"$ bb0vV!hY$JFU涸?[F{nXC4ʹ5q.g  SN-yY Agل_!8L.%K E 2= (Jd& ]d 7|Rm@Ѻ5=`l.Ki%WN"rְzAM7Udž!E9O'RO Ĭ"8 `Z8[ CSMܢ&%N1䁡62sSlFt"*Z67w/y(qUr^Th LFN5?f@E 9D DS7dY?K(* vvX|XsΔ$ˑ S`yA#K(3gCeßan1pDer9$ "Q[n%T*`NGZpbr욥sD`(p/{b _cA%#-UIY41=9(. wkV( ꢮd 34;wf`J 6;?Xd+' CȓD0DƋL {ƔQ$5N 3FPg}J xvqU!fHH*T/Sߗ9H7I4C hڔbR`PFt!~*fK^#\+LvA`lEG8&mS\t6u@Y/Zآޏ~t*K Xƕ;ӄO +lO6"[ѡjaY@ʌӚ݌ d\NA{(my -Z9(LUNXÕ) j-Pb _ S,@Tڋ)d?Q58.HiAە(~r^y eRXb,E "PCJ)LI31?:Se' 1Ph R@ !?9 XtBH#)(l+cD! Ymgc *)IJNd -,^&shrN.f'91nϥR Nu fy'B1i1Sy=&Q$ I 0=Ә 0DOldK@QƄȳ%al"0ƜTOP#'CA`C174o*(.9#г1Bٖ|OC{b⸻ q^񋑗Wā錭EM\3Hd~)05g(W63}/!I^$8XДdXV`LjQ4 ˯zt8_tfHR(aQc#F2\*-=\ uLӚ!Af/ &{ SP  5Ч/+e6'm yg1gA# 1_@y- 5#1, 5l+ Zs a@Qd˟d#[imH[6(F"@XΡNY{!(F9q;E2T)8MC#8D `1ѺdB$`w@L]8C'}*։3\@8Ok CW|DGs7ivn߲'2EkzmhŶO^)(BadpEGQf@S̘`s4-bHّ,J ) ZcH:~X&4)L2r0DE9!Q\*@XTXmbQ5&0󀘿LeL3T6<€ Ǐ: b*V}ed~O*{Kǐ # iF1%X&%(-1R}f"d @p"PX N*2hۧňxY``p r H aIfL`/j읈a3Upea|6WqY.lr)I87lwA"%@o4ى3iG܎(DR02%#^QgvqvH3t,P8OFn)d>/E(11 {}^* z lϚZt=. У %lW 8b܆ v Ti cb -Iph=%l`DC!9b]F1T?ډ;[ )y`,XX(q.giC]?2Qnb @%K={-?14[DK8`ed#'1bv#Xx)3UȆ6*:du{$F ؟XvQ!pD#G_b⦀(Kh=a2U6 M\$.HE<8; QNBw "D:+1I m@4$DOh{J`n0 Zb#Nv egqd,q?z~jQpp,0%buQЕIE/,jo0wb~έb&4ohc8l8-0Ys9lNwAY/-0y<ϸ旼$@Cn0 >3D̗a"^ׁ30ӑ̊ı1|j6jg݁-K4WŌB?M28& (N VP0s)pX2@|,TmXɰ(YsD4P)/fT>Xx秓vIENDB`kylin-video/src/res/next_normal.png0000664000175000017500000003636313214347337016370 0ustar fengfengPNG  IHDRp n pHYs  9iTXtXML:com.adobe.xmp xmp.did:24776fe3-5e39-7846-8bf7-7165f60dca4a xmp.did:D16B8C17524511E7918BD55A48746BA2 xmp.iid:b0a3a9f8-6807-fb46-977a-34b6ba3cc8fb xmp.iid:2a7af3b8-43b0-6745-a0f2-048f0ea0e907 adobe:docid:photoshop:772c815a-4f1d-11e7-a29c-ee28c792f004 saved xmp.iid:b0a3a9f8-6807-fb46-977a-34b6ba3cc8fb 2017-06-16T12:25:13+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-06-16T11:42:27+08:00 2017-06-16T12:25:13+08:00 2017-06-16T12:25:13+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 24 24 g- cHRMz%u0`:o_FIDATxb? 0000466 000D2bAQȈb?CccsM $` E0 #z(lΫ0T&I+T4& 쾈/Fpq_ $_n$ضDSFn:/58Z: P=3x`d,K䞠0^B0KHY^`x0-l?4{{q@Wc&/WDrm5H}7w-QC]OEX;[Si8S ַ*uU}րjBnw1p^@=v6&0^zQ| p讀o4"uxn>p2zgFID<϶lIENDB`kylin-video/src/res/option.png0000664000175000017500000000301213214347337015333 0ustar fengfengPNG  IHDRl$jZtEXtSoftwareAdobe ImageReadyqe<niTXtXML:com.adobe.xmp 62IDATxb?:>̀"x; 5L dd >?h$ %xj FAlDI6]0&&l I*Ĉ-J5DL2|bDB:\ -Ѥ8G=6Vv">RZ[:XG"R [{ /X84^>)#E 6$It>~)JD<6h#xI5Qk)0CxD0De @N{ܚtBՄT_bQ0 ذ'U]Fv˶{ye[LWd2ث5qt5~2{_+sm]xbmV<1Øa0f3Fp 00Rgقפ{IENDB`kylin-video/src/res/fullscreen_normal.png0000664000175000017500000000247113214347337017545 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp 3KIDATxb? s@1(khhU@566g@,HZe`~Hh~.g!@!@1\A[qhfʃ4N%Oz< G@ bθX 9He3œrP3M  )h,a6d+>|`Nb!` p)3dY 7ȹ ?(JwT+(60m$ QhPG-:@h"sr.$zͅP i$!FܛAIENDB`kylin-video/src/res/radiobutton_unchecked.png0000664000175000017500000000243413214347337020375 0ustar fengfengPNG  IHDRhOGtEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp L^ V.A= CvX >f$qm r$iCHr I1Ph@C2X_+ PWOP|*@@MQ nP (΅+a b?hPj4j9 L!Ac;(`i (ҡ09K А=(__@f,,TT?f,pnIENDB`kylin-video/src/res/playlist_delete_button.png0000664000175000017500000000537213214347337020614 0ustar fengfengPNG  IHDR Vu\ pHYs   MiCCPPhotoshop ICC profilexڝSwX>eVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/%ҟ3 cHRMz%u0`:o_F'IDATxb?)D05@IC8XHIENDB`kylin-video/src/res/quit_hover_press.png0000664000175000017500000000206413214347337017432 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp IDATxb?01@b  01«b> 2F 0@L8ہM$DH|?%`@alo0rp0#* "ࡈlC3& "YAM&IENDB`kylin-video/src/res/open_window_hover_press.png0000664000175000017500000000205713214347337021002 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp YIDATxb?01@}bDa  01"? `)!iLt@s Bd`b 0 H2Qج`g@ b=A)_bAr3+bc$O0(rpb$2/ IENDB`kylin-video/src/res/close_hover.png0000664000175000017500000000262713214347337016346 0ustar fengfengPNG  IHDR$$e?YtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp TIDATxb5w.`b@Po>#yL8M F4s>9]D})Ȉc̎X%C`ȱ\ x? GJ`? bmcga{{GnP3(Έ&Ϗl3Ղ|mDNt3בdi{Ǒ-mwWf W%Vȝ3:K3~VQy~= ~털̦D@6Ś. mFV&66&:hb#.,E DA+0AsPRLˀEɿ7o%X *& Xcggfb?֐g@["?WK*[O++xXX"x"ׂ%ȨeC2;9;IENDB`kylin-video/src/res/quit_normal.png0000664000175000017500000000030413214347337016356 0ustar fengfengPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<fIDATxb`00O (WO B0 a a`\y/*@jvr\T04d6T Dd&J@f%]2SIENDB`kylin-video/src/res/backoff_10_seconds_hover_press.png0000664000175000017500000000345113214347337022062 0ustar fengfengPNG  IHDR tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp E;IDATxb x.s~arCiF& &z F@ Hz3 le a bfM(m ST TU@ s tcN*Eq8Jb/ f @,נƢ1` @ a :,M##Ի&A! ߲ i E`j@T5jOt'5a1Ami g!$^r65ہcR C01!7Pt*04f! si1 Z$ ЃA84A&` PIF4X"l#+id&%aGX"ƽ@M0 gWR52@"K#4= nESwFXJ{?E UX2PS\SJYZǧAlVjA\b65U*+uZ3ؙw* [KgXqfXgOpacou$^<†܆~y= |$D=d ji]y3BC$jCU%|8K>ߒ qMH1N dR?]˱ۤ3S&Jc|%}pE~eu^vU4KvH2>a`Y9 S:g!tUC}`^ XY >CSʀ7Tz2I^ΟmmVP n6؅V]s-IENDB`kylin-video/src/res/volume_high_normal.png0000664000175000017500000000075613214347337017715 0ustar fengfengPNG  IHDRw=tEXtSoftwareAdobe ImageReadyqe<IDATxڴVq0 _`&ht!N@2Aݠl@Q?Tw:޳dI& u]y%m?sʱ1 y#r<-4InRNZQ?[$^[jҭ@~84_pO/d/8K}/7f_IS+(,# 3Q.Ц* Ι+FX;"H2i/H d2:3 GCn kقYB 6\Wl9ṬZ##q݊\0l s{K.0H{W惁4Nбjߓ!s\zS+g"F`ȋR%=2Dh|=8GTwVٞ7SO?dPqGɴ 1IENDB`kylin-video/src/res/forward_10_seconds_normal.png0000664000175000017500000000314313214347337021062 0ustar fengfengPNG  IHDR tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp uIDATxbj fa` p] !|`@|f~ ?TEKE;gb@@r @1 \-0{YlL, @u4 Yg+!@` nt1  j(#d46PqV"F# ) !O%@ NAQ Ѽ/E @38(0 g|04XİFo >b(XA O41 a&yc(^PBxq.Yb~P\ E؜K,*. 8CL3ԉ݃:#:Sab,p@ 5ހ78L `0g]GO8Bb?Rba!1ꈶPOH PG0 f nE[G]3:^r,d@+NOC|0r-.Z#b b> ~ϠYV>a] VCv̈́x U3>.{CQIP*4IIb@*:P ZHj>jHYhq!';h~FnS,Xux1~R]C\IENDB`kylin-video/src/res/single_cycle_normal.png0000664000175000017500000003521513214347337020045 0ustar fengfengPNG  IHDRw= pHYs  8$iTXtXML:com.adobe.xmp Adobe Photoshop CC 2017 (Windows) 2017-06-16T12:10:05+08:00 2017-06-19T09:09:50+08:00 2017-06-19T09:09:50+08:00 image/png 3 xmp.iid:1edaa08e-0eb0-ac4c-b6df-58b735adbacf xmp.did:1edaa08e-0eb0-ac4c-b6df-58b735adbacf xmp.did:1edaa08e-0eb0-ac4c-b6df-58b735adbacf created xmp.iid:1edaa08e-0eb0-ac4c-b6df-58b735adbacf 2017-06-16T12:10:05+08:00 Adobe Photoshop CC 2017 (Windows) 1 720000/10000 720000/10000 2 65535 24 24 - cHRMz%u0`:o_FIDATxڴ1KcAQAF,zl bNdAZ,lld[%ͲU၅css0(idf9=cem3q٣@C9p:ګI,Z֎%X?{LFdZ=F0>R%,UuT " l].̗s ?OnH޾?9`^zqh=^1"5߇W?8}%"wČ~?"#"]/^~oJ \E%k UtS{>,5Y*h]w<s2T}W1K-C{~n"5W-f)#rrCΧE.7&>h~#AS1K #"W^$"E7J1}7m9 &)Q+X tӀIےf}p\vƌ~G7.Bv=Eb ʋdg m*$f[֗L?IENDB`kylin-video/src/res/prefs.png0000664000175000017500000000267213214347337015155 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp ՜IDATxb?01@@1466N f##"ҵ Y  @p=07 "D3rpp=@,Р 2E%f # T=3P.L_( eW<=`W@ .bY"As  |:`H]@ 4z3PHA  ȥ@+@@t @A@%y H=NPh~H/ibO  04u] *1 .@@ـb[ qt=GC?v ď`~C@< % <Ӡj& {襥Ha*U @* q K1IDATxb? 01 8{7bĪ (#$%WX.EXmbN,PT*Th)_߃t!c ,&.ER c ❸O9P+} ݇?.ڍIK K _~ @z @`bD^(X7UI7/:) . @,'8w1O1&pa%D8ii"{a=AifX>G(>8Obl} bX4_@8Xs.'!c#9- k4p C?;+C38(=oLPİE@%ǵdX,Òȵy@JKa9e}, V<%2Lx [A9^'̂ɠAn "v5A%@ h]a) k>) T 1HQ @RAp}L@\x))oIENDB`kylin-video/src/res/previous_hover_press.png0000664000175000017500000003647013214347337020334 0ustar fengfengPNG  IHDRp n pHYs  9iTXtXML:com.adobe.xmp xmp.did:24776fe3-5e39-7846-8bf7-7165f60dca4a xmp.did:A160CEA9524511E7A7EA93AB15BEB749 xmp.iid:544bb771-b22d-a94d-bc34-a7c410cc4683 xmp.iid:2a7af3b8-43b0-6745-a0f2-048f0ea0e907 adobe:docid:photoshop:772c815a-4f1d-11e7-a29c-ee28c792f004 saved xmp.iid:544bb771-b22d-a94d-bc34-a7c410cc4683 2017-06-16T12:25:32+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-06-16T11:40:31+08:00 2017-06-16T12:25:32+08:00 2017-06-16T12:25:32+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 24 24 cHRMz%u0`:o_FIDATxb? 0000p/vA*0bAQƽ.$b?LC C0 1dc|{l͡ 0SpL` D2҉p Jڀ8<>l[jBAÜyE:>D…*B :Pc``5{75,8>*/[ X`k/ln=0=.7;J 300lf``:.+l`-L1 \a06Q:i(zHV4AHIp&$h]Gؚb/ Z[ fI`;̝jvUI!oU\ )j!#j?Tjc3 )"l,;G\ׅ_3w k\W*R C'B}ոMu#wmlC{aY0?͢џ`L-E 1)L1-`Q &X w6{|bG?TB=OTdshX αz\\W%0;̠3Y *IIDATxb?01@@1b\@VAX 0 6zI(G5SQ3*BQIENDB`kylin-video/src/res/min_normal.png0000664000175000017500000000216213214347337016163 0ustar fengfengPNG  IHDR$$tEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp ?IDATxb?:`b( Ftj#,@\Osh ""*0f4<d$ f9jАI,6 0guШF4Q:hA4pw^2IENDB`kylin-video/src/res/max.png0000664000175000017500000000273113214347337014617 0ustar fengfengPNG  IHDRl$jZtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp 蛐pIDATxb?:>̀"x; 5L d??EF^954Ĉ8-p(kbTyĈ-J5DZj p!0F,ZJ j#I}%|F(eG.2gT/AhXIH3%€w}OdKU1B t @Dejb1@L0Bq&1 *P [Zx G@hRبF=FQ'N7)=Gbڅx?5Z5m {Լc[TqTU nhبdžЮP EͅX߼")3b/ ģy }5 ƂB޹g7>ؙ (nİ3F k1\Eou*ܭ>I7a!J xmp.did:24776fe3-5e39-7846-8bf7-7165f60dca4a xmp.did:BE419F56524511E7A191DF328D946EBD xmp.iid:6d1e5c5d-0826-2544-86f0-1df23726026c xmp.iid:2a7af3b8-43b0-6745-a0f2-048f0ea0e907 adobe:docid:photoshop:772c815a-4f1d-11e7-a29c-ee28c792f004 saved xmp.iid:6d1e5c5d-0826-2544-86f0-1df23726026c 2017-06-16T12:25:26+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-06-16T11:41:55+08:00 2017-06-16T12:25:26+08:00 2017-06-16T12:25:26+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 24 24 uR cHRMz%u0`:o_FIDATxb? 0000022"80bAQS b?,VUDIBECC%'%b?Ccc"@}}=#$tЀjJ] Diwxm 'X>S🎡4ȴ􁈴"9-hS```Hs3b ,1Hy,Z0jA #aZyKB[DyIENDB`kylin-video/src/res/play_hover_press.png0000664000175000017500000000404113214347337017412 0ustar fengfengPNG  IHDR==ieQtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp >͎3IDATxb9À01( ~fP௲%/:)Vmjz˷V 67?)@1R7R__T "h@ߺ0E.*?l Y^iD6l" (Ӏ9}j^,˯^-_PÕ:g4d?Yi'ۧZLϯɓL@IZZNa5ށ8 /0[o ɲlgUrfdzݐ󟜭Who9JWxQ?+3WyXAZh[ԁG6tj<}nhsiЀ9ӈ QG-<`ל3E~@зF ,ta3鷎F2D隸Xw5{~oOT2sWvp5;*}YwgRŻ4蚏˶,? u㝅Z=WB?iJ\e{(b(٣O\"h)GN!R}tw%7XHOp^meZ'vmxr6]foI ~c 📟2EkWӬLʀ6J9YyWJI``dbd0FﰜqxL ];eI ~IDATxb? F Y 9` EP ! XU#.`s ŌP (:`@:͈*@ !n. >4 90`FcjZfĦD@m@OG t7A'P"w'Nx*%Jؒ 4сp b<8 ncIDATxb D?@1L Bf@@`E @,$ 90 @F>*D1 iI@AlIbbg\IENDB`kylin-video/src/res/delete_hover_press.png0000664000175000017500000010155013214347337017712 0ustar fengfengPNG  IHDR Vu\ pHYs  iTXtXML:com.adobe.xmp Adobe Photoshop CC 2014 (Windows) 2014-12-03T16:31:02+08:00 2014-12-03T16:31:31+08:00 2014-12-03T16:31:31+08:00 image/png 3 069505EF8348FA35AF3BB18BDB09ADFE 07806C65C4910A3DBED1594FDEF99235 0F9DB8F9B3C645EFF27E01C60D3F3432 241ED29BCF42C6B6BBA88600B23F125B 24C1BE3A34E81603B62E933DF8A45E04 257C7629B7F41750316EA19492C65422 298AE66CDDA0676D497FD662CC46E789 2CD3E2E172E32A23791A7458751FD50E 2D49CC94BB3723FCCC22EFB712EAB720 2FBE92DEC98BA5F0C3F3E23C7078B780 33743A05C6E6532EC0B1712581186ECE 358206C7573FC1FFE4A5F9E5999CB595 36760943676D0FFBABD1E11760C9009F 371C9251ADA2EF74EA8EAD34A8EAB242 3B333EB24BC8F5E19741BB267FEC98B4 3B6D44491F9DED4B94BD58F461F37FCB 3F5BC49E27AF78CC3190A749F65E0163 4ABB7175DE4B07BAF86A23279167654A 4BD5C758D3D06A39CBBACFC3CFA34792 4F466871FA7C5D2CBC9EE072C5CA5864 4F89C5CF4A3F2D476B60E939171F684D 504D76B74938B491EB6B067232EFFC41 51BD2AB38F4023E650CC00937FFDE48A 52F09DE3C1E8ACF272BD84B37AB1D87E 53E36C31D071914B7BE4C4F5796F9389 604350187D18A4970E7FC597D2F0A5AA 63087EAEBFC92B4F0A9CEDA020A7618D 6ACCB24275BD1BE78022AE063DA6073E 6EA6F2C20DDFA1CF96272D4DAB888B87 71C29B0895D1963EB7FE853A2CFA684A 73E907B19D895C7623D27D2384D97040 7C3AA90B8556B64CBE9D28EFC5F978D2 7FF4250D27CC1031E2530119C3171AB8 88451B5338AC1BDA3ACE7DA4E8058E11 890B1F3B327CCABD3C7034B167F38F5F 8C3CF085C262AE25F4A0A42D59BDD57A 8E912E694DCD59363B3F4B31DB3BCD35 9127D7520084DF27C836C2028CEB6E44 9BE9A189A40C66D2863CDDA550550285 9E72C6CB84A74DBB76AB0A27FE93F368 A067B8957FADDAD37CC313943DF049D6 A206FA618FBDF04BACAF0165D9621212 A473C2C9FF48C81F2852D3DD7167502B A907F48C2F43385ADC26A7530309EBB0 C237A0DA372A9D9CA8CC8B54B87ADA51 C271AA80C12C938D99C5A935933349F0 C526A4954A8EFB9C3D650E6E0277CCA8 CCEB9531E6B9A8923D10D2CF94B8EFC0 D2A51371CBD3BEF0EB2CA7A3C5B28A7F DB642544BD4335E4970EA86F0215C79F E6AF6CCA6224B98996A12A8A5B81E43E EBB4992A8B3645C35422D58834E532D7 ECE9EE73C1DF76FEE75B006943E411E3 ECFD9E473C1FCA3768337BECF00FD5D2 EE5F6B13980FB69B75DDE567C488B979 EE7580CAA349FD7D681D43075D5A0967 EF70ED6A534AA45A720426BE6A2F997D F590D937E6DD9183BDD272A16DFAC4DE F66863DA2FF0DCC3F1EF5ACA0E1BDE64 F757401DAC87D729C6522CD005D58C01 FDD4CDCD34A4D21D62D693E67B508FF8 adobe:docid:photoshop:042ec86a-52dd-11dc-bb7f-87d1a9f02b07 adobe:docid:photoshop:12edae61-fad8-11dc-a186-e0f9726909ef adobe:docid:photoshop:13ee9aa4-2aef-11dd-8d81-f27eb6d1002b adobe:docid:photoshop:24787f49-1441-11de-9fe4-bb120c50ae92 adobe:docid:photoshop:283bf7e9-2771-11de-a5f7-e5f9c0721d92 adobe:docid:photoshop:3c04fd19-7ab7-11e4-9582-b77f12e67c36 adobe:docid:photoshop:56e07c61-8f58-11dc-b747-dea064cdda7e adobe:docid:photoshop:5bb25fcb-00d5-11dc-8160-fe3baaea4664 adobe:docid:photoshop:6cc72dd4-c122-11da-9ea0-b410217bc604 adobe:docid:photoshop:74161145-7472-11e4-8b3f-d51ff019451e adobe:docid:photoshop:8b1a6435-1e48-11dc-a2d3-f7dac7540843 adobe:docid:photoshop:9d010613-7a9b-11e4-9582-b77f12e67c36 adobe:docid:photoshop:a8c0d594-1c60-11d8-a6cb-cdfe702634db adobe:docid:photoshop:ac3d7b75-e2d1-11de-9b84-fe9a494e706c adobe:docid:photoshop:bf1b42ff-0880-11d7-8913-9a827c8293a3 uuid:029F5456D042DD11AD43D811C1D79D3C uuid:19501508E2EF11DD8BECCB6B4552BEA7 uuid:240F7696E09BDF118943EC7D2E89C0BA uuid:32EB3BAD51E2DC118B9A98C8A0DD8215 uuid:32FF073A8473DE119FF6A9CB3A0D71C3 uuid:40B56E81A826DE11A84EB468E816AF14 uuid:483C8D6A09AEDD119ACB862DDB389351 uuid:4E28CD0BE5B0DE11ACB3A4B3E9D809A9 uuid:57D4D63C0537E011A635EBE38230B841 uuid:5B63012BB648DC11BFB9A185CAE90DF0 uuid:5D0DD3FDB305DF118437EB3D37DD64AD uuid:5D7B3DE51812DF119185DEA6EC2AA3B4 uuid:5EBC258199EAE11189C2DA1478C8C9F2 uuid:6638BA84298FDC119AC3F8EEB4E2F957 uuid:72BAB42AB8F511DBA0B48960EE8E18AC uuid:8418B9F71B19DE11ACD1FD0D79D1C48C uuid:90ADF7D5398A11DF86119436A17CB227 uuid:926b359d-9e47-431d-8750-bf845c6577cd uuid:A9F65486BA09DB11A9D28E7F7AED63E9 uuid:B540613DD2F2DE11B3B3E6BCC2B65928 uuid:B850031313CDDD119358D3EBF934974E uuid:B8D9606773E5DE119A42B7888D73246C uuid:D3A7CD576D58DE1193F18641FDF63895 uuid:D67DE9CEB841DC11A4C59F1431608251 uuid:D840B8FF2B1DDF118724A858B8454A8C uuid:DA1984435469DE11B944F4166779DEBA uuid:DC91D24E8353DE119534A3EB376DEA2D uuid:F4297B0AD6A7E0119054AEDAB6503153 xmp.did:01801174072068118F62EB2ADE46D273 xmp.did:01801174072068119109F305646EB57D xmp.did:018011740720681197A5DAF2583A0A4B xmp.did:0180117407206811A084BF28FE3D9E61 xmp.did:0180117407206811AB08E8E8EE3F0289 xmp.did:0180117407206811B2F4B2F0A10807CB xmp.did:0180117407206811BF9BEF79D798C243 xmp.did:02801174072068118A6DE8CC51352B1F xmp.did:02801174072068119109C65A70401340 xmp.did:03801174072068118A6DD9F43BB7607D xmp.did:038011740720681192B0DD1EFA0D88E6 xmp.did:038011740720681197A5AC1352A6FF54 xmp.did:048011740720681192B0EA0E866BB245 xmp.did:0580117407206811871FDCFA14F2CA87 xmp.did:05801174072068118F62AAC437B0569A xmp.did:058011740720681192B0B61BEB8C9F01 xmp.did:0580117407206811B2F4B2F0A10807CB xmp.did:068011740720681192B0E5094E035523 xmp.did:075DA6E20346E011A104DBD60A09BA11 xmp.did:0796F2FF2720681192B0C5B632F0693B xmp.did:0C6F3843B4FBE11188B1E8BDD53D90A9 xmp.did:0D74CB50B52AE111BCE2DE904F7749CA xmp.did:1354FDEAAC82E111BD62DB4BA1684708 xmp.did:135DA95E51C3E2119485CD76840DA0EC xmp.did:1368CA0A960BE311AE4682675B3E9A53 xmp.did:139A55462279E011B7C7BB0FA8A40C9E xmp.did:1568CA0A960BE311AE4682675B3E9A53 xmp.did:1B23937A3BA3E111A268C964C1959643 xmp.did:1B4CBCBCC095E01189CBD2A609D6972A xmp.did:1BFAE6F7A693E311AB2FAB742EAEDB5A xmp.did:1C8D9B97EDBADF119C55BA856872B7D0 xmp.did:1CC9394224F1E111B9ABE35673A80283 xmp.did:1D13CF493192E311AB2FAB742EAEDB5A xmp.did:23A33346BFA5E311A033D41CADCA8C69 xmp.did:26BFE5D14170DF11B28DA0B9164D66BE xmp.did:26CABB49C55BE2118543DC3ABC338EA4 xmp.did:2ACF258E325DE011A1A5CBD15F1C5D8A xmp.did:2C850DB82F4FE1118594EC5F608593F5 xmp.did:306C746ED2F7E111BD53CF94664BEBEA xmp.did:32013191-910b-f740-8ee4-e119302ccc18 xmp.did:333B092E0D68E1119633ACFF4D03496F xmp.did:375A0B3A38BDE211A0C7EEE8095E5998 xmp.did:3921327295FCE0119420D55B9D0DF2C6 xmp.did:3D21327295FCE0119420D55B9D0DF2C6 xmp.did:3EC156D08B26E311BD3FFBB138CA7E52 xmp.did:3EFA54B0F40FE111AA83ECCF63439026 xmp.did:40B5B13CC0D4E211A0F8A40ED08A7AE6 xmp.did:42D823653257E3118A7FB4DE32CAE3EE xmp.did:43B4CBE681D7E011A526BE08355470F9 xmp.did:4463A16AF341E311AA6AFF46E3A32C35 xmp.did:4476E48D7058E2119E5C9DC2D893986B xmp.did:49629383A75FE211BE5FD8DC69EDD003 xmp.did:4962B478AE93E311AB2FAB742EAEDB5A xmp.did:4B7A12ADF2FFE2119701C3E8E2CBA32A xmp.did:4B7D2A10B996E3119120D50133417628 xmp.did:50B031CCDB98E111BE19B05E1DE1772C xmp.did:51656EC5AD6CE1118573CC62542EF1EF xmp.did:5178A250EF6CE1118573CC62542EF1EF xmp.did:5284CF5C414EE1119A17DD19DF39F556 xmp.did:57A1C52DF060E111AA529252B4C34ED0 xmp.did:5E5CA02C6240E311A887D012E70C1E3F xmp.did:60271FD08F5FE211BE5FD8DC69EDD003 xmp.did:63D21F2E2241E111AEBED233B2B2BBDB xmp.did:6B27B4BD813ADF11BCAAEC6C5DC8AB8A xmp.did:6CF7F57A4588E0118E50D901036E7887 xmp.did:6EE15AA5BFEEE2118F9FEFF9352EDC83 xmp.did:7151EC9085C3E2119485CD76840DA0EC xmp.did:71dc56e5-e055-5b49-b8ac-08fc19339e47 xmp.did:763FC8C77EBAE111BC5594B8606FADF2 xmp.did:76A59B64F891E311AB2FAB742EAEDB5A xmp.did:78A59B64F891E311AB2FAB742EAEDB5A xmp.did:7C80FADD8B3111E2AB5AD75D2661B19B xmp.did:8279DFDDC2F7E111BD53CF94664BEBEA xmp.did:8579DFDDC2F7E111BD53CF94664BEBEA xmp.did:8A947733EA7FE211B026CA3D93CC6880 xmp.did:8B76D4190ACFE11194F189B929F1E3EB xmp.did:8CFA6888BDC9E0118A1894B66E94A91C xmp.did:8D76D4190ACFE11194F189B929F1E3EB xmp.did:90917B61A549E211AAF7D9B03FBC388E xmp.did:94C3EA66E545E3119876F23BD28AAF4A xmp.did:98FC0E0C89A0E111B29BBC3C38868882 xmp.did:99C2BF9AC2D0E011A663A3A0F235368B xmp.did:9C8BE9970400E3119701C3E8E2CBA32A xmp.did:9D1BECD81020681197A5F6F85A622253 xmp.did:9DA8EFF9299DE311B712B7EA38C9FEA8 xmp.did:9c93a680-24f1-c646-aeab-38faf49b228a xmp.did:A0774BA2B769E111A342FC9D7726AB8E xmp.did:A19B51187538E1119063BF48A3C51EAA xmp.did:A2571EBE69B3E11185C7C82D704336BF xmp.did:A51240381845E311B81F8883B98D3C93 xmp.did:A5175DB2056FE111B3D9A81555F1D5A8 xmp.did:A55DB8C3B87211E187B5B933E8DA83E6 xmp.did:A9371036BFF8E1119CC59C0B4EC1EC35 xmp.did:AA12E978F292E311AB2FAB742EAEDB5A xmp.did:AB33C7EFF402E311A629B015FE29A947 xmp.did:AB50521FAFC5E111BC42E26A02820592 xmp.did:ACA7AD64B2AEE1119D79D7B7DE21DF0F xmp.did:AD01ED608B95E111888CF2658EF196E5 xmp.did:AF014875B853E1118EE7E574C350A586 xmp.did:AF7B4A72262068119457B94B0A19120E xmp.did:B28F2993E3FBE1119665ED16B1B03E0D xmp.did:B2B3E4AC3A35E311A3A5CE099DA58CE0 xmp.did:B391F8CD01B511E1A18F97A8D26A3B0F xmp.did:B518C9D19CA7E1118964B3B7AF8C1D56 xmp.did:B6F845E40EC7E1119971B8D30BF0408F xmp.did:BB0F008D11206811BD35B6F06AAF40D7 xmp.did:C28274CEB193E311AB2FAB742EAEDB5A xmp.did:C408B747B4AEE1119D79D7B7DE21DF0F xmp.did:C5CC15B57300E211BB248AC6E3141EFE xmp.did:C79E1726F3CEE11187A5CC8B39C8961F xmp.did:CE153DAB66206811994C9B7F51AE0063 xmp.did:CE9D2C6B6D9EE111A0588B64C21F9F9E xmp.did:D16203B18A55E111AADBA99AFB78CE20 xmp.did:D2E52B51C2D0E111915AB30308CEF0D1 xmp.did:D3258C3318206811B83DC55B43B113F3 xmp.did:D5958034BB27E2118651A73FF7A01E2C xmp.did:D79444774A2068118DBBACDD367EC38B xmp.did:DAFF29841D2068118C14A2A33B576E28 xmp.did:DBD8F5553405E1119D46E5E691047188 xmp.did:DBEECEEDEB2EE111866E89F51FF7D987 xmp.did:DDE729E5E5D9E111B4E6E7878EF63782 xmp.did:E02D6D537529E2119580E8B1B8F1BF12 xmp.did:E15A30AD30F6E111A7FEDB98811DAC38 xmp.did:E15C8DF98B5AE011BBCFC6EA4EB55BFA xmp.did:E1721EF2DB2068119109B10BB0D0BCC2 xmp.did:E2969E558F2FE1119012DA2503D34408 xmp.did:E55A30AD30F6E111A7FEDB98811DAC38 xmp.did:E948F03ED04BE111A679A954F3256CC1 xmp.did:EE58428735206811822AC7D293D6ADD7 xmp.did:EF0E269367B1E1119D8AAF35690FFC21 xmp.did:EF17D91D3220681192B08B72887FDC11 xmp.did:F0EC54C91EF0E011BF318C473C42BF32 xmp.did:F75D918A1120681192B08BEE29C75DD2 xmp.did:F77F117407206811806C9A138DB80561 xmp.did:F77F1174072068119109F8FE27718D5A xmp.did:F77F11740720681192B0B6CBB13A5218 xmp.did:F77F117407206811AAF1F360BEADB6C0 xmp.did:F77F117407206811B04FBAAF7885AEEF xmp.did:F77F117407206811BC5391310951E999 xmp.did:F87F1174072068118AE4FE3FBF51A176 xmp.did:F97F1174072068119A7F833586C6F350 xmp.did:FA7F1174072068119109D4895471EB7A xmp.did:FB7F117407206811871F92CFDFF7440C xmp.did:FB7F1174072068119109C00FC3634517 xmp.did:FBC4D2040A2068119109CC642C44EC0C xmp.did:FC7F1174072068119109C00FC3634517 xmp.did:FD4D6DFF08C0E111A568F02E3B31897D xmp.did:FE7F1174072068119109FEAFD0139520 xmp.did:d56cdb07-1084-41c8-8beb-7032281b987f xmp.did:fb8297f3-4588-8e46-994c-581eb3803745 xmp.iid:dbe71356-5270-f24f-92c1-30ceeb0c7ad0 adobe:docid:photoshop:c4aa85b0-7ac6-11e4-9582-b77f12e67c36 xmp.did:43f19c41-da79-f349-b6cb-07ca22ff4f9e created xmp.iid:43f19c41-da79-f349-b6cb-07ca22ff4f9e 2014-12-03T16:31:02+08:00 Adobe Photoshop CC 2014 (Windows) saved xmp.iid:dbe71356-5270-f24f-92c1-30ceeb0c7ad0 2014-12-03T16:31:31+08:00 Adobe Photoshop CC 2014 (Windows) / 1 720000/10000 720000/10000 2 65535 12 12  cHRMz%u0`:o_F"IDATxڌj0ElS& B3zc֏g:D(K!dHFB) zA}OGOu]K`~' [;1V`Ƙ7 Fmmu.ov}O_F@^ z]E=E4opxBPfH0 ,"?16#0EaY!0Jsh9x5JKǟc=,ˎ.,r.i>I){f)Kk ܀x ZV=hIENDB`kylin-video/src/res/open_file_hover_press.png0000664000175000017500000000212513214347337020406 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp IDATxb?01@@1" Yip *iA@f&$v7n.c. HrQ P|R 9x?,Aq̠E% 0#!CDR:l?T 4H磉3@Ca hpp` u4D`aIENDB`kylin-video/src/res/max_hover.png0000664000175000017500000000232713214347337016023 0ustar fengfengPNG  IHDR$$e?YtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp B|IDATxb: 01RĈlϏn!8rjX#pZZ͠]N8 #Aّ}CP.J}Zu'@;FE<2lc*l!Z© 3 tHP Kt%B/qSD3To-r 3$nlXB"`)X W1Zi=1g&-I`4SZ6T,:8vIENDB`kylin-video/src/res/next_hover_press.png0000664000175000017500000003632213214347337017432 0ustar fengfengPNG  IHDRp n pHYs  9iTXtXML:com.adobe.xmp xmp.did:24776fe3-5e39-7846-8bf7-7165f60dca4a xmp.did:D7F1B4E5524511E7842DB2F90C2259E2 xmp.iid:906bdb84-5bce-534d-be6c-6d18a4a04c54 xmp.iid:2a7af3b8-43b0-6745-a0f2-048f0ea0e907 adobe:docid:photoshop:772c815a-4f1d-11e7-a29c-ee28c792f004 saved xmp.iid:906bdb84-5bce-534d-be6c-6d18a4a04c54 2017-06-16T12:25:45+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-06-16T11:42:38+08:00 2017-06-16T12:25:45+08:00 2017-06-16T12:25:45+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 24 24 =^1 cHRMz%u0`:o_FIDATxb? 31000p/&t&bBQƽo b?ϹkW P/Ԧ"?C!̘ \}Bvߘ|{so̖d``Ѓ\^Ļ \;`0000Ty Pfy((=m 7報1000r/l` 6 R ;ػl߯ \O5a``xvfw?ojД̆4l$ЂS&4|~r/Ɔ/Ё2CoDG&Uj^.1b4000|M2ch q;+4[\)G!eP <$hN3hF>L8$dt(l(}ەޮ/߹M&#;uZH?ed[55'WW@=]S94Vn79JWww#Y'E ܙJ dIHmCa*ݢ/`tLT&-**`*!ׁo ө;xN;pJT.MT2ɌE\MoIENDB`kylin-video/src/res/volume_mid_hover_press.png0000664000175000017500000000251713214347337020613 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp #IDATxb? p/1}&P FdeL@e @,@?bD &p1T @`+#L@؈ @8u",āp"D6 *H@`ڱY `$?1 {B~\nJDS|A\6;m#ms0'1 `ԖFO \ HSd XIP &H$b)p ' &3o{!SIENDB`kylin-video/src/res/pause_normal.png0000664000175000017500000000231613214347337016516 0ustar fengfengPNG  IHDR==ieQtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp xIDATxb9À01)1 b0@4b7-R "/0 G5jՌEҀFqj`||@@vaDud& S(5 v`p^ڱco-`c/a.2 @CCCCCCCM ާO#NرDIENDB`kylin-video/src/res/order_cycle_normal.png0000664000175000017500000000227213214347337017674 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp bIDATxb? s@1( ne$p@$"Z.S "= =&탈Uȵ;84JE'l###5}deAj,>IENDB`kylin-video/src/res/logo.png0000664000175000017500000000542613214347337014776 0ustar fengfengPNG  IHDRtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp 0GF(IDATxbd```bAx "l]ۻg0`BP/kٸZ? /7''N&T="uKJUpԌf={_a ?u %^7i1ܼ~ @<@̎fgF=ss_@m,ywF+SϿ:߸} {,| %&pjj ga`p!mkgv`W23r4e"T\a>_ @j`׿_\r Qn}3|tof gfOSkZF/2\'\?= ñ@ތ" M 7}rϯ3<{`ghڸ1p1|xpAt}.pa`8?22pq1<~ǯ_Dw_?݊8 3E==vv._2kE3f4`by a~ ~ "fY[PHhB,,KB]nA:A,qBjdnhK :L܅y><"ѵ#קt\MNnDEmUD:-<Ȱ"85%{;4.w vp 'v".s#+!v EUq5lxHm:FnSP0)HCݣ\+ytUGel0 `|1%3u孝Ǧef9sqcsR$(ۀktGpOT;cg(|)Rt4u|vlY=C`x1$ i5TY*cf.yu&i `)ճipi1cGȳ<#5~?.~Oߡ^b#$pPȺ އ ڛDƫz%*͡Vͪm}Lw>?rSmJqBYm D?2tǃH(diJ7Nlʹ~8w>ϿƈbǦ,fFM>(yf89(7:5M:& sx+l4EukcWt=ǸDVzKT)X3Z9 W~%HxvkZ#n¢c636~8!z+QGh~L6x|]^J^dԢl|?{{vP"?E+;oqR42R&L-b昙8:ho]kX1%ȋ>ot'qe%Vjz|='J LݕsN t!3IENDB`kylin-video/src/res/volume_low_hover_press.png0000664000175000017500000000230713214347337020640 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp dP7IDATxb? 0q/11 bDQ"J0d PLFf@1C]c0aW G6Qhtk9M !و$c3bODlHkA+=+1zqi`a<6a=N %8,%%#YWrQE6瓒 a4W.G@P)`@MD|hD *C}BZAʯ@lHv*BNATKEhHREN>@>yQ0W IENDB`kylin-video/src/res/unmax.png0000664000175000017500000000332213214347337015157 0ustar fengfengPNG  IHDRl$jZtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp +IDATxb?:>̀"x; 5L dd ).U##!+QTbD8L XjJ&3Iׄ#TB(`RU\ '|aKL XH[ jxz~3^95j$3j 2rS#.pl#o _ @@=U'PGOd#F"*Έd|b1à a<# DP%-^>B=&@JC.CAlF&^Yr9 b3aPi Hn(=+xyy1R։jp4ZA&QzlcTTC|`cCNߤ4`Rth@#Y +]##C[:1!##yٚ[ɑ9"@u 5#?FJK]nh=Q 9`TAS P'N-@hJ`4F#lF(a`hDcJf АFfj (2,#IjGa"]s; Ta4Ŀ~p/ߘAiY0FH a]G'"W1%*eXJ9Gߪ?=԰\e=E0 QG {0(!;:4EMQ0a`4F#l ~#,I IENDB`kylin-video/src/res/stop_hover_press.png0000664000175000017500000003541013214347337017436 0ustar fengfengPNG  IHDRp n pHYs  9iTXtXML:com.adobe.xmp xmp.did:24776fe3-5e39-7846-8bf7-7165f60dca4a xmp.did:B1B90886524511E7AF37F2B3552750E4 xmp.iid:9194b26d-3322-284e-8ee6-18e5c1dfc9d8 xmp.iid:2a7af3b8-43b0-6745-a0f2-048f0ea0e907 adobe:docid:photoshop:772c815a-4f1d-11e7-a29c-ee28c792f004 saved xmp.iid:9194b26d-3322-284e-8ee6-18e5c1dfc9d8 2017-06-16T12:25:19+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-06-16T11:40:52+08:00 2017-06-16T12:25:19+08:00 2017-06-16T12:25:19+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 24 24 p cHRMz%u0`:o_FIDATxb? 0{7LbDQ5+.TBIB0rY5$9.Fd xb`@ "O9*|?ai "Yn4)000|&p1b@_XHp6, "`IDATxb? _RĈvO>I3C d=N!2Zd @t0BURP1Y@p[ P#IG@K,gj!@@`WKLZ|@j;P/ U~0ub@(o)"+4| O߇id  q@ ݁x%? 'IDATxbT[ 01RĈlN9Ĉ |QC m` |~'AS\6IeaU7 stj#[@QF-ꖱfYiƍ&QF-h!8IENDB`kylin-video/src/res/checkbox_unchecked.png0000664000175000017500000000210213214347337017621 0ustar fengfengPNG  IHDRhOGtEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp ηY bIDATxbL @0 #T \-\> (0J$)}@|;i$ `xC3L4BTT>\?IENDB`kylin-video/src/res/dragbar_hover_press.png0000664000175000017500000000174213214347337020054 0ustar fengfengPNG  IHDR;֕JtEXtSoftwareAdobe ImageReadyqe<!iTXtXML:com.adobe.xmp 2VhWIDATxb?@ W'K{Oe3$iFhl$J3.ajlk@fblĪX14b# 0X0t+#病IENDB`kylin-video/src/res/help_normal.png0000664000175000017500000003467513214347337016346 0ustar fengfengPNG  IHDRa pHYs  8$iTXtXML:com.adobe.xmp Adobe Photoshop CC 2017 (Windows) 2017-07-28T15:55:05+08:00 2017-07-28T15:55:28+08:00 2017-07-28T15:55:28+08:00 image/png 3 xmp.iid:758cd1ed-0b8c-534a-b437-50faf656ee78 xmp.did:758cd1ed-0b8c-534a-b437-50faf656ee78 xmp.did:758cd1ed-0b8c-534a-b437-50faf656ee78 created xmp.iid:758cd1ed-0b8c-534a-b437-50faf656ee78 2017-07-28T15:55:05+08:00 Adobe Photoshop CC 2017 (Windows) 1 720000/10000 720000/10000 2 65535 16 16 ^2# cHRMz%u0`:o_FIDATxڤq@ De(( B*0TTR\ %#:xdW|^Жr ݀k3&j-x[/hՏLPeM:`.7N>gyxeһ3A]gIENDB`kylin-video/src/res/spin_top_arrow_normal.png0000664000175000017500000000232413214347337020445 0ustar fengfengPNG  IHDR |@~tEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp pIDATxbtpp`& ~ F  f -1#RdBAd bbs$a}b52`)qt"~޺㯟?ϟ>"b\%3 %IL!=#c!#:{ҹ&*((|t>W_|x/5~ xY!IENDB`kylin-video/src/res/playlist_open_hover_press.png0000664000175000017500000000253513214347337021335 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp ^!$oIDATxb? GFdB0!)C u7|_AlTUH]h.X%@Sd!DR?'#%.LfU|l DMBkV0 kfb dЖ(NBw3tV @@;\A KJmy" FhEJt ,Na8k#oJrA'Y-ٳj .9d%S"fqF -!۲/IENDB`kylin-video/src/res/fullscreen_hover_press.png0000664000175000017500000000247613214347337020621 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp jdPIDATxb? 01 @1(^?VeV, ,0.Fl M @(6"l.G-`gM7P`HsƇqdOu#AT7y(Al Rx3?. P9,>gǃG#: cb#̆ PvF<`ɇ )ٴ0\E ܇/%\,JJ\R   ; *` +H@F4s|[9@c0j[R\H&2 3e* >HrC*}  IENDB`kylin-video/src/res/trash_hover_press.png0000664000175000017500000000205713214347337017573 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp IDATxb?p/f#@1rʀ @H/H](4 0lAn2Y0 tdᲂOP` ɾL#60b fA2k@1_ G?.21P(6f$ր$,+:y5IENDB`kylin-video/src/res/play_normal.png0000664000175000017500000000345213214347337016350 0ustar fengfengPNG  IHDR==ieQtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp wH$$$8_xdg8<Dq4Ѩte,FFF CM`?Ì3΃hPH$&&HBba@Wˁ%C G>yn!a9@ Xcq=jţ3 222iii̚5뢑ɓ/O> {'?0ޕy螪7lp˗/4鞝޾}AqOzjYn0gΜOUTTՅgΜynq[nO^|Lɪ-J|,&&IQG-xhZ ]Wm8-)7qCK 8/ *(AmT`MR(%zO'B7 wq9_}4oIf ) A`bk Ü8Sf6hP۶[˲a9:ٶ]6M/iyi 9y R TBUEK=!F)eelS_op}%I LqEu+jAǝ:9""=᫐!(5˲ 4͌ʚFDz,_<υa"OQI:Ou%4b%I*&mTnZ}h "4B#4B#4B#^S2GIENDB`kylin-video/src/res/spin_bottom_arrow_disable.png0000664000175000017500000000227613214347337021270 0ustar fengfengPNG  IHDR |@~tEXtSoftwareAdobe ImageReadyqe<niTXtXML:com.adobe.xmp k IDATxbvpp`cceb``Ĩ@@@@ *  5`dϟ?!23 %%HKK311I S8 b52`bzzzh Qƭ[sQ!KN(!pESr333hx_~z԰`uݻwx-R3=Y>k#IENDB`kylin-video/src/res/unmax_hover.png0000664000175000017500000000246613214347337016372 0ustar fengfengPNG  IHDR$$e?YtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp 1zHIDATxb: 01()*?4ĈlNqsA8wY݊fPîWN L">r܉m/>RρZ3ѼA;4ࡊX9at FhAtB^V,0@$@ LXIxITₔWh96``q~#} NF&rkЊ!q6#3wՍZH@aI+cH ze@῁ ZbV0C xmp.did:24776fe3-5e39-7846-8bf7-7165f60dca4a xmp.did:39F06AE65A6E11E7ABB0C749112D8323 xmp.iid:4ef6ea1a-5efa-314b-91dc-e41167616597 xmp.iid:19f8c3b6-31f3-fd4b-a187-fd4fde014cd1 adobe:docid:photoshop:441a4ea5-5167-11e7-87e1-94ede75d9a45 saved xmp.iid:4ef6ea1a-5efa-314b-91dc-e41167616597 2017-06-29T15:09:07+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-06-29T15:05:49+08:00 2017-06-29T15:09:07+08:00 2017-06-29T15:09:07+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 438 81 t@$ cHRMz%u0`:o_FK-IDATxڼKHUQ9W$ B{SA0G![)$N#4jؠ!4RB eT9opMq~ܣ={oy;vDDDx):hea4DK0a D2cRqTOԇ8B}e~Hc u@R⪠DE}/ Qo+`+$ncf>2U#P$Ax VY.ԕ-}7[߿u)u*rk}Og!Hc;;NOOum2/WUW756 8d=Dfr&:P\n'遡AZ\n6ZNs-g=:$577~.Kն.a%dD:J-8zo? 6`(ހтuޜ$I ! heD3q/r3DKTQ[a(-ZP"($H B)l\J`Jjghҝ%dBdMo=.ޛfps B@X3Z.i00?HJ" 4@(L"3MBa- XB.!I\6p,b}@U1%A#)*iR)$ߩ+7h;^_=]ļ%0ۤ%Da}{JI~i'6έe.vy370>wR?t+wvji>4uyKzYSӯ[[C̏  ۮ}>lۺT,nln޸'H/OȻg[6R*%ȧ0S)|xrEOGWodu3|T#rw^SҀ!5=>*nO..6eg6M*),\o {W7QABȘ@?Bye#^[ɐQy S# `ܙ_hWƿsg] قQ4PEѴ%nB[%b,)*$(j!X[H+M4II@7lćK0*&3ý3[Wa0HMmm_@O*1 QAuUbzxQϳ+V'&4HBAM`; ;F8:P8i.*br< n:;gA% 5Wѕ,,4) \8Q^~bU*Ra^ULsr( 9eaʥ״"| i`WS-B^݀Hef$ck0z}զ_R?ypr2]"󹁨/MrE zHM7 j(ەbx]W_/ͬ\U#Κ{ϳ*ʥW v╁#o%;SWm]o_1KЙJy ykwFm_"~Qz*s y^W[Y}1;Nh?k8tJKpy Mm[X݉C ㍭fy=kn8`2+8DaPMv̆ukԾGO=^$5ȫߟ:z4cDK;sgjb8=dﱳ/--JGiA8ctf=s8]>L@@@| J],G7nw$遪V@\w JIeSY|Rl'DْEuQ  IQKRtBDnj to߃RS:ܛoUƟֆKhZ, TD!`"(r$@D$(1rIH4& bR(" l6v=<}偹*ݕo"a&xӘVT} w,ρ08mA:ylu{ǤX€A)B/vJdVF5^'tRy*Je ΄̸jL>. 2v !ݭj`nKjmLbr vkD둸p!Е52 NEa ,=&";goyoYT%@u[(EG|g*T VS7?}+/ՏK*VqwX-D8D-+D$g?#0w`i$$ o7{ߺy̖ݮ)42r G$N@>Q)dqw`EDyVGOWL^u|БC8qϢ-Tqo÷%Bq2͵G}|])b;`)JȮ=*q߫267?bhy#DQțkOfqv39xEoN1Gѵ~ukkۂ]F5,z8# 0mI)+ʺ1pQ^hEGNͮ#OXvƏu<2֤AИYRSѼ^XiIDA3d3:gZǶّY^K雱𺆍ӧNl+nT) @=&87` R{~jMԕɮo}9bZKZDlrrF˓gA0N|a B4Jս})2"^lXu(L>q&lH f9m a꘢1 /pBp]G} NJnzk3#,9ioq/ګ-J[Lҝ.N}A06ǷNjH~ƋJIu0qo20#"c[mU⃦V^&H$ $dwsg7G&ٽ9{woN/@J)PJDӕZgI媶&ȥGȊ9 !GD3Ol3x,+?wRerJ,Νgw+⺨"FJA Z>'BaEp&}`"dAeSUeY*8."b(O3" $yg-(fЅG/t x%r\X5@' f}p &60^E*@ ;r)$ ؔr@ !v 1SǙ=<)0Orgba rnoDP:sdf43)l+,B{+ P.25A w @e Â#DWyFԌe 󪙖6(`)B&&@t *2&Q(C!^TD."j3ad\Dz!|q$Vi@Z-Fb^, y=)R1;9ęqw_ Y>4B>!|=kq,{c*C lRi:1Pic g%HkYt;YpHU"2e + s)(.D&hǑg~rQV tfʑ 1fx+TTRg~T[҃u/ %+݋$28*X's a͟E Q/E TYy; ?ry9Ǽ^*;d ?#}ǃgPw/v?:ۋ$DDyɸw][{3yrk+O++qkOkƍ8%q~ٯl,#M}~VvaS$;Ҹf/SR߾7(| \M/f#"rV];o<W35Qg_Ĺ \TC{ZXv_ @e%*jhOKӌ]6۫37<7 3C!jS8[HfF8,[xLao}.??fGe@vt(lݶͯnLh׾CTWέ]mmݖ|O6]9w.y{ZV̙uկW?jJó .'d "wTF2#?h8۶=:sW~؂|+'BZ_e-mܴq盻4Zp[ /Aɸq3iV pK.`V̮ry%מ^TXdEpޏK_0K PN$"GւO#Uk׿qs2bpfgzwLA(';3m%dѓ} c |*@6mzjǻ+ dfκʚ%kV֮ h޹vJ*.. B'N Lb/Y\`E~l\b|j|eϹ'ɖM0LkΗct#N\]8kŠ`gpb&@d]ma#E9,10þR" d EEZaBp?a(ѴA]: mG)8# y HvD#HQhWA+;;:q<$SiGHEbԼh;$Eѱ75 Jg"FвqJGcykpASlHDnSR痯bd'4#Ի{#ojȭ`XξRItDc#I̅o(N޶jI#!IےM‘QS13|k ksf2ɄkTXR~ (rUB"UhŶկ/DMj *@ ` I ^qnh?&>$sN&=k'Ɗu]uEU ?:oA0-myN&h4%k]LVau͌;y[y/sAt";)-]9i-Qs4»>Vw)l17.ц"im'QM9G싈KD̳lu[➻)DvMEpri1ChnP@SDD=L,#0pҘS٫U%mZNC:إǻ/xmf.}  Y@hH3zJP\m\R]k9iq r|CTdwȤٷ}Dkq$ۘ)m,z`ǁkDx 0rvs#/t.#@`)NF0b&INv3GKͬ1%TWJ6 +-)HW)tڥs.h3Ȝm\(e@'"z@/-]8q12 %ozeҊB.΂5.A$%Mk_~(䜗?pX)- /aT{̗$#3z59093\=* YDm2Fyi$^{#SsJ LbFI9NdZc 8OU&#+a92kɛ}yJHO7i)8~LDzku`)):Z7==`F%###F +7~wE!m~" w vۋ,|N;V8d`ںFUS D,- ΟL8SiW)1$O9,w@]8>)7^ٗ1EʏFd@ D$"8tdkz-Gn @[*s|pF,YPqi7J&Eyf-\0fn#9#=W[ES[|ybWyٮbyg㆏pF~keE`ڕ9bKܾ},, gU|߀#6vo`O?AR?N.JߠIA R BјE,1$e|0zG+w̿|#Su{.ӟ@&h 2k'@01gM&v_{Q#[8# ZZZ E~g kNfH*g=IyŚ] ] yn_h+TgnwEIΔ􏜬>(Ɍ1&IO?|ĉNqPn Ҙ8  ?{ÃB\8NKpxs:  3R3gִO>g,.YWpe$ouPv^C1tPJ8~ɵ'NَogMR٭$Dig  N}>I@4ι(}Ж7szfq99CXzCE9ojjwܷK.+alhei f_~YUcc5x{5G g#kX7޵烏kO6mdqis- ؾy) 1.<;!"M1Iɒtjs}U%nd,- 8M7pd|~Ⴙś2ُ9ph+teqi3yWͲEkW <`ky7oY7.4;wȪO2jaÆyc Y8tq\{u~j|7ܼǍ3}c/, LW";gоJL_Z1':|Vɺe>-}Usn)5]i޵Cр c7fDվY7- g<njYŷΛpij 4eo',Uko[0P7TLbR's \KY>wSD&6|ب'RW5̌eY2'9q]@)SЏQF`[WY0ݝ-T %X0IIvwEuLpلTݧrdD @pGf?$c 8Gk\ij>X,'ypq]3!ki]r͓w\p,d3DhZGmC! 7'Olb۞#7&QdQ{̢iiTWi C==3=U̐\`DRڭ{'v_h!5GB)B`c#5Rc3Ϳn ӭ@5MκhvzŇmr:iΦ@u9G]*S`Y[ k,c ś:OV')VE) 1j2.ɨ6v맬O㭱PLb 9/N>= $diX,&+D0Rn#]dc&x1޵<'m-CQ 6 xi \R<7Ȕ;qH)Qxyi4NG@}rB%'\l ǭ}Dufr'l0G~%ۅn~$/1g '$:.+@HL|d][.$G@_1wQY^UeeNQmQt xvE[qfQ$hX@T@# mAPIBT{w珷RI3#wz#`vnp1 B/ B X|(fc'dR~6ez1ʼ8 ȒT8Cمn_djE#-=E)K݃23 B EsIK"c9ў &Hg钄n!&V,+9<5#Y(HMR]!p6SϡiG>*]JSn*̆#V jg'q2K0 pN\sB`i/-1GX햖~z%;&WޕNA͉tff6 Qm G@ A@RJ\/j{@QlaV[N/ $$ݍjBrL&4< ] ItPKN# \:-3c4`WM F'mR18@NoӒQoְֽ´FE[Ps{s&fp's)=#Mt$t41Xg"En1v/i#ѕԡwF- ]SM@)f*mDL-ۏ룫L;4 j:xŘѳ $ IR@\k; }N =r!dd%:DouwB2"gk|sѕD_:؇V oGÚqz蔳f,E| &iJv$k)s9RwHpȡd'li Q>=e!T`KF,1>_uI%lrjRS c wޢ*zoKHN[:0=3$LhtqV(xQ-ݐ q$5LaSK D% iMJi*hpD7{DFkn*>b>й/8 #5ze=9%uF {X&+8(2 ѧ(ᒥAt>]$n;IJN<̍#FqD1:iAtօ|hEdԠ2 }{J1~C?ԣ" vHYHk.,"5<OW,}5q32 J& A@PT@P(" W2mm_td;8+au$PeEus;IZL&V`7+Mh6K2!'DC+ж,SJ+AjԤza tV{v-~@E="]QILnj?_CѦVUsR9a؀}5kk|Xu$qMU1 3223p_hmcMک$cJG;E)|ޥlɦ6u$GP48Hχ>A9iI;A%d!m 60a1;y΍䬨e(!0ÌIDB\; $)F?GgN- \d7H>"&wM>7OzM_6}UEFy#'[77 KrFf_9aL27tq$皦$XfNq%77E ʁΆI2c ҂ͱڣ9Bާp BGGdR;h#"JGf Oojo"wE&Yʴ|u|Qp@ B2JZl#"#MD%p3:te[?2X?$D;LmoԮj_ߪ1 J, ԇvɺwE¡>$h5cANĈP(Oo^-Mʧ 1oXP6`! +D^ZaV#-0Y;L%V2DٯoJw CQr't( ?]5c TВ'Fjb>hM܅o Yz#?^߉r4.9ĠhF&ZP W)vk 2ٌB fK,xzL5ѷ7" Hp8q[~-Rc%e`)տp$52g\Q7Oq>$e~0v2Lwshջ rszԪ=,Mͪsq>T8L:zIR xg{?-*:gޓ !Cv4+ؚxzLJND&\/*6lvZDzVo~|mrB6O?Q>nxJK Wx P]Ui@Pb77&A-OuG V>~+IpYg=UtJ( ̟7gxM t2+X?Dv+$ )kf` TYrYV-|}gKHȐ2f?9ް\Wfmg<^ү 8!clkH*IL sNđs8Z9gF Nm05r5Ldmp5[U_:Gw˶j-\5FE+*,8pB=ł^ٽ|쭕+W?.O>kM A#/_X>VHoN^`ħڰ)&Xpauuu-ׯ* n=zEьPIU)+@BAdƸHZZCS3̜~7^Z]yԩ;qL #DD׈'DDmV!sVBs4D$@F(O40 Cq79ơw?0Ws}ZƊu=؇l&OQ?f٥_~;xWV}ov#8hźB*T]wNg1|3&_DWlj$p5fh)&dgg/Y(> Du 9Ii֔7#cC !"%Yb3O ++7,|iE}cCIa,4U#DB\c׈>V8O7eںWOWc$F ""tgc{PA~O?y?3|hQatVdffLe\jOn(=raEeG>l#F +7v&\O?rU8'Mɴ_o^Kfl7t(defvDnzW>RvpݕK`y:;++VL-\\-y\VGjr5Uma͑{fKXF0i@aFpXoNm]LVSs:!ve3. ):E^aa$X<~.N#kcC}<82 _8W9OD4~UoU-KWV{hfzPCDBDB`,Q[O%}sj.{&l*xG "effLe|WP6! F/zݘ+nS>֨Lp}٨_~Ue/SźM3gLn7+Y,sGZZ׼'ZLI.hs\}| hc77.9H 1 "ch_9ѩVPEUU "(]J7h? E%r!ԧHߘ5;ts9O-uba~;C E1Rw9͋oU6eN+lÿݲE>~饗<=YeffdfdT=lU[wXoWhLpc٨qe+W^de/DjǚP )١OtsQ32Gxwߺr?w`LIK.#ƵY94Ȑ1{cLkk% jQ'cXŸbźwC9UM%H3 aœpVP5AinĀsFU=txw '/}Nɷ^/^ ;NVmi#`箏333'O*mxǦ7Mo(-)\9bh֝C'P6j7D#]}`g2`7zj^|p]bK]RZmZ20cDHBQD@)ўLFWmHbI Zڏ76B!YE!UQEG$ FBH$k6쌌\"jq H#N@Fg9k˾xl$OT9=  ɷ۳ mXgITTZ\P[ߠbF:FܻK]EFъoSwraC/TP_{YJv'n-_T[@'h`VY z`ʤ[b&؎ kďGaႀq Z]|dHDG\ɷ5KqN)!Ⱦ #@k\UD2iZ$|녊*O﬌œD\UTDzaGF@h˺7 Q KȨLhC8{]SVCP]Uyo _~?񜑹##/IiIŜeW233n~g .Uκ]{Ȁ̕>H4 N|;:|דgI VPDbJǘcN z"iu}5Z Ò$qMEDUIdfedlk:ma^nzzzq^.) cˉ8qsN(|,R|)Ƹ!4Pv lsy.'Nqϖ\QCz_^yEY {%oW,-)vGwD1Um1W<=Sz{aܘ˧OP&DV ^+_ޱWPrsΠُu&v۝d~( 3N?1Q OF\;eJHZ[ii9-K @Imq",NqxNلO֪>M%i|^HE?/5[rկ_Pk4_wu-O!8h]{oTmQeIUsз"Ԫnںݼ!կZjq:uɯHeW\~#ftHHcY`m51V!H!hwvd_/~$|4$1ε,JR1쥬jW[g76!bgS=E @@J 4dZqZ'6?גV*AZv :5`>@>| {j4i~](>u'͍z( Vr1ы VOmb@DG"Y,?PyӼr燶瞕\?C Do2tɓodhw>nO"IpN56\G+:ZK:" oIFUd pkd@I#HKǞ$RA 2X؍V@ф!0!ѪMF"=&-Zֿ􋯷h#LdlRXOk8UiJ+j0nT >_4 $P #YC 871G^,"(SUL:½Q.Fc8YIъ;ڀ i ғ޲ifv߸>RrB`Ru4ǒS$vI*A80'@}#_h&o4"c862{ =kH νeCcrdtba*p z_HMj 2 XF o(y 쉖)beknFΦ&X V*mc2Prv4)G,>r ![;::С2di p9=a $TS&:U6W' 31i 'CϦD60':c;vHC y `-s 9HKO 挩7bN@Zn݇S䑆CB` ֙6OQxF80FՎN3I*D( 0T菹d|)K@)}3Ԏd|ڡr|%p;;G~(:\[\ AJDrLkIDxK7)̦i@fwTT]EK>h| HB D.!xSҒLk'њծ3t\a .NVgm_D>xg Ֆ}`biW-y`-2|R%FJ_w;N3/6PqTӓhUwS"#@K┥DAsJTv[O|3|Q|; VT~FFt)0C( DNWU }ƻx矠%yAXVd1vpI b!sJf9OYI\|y:p $dXD}gq-jBBvȈ|% ;x" >h:gr5+?Fc7;\!0lDEL\ahm?@-1kA4O|T V" 0ϤIh\h(Y~넱~Nx| 2sa7ֲlJo82JZe'j! QRTs)a ,9(x(iF7q~]go M=@` +dJCI 6p Ǟs+=J$~  tKaL~(eu*&C;Z2 2א!T|'m J=7u hxoB:` eVU٭h-_ƵKu0C@G$53Mi\ 15J)H(M kb=S[:n-H:a (ukؼYɈs9Wj@/z ҳ%֗;p7@Vd7%򝈤 xBK.}|i_È$JM!R<$R=SZ!Po06#@8|QIENDB`kylin-video/src/res/help_hover_press.png0000664000175000017500000000242613214347337017402 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp R)6IDATxb?01@bDa   NY\/H$w)3*kYj~d0[TH$t&Ad @0+  ,b4 : ȎC/00lF;)F<tLHCu#e@vzLںA-#{?6ASy|t,Ia=zZ4\-Ci?4.8*pr&odIENDB`kylin-video/src/res/screenshot_hover_press.png0000664000175000017500000000231613214347337020625 0ustar fengfengPNG  IHDRhtEXtSoftwareAdobe ImageReadyqe<&iTXtXML:com.adobe.xmp .=>IDATxb?01@}bDa `p%0@ P|,R4\E  d0UP|l>0W @@qYCt hP_xs57aB40+}= P r#P2q4@+~4† Ѓ=>adO0!ACgvjELoȡIY.g&@C0Բ 91b$9(E/:Pu@$~RRaH@d1X,GdBJYIENDB`kylin-video/src/res/min_hover.png0000664000175000017500000000216213214347337016016 0ustar fengfengPNG  IHDR$$e?YtEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp =IDATxb: 01RĈlN9Ĉ |QC m` |~'AS[\^95aU7 stj#[@QF-ꖱn)>THFȨe edKWIENDB`kylin-video/src/res/spin_bottom_arrow_normal.png0000664000175000017500000003555513214347337021163 0ustar fengfengPNG  IHDR |@~ pHYs  9iTXtXML:com.adobe.xmp xmp.did:25d3b678-10bc-fe4d-ba41-689616e973fe xmp.did:712C29225AD511E7A804E8AA5585B67F xmp.iid:5606b9fd-ecb7-4d4c-b815-f399c5d27cf3 xmp.iid:51e652ec-356d-ef43-a124-5fe63f3cb50c xmp.did:25d3b678-10bc-fe4d-ba41-689616e973fe saved xmp.iid:5606b9fd-ecb7-4d4c-b815-f399c5d27cf3 2017-06-27T09:11:13+08:00 Adobe Photoshop CC 2017 (Windows) / Adobe Photoshop CC 2017 (Windows) 2017-06-27T09:10:58+08:00 2017-06-27T09:11:13+08:00 2017-06-27T09:11:13+08:00 image/png 3 1 720000/10000 720000/10000 2 65535 17 12 M cHRMz%u0`:o_F=IDATxbrppPSSspp`b``02d``bRSSSSScb`````brppWSSwpp"1000100|O b VA1 1\!w?~_:w.bRT7$ؼf5+?o}{8?sS\%m$$\.&!anc/p!>~`6vv666`^>Gp֙YYn߰ V<)0J_ LIENDB`kylin-video/src/res/trash_normal.png0000664000175000017500000000024313214347337016517 0ustar fengfengPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<EIDATxb`0bXQb3$HR?\?4b0 fd-xRIENDB`kylin-video/src/res/playing.png0000664000175000017500000000042413214347337015472 0ustar fengfengPNG  IHDRJLtEXtSoftwareAdobe ImageReadyqe<IDATxb` h #@=,*Ҵt(m=bYon?+"EPq n=O>w4j#"$P,Bza}|GEHLa :$043,͋ 4_IJj/Ӭ*[^- .:tIENDB`kylin-video/src/res/about_normal.png0000664000175000017500000000050413214347337016510 0ustar fengfengPNG  IHDRatEXtSoftwareAdobe ImageReadyqe<IDATxڬSQ0 H@:s0pPO8X% a8=z]V8[45iScF~v8,(cD0 0* '*pa#R¿Mon>"*AjC|13 ֩w$rfCl tl,pbB HJr@ X^QA2ƒc޷ZI0~H[ڨ;.c=_W ^IENDB`kylin-video/src/res/order_cycle_hover_press.png0000664000175000017500000000223613214347337020743 0ustar fengfengPNG  IHDRp ntEXtSoftwareAdobe ImageReadyqe<iTXtXML:com.adobe.xmp <IDATxb? 01 @1VƽBQ0@JFeNv_c,IdOPaH!,N&]c4d 4R t_GhACb']hD'XR5A@? :xx)IENDB`kylin-video/src/res/combobox_arrow_normal.png0000664000175000017500000000235113214347337020422 0ustar fengfengPNG  IHDRtEXtSoftwareAdobe ImageReadyqe<viTXtXML:com.adobe.xmp 2 IDATxbtpp`& eA D!b[0 J@z+ ۑ`q9\Ά]8}HPÕ| ȀF(*dx{Ɩ@Gs gd 6=¢bN>\< ΓXIDATxbL by @E` ]g }@pd{(ǐG 0LEY D-2 &@(NA,8K:l> p/jP} #x"x0WHYqIbA.a"҆~&'S4 H@ @n; BDb7@Y`Oċ+L<=@>rIENDB`kylin-video/src/res/volume_mute_normal.png0000664000175000017500000000063113214347337017740 0ustar fengfengPNG  IHDRw=tEXtSoftwareAdobe ImageReadyqe<;IDATxU0 l <' p@Gp&zHcrW_/cL+ư| A'o$p 5bJă8l{Rq4%[p?s*9|=+_yB.'HN})I,H]OP7hI,e/_HH.SV2zbTd^U떣RQxQwHh7#>7m$ >GS35#&ԇBqwllJL/jma TOR4=fѲ/YIo.tQIENDB`kylin-video/src/src.pro0000664000175000017500000001511213214706400014027 0ustar fengfengTARGET = kylin-video TEMPLATE = app LANGUAGE = C++ CONFIG += c++11 CONFIG += qt warn_on CONFIG += release QT += network xml RESOURCES = res.qrc DEFINES += SINGLE_INSTANCE QMAKE_CPPFLAGS *= $(shell dpkg-buildflags --get CPPFLAGS) QMAKE_CFLAGS *= $(shell dpkg-buildflags --get CFLAGS) QMAKE_CXXFLAGS *= $(shell dpkg-buildflags --get CXXFLAGS) QMAKE_LFLAGS *= $(shell dpkg-buildflags --get LDFLAGS) isEqual(QT_MAJOR_VERSION, 5) { QT += widgets gui } HEADERS += smplayer/config.h \ smplayer/mplayerversion.h \ smplayer/mplayerprocess.h \ smplayer/inforeadermplayer.h \ smplayer/mpvprocess.h \ smplayer/inforeadermpv.h \ smplayer/version.h \ smplayer/global.h \ smplayer/paths.h \ smplayer/helper.h \ smplayer/colorutils.h \ smplayer/subtracks.h \ smplayer/tracks.h \ smplayer/titletracks.h \ smplayer/extensions.h \ smplayer/desktopinfo.h \ smplayer/myprocess.h \ smplayer/playerid.h \ smplayer/playerprocess.h \ smplayer/infoprovider.h \ smplayer/mplayerwindow.h \ smplayer/mediadata.h \ smplayer/mediasettings.h \ smplayer/preferences.h \ smplayer/images.h \ smplayer/inforeader.h \ smplayer/deviceinfo.h \ smplayer/recents.h \ smplayer/urlhistory.h \ smplayer/core.h \ smplayer/shortcutgetter.h \ smplayer/actionseditor.h \ smplayer/filechooser.h \ smplayer/mycombobox.h \ smplayer/mylineedit.h \ smplayer/tristatecombo.h \ smplayer/myslider.h \ smplayer/timeslider.h \ smplayer/myaction.h \ smplayer/myactiongroup.h \ smplayer/filedialog.h \ smplayer/timedialog.h \ smplayer/cleanconfig.h \ smplayer/kylinvideo.h \ smplayer/myapplication.h \ smplayer/infofile.h \ smplayer/translator.h \ smplayer/languages.h \ smplayer/filesettings.h \ smplayer/videopreview.h \ smplayer/prefwidget.h \ merge/basegui.h \ merge/playlist.h \ merge/lineedit_with_icon.h \ merge/preferencesdialog.h \ merge/prefgeneral.h \ merge/prefperformance.h \ merge/prefsubtitles.h \ merge/prefscreenshot.h \ merge/prefshortcut.h \ merge/prefvideo.h \ merge/prefaudio.h \ merge/filepropertiesdialog.h \ merge/audiodelaydialog.h \ merge/inputurl.h \ merge/errordialog.h \ kylin/titlewidget.h \ kylin/bottomwidget.h \ kylin/soundvolume.h \ kylin/playlistview.h \ kylin/playlistitem.h \ kylin/titlebutton.h \ kylin/aboutdialog.h \ kylin/playmask.h \ kylin/timetip.h \ kylin/esctip.h \ kylin/tipwidget.h \ kylin/messagedialog.h \ kylin/helpdialog.h \ kylin/supportformats.h \ kylin/systembutton.h SOURCES += smplayer/version.cpp \ smplayer/mplayerversion.cpp \ smplayer/mplayerprocess.cpp \ smplayer/inforeadermplayer.cpp \ smplayer/mpvprocess.cpp \ smplayer/inforeadermpv.cpp \ smplayer/mpvoptions.cpp \ smplayer/global.cpp \ smplayer/paths.cpp \ smplayer/helper.cpp \ smplayer/colorutils.cpp \ smplayer/subtracks.cpp \ smplayer/tracks.cpp \ smplayer/titletracks.cpp \ smplayer/extensions.cpp \ smplayer/desktopinfo.cpp \ smplayer/myprocess.cpp \ smplayer/playerid.cpp \ smplayer/playerprocess.cpp \ smplayer/mplayeroptions.cpp \ smplayer/infoprovider.cpp \ smplayer/mplayerwindow.cpp \ smplayer/mediadata.cpp \ smplayer/mediasettings.cpp \ smplayer/preferences.cpp \ smplayer/images.cpp \ smplayer/inforeader.cpp \ smplayer/deviceinfo.cpp \ smplayer/recents.cpp \ smplayer/urlhistory.cpp \ smplayer/core.cpp \ smplayer/shortcutgetter.cpp \ smplayer/actionseditor.cpp \ smplayer/filechooser.cpp \ smplayer/mycombobox.cpp \ smplayer/mylineedit.cpp \ smplayer/tristatecombo.cpp \ smplayer/myslider.cpp \ smplayer/timeslider.cpp \ smplayer/myaction.cpp \ smplayer/myactiongroup.cpp \ smplayer/filedialog.cpp \ smplayer/timedialog.cpp \ smplayer/cleanconfig.cpp \ smplayer/kylinvideo.cpp \ smplayer/main.cpp \ smplayer/infofile.cpp \ smplayer/translator.cpp \ smplayer/languages.cpp \ smplayer/filesettings.cpp \ smplayer/videopreview.cpp \ smplayer/prefwidget.cpp \ merge/lineedit_with_icon.cpp \ merge/basegui.cpp \ merge/playlist.cpp \ merge/preferencesdialog.cpp \ merge/prefgeneral.cpp \ merge/prefperformance.cpp \ merge/prefsubtitles.cpp \ merge/prefscreenshot.cpp \ merge/prefshortcut.cpp \ merge/prefvideo.cpp \ merge/prefaudio.cpp \ merge/filepropertiesdialog.cpp \ merge/audiodelaydialog.cpp \ merge/inputurl.cpp \ merge/errordialog.cpp \ kylin/titlewidget.cpp \ kylin/bottomwidget.cpp \ kylin/soundvolume.cpp \ kylin/playlistview.cpp \ kylin/playlistitem.cpp \ kylin/titlebutton.cpp \ kylin/aboutdialog.cpp \ kylin/playmask.cpp \ kylin/timetip.cpp \ kylin/esctip.cpp \ kylin/tipwidget.cpp \ kylin/messagedialog.cpp \ kylin/helpdialog.cpp \ kylin/supportformats.cpp \ kylin/systembutton.cpp FORMS = smplayer/timedialog.ui \ merge/preferencesdialog.ui \ merge/prefgeneral.ui \ merge/prefperformance.ui \ merge/prefsubtitles.ui \ merge/prefscreenshot.ui \ merge/prefshortcut.ui \ merge/prefvideo.ui \ merge/prefaudio.ui \ merge/filepropertiesdialog.ui \ merge/inputurl.ui \ merge/audiodelaydialog.ui \ merge/errordialog.ui \ kylin/helpdialog.ui \ kylin/supportformats.ui \ kylin/aboutdialog.ui # qtsingleapplication contains( DEFINES, SINGLE_INSTANCE ) { INCLUDEPATH += qtsingleapplication DEPENDPATH += qtsingleapplication SOURCES += qtsingleapplication/qtsingleapplication.cpp qtsingleapplication/qtlocalpeer.cpp HEADERS += qtsingleapplication/qtsingleapplication.h qtsingleapplication/qtlocalpeer.h } unix { UI_DIR = .ui MOC_DIR = .moc OBJECTS_DIR = .obj } TRANSLATIONS += \ translations/kylin-video_zh_CN.ts kylin-video/src/kylin/0000775000175000017500000000000013233766772013667 5ustar fengfengkylin-video/src/kylin/helpdialog.ui0000664000175000017500000000514313214706400016316 0ustar fengfeng HelpDialog 0 0 675 425 Kylin Video - Help 0 0 160 425 49 20 101 33 Help Qt::AlignCenter 0 72 160 353 0 0 QFrame::StyledPanel QFrame::Raised 14 20 32 32 Qt::AlignCenter 181 20 470 360 0 0 -1 570 390 91 25 OK kylin-video/src/kylin/playmask.h0000664000175000017500000000251013214706400015634 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #ifndef PLAYMASK_H #define PLAYMASK_H #include #include #include #include #include #include class PlayMask : public QWidget { Q_OBJECT public: PlayMask(QWidget *parent = 0); ~PlayMask(); void setTransparent(bool transparent); void set_widget_opacity(const float &opacity=0.8); protected: void paintEvent(QPaintEvent *event); signals: void signal_play_continue(); private: QPushButton *play_Btn; }; #endif // PLAYMASK_H kylin-video/src/kylin/playmask.cpp0000664000175000017500000000516413214706400016177 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #include "playmask.h" #include #include #include #define WAIT_TIME_TO_MAXIMIZE_OVERLAY_MS 300 #include #include #include PlayMask::PlayMask(QWidget *parent) : QWidget(parent, Qt::SubWindow) { setWindowFlags(windowFlags() | Qt::SubWindow); setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); // setTransparent(true); setFixedSize(172, 172); play_Btn = new QPushButton(this); play_Btn->setObjectName("PlayMaskBtn"); play_Btn->setFocusPolicy(Qt::NoFocus); play_Btn->setFixedSize(172, 172); QHBoxLayout *layout = new QHBoxLayout; layout->addWidget(play_Btn); layout->setMargin(0); this->setLayout(layout); connect(play_Btn, SIGNAL(released()), this, SIGNAL(signal_play_continue())); } PlayMask::~PlayMask() { } void PlayMask::setTransparent(bool transparent) { if (transparent) { setAttribute(Qt::WA_TranslucentBackground); setWindowFlags(windowFlags() | Qt::FramelessWindowHint|Qt::X11BypassWindowManagerHint); set_widget_opacity(0.5); } else { setAttribute(Qt::WA_TranslucentBackground,false); setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint); } } void PlayMask::set_widget_opacity(const float &opacity) { QGraphicsOpacityEffect* opacityEffect = new QGraphicsOpacityEffect; this->setGraphicsEffect(opacityEffect); opacityEffect->setOpacity(opacity); } void PlayMask::paintEvent(QPaintEvent *event) { Q_UNUSED(event); // QStyleOption opt; // opt.init(this); // QPainter p(this); // style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); QPainter p(this); p.setCompositionMode(QPainter::CompositionMode_Clear); p.fillRect(rect(), Qt::SolidPattern);//p.fillRect(0, 0, this->width(), this->height(), Qt::SolidPattern); } kylin-video/src/kylin/helpdialog.cpp0000664000175000017500000001565113214706400016470 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #include "helpdialog.h" #include #include #include #include #include #include #include "supportformats.h" //#include "supportshortcuts.h" #include "titlebutton.h" #include "../smplayer/preferences.h" HelpDialog::HelpDialog(QWidget * parent, Qt::WindowFlags f) : QDialog(parent, f ) , drag_state(NOT_HDRAGGING) , start_drag(QPoint(0,0)) { setupUi(this); this->setFixedSize(675, 425); this->setStyleSheet("QDialog{border: 1px solid #121212;border-radius:1px;background-color:#1f1f1f;}"); this->setWindowIcon(QIcon(":/res/kylin-video.png")); this->setAttribute(Qt::WA_DeleteOnClose); this->setWindowFlags(Qt::FramelessWindowHint); this->setAutoFillBackground(true); this->setMouseTracking(true); installEventFilter(this); title_widget->setAutoFillBackground(true); title_widget->setStyleSheet("QWidget{border:none;background-color:#2e2e2e;}"); connect(okButton, SIGNAL(clicked()), this, SLOT(accept())); okButton->setFixedSize(91, 25); okButton->setFocusPolicy(Qt::NoFocus); okButton->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); title_label->setStyleSheet("QLabel{background:transparent;font-family: 方正黑体_GBK;font-size:20px;color:#999999;}"); QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 5, 0, 0); layout->setSpacing(0); page_formats = new SupportFormats; addSection(page_formats); pages->setCurrentWidget(page_formats); TitleButton *btn = new TitleButton(0, false, tr("Supported formats")); connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); layout->addWidget(btn); m_buttonList << btn; btn->setActived(true); // page_shortcuts = new SupportShortcuts; // addSection(page_shortcuts); // btn = new TitleButton(1, false, tr("Supported shortcuts")); // connect(btn, SIGNAL(clicked(int)), this, SLOT(onButtonClicked(int))); // layout->addWidget(btn); // m_buttonList << btn; layout->addStretch(); sections->setLayout(layout); retranslateStrings(); } HelpDialog::~HelpDialog() { for(int i=0; iid() == id) { button->setActived(true); } else { button->setActived(false); } } } void HelpDialog::onButtonClicked(int id) { setCurrentID(id); if (id == 0) { pages->setCurrentWidget(page_formats); } // else if (id == 1) { // pages->setCurrentWidget(page_shortcuts); // } } void HelpDialog::showSection(Section s) { qDebug("HelpDialog::showSection: %d", s); } void HelpDialog::retranslateStrings() { retranslateUi(this); icon_label->setPixmap(QPixmap(":/res/help.png")); okButton->setText(tr("OK")); } void HelpDialog::accept() { hide(); setResult( QDialog::Accepted ); emit applied(); } void HelpDialog::addSection(QWidget *w) { pages->addWidget(w); } void HelpDialog::setData(Preferences * pref) { page_formats->setData(); // page_shortcuts->setData(pref); } // Language change stuff void HelpDialog::changeEvent(QEvent *e) { if (e->type() == QEvent::LanguageChange) { retranslateStrings(); } else { QDialog::changeEvent(e); } } void HelpDialog::moveDialog(QPoint diff) { #if QT_VERSION >= 0x050000 // Move the window with some delay. // Seems to work better with Qt 5 static QPoint d; static int count = 0; d += diff; count++; if (count > 3) { QPoint new_pos = pos() + d; if (new_pos.y() < 0) new_pos.setY(0); if (new_pos.x() < 0) new_pos.setX(0); move(new_pos); count = 0; d = QPoint(0,0); } #else move(pos() + diff); #endif } bool HelpDialog::eventFilter( QObject * object, QEvent * event ) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { drag_state = NOT_HDRAGGING; return false; } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_HDRAGGING; return false; } drag_state = START_HDRAGGING; start_drag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (drag_state != HDRAGGING || mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_HDRAGGING; return false; } // Stop dragging and eat event drag_state = NOT_HDRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (drag_state == NOT_HDRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { drag_state = NOT_HDRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - start_drag; if (drag_state == START_HDRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; drag_state = HDRAGGING; } this->moveDialog(diff); start_drag = pos; event->accept(); return true; } //#include "moc_helpdialog.cpp" kylin-video/src/kylin/messagedialog.h0000664000175000017500000000423313214706400016623 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #ifndef _MESSAGEDIALOG_H_ #define _MESSAGEDIALOG_H_ #include #include #include #include class QPushButton; class QPoint; enum MDragState {NOT_MDRAGGING, START_MDRAGGING, MDRAGGING}; class MessageDialog : public QDialog { Q_OBJECT public: MessageDialog(QWidget *parent = 0, const QString &title = "", const QString &text = "", QMessageBox::StandardButtons buttons = QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::StandardButton defaultButton = QMessageBox::Ok); ~MessageDialog(); QAbstractButton *clickedButton() const; QMessageBox::StandardButton standardButton(QAbstractButton *button) const; // void setDefaultButton(QPushButton *button); // void setDefaultButton(QMessageBox::StandardButton button); void setIcon(const QString &icon); void setDialogSize(int w, int h); void initConnect(); virtual bool eventFilter(QObject *, QEvent *); void moveDialog(QPoint diff); private slots: void onButtonClicked(QAbstractButton *button); private: int returnCodeByRun(QAbstractButton *button); private: QLabel *title_label; QLabel *icon_label; QLabel *msg_label; QPushButton *close_Btn; // QGridLayout *gridLayout; QVBoxLayout *main_layout; QDialogButtonBox *buttonBox; QAbstractButton *clickedBtn; QAbstractButton *defaultBtn; MDragState drag_state; QPoint start_drag; }; #endif kylin-video/src/kylin/supportformats.cpp0000664000175000017500000001227513214706400017467 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #include "supportformats.h" #include #include #include "../smplayer/extensions.h" SupportFormats::SupportFormats(QWidget * parent, Qt::WindowFlags f) : QWidget(parent, f ) { setupUi(this); retranslateStrings(); } SupportFormats::~SupportFormats() { } void SupportFormats::retranslateStrings() { retranslateUi(this); groupBox_video->setStyleSheet("QGroupBox{border:none;margin-top:20px;font-size:14px;}QGroupBox:title{subcontrol-origin: margin;subcontrol-position: top left;padding: 0px 1px;color: #999999;font-family: 方正黑体_GBK;font-weight:bold;}"); groupBox_audio->setStyleSheet("QGroupBox{border:none;margin-top:20px;font-size:14px;}QGroupBox:title{subcontrol-origin: margin;subcontrol-position: top left;padding: 0px 1px;color: #999999;font-family: 方正黑体_GBK;font-weight:bold;}"); groupBox_subtitles->setStyleSheet("QGroupBox{border:none;margin-top:20px;font-size:14px;}QGroupBox:title{subcontrol-origin: margin;subcontrol-position: top left;padding: 0px 1px;color: #999999;font-family: 方正黑体_GBK;font-weight:bold;}"); vedio_edit->setStyleSheet("QTextEdit {border: 1px solid #000000;color: #999999;background: #0f0f0f;font-family:方正黑体_GBK;font-size: 12px;}"); vedio_edit->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {width: 12px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:vertical {width: 12px;min-height: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:vertical:hover {background: #3e3e3e;}QScrollBar::handle:vertical:pressed {background: #272727;}QScrollBar::sub-line:vertical {height: 6px;background: transparent;subcontrol-position: top;}QScrollBar::add-line:vertical {height: 6px;background: transparent;subcontrol-position: bottom;}QScrollBar::sub-line:vertical:hover {background: #292929;}QScrollBar::add-line:vertical:hover {background: #292929;}QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;}"); audio_edit->setStyleSheet("QTextEdit {border: 1px solid #000000;color: #999999;background: #0f0f0f;font-family:方正黑体_GBK;font-size: 12px;}"); audio_edit->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {width: 12px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:vertical {width: 12px;min-height: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:vertical:hover {background: #3e3e3e;}QScrollBar::handle:vertical:pressed {background: #272727;}QScrollBar::sub-line:vertical {height: 6px;background: transparent;subcontrol-position: top;}QScrollBar::add-line:vertical {height: 6px;background: transparent;subcontrol-position: bottom;}QScrollBar::sub-line:vertical:hover {background: #292929;}QScrollBar::add-line:vertical:hover {background: #292929;}QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;}"); subtitles_edit->setStyleSheet("QTextEdit {border: 1px solid #000000;color: #999999;background: #0f0f0f;font-family:方正黑体_GBK;font-size: 12px;}"); subtitles_edit->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {width: 12px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:vertical {width: 12px;min-height: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:vertical:hover {background: #3e3e3e;}QScrollBar::handle:vertical:pressed {background: #272727;}QScrollBar::sub-line:vertical {height: 6px;background: transparent;subcontrol-position: top;}QScrollBar::add-line:vertical {height: 6px;background: transparent;subcontrol-position: bottom;}QScrollBar::sub-line:vertical:hover {background: #292929;}QScrollBar::add-line:vertical:hover {background: #292929;}QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;}"); QString video_tip = QString(tr("Some video formats do not support preview and seek by dragging, e.g. the swf.")); vedio_edit->setToolTip(""+ video_tip +""); } void SupportFormats::setData() { vedio_edit->clear(); audio_edit->clear(); subtitles_edit->clear(); Extensions e; vedio_edit->setText(e.video().forFilter()); audio_edit->setText(e.audio().forFilter()); subtitles_edit->setText(e.subtitles().forFilter()); vedio_edit->verticalScrollBar()->setValue(0); audio_edit->verticalScrollBar()->setValue(0); subtitles_edit->verticalScrollBar()->setValue(0); } //#include "moc_supportformats.cpp" kylin-video/src/kylin/aboutdialog.cpp0000664000175000017500000002307713214706400016653 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #include "aboutdialog.h" #include "../smplayer/images.h" #include "../smplayer/version.h" #include "../smplayer/global.h" #include "../smplayer/preferences.h" #include "../smplayer/paths.h" #include "../smplayer/inforeader.h" #include #include #include #include #include #include #include using namespace Global; AboutDialog::AboutDialog(QWidget * parent, Qt::WindowFlags f) : QDialog(parent, f) , drag_state(NOT_ADRAGGING) , tab_state(TAB_ABOUT) , start_drag(QPoint(0,0)) { setupUi(this); this->setWindowFlags(Qt::FramelessWindowHint); this->setFixedSize(438, 320); this->setStyleSheet("QDialog{border: 1px solid #121212;border-radius:1px;background-color: #ffffff;}"); this->setWindowIcon(QIcon(":/res/kylin-video.png"));//setWindowIcon( Images::icon("logo", 64) ); this->setAutoFillBackground(true); this->setMouseTracking(true); installEventFilter(this); // logo->setPixmap( QPixmap(":/default-theme/logo.png").scaledToHeight(64, Qt::SmoothTransformation) );//setPixmap( Images::icon("contributors" ) ); aboutGroup = NULL; contributorGroup = NULL; baseWidget->setAutoFillBackground(true); QPalette palette; palette.setBrush(QPalette::Background, QBrush(QPixmap(":/res/about_bg.png"))); baseWidget->setPalette(palette); closeBtn->setFocusPolicy(Qt::NoFocus); aboutBtn->setFocusPolicy(Qt::NoFocus); contributorBtn->setFocusPolicy(Qt::NoFocus); closeBtn->setStyleSheet("QPushButton{background-image:url(':/res/close_normal.png');border:0px;}QPushButton:hover{background:url(':/res/close_hover.png');}QPushButton:pressed{background:url(':/res/close_press.png');}"); // indicator->setStyleSheet("QLabel{background-image:url('://res/underline.png');background-position:center;}"); indicator->setStyleSheet("QLabel{background:#0a9ff5;background-position:center;}"); aboutBtn->setStyleSheet("QPushButton{background:transparent;border:none;text-align:center;font-family: 方正黑体_GBK;font-size:14px;color:#ffffff;}"); contributorBtn->setStyleSheet("QPushButton{background:transparent;border:none;text-align:center;font-family: 方正黑体_GBK;font-size:14px;color:#ffffff;}"); okBtn = buttonBox->button(QDialogButtonBox::Ok); okBtn->setFixedSize(91, 25); okBtn->setText(tr("OK")); okBtn->setFocusPolicy(Qt::NoFocus); okBtn->setStyleSheet("QPushButton{font-size:12px;background:#ffffff;border:1px solid #0a9ff5;color:#000000;}QPushButton:hover{background-color:#ffffff;border:1px solid #3f96e4;color:#000000;} QPushButton:pressed{background-color:#ffffff;border:1px solid #3f96e4;color:#000000;}"); this->initConnect(); this->initAnimation(); // InfoReader * i = InfoReader::obj(pref->mplayer_bin); // i->getInfo(); // aboutText->setText( // "
    " + // tr("Kylin Video is a graphical interface for MPlayer and MPV.") + "
    " + // "" + tr("Kylin Video") + tr("Version: %1").arg(Version::printable()) + "" + "
    " + // tr("Using Qt %1 (compiled with Qt %2)").arg(qVersion()).arg(QT_VERSION_STR) + "
    " + // tr("Playback engine:") + i->playerVersion() + "

    " // ); contributorText->setText("
    © 2006-2015 Ricardo Villalba <rvm@users.sourceforge.net>
    © 2017 lixiang <lixiang@kylinos.cn>

    "); contributorText->hide(); adjustSize(); aboutText->setStyleSheet("QTextBrowser{background-color:transparent;border:none;font-family:方正黑体_GBK;font-size:12px;color:#999999;}"); contributorText->setStyleSheet("QTextBrowser{background-color:transparent;border:none;font-family:方正黑体_GBK;font-size:12px;color:#999999;}"); /*


    */ } AboutDialog::~AboutDialog() { if(aboutGroup != NULL) { delete aboutGroup; aboutGroup = NULL; } if(contributorGroup != NULL) { delete contributorGroup; contributorGroup = NULL; } } void AboutDialog::initConnect() { connect(closeBtn, SIGNAL(clicked()), this, SLOT(accept())); connect(okBtn, SIGNAL(clicked()), this, SLOT(accept())); connect(aboutBtn, SIGNAL(clicked()), this, SLOT(onAboutBtnClicked())); connect(contributorBtn, SIGNAL(clicked()), this, SLOT(onContributorBtnClicked())); } void AboutDialog::initAnimation() { QRect mainAcitonRect(230, 70, 85, 2); QRect origAcitonRect(320, 70, 85, 2); QPropertyAnimation *aboutAnimation = new QPropertyAnimation(indicator, "geometry"); aboutAnimation->setDuration(300); aboutAnimation->setStartValue(origAcitonRect); aboutAnimation->setEndValue(mainAcitonRect); aboutGroup = new QParallelAnimationGroup(this); aboutGroup->addAnimation(aboutAnimation); QPropertyAnimation *contributorAnimation = new QPropertyAnimation(indicator, "geometry"); contributorAnimation->setDuration(300); contributorAnimation->setStartValue(mainAcitonRect); contributorAnimation->setEndValue(origAcitonRect); contributorGroup = new QParallelAnimationGroup(this); contributorGroup->addAnimation(contributorAnimation); } void AboutDialog::setVersions() { InfoReader * i = InfoReader::obj(pref->mplayer_bin); i->getInfo(); aboutText->setText( "
    " + tr("Kylin Video is developed on the basis of KylinVideo, is a graphical interface for MPlayer and MPV.") + "
    " + "" + tr("Kylin Video") + tr("Version: %1").arg(Version::printable()) + "" + "
    " + tr("Using Qt %1 (compiled with Qt %2)").arg(qVersion()).arg(QT_VERSION_STR) + "
    " + tr("Playback engine:") + i->playerVersion() + "

    " ); } void AboutDialog::onAboutBtnClicked() { if (tab_state != TAB_ABOUT) { tab_state = TAB_ABOUT; aboutGroup->start(); aboutText->show(); contributorText->hide(); } } void AboutDialog::onContributorBtnClicked() { if (tab_state != TAB_CONTRIBUTOR) { tab_state = TAB_CONTRIBUTOR; contributorGroup->start(); contributorText->show(); aboutText->hide(); } } void AboutDialog::moveDialog(QPoint diff) { #if QT_VERSION >= 0x050000 // Move the window with some delay. // Seems to work better with Qt 5 static QPoint d; static int count = 0; d += diff; count++; if (count > 3) { QPoint new_pos = pos() + d; if (new_pos.y() < 0) new_pos.setY(0); if (new_pos.x() < 0) new_pos.setX(0); move(new_pos); count = 0; d = QPoint(0,0); } #else move(pos() + diff); #endif } bool AboutDialog::eventFilter( QObject * object, QEvent * event ) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { drag_state = NOT_ADRAGGING; return false; } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_ADRAGGING; return false; } drag_state = START_ADRAGGING; start_drag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (drag_state != ADRAGGING || mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_ADRAGGING; return false; } // Stop dragging and eat event drag_state = NOT_ADRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (drag_state == NOT_ADRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { drag_state = NOT_ADRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - start_drag; if (drag_state == START_ADRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; drag_state = ADRAGGING; } this->moveDialog(diff); start_drag = pos; event->accept(); return true; } kylin-video/src/kylin/aboutdialog.ui0000664000175000017500000001001113214706400016466 0ustar fengfeng AboutDialog 0 0 438 320 438 320 438 320 About 0 0 438 81 0 0 402 1 36 36 230 40 85 24 About 320 40 85 24 Contributor 230 70 85 2 5 82 428 190 QFrame::NoFrame QFrame::Plain true 5 82 428 190 QFrame::NoFrame QFrame::Plain <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> true 0 285 428 27 Qt::Horizontal QDialogButtonBox::Ok kylin-video/src/kylin/messagedialog.cpp0000664000175000017500000002257713214706400017171 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #include "messagedialog.h" #include #include #include #include #include MessageDialog::MessageDialog(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton) : QDialog(parent) , drag_state(NOT_MDRAGGING) , start_drag(QPoint(0,0)) { this->setWindowFlags(Qt::FramelessWindowHint); this->setStyleSheet("QDialog{border: 1px solid #121212;border-radius:1px;background-color:#1f1f1f;}"); this->setWindowTitle(title); this->setWindowIcon(QIcon(":/res/kylin-video.png"));//setWindowIcon( Images::icon("logo", 64) ); this->setAutoFillBackground(true); this->setMouseTracking(true); installEventFilter(this); title_label = new QLabel(this); title_label->setAlignment(Qt::AlignCenter); title_label->setStyleSheet("QLabel{background:transparent;font-size:14px;color:#999999;font-family:方正黑体_GBK;}");//font-weight:bold; title_label->setText(title); close_Btn = new QPushButton(this); close_Btn->setFixedSize(36,36); close_Btn->setFocusPolicy(Qt::NoFocus); close_Btn->setStyleSheet("QPushButton{background-image:url(':/res/close_normal.png');border:0px;}QPushButton:hover{background:url(':/res/close_hover.png');}QPushButton:pressed{background:url(':/res/close_press.png');}"); QHBoxLayout *title_layout = new QHBoxLayout(); title_layout->addWidget(title_label); title_layout->addStretch(); title_layout->addWidget(close_Btn); title_layout->setMargin(0); title_layout->setContentsMargins(5,0,0,0); buttonBox = new QDialogButtonBox(this); buttonBox->setStandardButtons(QDialogButtonBox::StandardButtons(int(buttons))); QPushButton *okBtn = buttonBox->button(QDialogButtonBox::Ok); if (okBtn != NULL) { okBtn->setFixedSize(91, 25); okBtn->setText(tr("Ok")); okBtn->setFocusPolicy(Qt::NoFocus); okBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); } QPushButton *cancelBtn = buttonBox->button(QDialogButtonBox::Cancel); if (cancelBtn != NULL) { cancelBtn->setFixedSize(91, 25); cancelBtn->setText(tr("Cancel")); cancelBtn->setFocusPolicy(Qt::NoFocus); cancelBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #000000;color:#999999;}QPushButton:hover{background-color:#1f1f1f;border:1px solid #0f0f0f;color:#ffffff;} QPushButton:pressed{background-color:#0d0d0d;border:1px solid #000000;color:#ffffff;}"); } QPushButton *yesBtn = buttonBox->button(QDialogButtonBox::Yes); if (yesBtn != NULL) { yesBtn->setFixedSize(91, 25); yesBtn->setText(tr("Yes")); yesBtn->setFocusPolicy(Qt::NoFocus); yesBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); } QPushButton *noBtn = buttonBox->button(QDialogButtonBox::No); if (noBtn != NULL) { noBtn->setFixedSize(91, 25); noBtn->setText(tr("No")); noBtn->setFocusPolicy(Qt::NoFocus); noBtn->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #000000;color:#999999;}QPushButton:hover{background-color:#1f1f1f;border:1px solid #0f0f0f;color:#ffffff;} QPushButton:pressed{background-color:#0d0d0d;border:1px solid #000000;color:#ffffff;}"); } icon_label = new QLabel(this); QPixmap pixmap(":/res/warn.png"); icon_label->setPixmap(pixmap); // icon_label->setFixedSize(60, 58); // icon_label->setScaledContents(true); icon_label->adjustSize(); icon_label->setWordWrap(true); msg_label = new QLabel(this); msg_label->setMinimumWidth(100); msg_label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); msg_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#999999;font-family:方正黑体_GBK;}");//font-weight:bold; msg_label->setOpenExternalLinks(true); msg_label->setText(text); QHBoxLayout *hlayout = new QHBoxLayout(); hlayout->setMargin(0); hlayout->setContentsMargins(30,0,30,0); hlayout->setSpacing(30); hlayout->addStretch(); hlayout->addWidget(icon_label); hlayout->addWidget(msg_label); hlayout->addStretch(); QHBoxLayout *blayout = new QHBoxLayout(); blayout->addStretch(); blayout->addWidget(buttonBox); blayout->setContentsMargins(10,0,10,0); main_layout = new QVBoxLayout(this); main_layout->addLayout(title_layout); main_layout->addLayout(hlayout); main_layout->addLayout(blayout); main_layout->setMargin(0); main_layout->setSpacing(10); main_layout->setContentsMargins(0, 0, 0, 10); this->layout()->setSizeConstraint(QLayout::SetFixedSize); this->initConnect(); } MessageDialog::~MessageDialog() { } void MessageDialog::setDialogSize(int w, int h) { this->setFixedSize(w, h); } void MessageDialog::setIcon(const QString &icon) { icon_label->setPixmap(QPixmap(icon)); } QMessageBox::StandardButton MessageDialog::standardButton(QAbstractButton *button) const { return (QMessageBox::StandardButton)buttonBox->standardButton(button); } QAbstractButton *MessageDialog::clickedButton() const { return clickedBtn; } int MessageDialog::returnCodeByRun(QAbstractButton *button) { int ret = buttonBox->standardButton(button); return ret; } void MessageDialog::onButtonClicked(QAbstractButton *button) { clickedBtn = button; done(returnCodeByRun(button)); } //void MessageDialog::setDefaultButton(QPushButton *button) //{ // if (!buttonBox->buttons().contains(button)) // return; // defaultBtn = button; // button->setDefault(true); // button->setFocus(); //} //void MessageDialog::setDefaultButton(QMessageBox::StandardButton button) //{ // setDefaultButton(buttonBox->button(QDialogButtonBox::StandardButton(button))); //} void MessageDialog::initConnect() { connect(close_Btn, SIGNAL(clicked()), this, SLOT(close())); connect(buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(onButtonClicked(QAbstractButton*))); } void MessageDialog::moveDialog(QPoint diff) { #if QT_VERSION >= 0x050000 // Move the window with some delay. // Seems to work better with Qt 5 static QPoint d; static int count = 0; d += diff; count++; if (count > 3) { QPoint new_pos = pos() + d; if (new_pos.y() < 0) new_pos.setY(0); if (new_pos.x() < 0) new_pos.setX(0); move(new_pos); count = 0; d = QPoint(0,0); } #else move(pos() + diff); #endif } bool MessageDialog::eventFilter( QObject * object, QEvent * event ) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { drag_state = NOT_MDRAGGING; return false; } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_MDRAGGING; return false; } drag_state = START_MDRAGGING; start_drag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (drag_state != MDRAGGING || mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_MDRAGGING; return false; } // Stop dragging and eat event drag_state = NOT_MDRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (drag_state == NOT_MDRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { drag_state = NOT_MDRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - start_drag; if (drag_state == START_MDRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; drag_state = MDRAGGING; } this->moveDialog(diff); start_drag = pos; event->accept(); return true; } kylin-video/src/kylin/playlistview.cpp0000664000175000017500000001266013214706400017111 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #include "playlistview.h" #include #include #include #include #include "playlistitem.h" PlayListView::PlayListView(QWidget *parent) : QListWidget(parent) { setObjectName("PlayListView");//kobe:设置选中项的左侧的颜色栏 scrollBarWidth = 8;//滚动条的宽度 itemHeight = 32;//每个item的高度 /*setAcceptDrops(true)来接受放下事件,通过设置setDropIndicatorShown(true)则可以清晰地看到放下过程中的图标指示。 * 然后实现dragEnterEvent()、dropEvent()方法,当用户把一个对象拖动到这个窗体上时,就会调用dragEnterEvent(), * 如果对这个事件调用acceptProposedAction(),就表明可以在这个窗体上拖放对象。默认情况下窗口部件是不接受拖动的。 * Qt会自动改变光标向用户说明这个窗口部件不是有效的放下点。 */ setDragEnabled(true); // viewport()->setAcceptDrops(true);//不允许listitem项拖动 setDropIndicatorShown(true); setDefaultDropAction(Qt::MoveAction); // setDragDropMode(QAbstractItemView::DragOnly); // setResizeMode(QListWidget::Adjust); setMovement(QListWidget::Static);//设置单元项不可拖动 setSelectionMode(QListView::SingleSelection); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); this->setContextMenuPolicy(Qt::CustomContextMenu); // this->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {width: 12px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:vertical {width: 12px;min-height: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:vertical:hover {background: #3e3e3e;}QScrollBar::handle:vertical:pressed {background: #272727;}QScrollBar::sub-line:vertical {height: 6px;background: transparent;subcontrol-position: top;}QScrollBar::add-line:vertical {height: 6px;background: transparent;subcontrol-position: bottom;}QScrollBar::sub-line:vertical:hover {background: #292929;}QScrollBar::add-line:vertical:hover {background: #292929;}QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;}"); // this->verticalScrollBar()->setObjectName("PlayListViewScrollBar");//kobe:让滚动条可以鼠标拖动 // this->verticalScrollBar()->setFixedWidth(scrollBarWidth); //// this->verticalScrollBar()->move(this->size().width() - scrollBarWidth, 0); // this->verticalScrollBar()->setSingleStep(1); vscrollBar = new QScrollBar(this); vscrollBar->setObjectName("PlayListViewScrollBar");//kobe:让滚动条可以鼠标拖动 vscrollBar->setStyleSheet("QScrollBar:vertical {width: 12px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:vertical {width: 12px;min-height: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:vertical:hover {background: #3e3e3e;}QScrollBar::handle:vertical:pressed {background: #272727;}QScrollBar::sub-line:vertical {height: 6px;background: transparent;subcontrol-position: top;}QScrollBar::add-line:vertical {height: 6px;background: transparent;subcontrol-position: bottom;}QScrollBar::sub-line:vertical:hover {background: #292929;}QScrollBar::add-line:vertical:hover {background: #292929;}QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;}"); vscrollBar->setOrientation(Qt::Vertical); vscrollBar->raise(); connect(vscrollBar, SIGNAL(valueChanged(int)), this ,SLOT(slot_scrollbar_value_changed(int))); } PlayListView::~PlayListView() { if (vscrollBar != NULL) { delete vscrollBar; vscrollBar = NULL; } } void PlayListView::checkScrollbarSize() { int itemCount = this->model()->rowCount(); QSize size = this->size(); vscrollBar->resize(scrollBarWidth, size.height() - 2); vscrollBar->move(size.width() - scrollBarWidth , 0); vscrollBar->setSingleStep(1); vscrollBar->setPageStep(size.height() / itemHeight); if (itemCount > size.height() / itemHeight) { vscrollBar->show(); vscrollBar->setMaximum(itemCount - size.height() / itemHeight); } else { vscrollBar->hide(); vscrollBar->setMaximum(0); } } void PlayListView::slot_scrollbar_value_changed(int value) { this->verticalScrollBar()->setValue(value); } void PlayListView::wheelEvent(QWheelEvent *event) { QListWidget::wheelEvent(event); this->vscrollBar->setSliderPosition(verticalScrollBar()->sliderPosition()); } void PlayListView::resizeEvent(QResizeEvent *event) { QListWidget::resizeEvent(event); this->checkScrollbarSize(); } void PlayListView::updateScrollbar() { this->checkScrollbarSize(); } kylin-video/src/kylin/supportshortcuts.h0000664000175000017500000000223013214706400017505 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #ifndef _SUPPORTSHORTCUTS_H_ #define _SUPPORTSHORTCUTS_H_ #include "ui_supportshortcuts.h" #include "../smplayer/preferences.h" class SupportShortcuts : public QWidget, public Ui::SupportShortcuts { Q_OBJECT public: SupportShortcuts( QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~SupportShortcuts(); void setData(Preferences * pref); protected: virtual void retranslateStrings(); }; #endif kylin-video/src/kylin/playlistview.h0000664000175000017500000000245713214706400016561 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #include #include class PlayListView : public QListWidget { Q_OBJECT public: explicit PlayListView(QWidget *parent = 0); ~PlayListView(); void checkScrollbarSize(); public slots: void updateScrollbar(); void slot_scrollbar_value_changed(int value); signals: void customResort(const QStringList &uuids); protected: virtual void wheelEvent(QWheelEvent *event); virtual void resizeEvent(QResizeEvent *event); private: QScrollBar *vscrollBar; int scrollBarWidth; int itemHeight; }; kylin-video/src/kylin/supportshortcuts.cpp0000664000175000017500000001345113214706400020047 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #include "supportshortcuts.h" #include #include #include "../smplayer/extensions.h" #include "../smplayer/helper.h" #include "../smplayer/global.h" #include "../smplayer/preferences.h" using namespace Global; SupportShortcuts::SupportShortcuts(QWidget * parent, Qt::WindowFlags f) : QWidget(parent, f ) { setupUi(this); // groupBox_play->setParent(this); // groupBox_other->setParent(this); retranslateStrings(); } SupportShortcuts::~SupportShortcuts() { } void SupportShortcuts::retranslateStrings() { retranslateUi(this); groupBox_play->setStyleSheet("QGroupBox{border:none;margin-top:20px;font-size:14px;}QGroupBox:title{subcontrol-origin: margin;subcontrol-position: top left;padding: 0px 1px;color: #999999;font-family: 方正黑体_GBK;font-weight:bold;}"); groupBox_other->setStyleSheet("QGroupBox{border:none;margin-top:20px;font-size:14px;}QGroupBox:title{subcontrol-origin: margin;subcontrol-position: top left;padding: 0px 1px;color: #999999;font-family: 方正黑体_GBK;font-weight:bold;}"); play_edit->setStyleSheet("QTextEdit {border: 1px solid #000000;color: #999999;background: #0f0f0f;font-family:方正黑体_GBK;font-size: 12px;}"); play_edit->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {width: 12px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:vertical {width: 12px;min-height: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:vertical:hover {background: #3e3e3e;}QScrollBar::handle:vertical:pressed {background: #272727;}QScrollBar::sub-line:vertical {height: 6px;background: transparent;subcontrol-position: top;}QScrollBar::add-line:vertical {height: 6px;background: transparent;subcontrol-position: bottom;}QScrollBar::sub-line:vertical:hover {background: #292929;}QScrollBar::add-line:vertical:hover {background: #292929;}QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;}"); other_edit->setStyleSheet("QTextEdit {border: 1px solid #000000;color: #999999;background: #0f0f0f;font-family:方正黑体_GBK;font-size: 12px;}"); other_edit->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {width: 12px;background: #141414;margin:0px 0px 0px 0px;border:1px solid #141414;}QScrollBar::handle:vertical {width: 12px;min-height: 45px;background: #292929;margin-left: 0px;margin-right: 0px;}QScrollBar::handle:vertical:hover {background: #3e3e3e;}QScrollBar::handle:vertical:pressed {background: #272727;}QScrollBar::sub-line:vertical {height: 6px;background: transparent;subcontrol-position: top;}QScrollBar::add-line:vertical {height: 6px;background: transparent;subcontrol-position: bottom;}QScrollBar::sub-line:vertical:hover {background: #292929;}QScrollBar::add-line:vertical:hover {background: #292929;}QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: transparent;}"); } void SupportShortcuts::setData(Preferences * pref) { play_edit->clear(); other_edit->clear(); play_edit->append(tr("Play/Pause: Space")); // play_edit->append(tr("Previous: <, Media Previous")); // play_edit->append(tr("Next: >, Media Next")); play_edit->append(tr("Previous: %1").arg(pref->prev_key)); play_edit->append(tr("Next: %1").arg(pref->next_key)); QString line = QString(tr("Forward %1: Right(→)").arg(Helper::timeForJumps(pref->seeking1))); play_edit->append(line); line = QString(tr("Forward %1: Up(↑)").arg(Helper::timeForJumps(pref->seeking2))); play_edit->append(line); line = QString(tr("Forward %1: PgUp").arg(Helper::timeForJumps(pref->seeking3))); play_edit->append(line); line = QString(tr("Rewind %1: Left(←)").arg(Helper::timeForJumps(pref->seeking1))); play_edit->append(line); line = QString(tr("Rewind %1: Down(↓)").arg(Helper::timeForJumps(pref->seeking2))); play_edit->append(line); line = QString(tr("Rewind %1: PgDn").arg(Helper::timeForJumps(pref->seeking3))); play_edit->append(line); play_edit->append(tr("Jump to...: Ctrl + J")); play_edit->append(tr("Mute: M")); play_edit->append(tr("Volume +: 9")); play_edit->append(tr("Volume -: 0")); play_edit->append(tr("Set audio delay: Y")); play_edit->append(tr("Increase or decrease audio delay: + / - / =")); other_edit->append(tr("Playlist: %1").arg(pref->playlist_key));//F3 other_edit->append(tr("Open File: Ctrl + F")); other_edit->append(tr("Screenshot: S")); other_edit->append(tr("Preferences: Ctrl + P")); other_edit->append(tr("View info and properties...: Ctrl + I")); other_edit->append(tr("About: Ctrl + A")); other_edit->append(tr("Quit: Ctrl + Q")); other_edit->append(tr("FullScreen/Cancel fullScreen: Ctrl + Enter")); play_edit->verticalScrollBar()->setValue(0);//滚动到最顶层 无效?????????????????????? // play_edit->verticalScrollBar()->setValue(play_edit->verticalScrollBar()->maximum());//滚动到最底层 other_edit->verticalScrollBar()->setValue(0); } //#include "moc_supportshortcuts.cpp" kylin-video/src/kylin/bottomwidget.h0000664000175000017500000002161213214706400016527 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #ifndef BOTTOMWIDGET_H #define BOTTOMWIDGET_H #include #include #include #include #include #include #include #include #include #include #include #include #include class MplayerWindow; class QTimer; class QPropertyAnimation; class TimeSlider; class SoundVolume; class MyAction; enum BottomDragState {NOT_BDRAGGING, START_BDRAGGING, BDRAGGING}; class BottomWidget : public QWidget { Q_OBJECT public: explicit BottomWidget(QWidget *parent = 0); ~BottomWidget(); // enum Activation { Anywhere = 1, Bottom = 2 }; void enable_turned_on(); void update_widget_qss_property(QWidget *w, const char *name, const QVariant &value); void showAlways(); QString get_status(); void show_control_widget(); void setPreviewData(bool preview); // void setParentWindow(MplayerWindow* window) { p_mainwindow = window;} // void setParentWindow(MplayerWindow* window); signals: void sig_resize_corner(); void changeProgress(qint64 value, qint64 m_duration); void volumeChanged(int volume); void toggleMute(); void togglePlaylist(); void toggleFullScreen(); void signal_stop(); void signal_prev(); void signal_play_pause_status(); void signal_next(); void signal_open_file(); void signal_mute(/*bool*/); void mouseMoving(Qt::MouseButton botton); void start_open_file(); void valueChanged(int); void posChanged(int); void draggingPos(int); void delayedDraggingPos(int); void wheelUp(); void wheelDown(); void mouseMovedDiff(QPoint);//kobe void sig_show_or_hide_esc(bool b); void resize_bottom_widget_height(bool b); void need_to_save_pre_image(int time);//kobe void send_save_preview_image_name(int time, QString filepath);//kobe public slots: void showWidget(); void activate(); void deactivate(); void setMargin(int margin) { spacing = margin; }; // void setActivationArea(Activation m) { activation_area = m; } void setHideDelay(int ms); void slot_volumn_changed(int vol); void slot_playlist_btn_status(bool b); void onMusicPlayed(); void onMusicPause(); void onMusicStoped(); void onVolumeChanged(int volume); void onMutedChanged(bool muted, int volumn); void onFullScreen(); void onUnFullScreen(); void displayTime(QString cur_time, QString all_time); void setActionsEnabled(bool b); void setPlayOrPauseEnabled(bool b); void setStopEnabled(bool b); //progress virtual void setPos(int); virtual int ppos(); virtual void setDuration(double); virtual double duration() { return total_time; }; void setDragDelay(int); int dragDelay(); void slot_active_status(bool b); void spreadAniFinished(); void gatherAniFinished(); void update_playlist_count_label(int count); public: bool isActive() { return turned_on; }; int margin() { return spacing; }; // Activation activationArea() { return activation_area; } int hideDelay(); void setTransparent(bool transparent); void set_widget_opacity(const float &opacity=0.8); protected: bool eventFilter(QObject * obj, QEvent * event); virtual void resizeEvent(QResizeEvent *event); // virtual void mouseMoveEvent(QMouseEvent *event); // void mousePressEvent(QMouseEvent *); // void mouseMoveEvent(QMouseEvent *); // void mouseReleaseEvent(QMouseEvent *); // signals: // void signalMovePoint(QPoint); private slots: void checkUnderMouse(); void showSpreadAnimated(); void showGatherAnimated(); private: void installFilter(QObject *o); private: bool turned_on; int spacing; // Activation activation_area; QWidget * internal_widget; QTimer * timer; QPropertyAnimation *spreadAnimation; QPropertyAnimation *gatherAnimation; QLabel *playtime_label; QLabel *alltime_label; QPushButton *btStop; QPushButton *btPrev; QPushButton *btPlayPause; QPushButton *btNext; QPushButton *btSound; QPushButton *btFullScreen; QPushButton *btPlayList; QLabel *listCountLabel; TimeSlider *progress; QWidget *controlWidget; SoundVolume *volSlider; QFrame *metaWidget; QFrame *ctlWidget; QWidget *actWidget; bool enableMove; double total_time; int drag_delay; BottomDragState drag_state; QPoint start_drag; // bool isLeftPressDown; // 判断左键是否按下 QVBoxLayout *vboxlayout; // MplayerWindow *p_mainwindow; }; /*class BottomWidget : public QWidget { Q_OBJECT public: explicit BottomWidget(QWidget *parent = 0); ~BottomWidget(); enum Activation { Anywhere = 1, Bottom = 2 }; void enable_turned_on(); void update_widget_qss_property(QWidget *w, const char *name, const QVariant &value); void showAlways(); void show_control_widget(); void setPreviewData(bool preview); bool getCtrlWidgetVisible(); signals: void sig_resize_corner(); void changeProgress(qint64 value, qint64 m_duration); void volumeChanged(int volume); void toggleMute(); void togglePlaylist(); void toggleFullScreen(); void signal_stop(); void signal_prev(); void signal_play_pause_status(); void signal_next(); void signal_open_file(); void signal_mute(); void mouseMoving(Qt::MouseButton botton); void start_open_file(); void valueChanged(int); void posChanged(int); void draggingPos(int); void delayedDraggingPos(int); void wheelUp(); void wheelDown(); void mouseMovedDiff(QPoint);//kobe void sig_show_or_hide_esc(bool b); void resize_bottom_widget_height(bool b); void need_to_save_pre_image(int time);//kobe void send_save_preview_image_name(int time, QString filepath);//kobe public slots: void setMargin(int margin) { spacing = margin; }; void setActivationArea(Activation m) { activation_area = m; } void slot_volumn_changed(int vol); void slot_playlist_btn_status(bool b); void onMusicPlayed(); void onMusicPause(); void onMusicStoped(); void onVolumeChanged(int volume); void onMutedChanged(bool muted, int volumn); void onFullScreen(); void onUnFullScreen(); void displayTime(QString cur_time, QString all_time); void setActionsEnabled(bool b); void setPlayOrPauseEnabled(bool b); void setStopEnabled(bool b); //progress virtual void setPos(int); virtual int ppos(); virtual void setDuration(double); virtual double duration() { return total_time; }; void setDragDelay(int); int dragDelay(); void slot_active_status(bool b); void spreadAniFinished(); void gatherAniFinished(); void update_playlist_count_label(int count); void showSpreadAnimated(); void showGatherAnimated(); public: bool isActive() { return turned_on; }; int margin() { return spacing; }; Activation activationArea() { return activation_area; } void setTransparent(bool transparent); void set_widget_opacity(const float &opacity=0.8); protected: virtual void resizeEvent(QResizeEvent *event); private: void installFilter(QObject *o); private: bool turned_on; int spacing; Activation activation_area; QWidget * internal_widget; QPropertyAnimation *spreadAnimation; QPropertyAnimation *gatherAnimation; QLabel *playtime_label; QLabel *alltime_label; QPushButton *btStop; QPushButton *btPrev; QPushButton *btPlayPause; QPushButton *btNext; QPushButton *btSound; QPushButton *btFullScreen; QPushButton *btPlayList; QLabel *listCountLabel; TimeSlider *progress; QWidget *controlWidget; SoundVolume *volSlider; QFrame *metaWidget; QFrame *ctlWidget; QWidget *actWidget; bool enableMove; double total_time; int drag_delay; BottomDragState drag_state; QPoint start_drag; QVBoxLayout *vboxlayout; };*/ #endif // BOTTOMWIDGET_H kylin-video/src/kylin/systembutton.cpp0000664000175000017500000000363613214706400017140 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #include "systembutton.h" #include SystemButton::SystemButton(QWidget *parent) : QPushButton(parent) { this->setMouseTracking(false); status = NORMAL; mouse_press = false; } void SystemButton::loadPixmap(QString pic_name) { pixmap = QPixmap(pic_name); btn_width = pixmap.width()/3; btn_height = pixmap.height(); this->setFixedSize(btn_width, btn_height); } void SystemButton::enterEvent(QEvent *) { status = ENTER; update(); } void SystemButton::mousePressEvent(QMouseEvent *event) { if(event->button() == Qt::LeftButton) { mouse_press = true; status = PRESS; update(); } } void SystemButton::mouseReleaseEvent(QMouseEvent *event) { if(mouse_press && this->rect().contains(event->pos())) { mouse_press = false; status = ENTER; update(); emit clicked(); } } void SystemButton::leaveEvent(QEvent *) { status = NORMAL; update(); } void SystemButton::paintEvent(QPaintEvent *) { QPainter painter; painter.begin(this); painter.drawPixmap(this->rect(), pixmap.copy(btn_width * status, 0, btn_width, btn_height)); painter.end(); } kylin-video/src/kylin/playlistitem.h0000664000175000017500000000552313214706400016542 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #ifndef PLAYLISTITEM_H #define PLAYLISTITEM_H #include class QLineEdit; class QLabel; class QPushButton; class PlayListItem : public QFrame { Q_OBJECT Q_PROPERTY(QString animationPrefix READ animationPrefix WRITE setAnimationPrefix) Q_PROPERTY(QString highlightAnimationPrefix READ highlightAnimationPrefix WRITE setHighlightAnimationPrefix) public: explicit PlayListItem(QString mtype, QString filename, QString name, double duration, QWidget *parent = 0); void setName(QString name) { m_name = name; }; void setDuration(double duration) { m_duration = duration; }; void setPlayed(bool b) { m_played = b; }; void setMarkForDeletion(bool b) { m_deleted = b; }; QString filename() { return m_filename; }; QString name() { return m_name; }; double duration() { return m_duration; }; bool played() { return m_played; }; bool markedForDeletion() { return m_deleted; }; inline QString data() {return m_data;} void setActive(bool active); void mouseDoubleClickEvent(QMouseEvent *event); QString animationPrefix() const { return m_animationPrefix; } QString highlightAnimationPrefix() const { return m_highlightAnimationPrefix; } QString m_filename, m_name; double m_duration; bool m_played, m_deleted; void update_widget_qss_property(QWidget *w, const char *name, const QVariant &value); signals: void rename(const QString &newNameA); void remove(QString filename); void sig_doubleclicked_resource(QString filename); public slots: void onDelete(); void setAnimationPrefix(QString animationPrefix) { m_animationPrefix = animationPrefix; } void setHighlightAnimationPrefix(QString highlightAnimationPrefix) { m_highlightAnimationPrefix = highlightAnimationPrefix; } void update_time(QString duration); private: QLabel *icon_label; QLineEdit *m_titleedit; QLabel *time_label; QPushButton *delete_btn; QString m_data; QString m_animationPrefix; QString m_highlightAnimationPrefix; }; #endif // PLAYLISTITEM_H kylin-video/src/kylin/titlewidget.h0000664000175000017500000001355413214706400016352 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #ifndef TITLEWIDGET_H #define TITLEWIDGET_H #include #include #include #include #include #include #include #include #include #include "systembutton.h" class QHBoxLayout; class QProcess; class QMenu; class QTimer; class QPropertyAnimation; enum TitleDragState {NOT_TDRAGGING, START_TDRAGGING, TDRAGGING}; class TitleWidget : public QWidget { Q_OBJECT public: explicit TitleWidget(QWidget *parent = 0); ~TitleWidget(); // enum Activation { Anywhere = 1, Bottom = 2 }; void enable_turned_on(); void showAlways(); void update_max_status(bool is_maxed); void show_title_widget(); signals: void sig_min(); void sig_max(); void sig_menu(); void sig_close(); void mouseMovedDiff(QPoint); protected: void mouseDoubleClickEvent(QMouseEvent *event) override; private: enum MenuItemId { IdCreateAlbum, IdSwitchTheme, IdSetting, IdImport, IdHelp, IdAbout, IdQuick, IdSeparator }; void initLeftContent(); void initMiddleContent(); void initRightContent(); void initMenu(); void initWidgets(); private slots: void onMaxOrNormal(); void onMinBtnClicked(); private: QColor m_coverBrush; QColor m_topBorderColor; QColor m_bottomBorderColor; QPointer m_manualPro; QHBoxLayout *m_layout; QHBoxLayout *m_lLayout; QHBoxLayout *m_mLayout; QHBoxLayout *m_rLayout; // QPushButton *menu_button; // QPushButton *min_button; // QPushButton *max_button; // QPushButton *close_button; SystemButton *min_button; SystemButton *close_button; SystemButton *max_button; SystemButton *menu_button; public slots: void showWidget(); void activate(); void deactivate(); void setMargin(int margin) { spacing = margin; }; // void setActivationArea(Activation m) { activation_area = m; } void setHideDelay(int ms); void set_title_name(QString title); void clear_title_name(); void showSpreadAnimated(); void showGatherAnimated(); void spreadAniFinished(); void gatherAniFinished(); public: bool isActive() { return turned_on; }; int margin() { return spacing; }; // Activation activationArea() { return activation_area; } int hideDelay(); protected: bool eventFilter(QObject * obj, QEvent * event); void paintEvent(QPaintEvent *event); private slots: void checkUnderMouse(); private: void installFilter(QObject *o); private: bool turned_on; int spacing; // Activation activation_area; QWidget * internal_widget; QTimer * timer; QPropertyAnimation *spreadAnimation; QPropertyAnimation *gatherAnimation; QLabel *logo_label; QLabel *soft_label; QLabel *title_label; TitleDragState drag_state; QPoint start_drag; }; /*class TitleWidget : public QWidget { Q_OBJECT public: explicit TitleWidget(QWidget *parent = 0); ~TitleWidget(); enum Activation { Anywhere = 1, Bottom = 2 }; void enable_turned_on(); void showAlways(); void update_max_status(bool is_maxed); void show_title_widget(); signals: void sig_min(); void sig_max(); void sig_menu(); void sig_close(); void mouseMovedDiff(QPoint); protected: void mouseDoubleClickEvent(QMouseEvent *event) override; private: enum MenuItemId { IdCreateAlbum, IdSwitchTheme, IdSetting, IdImport, IdHelp, IdAbout, IdQuick, IdSeparator }; void initLeftContent(); void initMiddleContent(); void initRightContent(); void initMenu(); void initWidgets(); private slots: void onMaxOrNormal(); void onMinBtnClicked(); private: QColor m_coverBrush; QColor m_topBorderColor; QColor m_bottomBorderColor; QPointer m_manualPro; QHBoxLayout *m_layout; QHBoxLayout *m_lLayout; QHBoxLayout *m_mLayout; QHBoxLayout *m_rLayout; // QPushButton *menu_button; // QPushButton *min_button; // QPushButton *max_button; // QPushButton *close_button; SystemButton *min_button; SystemButton *close_button; SystemButton *max_button; SystemButton *menu_button; public slots: void setMargin(int margin) { spacing = margin; }; void setActivationArea(Activation m) { activation_area = m; } void set_title_name(QString title); void clear_title_name(); void showSpreadAnimated(); void showGatherAnimated(); void spreadAniFinished(); void gatherAniFinished(); public: bool isActive() { return turned_on; }; int margin() { return spacing; }; Activation activationArea() { return activation_area; } protected: void paintEvent(QPaintEvent *event); private: bool turned_on; int spacing; Activation activation_area; QWidget * internal_widget; QPropertyAnimation *spreadAnimation; QPropertyAnimation *gatherAnimation; QLabel *logo_label; QLabel *soft_label; QLabel *title_label; TitleDragState drag_state; QPoint start_drag; };*/ #endif // TITLEWIDGET_H kylin-video/src/kylin/titlewidget.cpp0000664000175000017500000004037413214706400016705 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #include "titlewidget.h" #include #include #include #include #include #include #include #include #include #include #include // TitleWidget::TitleWidget(QWidget *parent) : QWidget(parent) , turned_on(false) , spacing(0) // , activation_area(Anywhere) , internal_widget(0) , timer(0) , spreadAnimation(0) , gatherAnimation(0) , drag_state(NOT_TDRAGGING) , start_drag(QPoint(0,0)) { this->setMouseTracking(true); this->setAutoFillBackground(true);//20170615 this->setStyleSheet("QWidget{background:transparent;}");//20170615 rgba(255, 255, 255, 20%); QPalette palette; palette.setColor(QPalette::Background, QColor("#040404")); this->setPalette(palette); initWidgets(); parent->installEventFilter(this); installFilter(parent); timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(checkUnderMouse())); timer->setInterval(3000); } TitleWidget::~TitleWidget() { if (spreadAnimation) delete spreadAnimation; if (gatherAnimation) delete gatherAnimation; if (timer != NULL) { disconnect(timer,SIGNAL(timeout()),this,SLOT(checkUnderMouse())); if(timer->isActive()) { timer->stop(); } delete timer; timer = NULL; } if (menu_button) { delete menu_button; menu_button = NULL; } if (min_button) { delete min_button; min_button = NULL; } if (max_button) { delete max_button; max_button = NULL; } if (close_button) { delete close_button; close_button = NULL; } } void TitleWidget::initWidgets() { m_layout = new QHBoxLayout(this); m_layout->setContentsMargins(0, 0, 0, 0); m_layout->setSpacing(0); initLeftContent(); initMiddleContent(); initRightContent(); } //20170810 void TitleWidget::mouseDoubleClickEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { if (window()->isMaximized()) window()->showNormal(); else if (! window()->isFullScreen()) // It would be normal state window()->showMaximized(); } QWidget::mouseDoubleClickEvent(event); } void TitleWidget::initLeftContent() { QWidget *w = new QWidget; m_lLayout = new QHBoxLayout(w); m_lLayout->setContentsMargins(5, 0, 0, 0); m_lLayout->setSpacing(5); logo_label = new QLabel(this); // QImage image(":/res/logo.png"); // image = image.scaled(QSize(32, 32), Qt::KeepAspectRatio, Qt::SmoothTransformation); // logo_label->setPixmap(QPixmap::fromImage(image)); logo_label->setPixmap(QPixmap(":/res/logo.png")); // logo_label->setScaledContents(true);//自动缩放,显示图像大小自动调整为Qlabel大小 soft_label = new QLabel(this); soft_label->setText(tr("Kylin Video")); soft_label->setStyleSheet("QLabel{font-size:14px;font-style:italic;color:#ffffff;}");//font-weight:bold; m_lLayout->addWidget(logo_label); m_lLayout->addWidget(soft_label); m_layout->addWidget(w, 1, Qt::AlignLeft); } void TitleWidget::initMiddleContent() { QWidget *w = new QWidget; w->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); m_mLayout = new QHBoxLayout(w); m_mLayout->setContentsMargins(0, 0, 0, 0); m_mLayout->setSpacing(0); title_label = new QLabel(this); title_label->setMaximumWidth(300); title_label->setStyleSheet("QLabel{font-size:12px;color:#ffffff;}"); m_mLayout->addWidget(title_label, 0 , Qt::AlignHCenter); m_layout->addWidget(w); } void TitleWidget::set_title_name(QString title){ QFont ft; QFontMetrics fm(ft); QString elided_text = fm.elidedText(title, Qt::ElideRight, this->title_label->maximumWidth()); this->title_label->setText(elided_text); if(elided_text.endsWith("…")) this->title_label->setToolTip(title); } void TitleWidget::clear_title_name() { title_label->clear(); } void TitleWidget::initRightContent() { QWidget *w = new QWidget; m_rLayout = new QHBoxLayout(w); m_rLayout->setContentsMargins(0, 0, 0, 0); m_rLayout->setSpacing(0); m_layout->addWidget(w, 1, Qt::AlignRight); // menu_button = new QPushButton(); // min_button = new QPushButton(); // max_button = new QPushButton(); // close_button = new QPushButton(); menu_button = new SystemButton(); menu_button->loadPixmap(":/res/option.png"); menu_button->setObjectName("menu_button"); min_button = new SystemButton(); min_button->loadPixmap(":/res/min.png"); min_button->setObjectName("min_button"); max_button = new SystemButton(); max_button->loadPixmap(":/res/max.png"); max_button->setObjectName("max_button"); close_button = new SystemButton(); close_button->loadPixmap(":/res/close.png"); close_button->setObjectName("close_button"); menu_button->setFixedSize(36,36); min_button->setFixedSize(36,36); max_button->setFixedSize(36,36); close_button->setFixedSize(36,36); min_button->setObjectName("min_button"); close_button->setObjectName("close_button"); menu_button->setObjectName("menu_button"); max_button->setObjectName("max_button"); min_button->setFocusPolicy(Qt::NoFocus); close_button->setFocusPolicy(Qt::NoFocus); menu_button->setFocusPolicy(Qt::NoFocus); max_button->setFocusPolicy(Qt::NoFocus); // min_button->setStyleSheet("QPushButton{background-image:url(':/res/min_normal.png');border:0px;}QPushButton:hover{background:url(':/res/min_hover.png');}QPushButton:pressed{background:url(':/res/min_press.png');}"); // close_button->setStyleSheet("QPushButton{background-image:url(':/res/close_normal.png');border:0px;}QPushButton:hover{background:url(':/res/close_hover.png');}QPushButton:pressed{background:url(':/res/close_press.png');}"); // menu_button->setStyleSheet("QPushButton{background-image:url(':/res/option_normal.png');border:0px;}QPushButton:hover{background:url(':/res/option_hover.png');}QPushButton:pressed{background:url(':/res/option_press.png');}"); // max_button->setStyleSheet("QPushButton{background-image:url(':/res/max_normal.png');border:0px;}QPushButton:hover{background:url(':/res/max_hover.png');}QPushButton:pressed{background:url(':/res/max_press.png');}"); m_rLayout->addWidget(menu_button); m_rLayout->addWidget(min_button); m_rLayout->addWidget(max_button); m_rLayout->addWidget(close_button); connect(menu_button, SIGNAL(clicked()), this, SIGNAL(sig_menu())); connect(min_button, SIGNAL(clicked()), this, SLOT(onMinBtnClicked())); connect(close_button, SIGNAL(clicked()), this, SIGNAL(sig_close())); connect(max_button, SIGNAL(clicked()), this, SLOT(onMaxOrNormal())); } void TitleWidget::update_max_status(bool is_maxed) { if (is_maxed) { max_button->loadPixmap(":/res/unmax.png"); // max_button->setStyleSheet("QPushButton{background-image:url(':/res/unmax_normal.png');border:0px;}QPushButton:hover{background:url(':/res/unmax_hover.png');}QPushButton:pressed{background:url(':/res/unmax_press.png');}"); } else { max_button->loadPixmap(":/res/max.png"); // max_button->setStyleSheet("QPushButton{background-image:url(':/res/max_normal.png');border:0px;}QPushButton:hover{background:url(':/res/max_hover.png');}QPushButton:pressed{background:url(':/res/max_press.png');}"); } } void TitleWidget::onMaxOrNormal() { emit this->sig_max(); } void TitleWidget::onMinBtnClicked() { emit this->sig_min(); max_button->loadPixmap(":/res/max.png"); // max_button->setStyleSheet("QPushButton{background-image:url(':/res/max_normal.png');border:0px;}QPushButton:hover{background:url(':/res/max_hover.png');}QPushButton:pressed{background:url(':/res/max_press.png');}"); } void TitleWidget::setHideDelay(int ms) { timer->setInterval(ms); } int TitleWidget::hideDelay() { return timer->interval(); } void TitleWidget::installFilter(QObject *o) { QObjectList children = o->children(); for (int n=0; n < children.count(); n++) { if (children[n]->isWidgetType()) { if (children[n]->objectName() == "PlayListViewScrollBar") {//kobe:让滚动条可以鼠标拖动 continue; } else if (children[n]->objectName() == "min_button" || children[n]->objectName() == "close_button" || children[n]->objectName() == "menu_button" || children[n]->objectName() == "max_button") { continue; } else if (children[n]->objectName() == "StopBtn" || children[n]->objectName() == "PrevBtn" || children[n]->objectName() == "PlayBtn" || children[n]->objectName() == "NextBtn") { continue; } else if (children[n]->objectName() == "SoundBtn" || children[n]->objectName() == "FullScreenBtn" || children[n]->objectName() == "PlayListBtn" || children[n]->objectName() == "VolumeSlider") { continue; } QWidget *w = static_cast(children[n]); w->setMouseTracking(true); w->installEventFilter(this); installFilter(children[n]); } } } void TitleWidget::activate() { turned_on = true; if (timer->isActive()) timer->stop(); timer->start(); } void TitleWidget::deactivate() { turned_on = false; timer->stop(); this->showWidget(); } void TitleWidget::showAlways() { timer->stop(); QPoint dest_position = QPoint(0, 0); move(dest_position); QWidget::show(); } void TitleWidget::enable_turned_on() { turned_on = true; } void TitleWidget::showWidget() { showSpreadAnimated(); if (timer->isActive()) timer->stop(); timer->start(); } void TitleWidget::checkUnderMouse() { if ((isVisible()) && (!underMouse())) { this->showGatherAnimated(); } } bool TitleWidget::eventFilter(QObject * obj, QEvent * event) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { drag_state = NOT_TDRAGGING; return false; } if (turned_on) { if (event->type() == QEvent::MouseMove) { // qDebug() << "TitleWidget::eventFilter: mouse move" << obj; if (!isVisible()) { showWidget(); /*if (activation_area == Anywhere) { showWidget(); } else { QMouseEvent * mouse_event = dynamic_cast(event); QWidget * parent = parentWidget(); QPoint p = parent->mapFromGlobal(mouse_event->globalPos()); if (p.y() > (parent->height() - height() - spacing)) { showWidget(); } }*/ } } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_TDRAGGING; return false; } drag_state = START_TDRAGGING; start_drag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (drag_state != TDRAGGING || mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_TDRAGGING; return false; } // Stop dragging and eat event drag_state = NOT_TDRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (drag_state == NOT_TDRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { drag_state = NOT_TDRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - start_drag; if (drag_state == START_TDRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; drag_state = TDRAGGING; } emit mouseMovedDiff(diff); start_drag = pos; event->accept(); return true; } else { if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_TDRAGGING; return false; } drag_state = START_TDRAGGING; start_drag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (drag_state != TDRAGGING || mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_TDRAGGING; return false; } // Stop dragging and eat event drag_state = NOT_TDRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (drag_state == NOT_TDRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { drag_state = NOT_TDRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - start_drag; if (drag_state == START_TDRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; drag_state = TDRAGGING; } emit mouseMovedDiff(diff); start_drag = pos; event->accept(); return true; } } void TitleWidget::spreadAniFinished() { } void TitleWidget::gatherAniFinished() { QWidget::hide(); } void TitleWidget::show_title_widget() { QWidget::show(); } void TitleWidget::showSpreadAnimated() { if (!spreadAnimation) { spreadAnimation = new QPropertyAnimation(this, "pos"); connect(spreadAnimation, SIGNAL(finished()), this, SLOT(spreadAniFinished())); } QPoint initial_position = QPoint(pos().x(), -this->height()); QPoint final_position = QPoint(0, 0); move(initial_position); QWidget::show(); spreadAnimation->setDuration(300); spreadAnimation->setEndValue(final_position); spreadAnimation->setStartValue(initial_position); spreadAnimation->start(); } void TitleWidget::showGatherAnimated() { if (!gatherAnimation) { gatherAnimation = new QPropertyAnimation(this, "pos"); connect(gatherAnimation, SIGNAL(finished()), this, SLOT(gatherAniFinished())); } QPoint initial_position = QPoint(0, 0); QPoint final_position = QPoint(pos().x(), -this->height()); move(initial_position); gatherAnimation->setDuration(300); gatherAnimation->setStartValue(initial_position); gatherAnimation->setEndValue(final_position); gatherAnimation->start(); } void TitleWidget::paintEvent(QPaintEvent *event) { Q_UNUSED(event); // QStyleOption opt; // opt.init(this); // QPainter p(this); // style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); QPainter p(this); p.setCompositionMode(QPainter::CompositionMode_Clear); p.fillRect(rect(), Qt::SolidPattern);//p.fillRect(0, 0, this->width(), this->height(), Qt::SolidPattern); } kylin-video/src/kylin/timetip.cpp0000664000175000017500000000731213214706400016026 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #include "timetip.h" #include #include #include #include #include TimeTip::TimeTip(const QString &text, QWidget *parent) : QFrame(parent) { setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint); setAttribute(Qt::WA_TranslucentBackground); setContentsMargins(0, 0, 0, 0); QHBoxLayout *layout = new QHBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); repaint_flag = false; text_frame = new QFrame(); text_frame->setContentsMargins(0, 0, 0, 0); text_frame->adjustSize(); QHBoxLayout *textlayout = new QHBoxLayout(this->text_frame); textlayout->setContentsMargins(10, 2, 10, 0); // textlayout->setContentsMargins(0, 0, 0, 0); textlayout->setSpacing(0); text_label = new QLabel(text); text_label->setObjectName("WhiteTipText"); text_label->setAlignment(Qt::AlignCenter); split_line = new QLabel; split_line->setObjectName("SplitText"); split_line->setFixedWidth(1); // split_line->setFixedSize(1,20); textlayout->addWidget(text_label, 0, Qt::AlignVCenter); QVBoxLayout *vlayout = new QVBoxLayout; vlayout->setContentsMargins(0, 0, 0, 0); vlayout->setSpacing(0); vlayout->addWidget(text_frame, 0, Qt::AlignHCenter); vlayout->addWidget(split_line, 0, Qt::AlignHCenter); layout->addLayout(vlayout); hide(); } TimeTip::~TimeTip() { } void TimeTip::setText(const QString text) { repaint_flag = false; this->text_label->setText(text); } void TimeTip::setPixMapAndTime(QPixmap pixmap, const QString time) { repaint_flag = true; // Add current time text QPainter painter(&pixmap); painter.setPen(Qt::white); painter.drawText(pixmap.rect(), Qt::AlignHCenter | Qt::AlignBottom, time); this->text_label->setPixmap(pixmap); } void TimeTip::paintEvent(QPaintEvent *event) { if (!repaint_flag) { QFrame::paintEvent(event); return; } QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing); double w_pen = 2.0; QBrush background(QColor(255, 255, 255, 70)); QColor borderColor = QColor(0, 0, 0, 0.2 * 255); double margin = 9.0; QMarginsF shadow_margins = QMarginsF(margin, 0, margin, 26); //background QRectF bg_rect = QRectF(rect()).marginsRemoved(shadow_margins); QPainterPath bg_path; bg_path.addRoundedRect(bg_rect, 2, 2); painter.fillPath(bg_path, background); //border QPainterPath border_path; QRectF border_rect = QRectF(rect()); int border_radius = 4; QMarginsF border_margin(w_pen / 2, w_pen / 2, w_pen / 2, w_pen / 2); border_radius += w_pen / 2; border_rect = border_rect.marginsAdded(border_margin).marginsRemoved(shadow_margins); border_path.addRoundedRect(border_rect, border_radius, border_radius); QPen border_pen(borderColor); border_pen.setWidthF(w_pen); painter.strokePath(border_path, border_pen); } kylin-video/src/kylin/esctip.h0000664000175000017500000000327313214706400015311 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #ifndef _ESCTIP_H_ #define _ESCTIP_H_ #include class QLabel; class EscTip : public QFrame { Q_OBJECT Q_PROPERTY(int radius READ radius WRITE setRadius) Q_PROPERTY(QBrush background READ background WRITE setBackground) Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor) public: explicit EscTip(QWidget *parent = 0); ~EscTip(); void setBackgroundImage(const QPixmap &srcPixmap); int radius() const; QColor borderColor() const; QBrush background() const; public slots: void setBackground(QBrush background); void setRadius(int radius); void setBorderColor(QColor borderColor); void aniFinished(); protected: virtual void paintEvent(QPaintEvent *); private: QLabel *text_label; QBrush m_background; int m_radius; int w_shadow; QMargins shadow_margins; QColor m_borderColor; }; #endif kylin-video/src/kylin/supportformats.h0000664000175000017500000000212313214706400017123 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #ifndef _SUPPORTFORMATS_H_ #define _SUPPORTFORMATS_H_ #include "ui_supportformats.h" class SupportFormats : public QWidget, public Ui::SupportFormats { Q_OBJECT public: SupportFormats( QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~SupportFormats(); void setData(); protected: virtual void retranslateStrings(); }; #endif kylin-video/src/kylin/playlistitem.cpp0000664000175000017500000000732413214706400017076 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #include "playlistitem.h" #include #include #include #include #include #include #include #include #include #include #include #include "../smplayer/helper.h" PlayListItem::PlayListItem(QString mtype, QString filename, QString name, double duration, QWidget *parent) : QFrame(parent) { m_filename = filename; if (name.isDetached()) m_name = "lixiang"; m_name = name; m_duration = duration; m_played = false; m_deleted = false; m_data = filename; this->setFixedSize(220, 32); this->setToolTip(filename); icon_label = new QLabel(this); icon_label->setObjectName("PlayListIcon");//0616 icon_label->setGeometry(8,8,16,16); icon_label->setProperty("iconName", mtype); m_titleedit = new QLineEdit(this); m_titleedit->setObjectName("PlayListTitle");//0616 m_titleedit->setDisabled(true); m_titleedit->setReadOnly(true); m_titleedit->setAlignment(Qt::AlignLeft); m_titleedit->setGeometry(30,0,105,32); time_label = new QLabel(this); time_label->setStyleSheet("QLabel{color: #ffffff;font-size: 12px;background: transparent;}"); time_label->setText(Helper::formatTime((int)duration)); time_label->setGeometry(140,0,50,32); delete_btn = new QPushButton(this); delete_btn->setGeometry(192,8,16,16); delete_btn->setFocusPolicy(Qt::NoFocus); delete_btn->setObjectName("PlayListDelete"); connect(delete_btn, SIGNAL(clicked(bool)), this, SLOT(onDelete())); QFont font(m_titleedit->font()); font.setPixelSize(12); QFontMetrics fm(font); // m_titleedit->setText(fm.elidedText(QString(m_name), Qt::ElideMiddle, m_titleedit->maximumWidth())); m_titleedit->setText(fm.elidedText(QString(m_name), Qt::ElideMiddle, 105)); } void PlayListItem::update_widget_qss_property(QWidget *w, const char *name, const QVariant &value) { w->setProperty(name, value); this->style()->unpolish(w); this->style()->polish(w); w->update(); } void PlayListItem::setActive(bool active) { if (active) { this->update_widget_qss_property(m_titleedit, "status", "active"); this->update_widget_qss_property(delete_btn, "status", "active"); } else { this->update_widget_qss_property(m_titleedit, "status", ""); this->update_widget_qss_property(delete_btn, "status", ""); } } void PlayListItem::mouseDoubleClickEvent(QMouseEvent *event) { // QFrame::mouseDoubleClickEvent(event); emit this->sig_doubleclicked_resource(this->m_filename); QPoint lineeditMousePos = m_titleedit->mapFromParent(event->pos()); if (!m_titleedit->rect().contains(lineeditMousePos)) { return; } if (m_titleedit->isReadOnly()) { return; } } void PlayListItem::onDelete() { emit this->remove(m_data); } //kobe:更新视频的时长 void PlayListItem::update_time(QString duration) { time_label->setText(duration); } kylin-video/src/kylin/bottomwidget.cpp0000664000175000017500000011753713214706400017076 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #include "bottomwidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../smplayer/timeslider.h" #include "soundvolume.h" #include "../smplayer/colorutils.h" #include "../smplayer/myaction.h" #include "../smplayer/mplayerwindow.h" #include "../smplayer/global.h" #include "../smplayer/preferences.h" using namespace Global; static const QString playStatusPlaying = "playing"; static const QString playStatusPause = "pause"; static const QString playStatusStop = "stop"; static const QString playStatusPlayList = "close"; static const char *property_FullScreen = "fullscreen"; static const char *property_PlayStatus = "playstatus"; static const char *property_PlayListStatus = "playliststatus"; BottomWidget::BottomWidget(QWidget *parent) : QWidget(parent, Qt::SubWindow) , turned_on(false) , spacing(0) // , activation_area(Anywhere) , internal_widget(0) , timer(0) , spreadAnimation(0) , gatherAnimation(0) , drag_state(NOT_BDRAGGING) , start_drag(QPoint(0,0)) { this->setMouseTracking(true); setAutoFillBackground(true); setFocusPolicy(Qt::ClickFocus); QPalette palette; palette.setColor(QPalette::Background, QColor("#040404")); this->setPalette(palette); setWindowFlags(windowFlags() | Qt::SubWindow); setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); drag_delay = 200; enableMove = false; //20170810 parent->installEventFilter(this); // parent->setMouseTracking(true); installFilter(parent); timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(checkUnderMouse())); timer->setInterval(3000); controlWidget = new QWidget(this); controlWidget->setFixedHeight(61); progress = NULL; progress = new TimeSlider(this); progress->setMouseTracking(true); // progress->installEventFilter(this); // progress->setParent(this); progress->setDragDelay(100);//pref->time_slider_drag_delay connect(progress, SIGNAL(posChanged(int)), this, SIGNAL(posChanged(int))); connect(progress, SIGNAL(draggingPos(int)), this, SIGNAL(draggingPos(int))); connect(progress, SIGNAL(delayedDraggingPos(int)), this, SIGNAL(delayedDraggingPos(int))); connect(progress, SIGNAL(wheelUp()), this, SIGNAL(wheelUp())); connect(progress, SIGNAL(wheelDown()), this, SIGNAL(wheelDown())); connect(progress, SIGNAL(need_to_save_pre_image(int)), this, SIGNAL(need_to_save_pre_image(int))); connect(this, SIGNAL(send_save_preview_image_name(int,QString)), progress, SLOT(show_save_preview_image(int,QString))); progress->setObjectName("processProgress"); progress->setProperty("status", ""); connect(progress, SIGNAL(active_status(bool)), this, SLOT(slot_active_status(bool))); progress->setFixedHeight(24); progress->move(0,0); playtime_label = new QLabel; playtime_label->setText("00:00:00"); playtime_label->setFrameShape(QFrame::NoFrame); ColorUtils::setBackgroundColor(playtime_label, QColor(0,0,0) ); ColorUtils::setForegroundColor(playtime_label, QColor(255,255,255) ); playtime_label->setStyleSheet("QLabel{font-size:12px;color:#ffffff;}"); playtime_label->adjustSize(); alltime_label = new QLabel; alltime_label->setText(" / 00:00:00"); alltime_label->setFrameShape(QFrame::NoFrame); ColorUtils::setBackgroundColor( alltime_label, QColor(0,0,0) ); ColorUtils::setForegroundColor( alltime_label, QColor(255,255,255) ); alltime_label->setStyleSheet("QLabel{font-size:12px;color:#808080;}"); alltime_label->adjustSize(); btStop = new QPushButton; btStop->setObjectName("StopBtn"); btStop->setFixedSize(24, 24); btPrev = new QPushButton; btPrev->setObjectName("PrevBtn"); btPrev->setFixedSize(24, 24); btPlayPause = new QPushButton; // btPlayPause->setShortcut(Qt::Key_Space); btPlayPause->setObjectName("PlayBtn"); btPlayPause->setFixedSize(61, 61); btNext = new QPushButton; btNext->setObjectName("NextBtn"); btNext->setFixedSize(24, 24); btSound = new QPushButton; btSound->setObjectName("SoundBtn"); btSound->setFixedSize(24, 24); btSound->setProperty("volume", "mid"); btFullScreen = new QPushButton; // btFullScreen->setShortcut(QKeySequence("Ctrl+Return")); btFullScreen->setObjectName("FullScreenBtn"); btFullScreen->setFixedSize(24, 24); btPlayList = new QPushButton; // btPlayList->setShortcut(QKeySequence("F3")); btPlayList->setObjectName("PlayListBtn"); btPlayList->setFixedSize(24, 24); listCountLabel = new QLabel; ColorUtils::setBackgroundColor(listCountLabel, QColor("#141414") ); listCountLabel->setStyleSheet("QLabel{font-size:12px;color:#ffffff;}"); this->listCountLabel->setText("0"); volSlider = new SoundVolume(this); volSlider->setObjectName("VolumeSlider"); connect(this, SIGNAL(valueChanged(int)), volSlider, SLOT(setValue(int))); connect(btStop, SIGNAL(released()), this, SIGNAL(signal_stop())); connect(btPrev, SIGNAL(released()), this, SIGNAL(signal_prev())); connect(btPlayPause, SIGNAL(released()), this, SIGNAL(signal_play_pause_status())); connect(btNext, SIGNAL(released()), this, SIGNAL(signal_next())); connect(btSound, SIGNAL(pressed()), this, SIGNAL(signal_mute(/*bool*/))); connect(volSlider, SIGNAL(volumeChanged(int)), this, SLOT(slot_volumn_changed(int))); connect(btFullScreen, SIGNAL(pressed()), this, SIGNAL(toggleFullScreen())); connect(btPlayList, SIGNAL(released()), this, SIGNAL(togglePlaylist())); connect(this, SIGNAL(mouseMoving(Qt::MouseButton)), progress, SLOT(hideTip()));//20170714 QHBoxLayout *time_layout = new QHBoxLayout(); time_layout->setMargin(0); time_layout->setSpacing(2); time_layout->addWidget(playtime_label, 0, Qt::AlignLeft | Qt::AlignVCenter); time_layout->addWidget(alltime_label, 0, Qt::AlignLeft | Qt::AlignVCenter); metaWidget = new QFrame(this); metaWidget->setFixedHeight(61); QHBoxLayout *metaLayout = new QHBoxLayout(metaWidget); metaLayout->setMargin(0); metaLayout->setSpacing(10); metaLayout->addWidget(btPlayPause, 0, Qt::AlignVCenter); metaLayout->addLayout(time_layout); ctlWidget = new QFrame(this); ctlWidget->setFixedHeight(61); QHBoxLayout *ctlLayout = new QHBoxLayout(ctlWidget); ctlLayout->setMargin(0); ctlLayout->setSpacing(30); ctlLayout->addWidget(btPrev, 0, Qt::AlignCenter); ctlLayout->addWidget(btStop, 0, Qt::AlignCenter); ctlLayout->addWidget(btNext, 0, Qt::AlignCenter); ctlWidget->adjustSize(); QHBoxLayout *volume_layout = new QHBoxLayout(); volume_layout->setMargin(0); volume_layout->setSpacing(2); volume_layout->addWidget(btSound, 0, Qt::AlignRight | Qt::AlignVCenter); volume_layout->addWidget(volSlider, 0, Qt::AlignRight | Qt::AlignVCenter); QHBoxLayout *list_layout = new QHBoxLayout(); list_layout->setMargin(0); list_layout->setSpacing(2); list_layout->addWidget(btPlayList, 0, Qt::AlignRight | Qt::AlignVCenter); list_layout->addWidget(listCountLabel, 0, Qt::AlignRight | Qt::AlignVCenter); actWidget = new QWidget(this); actWidget->setFixedHeight(61); QHBoxLayout *actLayout = new QHBoxLayout(actWidget); actLayout->setMargin(0); actLayout->setSpacing(20); actLayout->addLayout(volume_layout); actLayout->addWidget(btFullScreen, 0, Qt::AlignRight | Qt::AlignVCenter); actLayout->addLayout(list_layout); QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Preferred); sp.setHorizontalStretch(33); metaWidget->setSizePolicy(sp); actWidget->setSizePolicy(sp); QHBoxLayout *layout = new QHBoxLayout(); layout->setContentsMargins(10, 0, 20, 0); layout->setSpacing(20); layout->addWidget(metaWidget, 0, Qt::AlignLeft/* | Qt::AlignVCenter*/); layout->addStretch(); layout->addWidget(ctlWidget, 0, Qt::AlignHCenter/*Qt::AlignCenter*/); layout->addStretch(); layout->addWidget(actWidget, 0, Qt::AlignRight/* | Qt::AlignVCenter*/); controlWidget->setLayout(layout); vboxlayout = new QVBoxLayout(this); vboxlayout->setSpacing(0); vboxlayout->setContentsMargins(0, 18, 0, 2); vboxlayout->addWidget(controlWidget); btStop->setFocusPolicy(Qt::NoFocus); btPrev->setFocusPolicy(Qt::NoFocus); btPlayPause->setFocusPolicy(Qt::NoFocus); btNext->setFocusPolicy(Qt::NoFocus); btFullScreen->setFocusPolicy(Qt::NoFocus); btSound->setFocusPolicy(Qt::NoFocus); volSlider->setFocusPolicy(Qt::NoFocus); btPlayList->setFocusPolicy(Qt::NoFocus); btStop->setToolTip(tr("Stop")); btPrev->setToolTip(tr("Prev")); btPlayPause->setToolTip(tr("Play / Pause")); btNext->setToolTip(tr("Next")); btSound->setToolTip(tr("Mute")); btPlayList->setToolTip(tr("Play List")); this->update_widget_qss_property(btPlayPause, property_PlayStatus, playStatusPause); this->update_widget_qss_property(this, property_PlayStatus, playStatusPause); } BottomWidget::~BottomWidget() { if (spreadAnimation) delete spreadAnimation; if (gatherAnimation) delete gatherAnimation; if (metaWidget) delete metaWidget; if (ctlWidget) delete ctlWidget; if (actWidget) delete actWidget; if (controlWidget) delete controlWidget; if (timer != NULL) { disconnect(timer,SIGNAL(timeout()),this,SLOT(checkUnderMouse())); if(timer->isActive()) { timer->stop(); } delete timer; timer = NULL; } } //void BottomWidget::setData(Preferences *pref) { // QString ao = pref->ao; // setAO(ao); // setGlobalVolume(pref->global_volume); // setSoftVol(pref->use_soft_vol); // setInitialVolNorm(pref->initial_volnorm); // setAmplification(pref->softvol_max); // setAudioChannels(pref->initial_audio_channels); // setAutoSyncActivated(pref->autosync); // setAutoSyncFactor(pref->autosync_factor); //} /*void BottomWidget::setParentWindow(MplayerWindow* window) { p_mainwindow = window; p_mainwindow->installEventFilter(this); p_mainwindow->setMouseTracking(true); }*/ void BottomWidget::setPreviewData(bool preview) { if (progress) { progress->set_preview_flag(preview); } } QString BottomWidget::get_status() { QString status = progress->property("active").toString(); return status; } void BottomWidget::update_playlist_count_label(int count) { this->listCountLabel->setText(QString::number(count)); } void BottomWidget::setTransparent(bool transparent) { if (transparent) { setAttribute(Qt::WA_TranslucentBackground); setWindowFlags(windowFlags() | Qt::FramelessWindowHint|Qt::X11BypassWindowManagerHint); set_widget_opacity(0.5); } else { setAttribute(Qt::WA_TranslucentBackground,false); setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint); } } void BottomWidget::set_widget_opacity(const float &opacity) { QGraphicsOpacityEffect* opacityEffect = new QGraphicsOpacityEffect; this->setGraphicsEffect(opacityEffect); opacityEffect->setOpacity(opacity); } void BottomWidget::slot_active_status(bool b) { if (b) { this->update_widget_qss_property(progress, "status", "active"); } else { this->update_widget_qss_property(progress, "status", ""); } } void BottomWidget::setPos(int v) { bool was_blocked= progress->blockSignals(true); progress->setPos(v); progress->blockSignals(was_blocked); } int BottomWidget::ppos() { return progress->pos(); } void BottomWidget::setDuration(double t) { total_time = t; progress->setDuration(t); } void BottomWidget::setDragDelay(int d) { drag_delay = d; progress->setDragDelay(drag_delay); } int BottomWidget::dragDelay() { return drag_delay; } void BottomWidget::setActionsEnabled(bool b) { btPrev->setEnabled(b); btPlayPause->setEnabled(b); btNext->setEnabled(b); btSound->setEnabled(b); btStop->setEnabled(b); progress->setEnabled(b); } void BottomWidget::setPlayOrPauseEnabled(bool b) { btPlayPause->setEnabled(b); } void BottomWidget::setStopEnabled(bool b) { btStop->setEnabled(b); } void BottomWidget::displayTime(QString cur_time, QString all_time) { playtime_label->setText(cur_time); alltime_label->setText(all_time); } void BottomWidget::slot_playlist_btn_status(bool b) { if (b) { this->update_widget_qss_property(btPlayList, property_PlayListStatus, playStatusPlayList); } else { this->update_widget_qss_property(btPlayList, property_PlayListStatus, ""); } } void BottomWidget::slot_volumn_changed(int vol) { this->onVolumeChanged(vol); emit this->volumeChanged(vol); } void BottomWidget::onMusicPlayed() { this->update_widget_qss_property(btPlayPause, property_PlayStatus, playStatusPlaying); this->update_widget_qss_property(this, property_PlayStatus, playStatusPlaying); } void BottomWidget::onMusicPause() { this->update_widget_qss_property(btPlayPause, property_PlayStatus, playStatusPause); this->update_widget_qss_property(this, property_PlayStatus, playStatusPause); } void BottomWidget::onMusicStoped() { this->update_widget_qss_property(btPlayPause, property_PlayStatus, playStatusStop); this->update_widget_qss_property(this, property_PlayStatus, playStatusStop); } void BottomWidget::onFullScreen() { this->update_widget_qss_property(btFullScreen, property_FullScreen, true); } void BottomWidget::onUnFullScreen() { this->update_widget_qss_property(btFullScreen, property_FullScreen, false); } void BottomWidget::onVolumeChanged(int volume) { QString status = "mid"; if (volume > 77) { status = "high"; } else if (volume > 33) { status = "mid"; } else if (volume > 0) { status = "low"; } else { status = "mute"; } this->update_widget_qss_property(btSound, "volume", status); this->volSlider->onVolumeChanged(volume); } void BottomWidget::onMutedChanged(bool muted, int volumn) { if (muted) { this->update_widget_qss_property(btSound, "volume", "mute"); this->volSlider->onVolumeChanged(0); } else { this->onVolumeChanged(volumn); } } void BottomWidget::setHideDelay(int ms) { timer->setInterval(ms); } int BottomWidget::hideDelay() { return timer->interval(); } void BottomWidget::update_widget_qss_property(QWidget *w, const char *name, const QVariant &value) { w->setProperty(name, value); this->style()->unpolish(w); this->style()->polish(w); w->update(); } void BottomWidget::installFilter(QObject *o) { QObjectList children = o->children(); for (int n=0; n < children.count(); n++) { if (children[n]->isWidgetType()) { if (children[n]->objectName() == "PlayListViewScrollBar") {//kobe:让滚动条可以鼠标拖动 continue; } else if (children[n]->objectName() == "min_button" || children[n]->objectName() == "close_button" || children[n]->objectName() == "menu_button" || children[n]->objectName() == "max_button") { continue; } else if (children[n]->objectName() == "StopBtn" || children[n]->objectName() == "PrevBtn" || children[n]->objectName() == "PlayBtn" || children[n]->objectName() == "NextBtn") { continue; } else if (children[n]->objectName() == "SoundBtn" || children[n]->objectName() == "FullScreenBtn" || children[n]->objectName() == "PlayListBtn" || children[n]->objectName() == "VolumeSlider") { continue; } QWidget *w = static_cast(children[n]); w->setMouseTracking(true); w->installEventFilter(this); installFilter(children[n]); } } } void BottomWidget::activate() { turned_on = true; if (timer->isActive()) timer->stop(); timer->start(); } void BottomWidget::deactivate() { turned_on = false; timer->stop(); this->showWidget(); } void BottomWidget::showAlways() { turned_on = false; timer->stop(); QPoint dest_position = QPoint(0, parentWidget()->size().height() - this->height()); move(dest_position); controlWidget->show(); QWidget::show(); } void BottomWidget::enable_turned_on() { turned_on = true; } void BottomWidget::showWidget() { showSpreadAnimated(); if (timer->isActive()) timer->stop(); timer->start(); } void BottomWidget::checkUnderMouse() { if ((ctlWidget->isVisible()) && (!underMouse())) {//0616 this->showGatherAnimated(); //0621 tell mainwindow to hide escwidget emit this->sig_show_or_hide_esc(false); } } bool BottomWidget::eventFilter(QObject * obj, QEvent * event) { QEvent::Type type = event->type(); if (type != QEvent::MouseButtonPress && type != QEvent::MouseButtonRelease && type != QEvent::MouseMove) return false; QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return false; if (mouseEvent->modifiers() != Qt::NoModifier) { drag_state = NOT_BDRAGGING; return false; } if (turned_on) { if (event->type() == QEvent::MouseMove) { if (!isVisible()) { showWidget(); /*if (activation_area == Anywhere) { showWidget(); } else { QMouseEvent * mouse_event = dynamic_cast(event); QWidget * parent = parentWidget(); QPoint p = parent->mapFromGlobal(mouse_event->globalPos()); if (p.y() > (parent->height() - height() - spacing)) { showWidget(); } }*/ } else if (!ctlWidget->isVisible()) { showWidget(); /*if (activation_area == Anywhere) { showWidget(); } else { QMouseEvent * mouse_event = dynamic_cast(event); QWidget * parent = parentWidget(); QPoint p = parent->mapFromGlobal(mouse_event->globalPos()); if (p.y() > (parent->height() - height() - spacing)) { showWidget(); } }*/ } } if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_BDRAGGING; return false; } drag_state = START_BDRAGGING; start_drag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (drag_state != BDRAGGING || mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_BDRAGGING; return false; } // Stop dragging and eat event drag_state = NOT_BDRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (drag_state == NOT_BDRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { drag_state = NOT_BDRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - start_drag; if (drag_state == START_BDRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; drag_state = BDRAGGING; } emit mouseMovedDiff(diff); start_drag = pos; event->accept(); return true; } else { if (type == QEvent::MouseButtonPress) { if (mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_BDRAGGING; return false; } drag_state = START_BDRAGGING; start_drag = mouseEvent->globalPos(); // Don't filter, so others can have a look at it too return false; } if (type == QEvent::MouseButtonRelease) { if (drag_state != BDRAGGING || mouseEvent->button() != Qt::LeftButton) { drag_state = NOT_BDRAGGING; return false; } // Stop dragging and eat event drag_state = NOT_BDRAGGING; event->accept(); return true; } // type == QEvent::MouseMove if (drag_state == NOT_BDRAGGING) return false; // buttons() note the s if (mouseEvent->buttons() != Qt::LeftButton) { drag_state = NOT_BDRAGGING; return false; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - start_drag; if (drag_state == START_BDRAGGING) { // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return false; drag_state = BDRAGGING; } emit mouseMovedDiff(diff); start_drag = pos; event->accept(); return true; } } void BottomWidget::spreadAniFinished() { } void BottomWidget::gatherAniFinished() { controlWidget->hide(); } void BottomWidget::show_control_widget() { controlWidget->show(); } void BottomWidget::showSpreadAnimated() { if (!spreadAnimation) { spreadAnimation = new QPropertyAnimation(this, "pos"); connect(spreadAnimation, SIGNAL(finished()), this, SLOT(spreadAniFinished())); } QPoint initial_position = QPoint(pos().x(), parentWidget()->size().height()); QPoint final_position = QPoint(0, parentWidget()->size().height() - this->height()); move(initial_position); QWidget::show(); controlWidget->show(); spreadAnimation->setDuration(300); spreadAnimation->setStartValue(initial_position); spreadAnimation->setEndValue(final_position); spreadAnimation->start(); //kobe: tell mainwindow to show escwidget emit this->sig_show_or_hide_esc(true); } void BottomWidget::showGatherAnimated() { if (!gatherAnimation) { gatherAnimation = new QPropertyAnimation(this, "pos"); connect(gatherAnimation, SIGNAL(finished()), this, SLOT(gatherAniFinished())); } QPoint initial_position = QPoint(0, parentWidget()->size().height() - this->height()); QPoint final_position = QPoint(pos().x(), parentWidget()->size().height() - 4);//kobe 0616:给最底下的进度条留下空间 move(initial_position); gatherAnimation->setDuration(300); gatherAnimation->setStartValue(initial_position); gatherAnimation->setEndValue(final_position); gatherAnimation->start(); } //-------------------------------------- /*void BottomWidget::mouseMoveEvent(QMouseEvent *event) { QPoint topLeftPoint (0, this->height()-140); QPoint rightBottomPoint(this->width(), this->height()); topLeftPoint = this->mapToGlobal(topLeftPoint); rightBottomPoint = this->mapToGlobal(rightBottomPoint); QPoint mouseGlobalPoint = this->mapToGlobal(event->pos()); if(isLeftPressDown) // { QMouseEvent *mouseEvent = dynamic_cast(event); if (!mouseEvent) return; if (mouseEvent->modifiers() != Qt::NoModifier) { return; } QPoint pos = mouseEvent->globalPos(); QPoint diff = pos - start_drag; // Don't start dragging before moving at least DRAG_THRESHOLD pixels if (abs(diff.x()) < 4 && abs(diff.y()) < 4) return; emit mouseMovedDiff(diff); start_drag = pos; // emit mouseMovedDiff(event->globalPos()-start_drag); // emit signalMovePoint(event->globalPos()-start_drag); } } void BottomWidget::mouseReleaseEvent(QMouseEvent *event) { if(event->button() == Qt::LeftButton) { isLeftPressDown = false; this->releaseMouse(); } } void BottomWidget::mousePressEvent(QMouseEvent *event) { switch(event->button()) { case Qt::LeftButton: { isLeftPressDown = true; // emit signalLeftPressDown(true); start_drag = event->globalPos(); break; } case Qt::RightButton: break; default: break; } }*/ //-------------------------------------- //void BottomWidget::mouseMoveEvent(QMouseEvent *event) //{ // QWidget::mouseMoveEvent(event); // Qt::MouseButton button = event->buttons() & Qt::LeftButton ? Qt::LeftButton : Qt::NoButton; // if (this->enableMove && event->buttons() == Qt::LeftButton) { // emit mouseMoving(button); // } //} void BottomWidget::resizeEvent(QResizeEvent *event) { //20170810 QWidget::resizeEvent(event); emit sig_resize_corner(); progress->resize(this->width(), 24); } /*BottomWidget::BottomWidget(QWidget *parent) : QWidget(parent, Qt::SubWindow) , turned_on(false) , spacing(0) , activation_area(Anywhere) , internal_widget(0) , spreadAnimation(0) , gatherAnimation(0) , drag_state(NOT_BDRAGGING) , start_drag(QPoint(0,0)) { this->setMouseTracking(true); setAutoFillBackground(true); setFocusPolicy(Qt::ClickFocus); QPalette palette; palette.setColor(QPalette::Background, QColor("#040404")); this->setPalette(palette); setWindowFlags(windowFlags() | Qt::SubWindow); setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); drag_delay = 200; enableMove = false; controlWidget = new QWidget(this); controlWidget->setFixedHeight(61); progress = NULL; progress = new TimeSlider(this); progress->setMouseTracking(true); progress->setDragDelay(100);//pref->time_slider_drag_delay connect(progress, SIGNAL(posChanged(int)), this, SIGNAL(posChanged(int))); connect(progress, SIGNAL(draggingPos(int)), this, SIGNAL(draggingPos(int))); connect(progress, SIGNAL(delayedDraggingPos(int)), this, SIGNAL(delayedDraggingPos(int))); connect(progress, SIGNAL(wheelUp()), this, SIGNAL(wheelUp())); connect(progress, SIGNAL(wheelDown()), this, SIGNAL(wheelDown())); connect(progress, SIGNAL(need_to_save_pre_image(int)), this, SIGNAL(need_to_save_pre_image(int))); connect(this, SIGNAL(send_save_preview_image_name(int,QString)), progress, SLOT(show_save_preview_image(int,QString))); progress->setObjectName("processProgress"); progress->setProperty("status", ""); connect(progress, SIGNAL(active_status(bool)), this, SLOT(slot_active_status(bool))); progress->setFixedHeight(24); progress->move(0,0); playtime_label = new QLabel; playtime_label->setText("00:00:00"); playtime_label->setFrameShape(QFrame::NoFrame); ColorUtils::setBackgroundColor(playtime_label, QColor(0,0,0) ); ColorUtils::setForegroundColor(playtime_label, QColor(255,255,255) ); playtime_label->setStyleSheet("QLabel{font-size:12px;color:#ffffff;}"); playtime_label->adjustSize(); alltime_label = new QLabel; alltime_label->setText(" / 00:00:00"); alltime_label->setFrameShape(QFrame::NoFrame); ColorUtils::setBackgroundColor( alltime_label, QColor(0,0,0) ); ColorUtils::setForegroundColor( alltime_label, QColor(255,255,255) ); alltime_label->setStyleSheet("QLabel{font-size:12px;color:#808080;}"); alltime_label->adjustSize(); btStop = new QPushButton; btStop->setObjectName("StopBtn"); btStop->setFixedSize(24, 24); btPrev = new QPushButton; btPrev->setObjectName("PrevBtn"); btPrev->setFixedSize(24, 24); btPlayPause = new QPushButton; btPlayPause->setShortcut(Qt::Key_Space); btPlayPause->setObjectName("PlayBtn"); btPlayPause->setFixedSize(61, 61); btNext = new QPushButton; btNext->setObjectName("NextBtn"); btNext->setFixedSize(24, 24); btSound = new QPushButton; btSound->setObjectName("SoundBtn"); btSound->setFixedSize(24, 24); btSound->setProperty("volume", "mid"); btFullScreen = new QPushButton; btFullScreen->setShortcut(QKeySequence("Ctrl+Return")); btFullScreen->setObjectName("FullScreenBtn"); btFullScreen->setFixedSize(24, 24); btPlayList = new QPushButton; btPlayList->setShortcut(QKeySequence("F3")); btPlayList->setObjectName("PlayListBtn"); btPlayList->setFixedSize(24, 24); listCountLabel = new QLabel; ColorUtils::setBackgroundColor(listCountLabel, QColor("#141414") ); listCountLabel->setStyleSheet("QLabel{font-size:12px;color:#ffffff;}"); this->listCountLabel->setText("0"); volSlider = new SoundVolume(this); volSlider->setObjectName("VolumeSlider"); connect(this, SIGNAL(valueChanged(int)), volSlider, SLOT(setValue(int))); connect(btStop, SIGNAL(released()), this, SIGNAL(signal_stop())); connect(btPrev, SIGNAL(released()), this, SIGNAL(signal_prev())); connect(btPlayPause, SIGNAL(released()), this, SIGNAL(signal_play_pause_status())); connect(btNext, SIGNAL(released()), this, SIGNAL(signal_next())); connect(btSound, SIGNAL(pressed()), this, SIGNAL(signal_mute())); connect(volSlider, SIGNAL(volumeChanged(int)), this, SLOT(slot_volumn_changed(int))); connect(btFullScreen, SIGNAL(pressed()), this, SIGNAL(toggleFullScreen())); connect(btPlayList, SIGNAL(released()), this, SIGNAL(togglePlaylist())); connect(this, SIGNAL(mouseMoving(Qt::MouseButton)), progress, SLOT(hideTip()));//20170714 QHBoxLayout *time_layout = new QHBoxLayout(); time_layout->setMargin(0); time_layout->setSpacing(2); time_layout->addWidget(playtime_label, 0, Qt::AlignLeft | Qt::AlignVCenter); time_layout->addWidget(alltime_label, 0, Qt::AlignLeft | Qt::AlignVCenter); metaWidget = new QFrame(this); metaWidget->setFixedHeight(61); QHBoxLayout *metaLayout = new QHBoxLayout(metaWidget); metaLayout->setMargin(0); metaLayout->setSpacing(10); metaLayout->addWidget(btPlayPause, 0, Qt::AlignVCenter); metaLayout->addLayout(time_layout); ctlWidget = new QFrame(this); ctlWidget->setFixedHeight(61); QHBoxLayout *ctlLayout = new QHBoxLayout(ctlWidget); ctlLayout->setMargin(0); ctlLayout->setSpacing(30); ctlLayout->addWidget(btPrev, 0, Qt::AlignCenter); ctlLayout->addWidget(btStop, 0, Qt::AlignCenter); ctlLayout->addWidget(btNext, 0, Qt::AlignCenter); ctlWidget->adjustSize(); QHBoxLayout *volume_layout = new QHBoxLayout(); volume_layout->setMargin(0); volume_layout->setSpacing(2); volume_layout->addWidget(btSound, 0, Qt::AlignRight | Qt::AlignVCenter); volume_layout->addWidget(volSlider, 0, Qt::AlignRight | Qt::AlignVCenter); QHBoxLayout *list_layout = new QHBoxLayout(); list_layout->setMargin(0); list_layout->setSpacing(2); list_layout->addWidget(btPlayList, 0, Qt::AlignRight | Qt::AlignVCenter); list_layout->addWidget(listCountLabel, 0, Qt::AlignRight | Qt::AlignVCenter); actWidget = new QWidget(this); actWidget->setFixedHeight(61); QHBoxLayout *actLayout = new QHBoxLayout(actWidget); actLayout->setMargin(0); actLayout->setSpacing(20); actLayout->addLayout(volume_layout); actLayout->addWidget(btFullScreen, 0, Qt::AlignRight | Qt::AlignVCenter); actLayout->addLayout(list_layout); QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Preferred); sp.setHorizontalStretch(33); metaWidget->setSizePolicy(sp); actWidget->setSizePolicy(sp); QHBoxLayout *layout = new QHBoxLayout(); layout->setContentsMargins(10, 0, 20, 0); layout->setSpacing(20); layout->addWidget(metaWidget, 0, Qt::AlignLeft); layout->addStretch(); layout->addWidget(ctlWidget, 0, Qt::AlignHCenter); layout->addStretch(); layout->addWidget(actWidget, 0, Qt::AlignRight); controlWidget->setLayout(layout); vboxlayout = new QVBoxLayout(this); vboxlayout->setSpacing(0); vboxlayout->setContentsMargins(0, 18, 0, 2); vboxlayout->addWidget(controlWidget); btStop->setFocusPolicy(Qt::NoFocus); btPrev->setFocusPolicy(Qt::NoFocus); btPlayPause->setFocusPolicy(Qt::NoFocus); btNext->setFocusPolicy(Qt::NoFocus); btFullScreen->setFocusPolicy(Qt::NoFocus); btSound->setFocusPolicy(Qt::NoFocus); volSlider->setFocusPolicy(Qt::NoFocus); btPlayList->setFocusPolicy(Qt::NoFocus); btStop->setToolTip(tr("Stop")); btPrev->setToolTip(tr("Prev")); btPlayPause->setToolTip(tr("Play / Pause")); btNext->setToolTip(tr("Next")); btSound->setToolTip(tr("Mute")); btPlayList->setToolTip(tr("Play List")); this->update_widget_qss_property(btPlayPause, property_PlayStatus, playStatusPause); this->update_widget_qss_property(this, property_PlayStatus, playStatusPause); } BottomWidget::~BottomWidget() { if (spreadAnimation) delete spreadAnimation; if (gatherAnimation) delete gatherAnimation; if (metaWidget) delete metaWidget; if (ctlWidget) delete ctlWidget; if (actWidget) delete actWidget; if (controlWidget) delete controlWidget; } void BottomWidget::setPreviewData(bool preview) { if (progress) { progress->set_preview_flag(preview); } } void BottomWidget::update_playlist_count_label(int count) { this->listCountLabel->setText(QString::number(count)); } void BottomWidget::setTransparent(bool transparent) { if (transparent) { setAttribute(Qt::WA_TranslucentBackground); setWindowFlags(windowFlags() | Qt::FramelessWindowHint|Qt::X11BypassWindowManagerHint); set_widget_opacity(0.5); } else { setAttribute(Qt::WA_TranslucentBackground,false); setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint); } } void BottomWidget::set_widget_opacity(const float &opacity) { QGraphicsOpacityEffect *opacityEffect = new QGraphicsOpacityEffect; this->setGraphicsEffect(opacityEffect); opacityEffect->setOpacity(opacity); } void BottomWidget::slot_active_status(bool b) { if (b) { this->update_widget_qss_property(progress, "status", "active"); } else { this->update_widget_qss_property(progress, "status", ""); } } void BottomWidget::setPos(int v) { bool was_blocked= progress->blockSignals(true); progress->setPos(v); progress->blockSignals(was_blocked); } int BottomWidget::ppos() { return progress->pos(); } void BottomWidget::setDuration(double t) { total_time = t; progress->setDuration(t); } void BottomWidget::setDragDelay(int d) { drag_delay = d; progress->setDragDelay(drag_delay); } int BottomWidget::dragDelay() { return drag_delay; } void BottomWidget::setActionsEnabled(bool b) { btPrev->setEnabled(b); btPlayPause->setEnabled(b); btNext->setEnabled(b); btSound->setEnabled(b); btStop->setEnabled(b); progress->setEnabled(b); } void BottomWidget::setPlayOrPauseEnabled(bool b) { btPlayPause->setEnabled(b); } void BottomWidget::setStopEnabled(bool b) { btStop->setEnabled(b); } void BottomWidget::displayTime(QString cur_time, QString all_time) { playtime_label->setText(cur_time); alltime_label->setText(all_time); } void BottomWidget::slot_playlist_btn_status(bool b) { if (b) { this->update_widget_qss_property(btPlayList, property_PlayListStatus, playStatusPlayList); } else { this->update_widget_qss_property(btPlayList, property_PlayListStatus, ""); } } void BottomWidget::slot_volumn_changed(int vol) { this->onVolumeChanged(vol); emit this->volumeChanged(vol); } void BottomWidget::onMusicPlayed() { this->update_widget_qss_property(btPlayPause, property_PlayStatus, playStatusPlaying); this->update_widget_qss_property(this, property_PlayStatus, playStatusPlaying); } void BottomWidget::onMusicPause() { this->update_widget_qss_property(btPlayPause, property_PlayStatus, playStatusPause); this->update_widget_qss_property(this, property_PlayStatus, playStatusPause); } void BottomWidget::onMusicStoped() { this->update_widget_qss_property(btPlayPause, property_PlayStatus, playStatusStop); this->update_widget_qss_property(this, property_PlayStatus, playStatusStop); } void BottomWidget::onFullScreen() { this->update_widget_qss_property(btFullScreen, property_FullScreen, true); } void BottomWidget::onUnFullScreen() { this->update_widget_qss_property(btFullScreen, property_FullScreen, false); } void BottomWidget::onVolumeChanged(int volume) { QString status = "mid"; if (volume > 77) { status = "high"; } else if (volume > 33) { status = "mid"; } else if (volume > 0) { status = "low"; } else { status = "mute"; } this->update_widget_qss_property(btSound, "volume", status); this->volSlider->onVolumeChanged(volume); } void BottomWidget::onMutedChanged(bool muted, int volumn) { if (muted) { this->update_widget_qss_property(btSound, "volume", "mute"); this->volSlider->onVolumeChanged(0); } else { this->onVolumeChanged(volumn); } } void BottomWidget::update_widget_qss_property(QWidget *w, const char *name, const QVariant &value) { w->setProperty(name, value); this->style()->unpolish(w); this->style()->polish(w); w->update(); } void BottomWidget::showAlways() { turned_on = false; QPoint dest_position = QPoint(0, parentWidget()->size().height() - this->height()); move(dest_position); controlWidget->show(); QWidget::show(); } void BottomWidget::enable_turned_on() { turned_on = true; } bool BottomWidget::getCtrlWidgetVisible() { return this->ctlWidget->isVisible(); } void BottomWidget::spreadAniFinished() { } void BottomWidget::gatherAniFinished() { controlWidget->hide(); } void BottomWidget::show_control_widget() { controlWidget->show(); } void BottomWidget::showSpreadAnimated() { if (!spreadAnimation) { spreadAnimation = new QPropertyAnimation(this, "pos"); connect(spreadAnimation, SIGNAL(finished()), this, SLOT(spreadAniFinished())); } QPoint initial_position = QPoint(pos().x(), parentWidget()->size().height()); QPoint final_position = QPoint(0, parentWidget()->size().height() - this->height()); move(initial_position); QWidget::show(); controlWidget->show(); spreadAnimation->setDuration(300); spreadAnimation->setStartValue(initial_position); spreadAnimation->setEndValue(final_position); spreadAnimation->start(); //kobe: tell mainwindow to show escwidget emit this->sig_show_or_hide_esc(true); } void BottomWidget::showGatherAnimated() { if (!gatherAnimation) { gatherAnimation = new QPropertyAnimation(this, "pos"); connect(gatherAnimation, SIGNAL(finished()), this, SLOT(gatherAniFinished())); } QPoint initial_position = QPoint(0, parentWidget()->size().height() - this->height()); QPoint final_position = QPoint(pos().x(), parentWidget()->size().height() - 4);//kobe 0616:给最底下的进度条留下空间 move(initial_position); gatherAnimation->setDuration(300); gatherAnimation->setStartValue(initial_position); gatherAnimation->setEndValue(final_position); gatherAnimation->start(); } void BottomWidget::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); emit sig_resize_corner(); progress->resize(this->width(), 24); } */ kylin-video/src/kylin/shortcutswidget.cpp0000664000175000017500000006525513214706400017627 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #include "shortcutswidget.h" #include #include #include #include #include #include #include #include "../smplayer/helper.h" #include "../smplayer/global.h" #include "../smplayer/preferences.h" using namespace Global; ShortcutsWidget *ShortcutsWidget::self = 0; ShortcutsWidget::ShortcutsWidget(QWidget *parent) : QWidget(parent) { this->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint); this->setWindowTitle(tr("Kylin Video - Shortcuts")); timer = NULL; parent_widget = 0; title_label = NULL; control_title_label = NULL; other_title_label = NULL; close_button = NULL; // control_form_layout = NULL; control_grid_layout = NULL; other_grid_layout = NULL; set_widget_opacity(0.7); set_background_color(QColor(0, 0, 0)); this->init_ui(); } ShortcutsWidget::~ShortcutsWidget() { self = 0; if (timer != NULL) { disconnect(timer,SIGNAL(timeout()),this,SLOT(hide_mask_widget())); if(timer->isActive()) { timer->stop(); } delete timer; timer = NULL; } if (title_label != NULL) { delete title_label; title_label = NULL; } if (control_title_label != NULL) { delete control_title_label; control_title_label = NULL; } if (other_title_label != NULL) { delete other_title_label; other_title_label = NULL; } if (close_button != NULL) { delete close_button; close_button = NULL; } while(control_grid_layout != NULL && control_grid_layout->count() > 0) { QWidget *widget = control_grid_layout->itemAt(0)->widget(); control_grid_layout->removeWidget(widget); delete widget; widget = NULL; } // for (int i=0; i < control_label_list.count(); i++) { // control_grid_layout->removeWidget(control_label_list[i]); //// control_form_layout->removeWidget(control_label_list[i]); // delete control_label_list[i]; // control_label_list[i] = NULL; // } // control_label_list.clear(); if (control_grid_layout != NULL) { delete control_grid_layout; control_grid_layout = NULL; } if (other_title_label != NULL) { delete other_title_label; other_title_label = NULL; } // for (int j=0; j < other_label_list.count(); j++) { // other_grid_layout->removeWidget(other_label_list[j]); // delete other_label_list[j]; // other_label_list[j] = NULL; // } // other_label_list.clear(); while(other_grid_layout != NULL && other_grid_layout->count() > 0) { QWidget *widget = other_grid_layout->itemAt(0)->widget(); other_grid_layout->removeWidget(widget); delete widget; widget = NULL; } if (other_grid_layout != NULL) { delete other_grid_layout; other_grid_layout = NULL; } // if(control_form_layout != NULL) // { // delete control_form_layout; // control_form_layout = NULL; // } } void ShortcutsWidget::set_parent_widget(QWidget *widget) { if (this->parent_widget != widget) { this->parent_widget = widget; } } void ShortcutsWidget::setPrefData(Preferences *pref) { forward_10s_title->setText(tr("Forward %1").arg(Helper::timeForJumps(pref->seeking1))); forward_1m_title->setText(tr("Forward %1").arg(Helper::timeForJumps(pref->seeking2))); forward_10m_title->setText(tr("Forward %1").arg(Helper::timeForJumps(pref->seeking3))); back_10s_title->setText(tr("Rewind %1").arg(Helper::timeForJumps(pref->seeking1))); back_1m_title->setText(tr("Rewind %1").arg(Helper::timeForJumps(pref->seeking2))); back_10m_title->setText(tr("Rewind %1").arg(Helper::timeForJumps(pref->seeking3))); } void ShortcutsWidget::init_ui() { control_grid_layout = new QGridLayout; control_grid_layout->setSpacing(10); control_grid_layout->setContentsMargins(0, 0, 0, 0); other_grid_layout = new QGridLayout; other_grid_layout->setSpacing(10); other_grid_layout->setContentsMargins(0, 0, 0, 0); title_label = new QLabel(); title_label->setText(tr("Kylin Video - Shortcuts")); title_label->setFrameShape(QFrame::NoFrame); title_label->setStyleSheet("QLabel{background:transparent;font-size:16px;color:#ffffff;font-family:方正黑体_GBK;}"); title_label->adjustSize(); control_title_label = new QLabel(); control_title_label->setText(tr("Play control")); control_title_label->setFrameShape(QFrame::NoFrame); control_title_label->setStyleSheet("QLabel{background:transparent;font-size:14px;color:#ffffff;font-family:方正黑体_GBK;}"); control_title_label->adjustSize(); other_title_label = new QLabel(); other_title_label->setText(tr("Other control")); other_title_label->setFrameShape(QFrame::NoFrame); other_title_label->setStyleSheet("QLabel{background:transparent;font-size:14px;color:#ffffff;font-family:方正黑体_GBK;}"); other_title_label->adjustSize(); close_button = new QPushButton(); close_button->setFixedSize(91, 25); close_button->setText(tr("Close")); close_button->setFocusPolicy(Qt::NoFocus); close_button->setStyleSheet("QPushButton{font-size:12px;background:#0f0f0f;border:1px solid #0a9ff5;color:#999999;}QPushButton:hover{background-color:#0a9ff5;border:1px solid #2db0f6;color:#ffffff;} QPushButton:pressed{background-color:#0993e3;border:1px solid #0a9ff5;color:#ffffff;}"); connect(close_button, SIGNAL(clicked(bool)), this, SLOT(onCloseButtonClicked())); // close_button->setAutoDefault(true); // close_button->setFocus(); // QWidget::setTabOrder(close_button, title_label); /*control_form_layout = new QFormLayout(); // control_form_layout->setSizeConstraint(QLayout::SetFixedSize);//frame will fixed with content's width control_form_layout->setSpacing(10); control_form_layout->setHorizontalSpacing(10); control_form_layout->setRowWrapPolicy(QFormLayout::DontWrapRows); control_form_layout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint);*/ play_title = new QLabel(); play_title->setText(tr("Play/Pause")); play_title->setFrameShape(QFrame::NoFrame); play_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); play_title->adjustSize(); control_grid_layout->addWidget(play_title,0,0); // control_label_list.append(play_title); play_label = new QLabel(); play_label->setText("Space"); play_label->setFrameShape(QFrame::NoFrame); play_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); play_label->adjustSize(); control_grid_layout->addWidget(play_label,0,1); // control_label_list.append(play_label); // control_form_layout->addRow(tr("Play/Pause"), play_label); play_pre_title = new QLabel(); play_pre_title->setText(tr("Previous")); play_pre_title->setFrameShape(QFrame::NoFrame); play_pre_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); play_pre_title->adjustSize(); control_grid_layout->addWidget(play_pre_title,1,0); // control_label_list.append(play_pre_title); play_pre_label = new QLabel(); play_pre_label->setText(pref->prev_key); play_pre_label->setFrameShape(QFrame::NoFrame); play_pre_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); play_pre_label->adjustSize(); control_grid_layout->addWidget(play_pre_label,1,1); // control_label_list.append(play_pre_label); play_next_title = new QLabel(); play_next_title->setText(tr("Next")); play_next_title->setFrameShape(QFrame::NoFrame); play_next_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); play_next_title->adjustSize(); control_grid_layout->addWidget(play_next_title,2,0); // control_label_list.append(play_next_title); play_next_label = new QLabel(); play_next_label->setText(pref->next_key);//">, Media Next" play_next_label->setFrameShape(QFrame::NoFrame); play_next_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); play_next_label->adjustSize(); control_grid_layout->addWidget(play_next_label,2,1); // control_label_list.append(play_next_label); forward_10s_title = new QLabel(); forward_10s_title->setFrameShape(QFrame::NoFrame); forward_10s_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); forward_10s_title->adjustSize(); control_grid_layout->addWidget(forward_10s_title,3,0); // control_label_list.append(forward_10s_title); forward_10s_label = new QLabel(); forward_10s_label->setText("Right(→)"); forward_10s_label->setFrameShape(QFrame::NoFrame); forward_10s_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); forward_10s_label->adjustSize(); control_grid_layout->addWidget(forward_10s_label,3,1); // control_label_list.append(forward_10s_label); forward_1m_title = new QLabel(); forward_1m_title->setFrameShape(QFrame::NoFrame); forward_1m_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); forward_1m_title->adjustSize(); control_grid_layout->addWidget(forward_1m_title,4,0); // control_label_list.append(forward_1m_title); forward_1m_label = new QLabel(); forward_1m_label->setText("Up(↑)"); forward_1m_label->setFrameShape(QFrame::NoFrame); forward_1m_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); forward_1m_label->adjustSize(); control_grid_layout->addWidget(forward_1m_label,4,1); // control_label_list.append(forward_1m_label); forward_10m_title = new QLabel(); forward_10m_title->setFrameShape(QFrame::NoFrame); forward_10m_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); forward_10m_title->adjustSize(); control_grid_layout->addWidget(forward_10m_title,5,0); // control_label_list.append(forward_10m_title); forward_10m_label = new QLabel(); forward_10m_label->setText("PgUp"); forward_10m_label->setFrameShape(QFrame::NoFrame); forward_10m_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); forward_10m_label->adjustSize(); control_grid_layout->addWidget(forward_10m_label,5,1); // control_label_list.append(forward_10m_label); back_10s_title = new QLabel(); back_10s_title->setFrameShape(QFrame::NoFrame); back_10s_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); back_10s_title->adjustSize(); control_grid_layout->addWidget(back_10s_title,6,0); // control_label_list.append(back_10s_title); back_10s_label = new QLabel(); back_10s_label->setText("Left(←)"); back_10s_label->setFrameShape(QFrame::NoFrame); back_10s_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); back_10s_label->adjustSize(); control_grid_layout->addWidget(back_10s_label,6,1); // control_label_list.append(back_10s_label); back_1m_title = new QLabel(); back_1m_title->setFrameShape(QFrame::NoFrame); back_1m_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); back_1m_title->adjustSize(); control_grid_layout->addWidget(back_1m_title,7,0); // control_label_list.append(back_1m_title); back_1m_label = new QLabel(); back_1m_label->setText("Down(↓)"); back_1m_label->setFrameShape(QFrame::NoFrame); back_1m_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); back_1m_label->adjustSize(); control_grid_layout->addWidget(back_1m_label,7,1); // control_label_list.append(back_1m_label); back_10m_title = new QLabel(); back_10m_title->setFrameShape(QFrame::NoFrame); back_10m_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); back_10m_title->adjustSize(); control_grid_layout->addWidget(back_10m_title,8,0); // control_label_list.append(back_10m_title); back_10m_label = new QLabel(); back_10m_label->setText("PgDn"); back_10m_label->setFrameShape(QFrame::NoFrame); back_10m_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); back_10m_label->adjustSize(); control_grid_layout->addWidget(back_10m_label,8,1); // control_label_list.append(back_10m_label); jump_title = new QLabel(); jump_title->setText(tr("Jump to...")); jump_title->setFrameShape(QFrame::NoFrame); jump_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); play_next_title->adjustSize(); control_grid_layout->addWidget(jump_title,9,0); // control_label_list.append(jump_title); jump_label = new QLabel(); jump_label->setText("Ctrl + J"); jump_label->setFrameShape(QFrame::NoFrame); jump_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); jump_label->adjustSize(); control_grid_layout->addWidget(jump_label,9,1); // control_label_list.append(jump_label); mute_title = new QLabel(); mute_title->setText(tr("Mute")); mute_title->setFrameShape(QFrame::NoFrame); mute_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); mute_title->adjustSize(); control_grid_layout->addWidget(mute_title,10,0); // control_label_list.append(mute_title); mute_label = new QLabel(); mute_label->setText("M"); mute_label->setFrameShape(QFrame::NoFrame); mute_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); mute_label->adjustSize(); control_grid_layout->addWidget(mute_label,10,1); // control_label_list.append(mute_label); vol_up_title = new QLabel(); vol_up_title->setText(tr("Volume +")); vol_up_title->setFrameShape(QFrame::NoFrame); vol_up_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); vol_up_title->adjustSize(); control_grid_layout->addWidget(vol_up_title,11,0); // control_label_list.append(vol_up_title); vol_up_label = new QLabel(); vol_up_label->setText("0"); vol_up_label->setFrameShape(QFrame::NoFrame); vol_up_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); vol_up_label->adjustSize(); control_grid_layout->addWidget(vol_up_label,11,1); // control_label_list.append(vol_up_label); vol_down_title = new QLabel(); vol_down_title->setText(tr("Volume -")); vol_down_title->setFrameShape(QFrame::NoFrame); vol_down_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); vol_down_title->adjustSize(); control_grid_layout->addWidget(vol_down_title,12,0); // control_label_list.append(vol_down_title); vol_down_label = new QLabel(); vol_down_label->setText("9"); vol_down_label->setFrameShape(QFrame::NoFrame); vol_down_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); vol_down_label->adjustSize(); control_grid_layout->addWidget(vol_down_label,12,1); // control_label_list.append(vol_down_label); set_audio_delay_title = new QLabel(); set_audio_delay_title->setText(tr("Set audio delay")); set_audio_delay_title->setFrameShape(QFrame::NoFrame); set_audio_delay_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); set_audio_delay_title->adjustSize(); control_grid_layout->addWidget(set_audio_delay_title,13,0); // control_label_list.append(set_audio_delay_title); set_audio_delay_label = new QLabel(); set_audio_delay_label->setText("Y"); set_audio_delay_label->setFrameShape(QFrame::NoFrame); set_audio_delay_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); set_audio_delay_label->adjustSize(); control_grid_layout->addWidget(set_audio_delay_label,13,1); // control_label_list.append(set_audio_delay_label); audio_delay_title = new QLabel(); audio_delay_title->setText(tr("Increase or decrease audio delay")); audio_delay_title->setFrameShape(QFrame::NoFrame); audio_delay_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); audio_delay_title->adjustSize(); control_grid_layout->addWidget(audio_delay_title,14,0); // control_label_list.append(audio_delay_title); audio_delay_label = new QLabel(); audio_delay_label->setText("+ / - / ="); audio_delay_label->setFrameShape(QFrame::NoFrame); audio_delay_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); audio_delay_label->adjustSize(); control_grid_layout->addWidget(audio_delay_label,14,1); // control_label_list.append(audio_delay_label); playlist_title = new QLabel(); playlist_title->setText(tr("Playlist")); playlist_title->setFrameShape(QFrame::NoFrame); playlist_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); playlist_title->adjustSize(); other_grid_layout->addWidget(playlist_title,0,0); playlist_label = new QLabel(); playlist_label->setText(pref->playlist_key);//F3 playlist_label->setFrameShape(QFrame::NoFrame); playlist_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); playlist_label->adjustSize(); other_grid_layout->addWidget(playlist_label,0,1); open_title = new QLabel(); open_title->setText(tr("Open File")); open_title->setFrameShape(QFrame::NoFrame); open_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); open_title->adjustSize(); other_grid_layout->addWidget(open_title,1,0); // other_label_list.append(open_title); open_label = new QLabel(); open_label->setText("Ctrl + F"); open_label->setFrameShape(QFrame::NoFrame); open_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); open_label->adjustSize(); other_grid_layout->addWidget(open_label,1,1); // other_label_list.append(open_label); screenshot_title = new QLabel(); screenshot_title->setText(tr("Screenshot")); screenshot_title->setFrameShape(QFrame::NoFrame); screenshot_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); screenshot_title->adjustSize(); other_grid_layout->addWidget(screenshot_title,2,0); // other_label_list.append(screenshot_title); screenshot_label = new QLabel(); screenshot_label->setText("S"); screenshot_label->setFrameShape(QFrame::NoFrame); screenshot_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); screenshot_label->adjustSize(); other_grid_layout->addWidget(screenshot_label,2,1); // other_label_list.append(screenshot_label); pref_title = new QLabel(); pref_title->setText(tr("Preferences")); pref_title->setFrameShape(QFrame::NoFrame); pref_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); pref_title->adjustSize(); other_grid_layout->addWidget(pref_title,3,0); // other_label_list.append(pref_title); pref_label = new QLabel(); pref_label->setText("Ctrl + P"); pref_label->setFrameShape(QFrame::NoFrame); pref_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); pref_label->adjustSize(); other_grid_layout->addWidget(pref_label,3,1); // other_label_list.append(pref_label); info_title = new QLabel(); info_title->setText(tr("View info and properties...")); info_title->setFrameShape(QFrame::NoFrame); info_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); info_title->adjustSize(); other_grid_layout->addWidget(info_title,4,0); // other_label_list.append(info_title); info_label = new QLabel(); info_label->setText("Ctrl + I"); info_label->setFrameShape(QFrame::NoFrame); info_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); info_label->adjustSize(); other_grid_layout->addWidget(info_label,4,1); // other_label_list.append(info_label); about_title = new QLabel(); about_title->setText(tr("About")); about_title->setFrameShape(QFrame::NoFrame); about_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); about_title->adjustSize(); other_grid_layout->addWidget(about_title,5,0); about_label = new QLabel(); about_label->setText("Ctrl + A"); about_label->setFrameShape(QFrame::NoFrame); about_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); about_label->adjustSize(); other_grid_layout->addWidget(about_label,5,1); quit_title = new QLabel(); quit_title->setText(tr("Quit")); quit_title->setFrameShape(QFrame::NoFrame); quit_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); quit_title->adjustSize(); other_grid_layout->addWidget(quit_title,6,0); quit_label = new QLabel(); quit_label->setText("Ctrl + Q"); quit_label->setFrameShape(QFrame::NoFrame); quit_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); quit_label->adjustSize(); other_grid_layout->addWidget(quit_label,6,1); fullscreen_title = new QLabel(); fullscreen_title->setText(tr("FullScreen/Cancel fullScreen")); fullscreen_title->setFrameShape(QFrame::NoFrame); fullscreen_title->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); fullscreen_title->adjustSize(); other_grid_layout->addWidget(fullscreen_title,7,0); fullscreen_label = new QLabel(); fullscreen_label->setText("Ctrl + Enter"); fullscreen_label->setFrameShape(QFrame::NoFrame); fullscreen_label->setStyleSheet("QLabel{background:transparent;font-size:12px;color:#ffffff;font-family:方正黑体_GBK;}"); fullscreen_label->adjustSize(); other_grid_layout->addWidget(fullscreen_label,7,1); QVBoxLayout *lhlayout = new QVBoxLayout; lhlayout->setSpacing(10); lhlayout->addWidget(control_title_label); lhlayout->addLayout(control_grid_layout); lhlayout->addStretch(); QVBoxLayout *rhlayout = new QVBoxLayout; rhlayout->setSpacing(10); rhlayout->addWidget(other_title_label); rhlayout->addLayout(other_grid_layout); rhlayout->addStretch(); QHBoxLayout *hlayout = new QHBoxLayout; hlayout->addStretch(); // hlayout->addLayout(control_form_layout); hlayout->addLayout(lhlayout); hlayout->addStretch(); hlayout->addLayout(rhlayout); hlayout->addStretch(); QVBoxLayout *layout = new QVBoxLayout; layout->setContentsMargins(10, 40, 10, 30); layout->setSpacing(20); // layout->setSizeConstraint(QLayout::SetFixedSize); layout->addWidget(title_label); layout->addStretch(); layout->addLayout(hlayout); layout->addStretch(); layout->addWidget(close_button, 0, Qt::AlignHCenter); this->setLayout(layout); } void ShortcutsWidget::onCloseButtonClicked() { if (timer->isActive()) timer->stop(); this->hide_mask_widget(); } void ShortcutsWidget::restart_timer() { if (timer == NULL) { timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(hide_mask_widget())); timer->setInterval(10000); } if (timer->isActive()) timer->stop(); timer->start(); } void ShortcutsWidget::set_widget_opacity(double opacity) { this->setWindowOpacity(opacity); } void ShortcutsWidget::set_background_color(const QColor &bgColor) { QPalette palette = this->palette(); palette.setBrush(QPalette::Background, bgColor); this->setPalette(palette); } void ShortcutsWidget::showEvent(QShowEvent *) { if (parent_widget != 0) { this->setGeometry(parent_widget->geometry()); } } void ShortcutsWidget::hide_mask_widget() { if (this->isVisible()) { this->hide(); } } //void ShortcutsWidget::keyReleaseEvent(QKeyEvent *event) { // if (this->isVisible()) { // this->hide(); // } // QWidget::keyReleaseEvent(event); //} kylin-video/src/kylin/soundvolume.cpp0000664000175000017500000000670313214706400016736 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #include "soundvolume.h" #include #include #include #include #include #include #include SoundVolume::SoundVolume(QWidget *parent) : QWidget(parent) { this->setObjectName("SoundVolume"); setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint); setAttribute(Qt::WA_TranslucentBackground); setFixedSize(106, 40);//setFixedSize(40, 106); QHBoxLayout *layout = new QHBoxLayout(this); layout->setContentsMargins(5, 0, 5, 0);//(0, 5, 0, 11);// layout->setSpacing(0); volSlider = 0; tborderColor = QColor(0, 0, 0, 255 * 2 / 10); tradius = 4; mouseIn = false; volSlider = new QSlider(Qt::Horizontal);//Qt::Vertical volSlider->setMinimum(0); volSlider->setMaximum(100); volSlider->setSingleStep(10);//VolumeStep volSlider->setValue(50); volSlider->setFocusPolicy(Qt::NoFocus); volSlider->setObjectName("VolumeProgress"); layout->addStretch(); layout->addWidget(volSlider, 0, Qt::AlignCenter); layout->addStretch(); setFixedSize(106, 24); connect(volSlider, SIGNAL(valueChanged(int)), this, SIGNAL(volumeChanged(int))); } SoundVolume::~SoundVolume() { } void SoundVolume::setValue(int vol) { bool was_blocked = volSlider->blockSignals(true); volSlider->setValue(vol); volSlider->blockSignals(was_blocked); } int SoundVolume::volume() const { return volSlider->value(); } QBrush SoundVolume::background() const { return tbackground; } int SoundVolume::radius() const { return this->tradius; } QColor SoundVolume::borderColor() const { return this->tborderColor; } void SoundVolume::setBackground(QBrush m_background) { this->tbackground = m_background; } void SoundVolume::setRadius(int m_adius) { this->tradius = m_adius; } void SoundVolume::setBorderColor(QColor m_borderColor) { this->tborderColor = m_borderColor; } void SoundVolume::deleyHide() { this->mouseIn = false; // QTimer::singleShot(1000, this, SLOT(slot_deley())); } void SoundVolume::slot_deley() { if (!this->mouseIn) { hide(); } } void SoundVolume::onVolumeChanged(int vol) { this->volSlider->blockSignals(true); this->volSlider->setValue(vol); this->volSlider->blockSignals(false); } void SoundVolume::showEvent(QShowEvent *event) { this->mouseIn = true; QWidget::showEvent(event); } void SoundVolume::enterEvent(QEvent *event) { this->mouseIn = true; QWidget::enterEvent(event); } void SoundVolume::leaveEvent(QEvent *event) { this->mouseIn = false; deleyHide(); QWidget::leaveEvent(event); } void SoundVolume::wheelEvent(QWheelEvent *event) { QWidget::wheelEvent(event); } kylin-video/src/kylin/systembutton.h0000664000175000017500000000265113214706400016601 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #ifndef SYSTEMBUTTON_H #define SYSTEMBUTTON_H #include #include #include class SystemButton : public QPushButton { Q_OBJECT public: explicit SystemButton(QWidget *parent = 0); void loadPixmap(QString pic_name); protected: void enterEvent(QEvent *); void leaveEvent(QEvent *); void mousePressEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); void paintEvent(QPaintEvent *); private: QPixmap pixmap; enum ButtonStatus{NORMAL, ENTER, PRESS}; ButtonStatus status; bool mouse_press; //按钮左键是否按下 int btn_width; int btn_height; }; #endif // SYSTEMBUTTON_H kylin-video/src/kylin/supportshortcuts.ui0000664000175000017500000000302013214706400017671 0ustar fengfeng SupportShortcuts 0 0 470 360 20 9 431 201 Play control shortcuts 10 24 411 170 true 20 213 431 141 Other control shortcuts 10 24 411 111 true kylin-video/src/kylin/tipwidget.cpp0000664000175000017500000000643313214706400016356 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #include "tipwidget.h" #include #include #include #include #include #include #include TipWidget::TipWidget(const QString &text, QWidget *parent) : QFrame(parent)//: QWidget(parent, Qt::SubWindow) { setWindowFlags(windowFlags() | Qt::SubWindow); setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); // setTransparent(true); setWindowFlags(/*Qt::ToolTip | */Qt::FramelessWindowHint); setAttribute(Qt::WA_TranslucentBackground); setContentsMargins(0, 0, 0, 0); setObjectName("TipWidget");//kobe:设置背景色 m_radius = 4; w_shadow = 20; shadow_margins = QMargins(20, 20, 20, 20); m_borderColor = QColor(0, 0, 0, 0.2 * 255); QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); text_label = new QLabel(text); text_label->adjustSize(); text_label->setStyleSheet("QLabel{font-size: 16px;color: #ffffff;}"); text_label->setAlignment(Qt::AlignCenter); layout->addStretch(); layout->addWidget(text_label); layout->addStretch(); this->setLayout(layout); layout->setSizeConstraint(QLayout::SetFixedSize); hide(); } TipWidget::~TipWidget() { } void TipWidget::setTransparent(bool transparent) { if (transparent) { setAttribute(Qt::WA_TranslucentBackground); setWindowFlags(windowFlags() | Qt::FramelessWindowHint|Qt::X11BypassWindowManagerHint); set_widget_opacity(0.5); } else { setAttribute(Qt::WA_TranslucentBackground,false); setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint); } } void TipWidget::set_widget_opacity(const float &opacity) { QGraphicsOpacityEffect* opacityEffect = new QGraphicsOpacityEffect; this->setGraphicsEffect(opacityEffect); opacityEffect->setOpacity(opacity); } void TipWidget::setText(const QString text) { this->text_label->setText(text); } QBrush TipWidget::background() const { return this->m_background; } int TipWidget::radius() const { return this->m_radius; } QColor TipWidget::borderColor() const { return this->m_borderColor; } void TipWidget::setBackground(QBrush background) { this->m_background = background; } void TipWidget::setRadius(int radius) { this->m_radius = radius; } void TipWidget::setBorderColor(QColor borderColor) { this->m_borderColor = borderColor; } void TipWidget::aniFinished() { this->hide(); } kylin-video/src/kylin/timetip.h0000664000175000017500000000243013214706400015467 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #ifndef _TIMETIP_H_ #define _TIMETIP_H_ #include class QLabel; class TimeTip : public QFrame { Q_OBJECT public: explicit TimeTip(const QString &text, QWidget *parent = 0); ~TimeTip(); public slots: void setText(const QString text); void setPixMapAndTime(QPixmap pixmap, const QString time); protected: virtual void paintEvent(QPaintEvent *event); private: QFrame *text_frame; QLabel *text_label; QLabel *split_line; bool repaint_flag; }; #endif kylin-video/src/kylin/shortcutswidget.h0000664000175000017500000000707413214706400017267 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #ifndef SHORTCUTSWIDGET_H #define SHORTCUTSWIDGET_H #include #include #include #include "../smplayer/preferences.h" class QTimer; class QLabel; class QPushButton; class QGridLayout; class QFormLayout; class ShortcutsWidget : public QWidget { Q_OBJECT public: explicit ShortcutsWidget(QWidget *parent = 0); ~ShortcutsWidget(); static ShortcutsWidget *Instance() { static QMutex mutex; if (!self) { QMutexLocker locker(&mutex); if (!self) { self = new ShortcutsWidget; } } return self; } void restart_timer(); void init_ui(); void setPrefData(Preferences * pref); protected: void showEvent(QShowEvent *); // virtual void keyReleaseEvent(QKeyEvent *event); public slots: void set_parent_widget(QWidget *idget); void set_background_color(const QColor &bgColor); void set_widget_opacity(double opacity); void hide_mask_widget(); void onCloseButtonClicked(); private: static ShortcutsWidget *self; QWidget *parent_widget; QTimer *timer; QLabel *title_label; QLabel *control_title_label; QLabel *other_title_label; QPushButton *close_button; // QFormLayout *control_form_layout; // QList control_label_list; QGridLayout *control_grid_layout; // QList other_label_list; QGridLayout *other_grid_layout; QLabel *play_title; QLabel *play_label; QLabel *play_pre_title; QLabel *play_pre_label; QLabel *play_next_title; QLabel *play_next_label; QLabel *forward_10s_title; QLabel *forward_10s_label; QLabel *forward_1m_title; QLabel *forward_1m_label; QLabel *forward_10m_title; QLabel *forward_10m_label; QLabel *back_10s_title; QLabel *back_10s_label; QLabel *back_1m_title; QLabel *back_1m_label; QLabel *back_10m_title; QLabel *back_10m_label; QLabel *jump_title; QLabel *jump_label; QLabel *mute_title; QLabel *mute_label; QLabel *vol_up_title; QLabel *vol_up_label; QLabel *vol_down_title; QLabel *vol_down_label; QLabel *set_audio_delay_title; QLabel *set_audio_delay_label; QLabel *audio_delay_title; QLabel *audio_delay_label; QLabel *playlist_title; QLabel *playlist_label; QLabel *open_title; QLabel *open_label; QLabel *screenshot_title; QLabel *screenshot_label; QLabel *pref_title; QLabel *pref_label; QLabel *info_title; QLabel *info_label; QLabel *about_title; QLabel *about_label; QLabel *quit_title; QLabel *quit_label; QLabel *fullscreen_title; QLabel *fullscreen_label; }; #endif // SHORTCUTSWIDGET_H kylin-video/src/kylin/titlebutton.h0000664000175000017500000000247213214706400016377 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #ifndef TITLEBUTTON_H #define TITLEBUTTON_H #include class TitleButton : public QWidget { Q_OBJECT public: explicit TitleButton(int id, bool bigFont, const QString &title, QWidget *parent = 0); int id() const; void setId(const int &id); bool isActived() const; void setActived(bool isActived); signals: void clicked(int id); protected: void mousePressEvent(QMouseEvent *e); void paintEvent(QPaintEvent *e); private: bool m_bigFont; bool m_isActived; int m_id; QString m_title; }; #endif // TITLEBUTTON_H kylin-video/src/kylin/titlebutton.cpp0000664000175000017500000000605713214706400016735 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #include "titlebutton.h" #include #include #include #include namespace { const int LEFT_WIDTH = 2; const int TITLE_LM_BIG = 10; const int TITLE_LM_NORMAL = 20; const int FONT_SIZE_BIG = 14; const int FONT_SIZE_NORMAL = 14; const QColor FONT_COLOR_ACTIVED = QColor("#ffffff"); const QColor FONT_COLOR_NORMAL = QColor("#999999"); const QColor LEFT_COLOR_ACTIVED = QColor("#0a9ff5"); const QColor RIGHT_COLOR_ACTIVED = QColor("#1f1f1f"); } TitleButton::TitleButton(int id, bool bigFont, const QString &title, QWidget *parent) : QWidget(parent) , m_bigFont(bigFont) , m_isActived(false) , m_id(id) , m_title(title) { setFixedHeight(45); this->setStyleSheet("QWidget{border:none;}"); } void TitleButton::mousePressEvent(QMouseEvent *e) { if (e->button() == Qt::LeftButton) { emit this->clicked(m_id); e->accept(); } } void TitleButton::paintEvent(QPaintEvent *e) { const QColor lbc = isActived() ? LEFT_COLOR_ACTIVED : QColor("#2e2e2e");//没有选中时,让其左侧2px宽度的区域颜色和title_widget背景颜色一致 const QColor rbc = isActived() ? RIGHT_COLOR_ACTIVED : QColor("#2e2e2e"); const QRect lr(0, 0, LEFT_WIDTH, height()); const QRect rr(LEFT_WIDTH, 0, width() - LEFT_WIDTH, height()); const QRect bfr(TITLE_LM_BIG, (height() - FONT_SIZE_BIG) / 4, width() - TITLE_LM_BIG, height()); const QRect nfr(TITLE_LM_NORMAL, (height() - FONT_SIZE_NORMAL) / 3, width() - TITLE_LM_NORMAL, height()); // background QPainter painter(this); painter.fillRect(lr, lbc); if (isActived()) { painter.fillRect(rr, rbc); } // title QFont f; if (m_bigFont) f.setWeight(700); f.setPixelSize(m_bigFont ? FONT_SIZE_BIG : FONT_SIZE_NORMAL); QPen p(isActived() ? FONT_COLOR_ACTIVED : FONT_COLOR_NORMAL); painter.setFont(f); painter.setPen(p); painter.drawText(m_bigFont ? bfr : nfr, m_title); // painter.drawText(rect(), Qt::AlignCenter, "Kobe"); } bool TitleButton::isActived() const { return m_isActived; } void TitleButton::setActived(bool isActived) { m_isActived = isActived; this->update(); } int TitleButton::id() const { return m_id; } void TitleButton::setId(const int &id) { m_id = id; } kylin-video/src/kylin/aboutdialog.h0000664000175000017500000000314413214706400016311 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #ifndef _ABOUTDIALOG_H_ #define _ABOUTDIALOG_H_ #include "ui_aboutdialog.h" #include #include class QParallelAnimationGroup; enum ADragState {NOT_ADRAGGING, START_ADRAGGING, ADRAGGING}; enum TabState {TAB_ABOUT, TAB_CONTRIBUTOR}; class AboutDialog : public QDialog, public Ui::AboutDialog { Q_OBJECT public: AboutDialog( QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~AboutDialog(); void initConnect(); void initAnimation(); virtual bool eventFilter(QObject *, QEvent *); void moveDialog(QPoint diff); void setVersions(); public slots: void onAboutBtnClicked(); void onContributorBtnClicked(); private: QPushButton *okBtn; QParallelAnimationGroup *aboutGroup; QParallelAnimationGroup *contributorGroup; ADragState drag_state; TabState tab_state; QPoint start_drag; }; #endif kylin-video/src/kylin/tipwidget.h0000664000175000017500000000345413214706400016023 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #ifndef _TIPWIDGET_H_ #define _TIPWIDGET_H_ #include class QLabel; class TipWidget : public QFrame { Q_OBJECT Q_PROPERTY(int radius READ radius WRITE setRadius) Q_PROPERTY(QBrush background READ background WRITE setBackground) Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor) public: explicit TipWidget(const QString &text, QWidget *parent = 0); ~TipWidget(); void setBackgroundImage(const QPixmap &srcPixmap); int radius() const; QColor borderColor() const; QBrush background() const; void setTransparent(bool transparent); void set_widget_opacity(const float &opacity); public slots: void setText(const QString text); void setBackground(QBrush background); void setRadius(int radius); void setBorderColor(QColor borderColor); void aniFinished(); private: QLabel *text_label; QBrush m_background; int m_radius; int w_shadow; QMargins shadow_margins; QColor m_borderColor; }; #endif kylin-video/src/kylin/helpdialog.h0000664000175000017500000000366613214706400016140 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #ifndef _HELPDIALOG_H_ #define _HELPDIALOG_H_ #include "ui_helpdialog.h" enum HDragState {NOT_HDRAGGING, START_HDRAGGING, HDRAGGING}; class QTextBrowser; class QPushButton; class SupportFormats; //class SupportShortcuts; class TitleButton; class Preferences; class HelpDialog : public QDialog, public Ui::HelpDialog { Q_OBJECT public: enum Section { Formats=0, Other=1 }; HelpDialog(QWidget * parent = 0, Qt::WindowFlags f = 0 ); ~HelpDialog(); void addSection(QWidget *w); // Pass data to the standard dialogs void setData(Preferences * pref); virtual bool eventFilter(QObject *, QEvent *); void moveDialog(QPoint diff); public slots: void showSection(Section s); virtual void accept(); // Reimplemented to send a signal signals: void applied(); protected: virtual void retranslateStrings(); virtual void changeEvent ( QEvent * event ) ; public slots: void onButtonClicked(int id); void setCurrentID(int id); void switchCurrentIDPage(int id); private: QList m_buttonList; protected: SupportFormats *page_formats; // SupportShortcuts *page_shortcuts; private: HDragState drag_state; QPoint start_drag; }; #endif kylin-video/src/kylin/esctip.cpp0000664000175000017500000000715213214706400015644 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #include "esctip.h" #include #include #include #include #include #include #include EscTip::EscTip(QWidget *parent) : QFrame(parent) { setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint); setAttribute(Qt::WA_TranslucentBackground); setContentsMargins(0, 0, 0, 0); setObjectName("EscTip");//设置背景色 m_radius = 4; w_shadow = 20; shadow_margins = QMargins(20, 20, 20, 20); m_borderColor = QColor(0, 0, 0, 0.2 * 255); QVBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); text_label = new QLabel(this); text_label->adjustSize(); text_label->setStyleSheet("QLabel{font-size: 16px;color: #ffffff;}"); text_label->setAlignment(Qt::AlignCenter); text_label->setText(tr("Press ESC to exit full screen mode")); layout->addStretch(); layout->addWidget(text_label); layout->addStretch(); this->setLayout(layout); hide(); } EscTip::~EscTip() { } QBrush EscTip::background() const { return this->m_background; } int EscTip::radius() const { return this->m_radius; } QColor EscTip::borderColor() const { return this->m_borderColor; } void EscTip::setBackground(QBrush background) { this->m_background = background; } void EscTip::setRadius(int radius) { this->m_radius = radius; } void EscTip::setBorderColor(QColor borderColor) { this->m_borderColor = borderColor; } void EscTip::aniFinished() { this->hide(); } void EscTip::paintEvent(QPaintEvent *) { bool outer = true; QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing); int radius = this->m_radius; double w_pen = 1.0; QBrush background = this->m_background; QColor border_color = this->m_borderColor; double margin = 2.0; QMarginsF shadow_margins = QMarginsF(margin, margin, margin, margin); //background QRectF bg_rect = QRectF(rect()).marginsRemoved(shadow_margins); QPainterPath bg_path; bg_path.addRoundedRect(bg_rect, radius, radius); painter.fillPath(bg_path, background); //border QPainterPath border_path; QRectF border_rect = QRectF(rect()); int border_radius = radius; QMarginsF border_margin(w_pen / 2, w_pen / 2, w_pen / 2, w_pen / 2); if (outer) { border_radius += w_pen / 2; border_rect = border_rect.marginsAdded(border_margin).marginsRemoved(shadow_margins); } else { border_radius -= w_pen / 2; border_rect = border_rect.marginsRemoved(border_margin).marginsRemoved(shadow_margins); } border_path.addRoundedRect(border_rect, border_radius, border_radius); QPen border_pen(border_color); border_pen.setWidthF(w_pen); painter.strokePath(border_path, border_pen); } kylin-video/src/kylin/supportformats.ui0000664000175000017500000000410313214706400017311 0ustar fengfeng SupportFormats 0 0 470 360 20 9 431 141 Video formats 10 24 411 100 true 20 160 431 91 Audio formats 10 24 411 50 true 20 259 431 91 Subtitles formats 10 24 411 50 true kylin-video/src/kylin/soundvolume.h0000664000175000017500000000360213214706400016376 0ustar fengfeng/* * Copyright (C) 2013 ~ 2017 National University of Defense Technology(NUDT) & Tianjin Kylin Ltd. * * Authors: * Kobe Lee lixiang@kylinos.cn/kobe24_lixiang@126.com * * 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; version 3. * * 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, see . */ #include #include class QSlider; #include class SoundVolume : public QWidget { Q_OBJECT Q_PROPERTY(int radius READ radius WRITE setRadius) Q_PROPERTY(QBrush background READ background WRITE setBackground) Q_PROPERTY(QColor borderColor READ borderColor WRITE setBorderColor) public: explicit SoundVolume(QWidget *parent = 0); ~SoundVolume(); int volume() const; int radius() const; QColor borderColor() const; QBrush background() const; signals: void volumeChanged(int vol); public slots: void deleyHide(); void onVolumeChanged(int vol); void setBackground(QBrush m_background); void setRadius(int m_radius); void setBorderColor(QColor m_borderColor); void slot_deley(); virtual void setValue(int); protected: virtual void showEvent(QShowEvent *event); virtual void enterEvent(QEvent *event); virtual void leaveEvent(QEvent *event); virtual void wheelEvent(QWheelEvent *event); private: int tradius; QBrush tbackground; QColor tborderColor; QSlider *volSlider; bool mouseIn; }; kylin-video/COPYING0000664000175000017500000004312213214351467012775 0ustar fengfeng GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 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 Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. kylin-video/autogen.sh0000775000175000017500000000012713214347337013742 0ustar fengfeng#!/bin/sh # Run this to generate all the initial makefiles, etc. lrelease src/src.pro kylin-video/README.md0000664000175000017500000000117113214362355013215 0ustar fengfengkylin-video =========== Kylin Video utilizes MPV and MPlayer as background play engine (use MPV by default). Its GUI front end is written by Gt5. Plus, it supports both x86 and ARM platform. As a powerful video player, Kylin Video supports most of the audio and video formats. Functions of shortcut keys/ preview/ screenshot/ sound settings/ subtitles and so on are provided. Users can even customize settings as they like. Installation ============ qmake make sudo make install How to report bugs ================== Bugs should be report to the kylin-video bug tracking system: https://github.com/ukui/kylin-video/issues kylin-video/kylin-video.pro0000664000175000017500000000004713214347337014716 0ustar fengfengTEMPLATE = subdirs SUBDIRS = \ src kylin-video/AUTHORS0000664000175000017500000000004313214370406012777 0ustar fengfengli xiang kylin-video/kylin-video.desktop0000664000175000017500000000144213214347337015567 0ustar fengfeng[Desktop Entry] Name=Kylin Video Name[zh_CN]=麒麟影音 Comment=A great MPlayer front-end Comment[zh_CN]=麒麟影音 GenericName=Kylin Video GenericName[zh_CN]=麒麟影音 Exec=kylin-video %U Icon=kylin-video MimeType=audio/ac3;audio/mp4;audio/mpeg;audio/vnd.rn-realaudio;audio/vorbis;audio/x-adpcm;audio/x-matroska;audio/x-mp2;audio/x-mp3;audio/x-ms-wma;audio/x-vorbis;audio/x-wav;audio/mpegurl;audio/x-mpegurl;audio/x-pn-realaudio;audio/x-scpls;audio/aac;audio/flac;audio/ogg;video/avi;video/mp4;video/flv;video/mpeg;video/quicktime;video/vnd.rn-realvideo;video/x-matroska;video/x-ms-asf;video/x-msvideo;video/x-ms-wmv;video/x-ogm;video/x-theora;video/webm; Type=Application Categories=Qt;KDE;AudioVideo;Player;Video; Keywords=movie;player;media;kde;qt; X-Ayatana-Desktop-Shortcuts=Screen;Window kylin-video/man/0000775000175000017500000000000013233760622012511 5ustar fengfengkylin-video/man/kylin-video.10000664000175000017500000000156713216412555015036 0ustar fengfeng.TH kylin-video 1 "19 June 2017" "The Kylin Video Project" "Kylin Video" .SH NAME kylin-video \- The best GUI frontend for MPlayer .SH SYNOPSIS .B kylin-video .SH DESCRIPTION .TP Kylin Video is a GUI media player based on Qt 5, using \fBmplayer\fR(1) as its backend. .PP .SH SEE ALSO \fBmplayer\fR(1) .SH AUTHOR The author of Kylin Video is lixiang . This manual page was written by lixiang for the Kylin project (but may be used by others). Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 or any later version published by the Free Software Foundation. On Debian systems, the complete text of the GNU General Public License can be found in \fB/usr/share/common-licenses/GPL\fR. .SH BUGS Please submit bugs to \fBhttps://github.com/ukui/kylin-video/issues\fR. kylin-video/ChangeLog0000664000175000017500000000005613214364115013505 0ustar fengfengUse 'git log' for a detailed list of changes. kylin-video/NEWS0000664000175000017500000000504213214363257012440 0ustar fengfeng============== Version 1.1.0 ============== - Add Stereo mode for audio. - Add frame rotation for video. - Show logo normal(LP: #4979). - Display the correct shortcut key of increase volume or decrease volume(LP: #4916). - When the playing video file is removed from the playlist, then stop playing it(LP: #4915). - Solved the mouse drag problem for playlist items(LP: #4907). - Add Shortcut for the button of setting audio delay(LP: #4917). ============== Version 1.0.9 ============== - Support URL. - Optimize the aboutdialog. - Solved the problem that clicking on some buttons causes the interface to move sometimes. ============== Version 1.0.8 ============== - Solve the background problem of pause button. - Optimize the scrollbar for playlist. - if the state is pause in unfullscreen, then show title bar and control bar. - if the state is not pause and playing in fullscreen, then show title bar and control bar. - Show normal window size when the icon on the taskbar is clicked, because of the bug of Qt5. ============== Version 1.0.7 ============== - Set windown stay on top. - Add play order swither. - Add help page. - Add more shortcuts, such as full screen, playlist, about and exit. - Resolve the problem that text color settings is invalid of QComboBox. - Deal with the log records. ============== Version 1.0.6 ============== - Add open screenshots action into systemtray. - Make the seek position work properly when using Mplayer. - Rewrite mainwindow with QStackedLayout. - Show detail info when the file does not exist(LP: #4372). - Resize TipWidget depending on the length of the tip text. - Show screenshot's information when it is saved successfully. - Add shortcut key notes. - Add Preview. ============== Version 1.0.5 ============== - Add slot function for some actions. - Resolved the problem of selecting item is inaccurate when open files in different ways. - Modify progressbar. - Add error tip for the file has been removed from disk which double click play. - Add MessageDialog. - Modify QComboBox qss. - Remove Qt::ToolTip from TipWidget, make it be inside the mainwindow, but it's not transparent at this time. - Add tip when remove file from playlist. - Fixed some bugs. ============== Version 1.0.4 ============== - Support MPV. - Support auto restart when the playback engine changed. ============== Version 1.0.3 ============== - Update sub interfaces. - Update menu qss. ============== Version 1.0.2 ============== - Update the main interface. ============== Version 1.0.0 ============== - A great MPlayer front-end with Qt5.