[DEV] Continue integration for a better player video

This commit is contained in:
Edouard DUPIN 2017-02-07 21:35:58 +01:00
parent fe927ac297
commit 27e0a4e603
15 changed files with 512 additions and 213 deletions

View File

@ -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>);

View File

@ -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();
};
}

View File

@ -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);

View File

@ -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();
};
}

View File

@ -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--;

View File

@ -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;

View File

@ -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();
}

View File

@ -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);
};
};
};

View File

@ -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;

View File

@ -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;
};
}

View File

@ -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) {

View File

@ -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>

View File

@ -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>

View File

@ -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',

View File

@ -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) {