Merge branch 'devel'
This commit is contained in:
commit
30449a50e2
9 files changed
+322
-56
No files matched your search
+42
-28
@@ -42,6 +42,46 @@ OPTION( USE_QT4 "Build with QT4" OFF )
|
||||
ADD_FEATURE_INFO(Fervor USE_FERVOR "Fervor lib includes check for updates feature.")
|
||||
ADD_FEATURE_INFO(WErrors PLAYUVER_WERROR "Warnings as errors" )
|
||||
|
||||
#####################################################################################
|
||||
# Qt library
|
||||
######################################################################################
|
||||
|
||||
IF( USE_QT4 )
|
||||
SET( DEPENDENCIES_STRING "${DEPENDENCIES_STRING}QT4" )
|
||||
FIND_PACKAGE( Qt4 REQUIRED COMPONENTS QtCore QtGui QtNetwork QtWebKit )
|
||||
|
||||
SET( USE_QTDBUS FALSE )
|
||||
|
||||
IF( NOT QT4_FOUND )
|
||||
SET(USE_QT4 FALSE)
|
||||
ELSE()
|
||||
INCLUDE( ${QT_USE_FILE} )
|
||||
ADD_DEFINITIONS( ${QT_DEFINITIONS} )
|
||||
SET( QT_LINKER_LIBS ${QT_LIBRARIES} )
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF( NOT USE_QT4 )
|
||||
|
||||
SET( DEPENDENCIES_STRING "${DEPENDENCIES_STRING}QT5" )
|
||||
|
||||
FIND_PACKAGE( Qt5 REQUIRED COMPONENTS Core Gui Widgets )
|
||||
FIND_PACKAGE( Qt5 COMPONENTS DBus )
|
||||
|
||||
|
||||
LIST(APPEND QT_LINKER_LIBS Qt5::Core Qt5::Gui Qt5::Widgets )
|
||||
LIST(APPEND QT_MODULES Core Gui Widgets )
|
||||
IF( ${Qt5DBus_FOUND} )
|
||||
SET( USE_QTDBUS ${Qt5DBus_FOUND} )
|
||||
LIST(APPEND QT_LINKER_LIBS Qt5::DBus )
|
||||
LIST(APPEND QT_MODULES DBus )
|
||||
ENDIF()
|
||||
|
||||
INCLUDE_DIRECTORIES( ${Qt5Core_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} ${Qt5DBus_INCLUDE_DIRS})
|
||||
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}" )
|
||||
|
||||
ENDIF()
|
||||
|
||||
######################################################################################
|
||||
# Dependencies
|
||||
######################################################################################
|
||||
@@ -64,32 +104,6 @@ IF( WIN32 )
|
||||
INCLUDE( cmake/Win32.cmake )
|
||||
ENDIF()
|
||||
|
||||
#####################################################################################
|
||||
# Qt library
|
||||
######################################################################################
|
||||
|
||||
IF( USE_QT4 )
|
||||
SET( DEPENDENCIES_STRING "${DEPENDENCIES_STRING}QT4" )
|
||||
FIND_PACKAGE( Qt4 REQUIRED QtCore QtGui QtNetwork QtWebKit )
|
||||
IF( NOT QT4_FOUND )
|
||||
SET(USE_QT4 FALSE)
|
||||
ELSE()
|
||||
INCLUDE( ${QT_USE_FILE} )
|
||||
ADD_DEFINITIONS( ${QT_DEFINITIONS} )
|
||||
SET( QT_LINKER_LIBS ${QT_LIBRARIES} )
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF( NOT USE_QT4 )
|
||||
SET( DEPENDENCIES_STRING "${DEPENDENCIES_STRING}QT5" )
|
||||
FIND_PACKAGE( Qt5 REQUIRED Core Gui Widgets )
|
||||
INCLUDE_DIRECTORIES( ${Qt5Core_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} )
|
||||
# Add compiler flags for building executables (-fPIE)
|
||||
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}" )
|
||||
LIST(APPEND QT_LINKER_LIBS Qt5::Core Qt5::Gui Qt5::Widgets )
|
||||
LIST(APPEND QT_MODULES Core Gui Widgets )
|
||||
ENDIF()
|
||||
|
||||
######################################################################################
|
||||
# Configuration
|
||||
######################################################################################
|
||||
@@ -132,11 +146,11 @@ SET(CPACK_PACKAGE_ARCHITECTURE "amd64")
|
||||
|
||||
IF( USE_QT4 )
|
||||
SET( DEPENDENCIES_STRING "${DEPENDENCIES_STRING}QT4" )
|
||||
LIST(APPEND CPACK_DEBIAN_PACKAGE_DEPENDS "libqtcore4 (>= 4:4.8.5), libqtgui4 (>= 4:4.8.5)" )
|
||||
LIST(APPEND CPACK_DEBIAN_PACKAGE_DEPENDS "libqtcore4 (>= 4:4.8.5), libqtgui4 (>= 4:4.8.5), libqt4-dbus (>= 4:4.8.5)" )
|
||||
SET( APPEND_VERSION "${APPEND_VERSION}_wQT4" )
|
||||
ELSE()
|
||||
SET( DEPENDENCIES_STRING "${DEPENDENCIES_STRING}QT5" )
|
||||
LIST(APPEND CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5core5a (>= 5.2.1~), libqt5gui5 (>= 5.2.1~), libqt5widgets5 (>= 5.2.1~)")
|
||||
LIST(APPEND CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5core5a (>= 5.2.1~), libqt5gui5 (>= 5.2.1~), libqt5widgets5 (>= 5.2.1~), libqt5dbus5 (>= 5.2.1~)")
|
||||
SET( APPEND_VERSION "${APPEND_VERSION}_wQT5" )
|
||||
ENDIF()
|
||||
|
||||
|
||||
@@ -30,6 +30,10 @@ set(plaYUver_App_SRCS
|
||||
WidgetFrameNumber.cpp
|
||||
)
|
||||
|
||||
IF( USE_QTDBUS )
|
||||
LIST( APPEND plaYUver_App_SRCS PlaYUVerAppAdaptor.cpp )
|
||||
ENDIF()
|
||||
|
||||
set(plaYUver_App_UI "" )
|
||||
|
||||
set(plaYUver_App_RCC
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/* This file is a part of plaYUVer project
|
||||
* Copyright (C) 2014 by Luis Lucas (luisfrlucas@gmail.com)
|
||||
* Joao Carreira (jfmcarreira@gmail.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; 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file PlaYUVerAppAdaptor.h
|
||||
* \brief Define function to manage the interface in DBus
|
||||
*/
|
||||
|
||||
#include <QDBusAbstractAdaptor>
|
||||
#include "PlaYUVerAppAdaptor.h"
|
||||
#include "plaYUVerApp.h"
|
||||
|
||||
namespace plaYUVer
|
||||
{
|
||||
|
||||
PlaYUVerAppAdaptor::PlaYUVerAppAdaptor( plaYUVerApp *app ) :
|
||||
QDBusAbstractAdaptor( app ),
|
||||
m_app( app )
|
||||
{
|
||||
// application dbus interface
|
||||
QDBusConnection::sessionBus().registerObject( QStringLiteral( PLAYUVER_DBUS_PATH ), this, QDBusConnection::ExportAllSlots );
|
||||
}
|
||||
|
||||
PlaYUVerAppAdaptor::~PlaYUVerAppAdaptor()
|
||||
{
|
||||
QDBusConnection::sessionBus().unregisterObject( QStringLiteral( PLAYUVER_DBUS_PATH ) );
|
||||
}
|
||||
|
||||
void PlaYUVerAppAdaptor::activate()
|
||||
{
|
||||
if( !m_app )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_app->show();
|
||||
//m_app->activateWindow();
|
||||
//m_app->raise();
|
||||
|
||||
}
|
||||
|
||||
QString PlaYUVerAppAdaptor::activeSession()
|
||||
{
|
||||
//return m_app->sessionManager()->activeSession()->name();
|
||||
return QString( "PlaYUVer" );
|
||||
}
|
||||
|
||||
bool PlaYUVerAppAdaptor::loadFile( QString filename )
|
||||
{
|
||||
m_app->loadFile( filename );
|
||||
return true;
|
||||
}
|
||||
|
||||
} // NAMESPACE
|
||||
@@ -0,0 +1,87 @@
|
||||
/* This file is a part of plaYUVer project
|
||||
* Copyright (C) 2014 by Luis Lucas (luisfrlucas@gmail.com)
|
||||
* Joao Carreira (jfmcarreira@gmail.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; 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file PlaYUVerAppAdaptor.h
|
||||
* \brief Define function to manage the interface in DBus
|
||||
*/
|
||||
|
||||
#ifndef __PlaYUVerAppAdaptor_H__
|
||||
#define __PlaYUVerAppAdaptor_H__
|
||||
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusMessage>
|
||||
#include <QDBusReply>
|
||||
#include <QtDBus>
|
||||
#include <QtCore>
|
||||
|
||||
namespace plaYUVer
|
||||
{
|
||||
|
||||
#define PLAYUVER_DBUS_SESSION_NAME "org.pixlra.PlaYUVer.application"
|
||||
#define PLAYUVER_DBUS_PATH "/MainApplication"
|
||||
|
||||
class plaYUVerApp;
|
||||
|
||||
class PlaYUVerAppAdaptor: public QDBusAbstractAdaptor
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", PLAYUVER_DBUS_SESSION_NAME)
|
||||
Q_PROPERTY(QString activeSession READ activeSession)
|
||||
public:
|
||||
PlaYUVerAppAdaptor( plaYUVerApp *app );
|
||||
~PlaYUVerAppAdaptor();
|
||||
/**
|
||||
* emit the exiting signal
|
||||
*/
|
||||
//void emitExiting();
|
||||
//void emitDocumentClosed(const QString &token);
|
||||
public Q_SLOTS:
|
||||
/**
|
||||
* open a file with given url and encoding
|
||||
* will get view created
|
||||
* @param url url of the file
|
||||
* @param encoding encoding name
|
||||
* @return success
|
||||
*/
|
||||
bool loadFile( QString filename );
|
||||
|
||||
/**
|
||||
* activate this kate instance
|
||||
*/
|
||||
void activate();
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* Notify the world that this kate instance is exiting.
|
||||
* All apps should stop using the dbus interface of this instance after this signal got emitted.
|
||||
*/
|
||||
//void exiting();
|
||||
//void documentClosed(const QString &token);
|
||||
public:
|
||||
QString activeSession();
|
||||
private:
|
||||
plaYUVerApp *m_app;
|
||||
};
|
||||
|
||||
} // NAMESPACE
|
||||
|
||||
#endif // __PlaYUVerAppAdaptor_H__
|
||||
|
||||
+98
-13
@@ -22,10 +22,14 @@
|
||||
* \brief main file
|
||||
*/
|
||||
|
||||
#include <QApplication>
|
||||
#include "config.h"
|
||||
#include "lib/PlaYUVerDefs.h"
|
||||
#include <QApplication>
|
||||
#include "plaYUVerApp.h"
|
||||
#include "SubWindowHandle.h"
|
||||
#ifdef USE_QTDBUS
|
||||
#include "PlaYUVerAppAdaptor.h"
|
||||
#endif
|
||||
#ifdef USE_FERVOR
|
||||
#include "fvupdater.h"
|
||||
#endif
|
||||
@@ -38,21 +42,102 @@ using namespace plaYUVer;
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
QApplication a( argc, argv );
|
||||
QApplication::setApplicationName("PlaYUVer");
|
||||
QApplication::setApplicationVersion(PLAYUVER_VERSION_STRING);
|
||||
QApplication::setOrganizationName("pixlra");
|
||||
QApplication::setOrganizationDomain("playuver.pixlra");
|
||||
qRegisterMetaType<PlaYUVerStreamInfoVector>( "PlaYUVerStreamInfoVector" );
|
||||
qRegisterMetaTypeStreamOperators<PlaYUVerStreamInfoVector>( "PlaYUVerStreamInfoVector" );
|
||||
|
||||
qRegisterMetaType<PlaYUVerStreamInfoVector>("PlaYUVerStreamInfoVector");
|
||||
qRegisterMetaTypeStreamOperators<PlaYUVerStreamInfoVector>("PlaYUVerStreamInfoVector");
|
||||
QApplication application( argc, argv );
|
||||
QApplication::setApplicationName( "PlaYUVer" );
|
||||
QApplication::setApplicationVersion( PLAYUVER_VERSION_STRING );
|
||||
QApplication::setOrganizationName( "pixlra" );
|
||||
QApplication::setOrganizationDomain( "playuver.pixlra" );
|
||||
|
||||
plaYUVerApp w;
|
||||
w.show();
|
||||
w.parseArgs( argc, argv );
|
||||
#ifdef USE_QTDBUS
|
||||
/**
|
||||
* use dbus, if available
|
||||
* allows for resuse of running Kate instances
|
||||
*/
|
||||
QDBusConnectionInterface * const sessionBusInterface = QDBusConnection::sessionBus().interface();
|
||||
if( sessionBusInterface )
|
||||
{
|
||||
|
||||
Bool force_new = false;
|
||||
QStringList filenameList;
|
||||
for( Int i = 1; i < argc; i++ )
|
||||
{
|
||||
filenameList.append( QString( argv[i] ) );
|
||||
}
|
||||
if( filenameList.isEmpty() )
|
||||
{
|
||||
force_new = true;
|
||||
}
|
||||
|
||||
//check again if service is still running
|
||||
bool foundRunningService = false;
|
||||
if( !force_new )
|
||||
{
|
||||
QDBusReply<bool> there = sessionBusInterface->isServiceRegistered( PLAYUVER_DBUS_SESSION_NAME );
|
||||
foundRunningService = there.isValid() && there.value();
|
||||
}
|
||||
|
||||
if( foundRunningService )
|
||||
{
|
||||
// open given session
|
||||
QDBusMessage m = QDBusMessage::createMethodCall( PLAYUVER_DBUS_SESSION_NAME, QStringLiteral( PLAYUVER_DBUS_PATH ),
|
||||
QStringLiteral( PLAYUVER_DBUS_SESSION_NAME ), QStringLiteral( "activate" ) );
|
||||
|
||||
QDBusConnection::sessionBus().call( m );
|
||||
|
||||
// only block, if files to open there....
|
||||
bool needToBlock = false;
|
||||
|
||||
QStringList tokens;
|
||||
|
||||
// open given files...
|
||||
foreach(const QString & file, filenameList)
|
||||
{
|
||||
QDBusMessage m = QDBusMessage::createMethodCall(PLAYUVER_DBUS_SESSION_NAME,
|
||||
QStringLiteral(PLAYUVER_DBUS_PATH), QStringLiteral(PLAYUVER_DBUS_SESSION_NAME), QStringLiteral("loadFile"));
|
||||
|
||||
QList<QVariant> dbusargs;
|
||||
dbusargs.append( file );
|
||||
m.setArguments(dbusargs);
|
||||
|
||||
QDBusMessage res = QDBusConnection::sessionBus().call(m);
|
||||
if (res.type() == QDBusMessage::ReplyMessage)
|
||||
{
|
||||
if (res.arguments().count() == 1)
|
||||
{
|
||||
QVariant v = res.arguments()[0];
|
||||
if (v.isValid())
|
||||
{
|
||||
QString s = v.toString();
|
||||
if ((!s.isEmpty()) && (s != QStringLiteral("ERROR")))
|
||||
{
|
||||
tokens << s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// this will wait until exiting is emitted by the used instance, if wanted...
|
||||
return needToBlock ? application.exec() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* if we arrive here, we need to start a new playuver instance!
|
||||
*/
|
||||
QDBusConnection::sessionBus().registerService( PLAYUVER_DBUS_SESSION_NAME );
|
||||
#endif
|
||||
plaYUVerApp mainwindow;
|
||||
mainwindow.show();
|
||||
mainwindow.parseArgs( argc, argv );
|
||||
#ifdef USE_FERVOR
|
||||
FvUpdater::sharedUpdater()->SetFeedURL("http://192.168.96.201/share/jcarreira.it.pub/plaYUVer/PlaYUVerUpdate.xml");
|
||||
FvUpdater::sharedUpdater()->SetFeedURL("http://192.168.96.201/share/pixLRA/plaYUVer/PlaYUVerUpdate.xml");
|
||||
FvUpdater::sharedUpdater()->SetDependencies(DEPENDENCIES_STRING);
|
||||
#endif
|
||||
return a.exec();
|
||||
|
||||
|
||||
|
||||
return application.exec();
|
||||
}
|
||||
+9
-12
@@ -22,19 +22,13 @@
|
||||
* \brief Main definition of the plaYUVerApp app
|
||||
*/
|
||||
|
||||
#include "plaYUVerApp.h"
|
||||
#include "lib/PlaYUVerStream.h"
|
||||
#include "DialogSubWindowSelector.h"
|
||||
|
||||
#include <QtDebug>
|
||||
#ifdef USE_FERVOR
|
||||
#include "fvupdater.h"
|
||||
#endif
|
||||
|
||||
#if( QT_VERSION_PLAYUVER == 5 )
|
||||
#include <QtWidgets>
|
||||
#elif( QT_VERSION_PLAYUVER == 4 )
|
||||
#include <QtGui>
|
||||
#endif
|
||||
#include <QtDebug>
|
||||
#include "plaYUVerApp.h"
|
||||
#include "DialogSubWindowSelector.h"
|
||||
#include "WidgetFrameNumber.h"
|
||||
#include "Settings.h"
|
||||
|
||||
@@ -48,10 +42,13 @@ plaYUVerApp::plaYUVerApp()
|
||||
|
||||
setWindowModality( Qt::ApplicationModal );
|
||||
|
||||
// DBus
|
||||
#ifdef USE_QTDBUS
|
||||
m_pDBusAdaptor = new PlaYUVerAppAdaptor(this);
|
||||
#endif
|
||||
|
||||
mdiArea = new PlaYUVerMdiArea;
|
||||
setCentralWidget( mdiArea );
|
||||
//mdiArea->setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded );
|
||||
//mdiArea->setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded );
|
||||
mdiArea->setActivationOrder( QMdiArea::ActivationHistoryOrder );
|
||||
|
||||
connect( mdiArea, SIGNAL( subWindowActivated(QMdiSubWindow*) ), this, SLOT( chageSubWindowSelection() ) );
|
||||
|
||||
+7
-3
@@ -26,13 +26,16 @@
|
||||
#define __PLAYUVERAPP_H__
|
||||
|
||||
#include "config.h"
|
||||
#include "lib/PlaYUVerDefs.h"
|
||||
#if( QT_VERSION_PLAYUVER == 5 )
|
||||
#include <QtWidgets>
|
||||
#elif( QT_VERSION_PLAYUVER == 4 )
|
||||
#include <QtGui>
|
||||
#endif
|
||||
#ifdef USE_QTDBUS
|
||||
#include "PlaYUVerAppAdaptor.h"
|
||||
#endif
|
||||
#include <QMainWindow>
|
||||
#include "lib/PlaYUVerDefs.h"
|
||||
#include "SubWindowHandle.h"
|
||||
#include "ModulesHandle.h"
|
||||
#include "PropertiesSidebar.h"
|
||||
@@ -44,6 +47,7 @@ namespace plaYUVer
|
||||
{
|
||||
|
||||
class PlaYUVerStream;
|
||||
class PlaYUVerAppAdaptor;
|
||||
|
||||
class plaYUVerApp: public QMainWindow
|
||||
{
|
||||
@@ -52,6 +56,7 @@ Q_OBJECT
|
||||
public:
|
||||
plaYUVerApp();
|
||||
Void parseArgs( Int argc, Char *argv[] );
|
||||
Void loadFile( QString fileName, PlaYUVerStreamInfo* pStreamInfo = NULL );
|
||||
|
||||
protected:
|
||||
Void closeEvent( QCloseEvent *event );
|
||||
@@ -143,6 +148,7 @@ private:
|
||||
QPixmap m_pixmapLogo;
|
||||
};
|
||||
|
||||
PlaYUVerAppAdaptor* m_pDBusAdaptor;
|
||||
PlaYUVerMdiArea *mdiArea;
|
||||
SubWindowHandle *m_pcCurrentSubWindow;
|
||||
ModulesHandle *m_pcModulesHandle;
|
||||
@@ -153,8 +159,6 @@ private:
|
||||
QTime m_cTimer;
|
||||
UInt m_uiAveragePlayInterval;
|
||||
|
||||
Void loadFile( QString fileName, PlaYUVerStreamInfo* pStreamInfo = NULL );
|
||||
|
||||
Void readRecentFileList();
|
||||
Void writeRecentFileList();
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
# DLLs and Win32 specific code
|
||||
######################################################################################
|
||||
|
||||
SET( USE_QTDBUS FALSE )
|
||||
|
||||
foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} )
|
||||
string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG )
|
||||
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} "." )
|
||||
|
||||
@@ -45,6 +45,9 @@
|
||||
#define QT_VERSION_PLAYUVER 4
|
||||
#endif
|
||||
|
||||
/* QtDBus */
|
||||
#cmakedefine USE_QTDBUS
|
||||
|
||||
#cmakedefine PLAYUVER_THREADED_MODULES
|
||||
|
||||
/* OpenCV */
|
||||
|
||||
Reference in new issue
Block a user