[DEV] Continue integration for a better player video
This commit is contained in:
parent
fe927ac297
commit
27e0a4e603
@ -26,10 +26,40 @@
|
||||
#include <etk/stdTools.hpp>
|
||||
#include <ejson/ejson.hpp>
|
||||
|
||||
appl::ClientProperty::ClientProperty() {
|
||||
address = "127.0.0.1";
|
||||
port = 1983;
|
||||
}
|
||||
|
||||
ejson::Object appl::ClientProperty::toJson() {
|
||||
ejson::Object out;
|
||||
out.add("user", ejson::String(fromUser));
|
||||
out.add("pass", ejson::String(pass));
|
||||
out.add("address", ejson::String(address));
|
||||
out.add("port", ejson::Number(port));
|
||||
return out;
|
||||
}
|
||||
|
||||
void appl::ClientProperty::fromJson(ejson::Object _obj) {
|
||||
fromUser = _obj["user"].toString().get();
|
||||
toUser = fromUser;
|
||||
pass = _obj["pass"].toString().get();
|
||||
address = _obj["address"].toString().get();
|
||||
port = _obj["port"].toNumber().getU64();
|
||||
}
|
||||
|
||||
void appl::ClientProperty::connect() {
|
||||
// Generate IP and Port in the client interface
|
||||
connection.propertyIp.set(address);
|
||||
connection.propertyPort.set(port);
|
||||
if (address == "") {
|
||||
connection.propertyIp.set("127.0.0.1");
|
||||
} else {
|
||||
connection.propertyIp.set(address);
|
||||
}
|
||||
if (port == 0) {
|
||||
connection.propertyPort.set(1983);
|
||||
} else {
|
||||
connection.propertyPort.set(port);
|
||||
}
|
||||
// Connection depending on the mode requested
|
||||
if (fromUser == toUser) {
|
||||
bool ret = connection.connect(fromUser, pass);
|
||||
@ -45,7 +75,7 @@ void appl::ClientProperty::connect() {
|
||||
APPL_ERROR(" ==> NOT Connected to '" << toUser << "' with '" << fromUser << "'");
|
||||
return;
|
||||
} else {
|
||||
APPL_INFO(" ==> Connected with '" << toUser << "'");
|
||||
APPL_INFO(" ==> Connected with '" << toUser << "' with '" << fromUser << "'");
|
||||
}
|
||||
} else {
|
||||
bool ret = connection.connect(toUser);
|
||||
@ -58,6 +88,59 @@ void appl::ClientProperty::connect() {
|
||||
}
|
||||
}
|
||||
|
||||
void appl::ClientProperty::setLogin(std::string _login) {
|
||||
fromUser = "";
|
||||
toUser = "";
|
||||
// separate loggin and IP adress ...
|
||||
std::string login;
|
||||
std::vector<std::string> listElem = etk::split(_login, '~');
|
||||
if (listElem.size() == 0) {
|
||||
APPL_ERROR("Not enouth element in the login ...");
|
||||
return;
|
||||
}
|
||||
fromUser = listElem[0];
|
||||
toUser = listElem[0];
|
||||
if (listElem.size() == 1) {
|
||||
// connnect on local host ... nothing to do
|
||||
} else {
|
||||
std::vector<std::string> listElem2 = etk::split(listElem[1], ':');
|
||||
if (listElem2.size() >= 1) {
|
||||
address = listElem2[0];
|
||||
}
|
||||
if (listElem2.size() >= 2) {
|
||||
port = etk::string_to_uint32_t(listElem2[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string appl::ClientProperty::getLogin() {
|
||||
std::string out = fromUser;
|
||||
bool hasTild = false;
|
||||
if (address != "") {
|
||||
if (hasTild == false) {
|
||||
out += "~" ;
|
||||
hasTild = true;
|
||||
}
|
||||
out += address;
|
||||
}
|
||||
if ( port != 1983
|
||||
&& port != 0) {
|
||||
if (hasTild == false) {
|
||||
out += "~" ;
|
||||
hasTild = true;
|
||||
}
|
||||
out += ":" + etk::to_string(port);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void appl::ClientProperty::setPassword(std::string _password) {
|
||||
pass = _password;
|
||||
}
|
||||
|
||||
std::string appl::ClientProperty::getPassword() {
|
||||
return pass;
|
||||
}
|
||||
|
||||
#include <esignal/details/Signal.hxx>
|
||||
ESIGNAL_DECLARE_SIGNAL(ememory::SharedPtr<appl::ClientProperty>);
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <esignal/Signal.hpp>
|
||||
|
||||
#include <zeus/Client.hpp>
|
||||
#include <ejson/ejson.hpp>
|
||||
|
||||
namespace appl {
|
||||
class ClientProperty {
|
||||
@ -24,8 +25,15 @@ namespace appl {
|
||||
std::string address;
|
||||
uint16_t port;
|
||||
zeus::Client connection;
|
||||
ClientProperty();
|
||||
void connect();
|
||||
void disconnect();
|
||||
ejson::Object toJson();
|
||||
void fromJson(ejson::Object _obj);
|
||||
void setLogin(std::string _login);
|
||||
std::string getLogin();
|
||||
void setPassword(std::string _password);
|
||||
std::string getPassword();
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,34 @@
|
||||
#include <ewol/object/Manager.hpp>
|
||||
#include <etk/tool.hpp>
|
||||
#include <egami/egami.hpp>
|
||||
#include <utility>
|
||||
|
||||
#define BUFFER_SIZE_GET_SLOT (1024*512)
|
||||
|
||||
|
||||
|
||||
static int g_readFunc(void* _opaque, uint8_t* _buf, int _bufSize) {
|
||||
if (_opaque == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return static_cast<appl::MediaDecoder*>(_opaque)->readFunc(_buf, _bufSize);
|
||||
}
|
||||
|
||||
static int g_writeFunc(void* _opaque, uint8_t* _buf, int _bufSize) {
|
||||
if (_opaque == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return static_cast<appl::MediaDecoder*>(_opaque)->writeFunc(_buf, _bufSize);
|
||||
}
|
||||
|
||||
static int64_t g_seekFunc(void* _opaque, int64_t _offset, int _whence) {
|
||||
if (_opaque == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
return static_cast<appl::MediaDecoder*>(_opaque)->seekFunc(_offset, _whence);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void init_ffmpeg() {
|
||||
static bool isInit = false;
|
||||
@ -132,6 +160,7 @@ void appl::MessageElementAudio::configure(audio::format _format, uint32_t _sampl
|
||||
|
||||
appl::MediaDecoder::MediaDecoder() {
|
||||
init_ffmpeg();
|
||||
m_IOContext = nullptr;
|
||||
m_formatContext = nullptr;
|
||||
m_videoDecoderContext = nullptr;
|
||||
m_audioDecoderContext = nullptr;
|
||||
@ -315,7 +344,7 @@ double appl::MediaDecoder::getFps(AVCodecContext *_avctx) {
|
||||
|
||||
void appl::MediaDecoder::init(ememory::SharedPtr<ClientProperty> _property, uint32_t _mediaId) {
|
||||
// TODO : Correct this later ... We first download the media and after we play it
|
||||
// TODO : We need to down load only a small part ...
|
||||
// TODO : We need to download only a small part ...
|
||||
// get the requested node:
|
||||
if (_property == nullptr) {
|
||||
APPL_ERROR("Request play of not handle property ==> nullptr");
|
||||
@ -328,37 +357,187 @@ void appl::MediaDecoder::init(ememory::SharedPtr<ClientProperty> _property, uint
|
||||
zeus::service::ProxyVideo remoteServiceVideo = _property->connection.getService("video");
|
||||
// remove all media (for test)
|
||||
if (remoteServiceVideo.exist() == false) {
|
||||
APPL_ERROR("Vide servie is ==> 'not alive'");
|
||||
APPL_ERROR("Video service is ==> 'not alive'");
|
||||
return;
|
||||
}
|
||||
// TODO : Do it better ...
|
||||
zeus::ProxyFile dataFile = remoteServiceVideo.mediaGet(_mediaId).wait().get();
|
||||
m_remoteFileHandle = remoteServiceVideo.mediaGet(_mediaId).wait().get();
|
||||
|
||||
std::string mimeType = m_remoteFileHandle.getMineType().wait().get();
|
||||
uint64_t fileSize = m_remoteFileHandle.getSize().wait().get();
|
||||
// pre-allcocate data file size:
|
||||
m_remoteBuffer.resize(fileSize, 0);
|
||||
// start with loading of 1 Mo
|
||||
auto futData = m_remoteFileHandle.getPart(0, BUFFER_SIZE_GET_SLOT);
|
||||
futData.wait();
|
||||
if (futData.hasError() == true) {
|
||||
APPL_ERROR("Error when loading data (First 1 MB)");
|
||||
}
|
||||
zeus::Raw buffer = futData.get();
|
||||
memcpy(&m_remoteBuffer[0], buffer.data(), buffer.size());
|
||||
m_remoteBufferFillSection.push_back(std::pair<uint32_t,uint32_t>(0,buffer.size()));
|
||||
m_remoteBufferReadPosition = 0;
|
||||
m_remoteProperty = _property;
|
||||
m_remoteMediaId = _mediaId;
|
||||
|
||||
std::string mimeType = dataFile.getMineType().wait().get();
|
||||
// create temporary file:
|
||||
/*
|
||||
etk::FSNode tmpFile("CACHE:videoPlayer." + zeus::getExtention(mimeType));
|
||||
APPL_WARNING("Store in tmpFile : " << tmpFile << " ==> " << tmpFile.getName());
|
||||
std::string sha512String = zeus::storeInFile(dataFile, tmpFile.getName());
|
||||
APPL_WARNING("Store in tmpFile : " << tmpFile << " ==> " << tmpFile.getFileSystemName() << " DONE");
|
||||
|
||||
init(tmpFile.getFileSystemName());
|
||||
*/
|
||||
init("");
|
||||
// TODO : init(tmpFile);
|
||||
}
|
||||
|
||||
int appl::MediaDecoder::readFunc(uint8_t* _buf, int _bufSize) {
|
||||
APPL_ERROR("call read ... " << m_remoteBufferReadPosition << " size=" << _bufSize);
|
||||
// check if enought data:
|
||||
bool find = false;
|
||||
for (auto &it : m_remoteBufferFillSection) {
|
||||
if ( m_remoteBufferReadPosition >= it.first
|
||||
&& m_remoteBufferReadPosition < it.second) {
|
||||
find = true;
|
||||
// part already download...
|
||||
if (it.second - m_remoteBufferReadPosition < _bufSize) {
|
||||
// missing data ==> reduce copy size
|
||||
_bufSize = it.second - m_remoteBufferReadPosition;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (find == false) {
|
||||
// No data in the buffer
|
||||
return 0;
|
||||
}
|
||||
memcpy(_buf, &m_remoteBuffer[m_remoteBufferReadPosition], _bufSize);
|
||||
m_remoteBufferReadPosition += _bufSize;
|
||||
return _bufSize;
|
||||
}
|
||||
|
||||
int appl::MediaDecoder::writeFunc(uint8_t* _buf, int _bufSize) {
|
||||
APPL_ERROR("call write ...");
|
||||
return _bufSize;
|
||||
}
|
||||
|
||||
int64_t appl::MediaDecoder::seekFunc(int64_t _offset, int _whence) {
|
||||
int64_t lastPosition = m_remoteBufferReadPosition;
|
||||
switch (_whence) {
|
||||
case AVSEEK_SIZE:
|
||||
APPL_ERROR("call seek 'SIZE' ... " << m_remoteBuffer.size());
|
||||
return m_remoteBuffer.size();
|
||||
case AVSEEK_FORCE:
|
||||
APPL_ERROR("call seek 'FORCE' ... pos=" << _offset << " size=" << m_remoteBuffer.size());
|
||||
m_remoteBufferReadPosition = _offset;
|
||||
break;
|
||||
case SEEK_SET:
|
||||
APPL_ERROR("call seek 'SET' ... pos=" << _offset << " size=" << m_remoteBuffer.size());
|
||||
m_remoteBufferReadPosition = _offset;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
APPL_ERROR("call seek 'CUR' ... _offset=" << _offset << " size=" << m_remoteBuffer.size());
|
||||
m_remoteBufferReadPosition += _offset;
|
||||
break;
|
||||
case SEEK_END:
|
||||
APPL_ERROR("call seek 'END' ... _end=" << _offset << " size=" << m_remoteBuffer.size());
|
||||
m_remoteBufferReadPosition = m_remoteBuffer.size()-_offset;
|
||||
break;
|
||||
default:
|
||||
APPL_ERROR("Unknow the _whence=" << _whence);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
if (m_remoteBufferReadPosition < 0 ) {
|
||||
APPL_WARNING("Request seek before start of the File");
|
||||
m_remoteBufferReadPosition = 0;
|
||||
}
|
||||
if (m_remoteBufferReadPosition > m_remoteBuffer.size()) {
|
||||
APPL_WARNING("Request seek after end of the File");
|
||||
m_remoteBufferReadPosition = m_remoteBuffer.size()-1;
|
||||
}
|
||||
if (lastPosition != m_remoteBufferReadPosition) {
|
||||
checkIfWeNeedMoreDataFromNetwork();
|
||||
}
|
||||
return m_remoteBufferReadPosition;
|
||||
}
|
||||
|
||||
void appl::MediaDecoder::checkIfWeNeedMoreDataFromNetwork() {
|
||||
// check if enought data:
|
||||
bool find = false;
|
||||
auto it = m_remoteBufferFillSection.begin();
|
||||
if (it == m_remoteBufferFillSection.end()) {
|
||||
// no data in the buffer...
|
||||
//Get some
|
||||
// start with loading of 1 Mo
|
||||
auto futData = m_remoteFileHandle.getPart(0, BUFFER_SIZE_GET_SLOT);
|
||||
futData.andThen([=](zeus::Future<zeus::Raw> _fut) mutable {
|
||||
return true;
|
||||
});
|
||||
/*
|
||||
futData.wait();
|
||||
if (futData.hasError() == true) {
|
||||
APPL_ERROR("Error when loading data (First 1 MB)");
|
||||
}
|
||||
zeus::Raw buffer = futData.get();
|
||||
memcpy(&m_remoteBuffer[0], buffer.data(), buffer.size());
|
||||
m_remoteBufferFillSection.push_back(std::pair<uint32_t,uint32_t>(0,buffer.size()));
|
||||
return;
|
||||
*/
|
||||
}
|
||||
/*
|
||||
for (auto &it : m_remoteBufferFillSection) {
|
||||
if ( m_remoteBufferReadPosition >= it.first
|
||||
&& m_remoteBufferReadPosition < it.second) {
|
||||
find = true;
|
||||
// part already download...
|
||||
if (it.second - m_remoteBufferReadPosition < _bufSize) {
|
||||
// missing data ==> reduce copy size
|
||||
_bufSize = it.second - m_remoteBufferReadPosition;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (find == false) {
|
||||
// No data in the buffer
|
||||
return;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void appl::MediaDecoder::init(const std::string& _filename) {
|
||||
m_updateVideoTimeStampAfterSeek = false;
|
||||
m_sourceFilename = _filename;
|
||||
ethread::setName("ffmpegThread");
|
||||
// open input file, and allocate format context
|
||||
if (avformat_open_input(&m_formatContext, m_sourceFilename.c_str(), nullptr, nullptr) < 0) {
|
||||
APPL_ERROR("Could not open source file " << m_sourceFilename);
|
||||
exit(1);
|
||||
}
|
||||
#ifdef APPL_USE_GENERIC_FFMPEG
|
||||
if (avformat_open_input(&m_formatContext, m_sourceFilename.c_str(), nullptr, nullptr) < 0) {
|
||||
APPL_ERROR("Could not open source file " << m_sourceFilename);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
|
||||
if (!(m_formatContext = avformat_alloc_context())) {
|
||||
APPL_ERROR("Could not create Format context");
|
||||
return;
|
||||
}
|
||||
m_bufferFFMPEG.resize(1024*1024); // 1Mo buffer is good enought
|
||||
m_IOContext = avio_alloc_context(&m_bufferFFMPEG[0], m_bufferFFMPEG.size(), 0 /* can not write */, this, g_readFunc, g_writeFunc, g_seekFunc);
|
||||
if (m_IOContext == nullptr) {
|
||||
APPL_ERROR("Could not create IO stream");
|
||||
return;
|
||||
}
|
||||
// set IO read and write interface
|
||||
m_formatContext->pb = m_IOContext;
|
||||
if (avformat_open_input(&m_formatContext, nullptr, nullptr, nullptr) < 0) {
|
||||
APPL_ERROR("Could not open source file " << m_sourceFilename);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// retrieve stream information
|
||||
if (avformat_find_stream_info(m_formatContext, nullptr) < 0) {
|
||||
APPL_ERROR("Could not find stream information");
|
||||
// TODO : check this, this will create a memeory leak
|
||||
return;;
|
||||
return;
|
||||
}
|
||||
m_duration = echrono::Duration(double(m_formatContext->duration)/double(AV_TIME_BASE));
|
||||
APPL_INFO("Stream duration : " << m_duration);
|
||||
|
@ -10,12 +10,14 @@
|
||||
#include <audio/channel.hpp>
|
||||
#include <audio/format.hpp>
|
||||
#include <appl/ClientProperty.hpp>
|
||||
#include <zeus/ProxyFile.hpp>
|
||||
|
||||
extern "C" {
|
||||
#include <libavutil/imgutils.h>
|
||||
#include <libavutil/samplefmt.h>
|
||||
#include <libavutil/timestamp.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavformat/avio.h>
|
||||
#include <libswscale/swscale.h>
|
||||
}
|
||||
|
||||
@ -78,6 +80,8 @@ namespace appl {
|
||||
int32_t videoGetEmptySlot();
|
||||
int32_t audioGetEmptySlot();
|
||||
private:
|
||||
AVIOContext* m_IOContext;
|
||||
std::vector<uint8_t> m_bufferFFMPEG;
|
||||
AVFormatContext* m_formatContext;
|
||||
AVCodecContext* m_videoDecoderContext;
|
||||
AVCodecContext* m_audioDecoderContext;
|
||||
@ -131,6 +135,26 @@ namespace appl {
|
||||
void flushMessage();
|
||||
|
||||
void stop() override;
|
||||
/* ***********************************************
|
||||
** Section temporary buffer
|
||||
***********************************************/
|
||||
protected:
|
||||
ememory::SharedPtr<appl::ClientProperty> m_remoteProperty; //!< Remote interface that must get data
|
||||
uint32_t m_remoteMediaId; //!< remote media ID that need to get data
|
||||
zeus::ProxyFile m_remoteFileHandle; //!< Reference on the remote file
|
||||
std::vector<uint8_t> m_remoteBuffer; //!< preallocated with all needed data
|
||||
int32_t m_remoteBufferReadPosition; //!< Current position that is read
|
||||
std::vector<std::pair<uint32_t,uint32_t>> m_remoteBufferFillSection; //!< List of <start-stop> position that contain data
|
||||
public:
|
||||
// @brief INTERNAL read callback
|
||||
int readFunc(uint8_t* _buf, int _bufSize);
|
||||
// @brief INTERNAL write callback
|
||||
int writeFunc(uint8_t* _buf, int _bufSize);
|
||||
// @brief INTERNAL seek callback
|
||||
int64_t seekFunc(int64_t _offset, int _whence);
|
||||
protected:
|
||||
void checkIfWeNeedMoreDataFromNetwork();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <ewol/widget/Button.hpp>
|
||||
#include <ewol/widget/Entry.hpp>
|
||||
#include <ewol/widget/Slider.hpp>
|
||||
#include <ewol/widget/Menu.hpp>
|
||||
#include <appl/widget/VideoPlayer.hpp>
|
||||
#include <ewol/tools/message.hpp>
|
||||
|
||||
@ -23,14 +24,20 @@
|
||||
#include <zeus/FutureGroup.hpp>
|
||||
#include <etk/stdTools.hpp>
|
||||
#include <ejson/ejson.hpp>
|
||||
#include <appl/widget/Connection.hpp>
|
||||
#include <ewol/context/Context.hpp>
|
||||
|
||||
|
||||
static std::string g_baseDBName = "USERDATA:config.json";
|
||||
|
||||
void appl::Windows::store_db() {
|
||||
APPL_DEBUG("Store database [START]");
|
||||
ejson::Document database;
|
||||
database.add("login", ejson::String(m_login));
|
||||
database.add("pass", ejson::String(m_password));
|
||||
if (m_clientProp != nullptr) {
|
||||
database.add("access", m_clientProp->toJson());
|
||||
}
|
||||
//database.add("login", ejson::String(m_login));
|
||||
//database.add("pass", ejson::String(m_password));
|
||||
bool retGenerate = database.storeSafe(g_baseDBName);
|
||||
APPL_ERROR("Store database [STOP] : " << (g_baseDBName) << " ret = " << retGenerate);
|
||||
}
|
||||
@ -41,8 +48,19 @@ void appl::Windows::load_db() {
|
||||
if (ret == false) {
|
||||
APPL_WARNING(" ==> LOAD error");
|
||||
}
|
||||
m_login = database["login"].toString().get();
|
||||
m_password = database["pass"].toString().get();
|
||||
if (m_clientProp == nullptr) {
|
||||
m_clientProp = ememory::makeShared<appl::ClientProperty>();
|
||||
if (m_clientProp == nullptr) {
|
||||
APPL_ERROR(" can not allocate the pointer of data ==> must auto kill");
|
||||
autoDestroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (m_clientProp != nullptr) {
|
||||
m_clientProp->fromJson(database["access"].toObject());
|
||||
}
|
||||
//m_login = database["login"].toString().get();
|
||||
//m_password = database["pass"].toString().get();
|
||||
}
|
||||
|
||||
|
||||
@ -94,15 +112,76 @@ void appl::Windows::init() {
|
||||
|
||||
// Direct display list:
|
||||
ewol::propertySetOnObjectNamed("view-selection", "select", "ws-name-list-viewer");
|
||||
// check if we are connected:
|
||||
if (m_login == "") {
|
||||
// must create pop-up connection
|
||||
|
||||
subBind(ewol::widget::Menu, "menu-bar", signalSelect, sharedFromThis(), &appl::Windows::onCallbackMenuEvent);
|
||||
shortCutAdd("alt+F4", "menu:exit");
|
||||
shortCutAdd("F12", "menu:reload-shader");
|
||||
shortCutAdd("F11", "menu:connect");
|
||||
signalShortcut.connect(sharedFromThis(), &appl::Windows::onCallbackShortCut);
|
||||
// TODO: try to connect the last connection availlable ...
|
||||
if (m_clientProp == nullptr) {
|
||||
onCallbackMenuEvent("menu:connect");
|
||||
} else {
|
||||
m_clientProp->connect();
|
||||
if (m_clientProp->connection.isAlive() == false) {
|
||||
onCallbackMenuEvent("menu:connect");
|
||||
} else {
|
||||
if (m_listViewer != nullptr) {
|
||||
m_listViewer->setClientProperty(m_clientProp);
|
||||
m_listViewer->searchElements();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void appl::Windows::onCallbackShortCut(const std::string& _value) {
|
||||
APPL_WARNING("Event from ShortCut : " << _value);
|
||||
onCallbackMenuEvent(_value);
|
||||
}
|
||||
|
||||
void appl::Windows::onCallbackMenuEvent(const std::string& _value) {
|
||||
APPL_WARNING("Event from Menu : " << _value);
|
||||
if (_value == "menu:connect") {
|
||||
appl::widget::ConnectionShared tmpWidget = appl::widget::Connection::create();
|
||||
if (tmpWidget == nullptr) {
|
||||
APPL_ERROR("Can not open File chooser !!! ");
|
||||
return;
|
||||
}
|
||||
tmpWidget->setProperty(m_clientProp);
|
||||
// register on the Validate event:
|
||||
tmpWidget->signalValidate.connect(sharedFromThis(), &appl::Windows::onCallbackConnectionValidate);
|
||||
// no need of this event watching ...
|
||||
tmpWidget->signalCancel.connect(sharedFromThis(), &appl::Windows::onCallbackConnectionCancel);
|
||||
// add the widget as windows pop-up ...
|
||||
popUpWidgetPush(tmpWidget);
|
||||
} else if (_value == "menu:exit") {
|
||||
gale::getContext().stop();
|
||||
} else if (_value == "menu:reload-shader") {
|
||||
ewol::getContext().getResourcesManager().reLoadResources();
|
||||
ewol::getContext().forceRedrawAll();
|
||||
} else {
|
||||
APPL_ERROR("Event from Menu UNKNOW : '" << _value << "'");
|
||||
}
|
||||
}
|
||||
|
||||
void appl::Windows::onCallbackConnectionValidate(const ememory::SharedPtr<ClientProperty>& _prop) {
|
||||
m_clientProp = _prop;
|
||||
if (m_clientProp == nullptr) {
|
||||
// TODO: set back in public mode ...
|
||||
return;
|
||||
}
|
||||
store_db();
|
||||
// Update viewer to show all ...
|
||||
if (m_listViewer != nullptr) {
|
||||
m_listViewer->setClientProperty(m_clientProp);
|
||||
m_listViewer->searchElements();
|
||||
}
|
||||
}
|
||||
|
||||
void appl::Windows::onCallbackConnectionCancel() {
|
||||
// TODO: set back in public mode ...
|
||||
|
||||
}
|
||||
|
||||
void appl::Windows::onCallbackPrevious() {
|
||||
m_id--;
|
||||
|
@ -34,6 +34,12 @@ namespace appl {
|
||||
void addFile(const std::string& _file);
|
||||
void onCallbackSeekRequest(const float& _value);
|
||||
|
||||
|
||||
void onCallbackConnectionValidate(const ememory::SharedPtr<ClientProperty>& _prop);
|
||||
void onCallbackConnectionCancel();
|
||||
|
||||
void onCallbackShortCut(const std::string& _value);
|
||||
void onCallbackMenuEvent(const std::string& _value);
|
||||
protected:
|
||||
std::string m_login;
|
||||
std::string m_password;
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <ewol/widget/meta/Connection.hpp>
|
||||
#include <appl/widget/Connection.hpp>
|
||||
#include <ewol/widget/Sizer.hpp>
|
||||
#include <ewol/widget/List.hpp>
|
||||
#include <ewol/widget/Button.hpp>
|
||||
@ -19,14 +19,10 @@
|
||||
//#include <vector>
|
||||
#include <vector>
|
||||
#include <etk/tool.hpp>
|
||||
#include <etk/os/FSNode.hpp>
|
||||
|
||||
extern "C" {
|
||||
// file browsing ...
|
||||
#include <dirent.h>
|
||||
}
|
||||
#include <appl/debug.hpp>
|
||||
|
||||
#include <ewol/ewol.hpp>
|
||||
#include <ewol/tools/message.hpp>
|
||||
|
||||
appl::widget::Connection::Connection() :
|
||||
signalCancel(this, "cancel", ""),
|
||||
@ -34,148 +30,69 @@ appl::widget::Connection::Connection() :
|
||||
addObjectType("appl::widget::Connection");
|
||||
}
|
||||
|
||||
void appl::widget::Connection::init(ememory::SharedPtr<appl::ClientProperty> _baseProperty) {
|
||||
appl::widget::Composer::init();
|
||||
m_baseProperty = _baseProperty;
|
||||
void appl::widget::Connection::init() {
|
||||
ewol::widget::Composer::init();
|
||||
loadFromFile("DATA:gui-connection.xml", getId());
|
||||
subBind(appl::widget::CheckBox, "[" + etk::to_string(getId()) + "]file-shooser:show-hiden-file", signalValue, sharedFromThis(), &appl::widget::Connection::onCallbackHidenFileChangeChangeValue);
|
||||
subBind(appl::widget::Button, "[" + etk::to_string(getId()) + "]file-shooser:button-validate", signalPressed, sharedFromThis(), &appl::widget::Connection::onCallbackListValidate);
|
||||
subBind(appl::widget::Button, "[" + etk::to_string(getId()) + "]file-shooser:button-cancel", signalPressed, sharedFromThis(), &appl::widget::Connection::onCallbackButtonCancelPressed);
|
||||
subBind(appl::widget::ListFileSystem, "[" + etk::to_string(getId()) + "]file-shooser:list-folder", signalFolderValidate, sharedFromThis(), &appl::widget::Connection::onCallbackListFolderSelectChange);
|
||||
subBind(appl::widget::ListFileSystem, "[" + etk::to_string(getId()) + "]file-shooser:list-files", signalFileSelect, sharedFromThis(), &appl::widget::Connection::onCallbackListFileSelectChange);
|
||||
subBind(appl::widget::ListFileSystem, "[" + etk::to_string(getId()) + "]file-shooser:list-files", signalFileValidate, sharedFromThis(), &appl::widget::Connection::onCallbackListFileValidate);
|
||||
subBind(appl::widget::Entry, "[" + etk::to_string(getId()) + "]file-shooser:entry-file", signalModify, sharedFromThis(), &appl::widget::Connection::onCallbackEntryFileChangeValue);
|
||||
subBind(appl::widget::Entry, "[" + etk::to_string(getId()) + "]file-shooser:entry-file", signalEnter, sharedFromThis(), &appl::widget::Connection::onCallbackListFileValidate);
|
||||
subBind(appl::widget::Entry, "[" + etk::to_string(getId()) + "]file-shooser:entry-folder", signalModify, sharedFromThis(), &appl::widget::Connection::onCallbackEntryFolderChangeValue);
|
||||
//composerBind(appl::widget::CheckBox, "[" + etk::to_string(getId()) + "]file-shooser:entry-folder", signalEnter, sharedFromThis(), &appl::widget::Connection::);
|
||||
subBind(appl::widget::Image, "[" + etk::to_string(getId()) + "]file-shooser:img-home", signalPressed, sharedFromThis(), &appl::widget::Connection::onCallbackHomePressed);
|
||||
// set the default Folder properties:
|
||||
updateCurrentFolder();
|
||||
subBind(ewol::widget::Entry, "[" + etk::to_string(getId()) + "]connect-login", signalModify, sharedFromThis(), &appl::widget::Connection::onCallbackEntryLoginChangeValue);
|
||||
subBind(ewol::widget::Entry, "[" + etk::to_string(getId()) + "]connect-password", signalModify, sharedFromThis(), &appl::widget::Connection::onCallbackEntryPasswordChangeValue);
|
||||
subBind(ewol::widget::Button, "[" + etk::to_string(getId()) + "]connect-bt", signalPressed, sharedFromThis(), &appl::widget::Connection::onCallbackButtonValidate);
|
||||
subBind(ewol::widget::Button, "[" + etk::to_string(getId()) + "]cancel-bt", signalPressed, sharedFromThis(), &appl::widget::Connection::onCallbackButtonCancel);
|
||||
setProperty(nullptr);
|
||||
propertyCanFocus.set(true);
|
||||
}
|
||||
|
||||
|
||||
void appl::widget::Connection::setProperty(ememory::SharedPtr<appl::ClientProperty> _baseProperty) {
|
||||
m_baseProperty = _baseProperty;
|
||||
if (m_baseProperty == nullptr) {
|
||||
m_baseProperty = ememory::makeShared<appl::ClientProperty>();
|
||||
if (m_baseProperty == nullptr) {
|
||||
APPL_ERROR(" can not allocate the pointer of data ==> must auto kill");
|
||||
autoDestroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_login = m_baseProperty->getLogin();
|
||||
m_password = m_baseProperty->getPassword();
|
||||
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]connect-login", "value", m_login);
|
||||
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]connect-password", "value", m_password);
|
||||
}
|
||||
|
||||
void appl::widget::Connection::onGetFocus() {
|
||||
// transfert focus on a specific widget...
|
||||
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]file-shooser:entry-file", "focus", "true");
|
||||
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]connect-login", "focus", "true");
|
||||
}
|
||||
|
||||
appl::widget::Connection::~Connection() {
|
||||
|
||||
}
|
||||
|
||||
void appl::widget::Connection::onChangePropertyPath() {
|
||||
propertyPath.getDirect() = *propertyPath + "/";
|
||||
updateCurrentFolder();
|
||||
void appl::widget::Connection::onCallbackEntryLoginChangeValue(const std::string& _value) {
|
||||
m_login = _value;
|
||||
}
|
||||
|
||||
void appl::widget::Connection::onChangePropertyFile() {
|
||||
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]file-shooser:entry-file", "value", propertyFile);
|
||||
//updateCurrentFolder();
|
||||
void appl::widget::Connection::onCallbackEntryPasswordChangeValue(const std::string& _value) {
|
||||
m_password = _value;
|
||||
}
|
||||
|
||||
void appl::widget::Connection::onChangePropertyLabelTitle() {
|
||||
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]file-shooser:title-label", "value", propertyLabelTitle);
|
||||
void appl::widget::Connection::onCallbackButtonValidate() {
|
||||
// ckeck if connection is valid ...
|
||||
APPL_INFO("Connect with : '" << m_login << "' ... '" << m_password << "'");
|
||||
m_baseProperty->setLogin(m_login);
|
||||
m_baseProperty->setPassword(m_password);
|
||||
m_baseProperty->connect();
|
||||
if (m_baseProperty->connection.isAlive() == false) {
|
||||
APPL_ERROR(" ==> NOT Authentify to '" << m_baseProperty->getLogin() << "'");
|
||||
ewol::tools::message::displayError("Can not connect the server with <br/>'" + m_baseProperty->getLogin() + "'");
|
||||
} else {
|
||||
APPL_INFO(" ==> Authentify with '" << m_baseProperty->getLogin() << "'");
|
||||
signalValidate.emit(m_baseProperty);
|
||||
autoDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
void appl::widget::Connection::onChangePropertyLabelValidate() {
|
||||
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]file-shooser:validate-label", "value", propertyLabelValidate);
|
||||
}
|
||||
|
||||
void appl::widget::Connection::onChangePropertyLabelCancel() {
|
||||
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]file-shooser:cancel-label", "value", propertyLabelCancel);
|
||||
}
|
||||
|
||||
void appl::widget::Connection::onCallbackEntryFolderChangeValue(const std::string& _value) {
|
||||
// == > change the folder name
|
||||
// TODO : change the folder, if it exit ...
|
||||
}
|
||||
|
||||
void appl::widget::Connection::onCallbackEntryFileChangeValue(const std::string& _value) {
|
||||
// == > change the file name
|
||||
propertyFile.setDirect(_value);
|
||||
// update the selected file in the list :
|
||||
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]file-shooser:list-files", "select", propertyFile);
|
||||
}
|
||||
|
||||
void appl::widget::Connection::onCallbackButtonCancelPressed() {
|
||||
// == > Auto remove ...
|
||||
void appl::widget::Connection::onCallbackButtonCancel() {
|
||||
signalCancel.emit();
|
||||
autoDestroy();
|
||||
}
|
||||
|
||||
void appl::widget::Connection::onCallbackHidenFileChangeChangeValue(const bool& _value) {
|
||||
if (_value == true) {
|
||||
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]file-shooser:list-folder", "show-hidden", "true");
|
||||
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]file-shooser:list-files", "show-hidden", "true");
|
||||
} else {
|
||||
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]file-shooser:list-folder", "show-hidden", "false");
|
||||
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]file-shooser:list-files", "show-hidden", "false");
|
||||
}
|
||||
}
|
||||
|
||||
void appl::widget::Connection::onCallbackListFolderSelectChange(const std::string& _value) {
|
||||
// == > this is an internal event ...
|
||||
EWOL_DEBUG(" old PATH: '" << *propertyPath << "' + '" << _value << "'");
|
||||
propertyPath.setDirect(propertyPath.get() + _value);
|
||||
EWOL_DEBUG("new PATH: '" << *propertyPath << "'");
|
||||
propertyPath.setDirect(etk::simplifyPath(*propertyPath));
|
||||
propertyFile.setDirect("");
|
||||
updateCurrentFolder();
|
||||
}
|
||||
|
||||
void appl::widget::Connection::onCallbackListFileSelectChange(const std::string& _value) {
|
||||
propertyFile.set(_value);
|
||||
/*
|
||||
std::string tmpFileCompleatName = m_folder;
|
||||
tmpFileCompleatName += m_file;
|
||||
// TODO : generateEventId(_msg.getMessage(), tmpFileCompleatName);
|
||||
*/
|
||||
}
|
||||
|
||||
void appl::widget::Connection::onCallbackListFileValidate(const std::string& _value) {
|
||||
// select the file == > generate a validate
|
||||
propertyFile.set(_value);
|
||||
EWOL_VERBOSE(" generate a fiel opening : '" << propertyPath << "' / '" << propertyFile << "'");
|
||||
signalValidate.emit(getCompleateFileName());
|
||||
autoDestroy();
|
||||
}
|
||||
|
||||
void appl::widget::Connection::onCallbackListValidate() {
|
||||
if (propertyFile.get() == "") {
|
||||
EWOL_WARNING(" Validate : '" << propertyPath << "' / '" << propertyFile << "' ==> error No name ...");
|
||||
return;
|
||||
}
|
||||
EWOL_DEBUG(" generate a file opening : '" << propertyPath << "' / '" << propertyFile << "'");
|
||||
signalValidate.emit(getCompleateFileName());
|
||||
autoDestroy();
|
||||
}
|
||||
|
||||
void appl::widget::Connection::onCallbackHomePressed() {
|
||||
std::string tmpUserFolder = etk::getUserHomeFolder();
|
||||
EWOL_DEBUG("new PATH : \"" << tmpUserFolder << "\"");
|
||||
|
||||
propertyPath.setDirect(etk::simplifyPath(tmpUserFolder));
|
||||
|
||||
propertyFile.setDirect("");
|
||||
updateCurrentFolder();
|
||||
}
|
||||
|
||||
void appl::widget::Connection::updateCurrentFolder() {
|
||||
if (*propertyPath != "") {
|
||||
if (propertyPath.get()[propertyPath->size()-1] != '/') {
|
||||
propertyPath.getDirect() += "/";
|
||||
}
|
||||
}
|
||||
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]file-shooser:list-files", "path", propertyPath);
|
||||
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]file-shooser:list-folder", "path", propertyPath);
|
||||
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]file-shooser:entry-folder", "value", propertyPath);
|
||||
markToRedraw();
|
||||
}
|
||||
|
||||
std::string appl::widget::Connection::getCompleateFileName() {
|
||||
std::string tmpString = propertyPath;
|
||||
tmpString += "/";
|
||||
tmpString += propertyFile;
|
||||
etk::FSNode node(tmpString);
|
||||
return node.getName();
|
||||
}
|
||||
|
@ -23,26 +23,20 @@ namespace appl {
|
||||
*
|
||||
* Fist global static declaration and inclusion:
|
||||
* [code style=c++]
|
||||
* #include <ewol/widget/meta/Connection.h>
|
||||
* #include <appl/widget/Connection.hpp>
|
||||
* [/code]
|
||||
*
|
||||
* The first step is to create the file chooser pop-up : (never in the constructor!!!)
|
||||
* [code style=c++]
|
||||
* ewol::widget::ConnectionShared tmpWidget = ewol::Widget::Connection::create();
|
||||
* appl::widget::ConnectionShared tmpWidget = appl::widget::Connection::create();
|
||||
* if (tmpWidget == nullptr) {
|
||||
* APPL_ERROR("Can not open File chooser !!! ");
|
||||
* return -1;
|
||||
* }
|
||||
* // register on the Validate event:
|
||||
* tmpWidget->signalValidate.connect(sharedFromThis(), &****::onCallbackOpenFile);
|
||||
* tmpWidget->signalValidate.connect(sharedFromThis(), &****::onCallbackConnectionValidate);
|
||||
* // no need of this event watching ...
|
||||
* tmpWidget->signalCancel.connect(sharedFromThis(), &****::onCallbackClosePopUp);
|
||||
* // set the title:
|
||||
* tmpWidget->propertyLabelTitle.set("Open files ...");
|
||||
* // Set the validate Label:
|
||||
* tmpWidget->propertyLabelValidate.set("Open");
|
||||
* // simply set a folder (by default this is the home folder)
|
||||
* //tmpWidget->propertyPath.set("/home/me");
|
||||
* tmpWidget->signalCancel.connect(sharedFromThis(), &****::onCallbackConnectionCancel);
|
||||
* // add the widget as windows pop-up ...
|
||||
* ewol::widget::WindowsShared tmpWindows = getWindows();
|
||||
* if (tmpWindows == nullptr) {
|
||||
@ -55,11 +49,11 @@ namespace appl {
|
||||
* Now we just need to wait the the open event message.
|
||||
*
|
||||
* [code style=c++]
|
||||
* void ****::onCallbackOpenFile(const std::string& _value) {
|
||||
* APPL_INFO("Request open file : '" << _value << "'");
|
||||
* void ****::onCallbackConnectionValidate(const ememory::SharedPtr<appl::ClientProperty>& _prop) {
|
||||
* APPL_INFO("New connection : '" << _value << "'");
|
||||
* }
|
||||
* void ****::onCallbackClosePopUp() {
|
||||
* APPL_INFO("The File chooser has been closed");
|
||||
* void ****::onCallbackConnectionCancel() {
|
||||
* APPL_INFO("cancel connection");
|
||||
* }
|
||||
* [/code]
|
||||
* This is the best example of a Meta-widget.
|
||||
@ -70,11 +64,14 @@ namespace appl {
|
||||
esignal::Signal<ememory::SharedPtr<appl::ClientProperty>> signalValidate; //!< select file(s)
|
||||
protected:
|
||||
ememory::SharedPtr<appl::ClientProperty> m_baseProperty;
|
||||
std::string m_login;
|
||||
std::string m_password;
|
||||
Connection();
|
||||
void init(ememory::SharedPtr<appl::ClientProperty> _baseProperty=nullptr) override;
|
||||
void init() override;
|
||||
public:
|
||||
DECLARE_WIDGET_FACTORY(Connection, "Connection");
|
||||
virtual ~Connection();
|
||||
void setProperty(ememory::SharedPtr<appl::ClientProperty> _baseProperty=nullptr);
|
||||
private:
|
||||
std::string getCompleateFileName();
|
||||
void updateCurrentFolder();
|
||||
@ -82,21 +79,10 @@ namespace appl {
|
||||
void onGetFocus() override;
|
||||
private:
|
||||
// callback functions:
|
||||
void onCallbackEntryFolderChangeValue(const std::string& _value);
|
||||
void onCallbackEntryFileChangeValue(const std::string& _value);
|
||||
void onCallbackButtonCancelPressed();
|
||||
void onCallbackHidenFileChangeChangeValue(const bool& _value);
|
||||
void onCallbackListFolderSelectChange(const std::string& _value);
|
||||
void onCallbackListFileSelectChange(const std::string& _value);
|
||||
void onCallbackListFileValidate(const std::string& _value);
|
||||
void onCallbackListValidate();
|
||||
void onCallbackHomePressed();
|
||||
protected:
|
||||
virtual void onChangePropertyPath();
|
||||
virtual void onChangePropertyFile();
|
||||
virtual void onChangePropertyLabelTitle();
|
||||
virtual void onChangePropertyLabelValidate();
|
||||
virtual void onChangePropertyLabelCancel();
|
||||
void onCallbackButtonValidate();
|
||||
void onCallbackButtonCancel();
|
||||
void onCallbackEntryLoginChangeValue(const std::string& _value);
|
||||
void onCallbackEntryPasswordChangeValue(const std::string& _value);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -65,7 +65,7 @@ void appl::widget::ListViewer::searchElements(std::string _filter) {
|
||||
} else if (_filter == "courses") {
|
||||
_filter = "'type' == 'courses'";
|
||||
} else {
|
||||
_filter = "";
|
||||
_filter = "*";
|
||||
}
|
||||
|
||||
if (m_clientProp->connection.isAlive() == false) {
|
||||
@ -80,8 +80,11 @@ void appl::widget::ListViewer::searchElements(std::string _filter) {
|
||||
APPL_ERROR(" ==> Service does not exist : 'video'");
|
||||
return;
|
||||
}
|
||||
zeus::Future<std::vector<uint32_t>> listElem = remoteServiceVideo.getMediaWhere(_filter);
|
||||
listElem.wait();
|
||||
zeus::Future<std::vector<uint32_t>> listElem = remoteServiceVideo.getMediaWhere(_filter).wait();
|
||||
if (listElem.hasError() == true) {
|
||||
APPL_ERROR(" ==> Can not get element from video service <with fileter ! '" << _filter << "' : " << listElem.getErrorType() << " : " << listElem.getErrorHelp());
|
||||
return;
|
||||
}
|
||||
std::vector<uint32_t> returnValues = listElem.get();
|
||||
APPL_INFO("Get some Values: " << returnValues << "");
|
||||
for (auto &it : returnValues) {
|
||||
@ -96,13 +99,12 @@ void appl::widget::ListViewer::searchElements(std::string _filter) {
|
||||
// TODO : Add the reference on the typed future in the function andTrn ... ==> then we can add later the cancel
|
||||
appl::widget::ListViewerShared tmpWidget = ememory::staticPointerCast<appl::widget::ListViewer>(sharedFromThis());
|
||||
remoteServiceVideo.mediaMetadataGetKey(it, "title")
|
||||
.andThen([=](zeus::FutureBase _fut) mutable {
|
||||
.andThen([=](zeus::Future<std::string> _fut) mutable {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
zeus::Future<std::string> futTmp(_fut);
|
||||
APPL_INFO(" [" << elem->m_id << "] get title: " << futTmp.get());
|
||||
APPL_INFO(" [" << elem->m_id << "] get title: " << _fut.get());
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(elem->m_mutex);
|
||||
elem->m_title = futTmp.get();
|
||||
elem->m_title = _fut.get();
|
||||
}
|
||||
tmpWidget->markToRedraw();
|
||||
return true;
|
||||
|
@ -84,7 +84,7 @@ namespace appl {
|
||||
void setClientProperty(ememory::SharedPtr<ClientProperty> _prop) {
|
||||
m_clientProp = _prop;
|
||||
}
|
||||
void searchElements(std::string _filter);
|
||||
void searchElements(std::string _filter="");
|
||||
bool onEventInput(const ewol::event::Input& _event) override;
|
||||
};
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ void appl::widget::VideoDisplay::onRegenerateDisplay() {
|
||||
|
||||
void appl::widget::VideoDisplay::periodicEvent(const ewol::event::Time& _event) {
|
||||
if (m_isPalying == true) {
|
||||
APPL_INFO("tick: " << _event);
|
||||
APPL_VERBOSE("tick: " << _event);
|
||||
m_currentTime += _event.getDeltaCallDuration();
|
||||
}
|
||||
if (m_decoder == nullptr) {
|
||||
|
@ -1,11 +1,14 @@
|
||||
<PopUp >
|
||||
<sizer mode="vert" fill="true,true" expand="false,false" lock="true,true" addmode="invert" min-size="45,10%">
|
||||
<label>login</label>
|
||||
<label>_T{Login}</label>
|
||||
<entry name="[{ID}]connect-login" fill="true,false" expand="true,false"/>
|
||||
<label>password</label>
|
||||
<label>_T{Password}</label>
|
||||
<entry name="[{ID}]connect-password" fill="true,false" expand="true,false"/>
|
||||
<button name="[{ID}]connect-bt" toggle="false" fill="false,false" expand="true,false" gravity="right">
|
||||
<label>Connect</label>
|
||||
<label>_T{Connect}</label>
|
||||
</button>
|
||||
<button name="[{ID}]cancel-bt" toggle="false" fill="false,false" expand="true,false" gravity="right">
|
||||
<label>_T{Cancel}</label>
|
||||
</button>
|
||||
</sizer>
|
||||
</PopUp>
|
@ -68,6 +68,14 @@
|
||||
</button>
|
||||
</sizer>
|
||||
<sizer mode="hori" fill="true,false" expand="true,false" lock="true,true">
|
||||
<menu name="menu-bar">
|
||||
<elem title="" image="DATA:List.svg" event="">
|
||||
<elem title="_T{Connect}" image="" event="menu:connect"/>
|
||||
<elem title="_T{Home}" image="DATA:Home.svg" event="menu:home"/>
|
||||
<separator/>
|
||||
<elem title="_T{Exit}" image="" event="menu:exit"/>
|
||||
</elem>
|
||||
</menu>
|
||||
<button name="menu-bt">
|
||||
<image src="DATA:List.svg" size='8,8mm'/>
|
||||
</button>
|
||||
|
@ -35,6 +35,8 @@ def configure(target, my_module):
|
||||
'appl/MediaDecoder.cpp',
|
||||
'appl/widget/VideoPlayer.cpp',
|
||||
'appl/widget/ListViewer.cpp',
|
||||
'appl/ClientProperty.cpp',
|
||||
'appl/widget/Connection.cpp',
|
||||
])
|
||||
my_module.add_depend([
|
||||
'ffmpeg-libs',
|
||||
|
@ -281,26 +281,28 @@ namespace appl {
|
||||
if (_sqlLikeRequest == "") {
|
||||
throw std::invalid_argument("empty request");
|
||||
}
|
||||
std::vector<std::string> listAnd = etk::split(_sqlLikeRequest, "AND");
|
||||
std::vector<std::vector<std::string>> listAndParsed;
|
||||
APPL_INFO("Find list AND : ");
|
||||
for (auto &it : listAnd) {
|
||||
it = removeSpaceOutQuote(it);
|
||||
std::vector<std::string> elements = splitAction(it);
|
||||
if (elements.size() != 3) {
|
||||
APPL_ERROR("element : '" + it + "' have wrong spliting " << elements);
|
||||
throw std::invalid_argument("element : \"" + it + "\" have wrong spliting");
|
||||
if (_sqlLikeRequest != "*") {
|
||||
std::vector<std::string> listAnd = etk::split(_sqlLikeRequest, "AND");
|
||||
APPL_INFO("Find list AND : ");
|
||||
for (auto &it : listAnd) {
|
||||
it = removeSpaceOutQuote(it);
|
||||
std::vector<std::string> elements = splitAction(it);
|
||||
if (elements.size() != 3) {
|
||||
APPL_ERROR("element : '" + it + "' have wrong spliting " << elements);
|
||||
throw std::invalid_argument("element : \"" + it + "\" have wrong spliting");
|
||||
}
|
||||
if ( elements[1] != "=="
|
||||
&& elements[1] != "!="
|
||||
&& elements[1] != ">="
|
||||
&& elements[1] != "<="
|
||||
&& elements[1] != ">"
|
||||
&& elements[1] != "<") {
|
||||
throw std::invalid_argument("action invalid : '" + elements[1] + "' only availlable : [==,!=,<=,>=,<,>]");
|
||||
}
|
||||
APPL_INFO(" - '" << elements[0] << "' action='" << elements[1] << "' with='" << elements[2] << "'");
|
||||
listAndParsed.push_back(elements);
|
||||
}
|
||||
if ( elements[1] != "=="
|
||||
&& elements[1] != "!="
|
||||
&& elements[1] != ">="
|
||||
&& elements[1] != "<="
|
||||
&& elements[1] != ">"
|
||||
&& elements[1] != "<") {
|
||||
throw std::invalid_argument("action invalid : '" + elements[1] + "' only availlable : [==,!=,<=,>=,<,>]");
|
||||
}
|
||||
APPL_INFO(" - '" << elements[0] << "' action='" << elements[1] << "' with='" << elements[2] << "'");
|
||||
listAndParsed.push_back(elements);
|
||||
}
|
||||
std::unique_lock<std::mutex> lock(g_mutex);
|
||||
for (auto &it : m_listFile) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user