Description
Shows how to create an UI service or application to remote access the recorder interface.
- Note
- This is demonstration purpose only!
For please use the integrated recorder functionality in Qt5 ADTF XSystem UI Service.
Prebuilt Binaries
Source Code
./examples/demo_adtfplugins/demo_qt5_recorder_control_view/
Library
demo_rec_ctrl_widget.h
#pragma once
#include <plugins/recorder_intf.h>
#include <unordered_set>
#include <QLabel>
#include <QPushButton>
#include <QGroupBox>
#include "demo_rec_ctrl_view_intf.h"
struct tRecorderInfo
{
tRecorderInfo(): strRecorderName(QString()), strFile(QString()), eState(
adtf::services::IRecorder::Closed) {};
QString strRecorderName;
QString strFile;
adtf::services::IRecorder::tState eState;
};
class cSingleRecorderControlWidget : public QGroupBox
{
Q_OBJECT
public:
explicit cSingleRecorderControlWidget(IRecorderControlView& oControlView, const tRecorderInfo& sInfo);
~cSingleRecorderControlWidget();
void EnableByState(const tRecorderInfo& sRecorderInfo);
void Disable();
struct tUIElems
{
explicit tUIElems(QWidget* pWidget, const QString& strName);
void EnableByState(const tRecorderInfo& lstRecorderInfo);
void Disable();
QLabel* m_pName;
QPushButton* m_pStartStop;
QPushButton* m_pSplit;
QLabel* m_pCurrentFile;
};
private:
IRecorderControlView& m_oControlView;
tUIElems* m_pUI = nullptr;
protected slots:
void OnStartStop();
void OnSplit();
};
class cRecorderControlWidget : public QWidget
{
Q_OBJECT
public:
explicit cRecorderControlWidget(QWidget* pParent, IRecorderControlView& oControlView);
~cRecorderControlWidget();
tResult Update(const std::list<tRecorderInfo>&, tTimeStamp nMinInterval = 25000);
private:
tTimeStamp m_tmLastUpdate = 0;
IRecorderControlView& m_oControlView;
struct tUIElems
{
explicit tUIElems(QWidget* pWidget);
std::map<QString, cSingleRecorderControlWidget*> m_mapRecorderWidgets;
void EnableByState(QWidget* pWidget,
IRecorderControlView& oControl,
const std::list<tRecorderInfo>& lstRecorderInfo);
void Disable();
};
tUIElems* m_pUI = nullptr;
adtf::util::cFilename m_strLastFolder;
protected slots:
};
Namespace for all functionality provided by ADTF and its SDKs.
Definition adtfui_pkg.h:13
demo_rec_ctrl_widget.cpp
#include "demo_rec_ctrl_widget.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGroupBox>
#include <QPushButton>
#include <QLabel>
using namespace adtf::util;
#define REC_STR QString("Rec")
#define STOP_STR QString("Stop")
#define SPLIT_STR QString("Split")
namespace
{
cString calculate_time_string(tTimeStamp tmStreamTime)
{
char strBuf[32];
int nDurationHou = (int) (tmStreamTime / 1000000 / 60 / 60);
int nDurationMin = (int) (tmStreamTime / 1000000 / 60 - (nDurationHou * 60));
int nDurationSec = (int) (tmStreamTime / 1000000 - (nDurationMin * 60) - (nDurationHou * 60 * 60));
int nDurationMil =
(int) (tmStreamTime / 1000 - (nDurationHou * 60 * 60000) - (nDurationMin * 60000) - (nDurationSec * 1000));
#ifdef _WIN32
sprintf_s(strBuf, "%02d:%02d:%02d.%03d", nDurationHou, nDurationMin, nDurationSec, nDurationMil);
#else
sprintf(strBuf, "%02d:%02d:%02d.%03d", nDurationHou, nDurationMin, nDurationSec, nDurationMil);
#endif
if (nDurationHou > 24)
{
int nDurationDay = nDurationHou / 24;
nDurationHou = nDurationHou - (nDurationDay * 24);
return cString::Format("[%dd] %02d:%02d:%02d.%03d", nDurationDay, nDurationHou, nDurationMin, nDurationSec,
nDurationMil);
}
return cString(strBuf);
}
}
cSingleRecorderControlWidget::tUIElems::tUIElems(QWidget* pWidget, const QString& strName)
{
QVBoxLayout* pVbox = new QVBoxLayout();
QGroupBox* pBox = new QGroupBox();
QHBoxLayout* pHLayout = new QHBoxLayout();
pBox->setMaximumHeight(50);
m_pName = new QLabel(strName);
m_pStartStop = new QPushButton(REC_STR);
m_pSplit = new QPushButton(SPLIT_STR);
pHLayout->addWidget(m_pName);
pHLayout->addWidget(m_pStartStop);
pHLayout->addWidget(m_pSplit);
pBox->setLayout(pHLayout);
pVbox->addWidget(pBox);
pBox = new QGroupBox();
pHLayout = new QHBoxLayout();
m_pCurrentFile = new QLabel();
pHLayout->addWidget(m_pCurrentFile);
pBox->setLayout(pHLayout);
pVbox->addWidget(pBox);
pWidget->setLayout(pVbox);
Disable();
}
void cSingleRecorderControlWidget::tUIElems::EnableByState(const tRecorderInfo& sRecorderInfo)
{
switch (sRecorderInfo.eState)
{
case adtf::services::IRecorder::Closed:
{
m_pStartStop->setEnabled(false);
m_pStartStop->setText(REC_STR);
m_pSplit->setEnabled(false);
break;
}
case adtf::services::IRecorder::Idle:
case adtf::services::IRecorder::Queueing:
{
m_pStartStop->setEnabled(true);
m_pStartStop->setText(REC_STR);
m_pSplit->setEnabled(false);
break;
}
case adtf::services::IRecorder::Recording:
{
m_pStartStop->setEnabled(true);
m_pStartStop->setText(STOP_STR);
m_pSplit->setEnabled(true);
break;
}
}
QString strCurrentFile = sRecorderInfo.strFile;
;
strCurrentFile.detach();
if (strCurrentFile.count() > 40)
{
m_pCurrentFile->setText("..." + strCurrentFile.right(37));
}
else
{
m_pCurrentFile->setText(strCurrentFile);
}
strCurrentFile.replace(",", "\n");
m_pCurrentFile->setToolTip(strCurrentFile);
}
void cSingleRecorderControlWidget::tUIElems::Disable()
{
m_pStartStop->setEnabled(false);
m_pSplit->setEnabled(false);
m_pCurrentFile->setText(QString());
}
cSingleRecorderControlWidget::cSingleRecorderControlWidget(IRecorderControlView& oControlView,
const tRecorderInfo& sInfo):
QGroupBox(), m_oControlView(oControlView)
{
m_pUI = new tUIElems(this, sInfo.strRecorderName);
QObject::connect(m_pUI->m_pStartStop, SIGNAL(clicked()), this, SLOT(OnStartStop()));
QObject::connect(m_pUI->m_pSplit, SIGNAL(clicked()), this, SLOT(OnSplit()));
}
cSingleRecorderControlWidget::~cSingleRecorderControlWidget()
{
delete m_pUI;
m_pUI = nullptr;
}
void cSingleRecorderControlWidget::EnableByState(const tRecorderInfo& sRecorderInfo)
{
m_pUI->EnableByState(sRecorderInfo);
}
void cSingleRecorderControlWidget::Disable()
{
m_pUI->Disable();
}
void cSingleRecorderControlWidget::OnStartStop()
{
if (m_pUI->m_pStartStop->text() == REC_STR)
{
m_oControlView.StartRecording(static_cast<const char*>(m_pUI->m_pName->text().toUtf8()));
}
else
{
m_oControlView.StopRecording(static_cast<const char*>(m_pUI->m_pName->text().toUtf8()));
}
}
void cSingleRecorderControlWidget::OnSplit()
{
m_oControlView.SplitRecording(static_cast<const char*>(m_pUI->m_pName->text().toUtf8()));
}
cRecorderControlWidget::tUIElems::tUIElems(QWidget* pWidget)
{
QVBoxLayout* pVbox = new QVBoxLayout();
pWidget->setLayout(pVbox);
Disable();
}
void cRecorderControlWidget::tUIElems::EnableByState(QWidget* pWidget,
IRecorderControlView& oControl,
const std::list<tRecorderInfo>& lstRecorderInfo)
{
for (auto it : lstRecorderInfo)
{
auto itWidget = m_mapRecorderWidgets.find(it.strRecorderName);
if (itWidget != m_mapRecorderWidgets.end())
{
itWidget->second->EnableByState(it);
}
else
{
auto pNewWidget = new cSingleRecorderControlWidget(oControl, it);
pWidget->layout()->addWidget(pNewWidget);
m_mapRecorderWidgets[it.strRecorderName] = pNewWidget;
pNewWidget->EnableByState(it);
}
}
for (decltype(m_mapRecorderWidgets)::iterator itMap = m_mapRecorderWidgets.begin();
itMap != m_mapRecorderWidgets.end(); itMap++)
{
bool bFound = false;
for (auto itInfo : lstRecorderInfo)
{
if (itInfo.strRecorderName == itMap->first)
{
bFound = true;
break;
}
}
if (!bFound)
{
m_mapRecorderWidgets.erase(itMap->first);
itMap = m_mapRecorderWidgets.begin();
}
}
}
void cRecorderControlWidget::tUIElems::Disable()
{
for (auto it : m_mapRecorderWidgets)
{
it.second->setParent(nullptr);
delete it.second;
}
m_mapRecorderWidgets.clear();
}
cRecorderControlWidget::cRecorderControlWidget(QWidget* pParent, IRecorderControlView& oControl):
QWidget(pParent), m_oControlView(oControl)
{
m_pUI = new tUIElems(this);
}
cRecorderControlWidget::~cRecorderControlWidget()
{
delete m_pUI;
}
tResult cRecorderControlWidget::Update(const std::list<tRecorderInfo>& lstRecorder, tTimeStamp nMinInterval)
{
if (cHighResTimer::GetTime() - m_tmLastUpdate < nMinInterval)
{
RETURN_ERROR(ERR_NOERROR);
}
setUpdatesEnabled(false);
if (!lstRecorder.empty())
{
m_pUI->EnableByState(this, m_oControlView, lstRecorder);
}
else
{
m_pUI->Disable();
}
setUpdatesEnabled(true);
m_tmLastUpdate = cHighResTimer::GetTime();
RETURN_NOERROR;
}
UI Service
demo_rec_ctrl_view.h
#pragma once
#include <adtf_systemsdk.h>
#include <adtf_ui.h>
#include <plugins/recorder_intf.h>
#include <demo_rec_ctrl_view_intf.h>
#ifndef ADTF_EXAMPLES_CID
#define ADTF_EXAMPLES_CID ".local.cid"
#endif
class cRecorderControlWidget;
{
public:
ADTF_CLASS_ID_NAME(cRecorderControlViewSrv,
"demo_qt_recorder_control_view.ui_service" ADTF_EXAMPLES_CID,
"Demo Qt5 Recorder Control View");
protected:
cRecorderControlWidget* m_pWidget;
std::map<adtf::util::cString, adtf::ucom::object_ptr<adtf::services::IRecorder>> m_mapRecorders;
tTimeStamp m_tmLastUpdate = 0;
tTimeStamp m_tmMinInterval = 200000;
public:
cRecorderControlViewSrv();
tResult ServiceEvent(int nEventId,
uint32_t ui32Param1 = 0,
uint32_t ui32Param2 = 0,
void* pvData = nullptr,
int szData = 0) override;
protected:
public:
void StartRecording(const QString& strRecorderName) override;
void StopRecording(const QString& strRecorderName) override;
void SplitRecording(const QString& strRecorderName) override;
};
virtual QWidget * CreateView()=0
virtual void ReleaseView()=0
tResult OnIdle() override
Definition xsystem_qtwindow.h:127
Interface definition for the ADTF XSystem based on Qt. Use this interface to create your own displays...
Definition qtxsystem_intf.h:385
v0::qt_ui_service< adtf::system::ant::cADTFService, v1::cQtWindow > cQtUIService
Definition qt_ui_service.h:309
demo_rec_ctrl_view.cpp
#include "demo_rec_ctrl_view.h"
#include <demo_rec_ctrl_widget.h>
ADTF_PLUGIN("Demo Qt5 Recorder Control View Plugin", cRecorderControlViewSrv)
#ifdef GetObject
#undef GetObject
#endif
#ifdef GetCurrentTime
#undef GetCurrentTime
#endif
namespace
{
void show_result(QWidget* pWidget, tResult nRes)
{
LOG_RESULT(nRes);
QMessageBox::critical(
pWidget,
adtf::util::cString::Format("Error %d - [%s] ", nRes.GetErrorCode().value, nRes.GetErrorString()).GetPtr(),
nRes.GetDescription());
}
tResult local_set_run_level(QWidget* pWidget, adtf::base::tADTFRunLevel eLevel)
{
tResult nRes = _runtime->SetRunLevel(eLevel);
if (IS_FAILED(nRes))
{
show_result(pWidget, nRes);
}
return nRes;
}
}
cRecorderControlViewSrv::cRecorderControlViewSrv()
{
m_strTitle = adtf::util::cString("Demo Recorder Control");
m_pWidget = nullptr;
SetDefaultRunlevel(adtf::base::tADTFRunLevel::RL_StreamingGraph);
SetDescription(
"Use this UI Service to extend the ADTF System with a User Interface to control the ADTFDAT File Recorder.");
SetHelpLink("$(ADTF_QT5_DIR)/doc/html/page_demo_qt5_recorder_control_view.html");
}
QWidget* cRecorderControlViewSrv::CreateView()
{
m_pWidget = new cRecorderControlWidget(nullptr, *this);
return m_pWidget;
}
void cRecorderControlViewSrv::ReleaseView()
{
delete m_pWidget;
m_pWidget = nullptr;
}
tResult cRecorderControlViewSrv::OnIdle()
{
RETURN_IF_POINTER_NULL(m_pWidget);
if (adtf::util::cHighResTimer::GetTime() - m_tmLastUpdate < m_tmMinInterval)
{
RETURN_ERROR(ERR_NOERROR);
}
if (m_pWidget)
{
std::list<tRecorderInfo> lstInfo;
if (!m_mapRecorders.empty())
{
for (auto it : m_mapRecorders)
{
tRecorderInfo sInfo;
sInfo.eState = it.second->GetCurrentState();
it.second->GetCurrentFileName(adtf_string_intf(sInfo.strFile));
sInfo.strRecorderName = it.first.GetPtr();
lstInfo.push_back(sInfo);
}
}
m_pWidget->Update(lstInfo);
}
m_tmLastUpdate = adtf::util::cHighResTimer::GetTime();
RETURN_NOERROR;
}
tResult cRecorderControlViewSrv::ServiceEvent(
int nEventId, uint32_t ui32Param1, uint32_t ui32Param2, void* pvData, int szData)
{
if (nEventId == IService::SE_ChangeRunLevel)
{
if (ui32Param2 == adtf::ucom::IRuntime::CRLF_PostIncrementLevel ||
ui32Param2 == adtf::ucom::IRuntime::CRLF_PostDecrementLevel)
{
m_mapRecorders.clear();
adtf::ucom::object_list<adtf::services::IRecorder> lstRecorder;
adtf::services::get_recorders(lstRecorder);
int nIdx = 0;
for (auto it : lstRecorder)
{
adtf::util::cString strRecorderName;
adtf::streaming::INamedGraphObject* pNamedObject =
adtf::ucom::ucom_cast<adtf::streaming::INamedGraphObject*>(it.Get());
if (pNamedObject)
{
strRecorderName = get_named_graph_object_full_name(*pNamedObject);
}
else
{
strRecorderName = adtf::util::cString::Format("Recorder_index_%d", ++nIdx);
}
m_mapRecorders[strRecorderName] = it;
}
}
}
return adtf::ui::cQtUIService::ServiceEvent(nEventId, ui32Param1, ui32Param2, pvData, szData);
}
void cRecorderControlViewSrv::StartRecording(const QString& strRecorderName)
{
auto itRecorder = m_mapRecorders.find(adtf::util::cString(static_cast<const char*>(strRecorderName.toUtf8())));
if (itRecorder != m_mapRecorders.end())
{
itRecorder->second->Start("");
}
}
void cRecorderControlViewSrv::StopRecording(const QString& strRecorderName)
{
auto itRecorder = m_mapRecorders.find(adtf::util::cString(static_cast<const char*>(strRecorderName.toUtf8())));
if (itRecorder != m_mapRecorders.end())
{
itRecorder->second->Stop("");
}
}
void cRecorderControlViewSrv::SplitRecording(const QString& strRecorderName)
{
auto itRecorder = m_mapRecorders.find(adtf::util::cString(static_cast<const char*>(strRecorderName.toUtf8())));
if (itRecorder != m_mapRecorders.end())
{
itRecorder->second->Split("");
}
}
UI Application
demo_recorder_control_app.h
#pragma once
#include <adtf_remotesdk.h>
#include <adtf_ui.h>
#include <QTimer>
#include <QPushButton>
#include <QTextEdit>
#include <demo_rec_ctrl_view_intf.h>
class cRecorderControlWidget;
class cRecorderControlAppWindow : public QWidget, public IRecorderControlView
{
Q_OBJECT
private:
cRecorderControlWidget* m_pWidget;
tTimeStamp m_tmMinInterval = 200000;
adtf::util::cString m_strADTFControlURL;
adtf::remote::cADTFRemoteSystem* m_pSystem = nullptr;
QTimer m_oTimer;
QPushButton* m_pConnectButton;
QTextEdit* m_pURL;
public:
explicit cRecorderControlAppWindow(const adtf::util::cString& strADTFControlURL);
~cRecorderControlAppWindow();
tResult Connect(bool bWithError);
public:
void StartRecording(const QString& strRecorderName) override;
void StopRecording(const QString& strRecorderName) override;
void SplitRecording(const QString& strRecorderName) override;
public slots:
void OnTimer();
void OnConnect();
private:
std::map<adtf::util::cString, adtf::remote::rpc_object_client_ptr<adtf::remote::IRecorder>> GetAllRecorders();
bool GetRecorder(const QString& strRecorderName,
adtf::remote::rpc_object_client_ptr<adtf::remote::IRecorder>& pRecorder);
};
demo_recorder_control_app.cpp
#include "demo_recorder_control_app.h"
#include <demo_rec_ctrl_widget.h>
void show_result(QWidget* pWidget, tResult nRes)
{
LOG_RESULT(nRes);
QMessageBox::critical(
pWidget, adtf::util::cString::Format("Error %d - [%s] ", nRes.GetErrorCode().value, nRes.GetErrorString()).GetPtr(),
nRes.GetDescription());
}
tResult remote_set_run_level(QWidget* pWidget, adtf::remote::ISystem* pSystem, adtf::base::tADTFRunLevel eLevel)
{
tResult nRes = pSystem->SetRunlevel(eLevel);
if (IS_FAILED(nRes))
{
show_result(pWidget, nRes);
}
return nRes;
}
std::map<adtf::util::cString, adtf::remote::rpc_object_client_ptr<adtf::remote::IRecorder>> cRecorderControlAppWindow::GetAllRecorders()
{
std::map<adtf::util::cString, adtf::remote::rpc_object_client_ptr<adtf::remote::IRecorder>> mapResult;
if (m_pSystem)
{
adtf::util::cStringList lstRecorderIds =
m_pSystem->FindObjectsByRPCIID(adtf::ucom::get_iid<adtf::remote::IRecorder>());
for (auto it : lstRecorderIds)
{
adtf::remote::rpc_object_client_ptr<adtf::remote::IRecorder> pRecorder;
if (IS_OK(m_pSystem->GetObjectClient(it, pRecorder)))
{
mapResult[it] = pRecorder;
}
}
}
return mapResult;
}
bool cRecorderControlAppWindow::GetRecorder(const QString& strRecorderName,
adtf::remote::rpc_object_client_ptr<adtf::remote::IRecorder>& pRecorder)
{
if (m_pSystem)
{
return IS_OK(m_pSystem->GetObjectClient(static_cast<const char*>(strRecorderName.toUtf8()), pRecorder));
}
return false;
}
cRecorderControlAppWindow::cRecorderControlAppWindow(const adtf::util::cString& strADTFControlURL):
QWidget(), m_strADTFControlURL(strADTFControlURL)
{
QGroupBox* pGroupBox = new QGroupBox();
pGroupBox->setMaximumHeight(50);
QHBoxLayout* pHLayout = new QHBoxLayout();
m_pConnectButton = new QPushButton("Connect");
m_pURL = new QTextEdit(strADTFControlURL.GetPtr());
pHLayout->addWidget(m_pConnectButton);
pHLayout->addWidget(m_pURL);
pGroupBox->setLayout(pHLayout);
QVBoxLayout* pVLayout = new QVBoxLayout();
m_pWidget = new cRecorderControlWidget(nullptr, *this);
pVLayout->addWidget(pGroupBox);
pVLayout->addWidget(m_pWidget);
setLayout(pVLayout);
setWindowTitle("Demo Recorder Control App ... ");
QObject::connect(&m_oTimer, SIGNAL(timeout()), this, SLOT(OnTimer()));
QObject::connect(m_pConnectButton, SIGNAL(clicked()), this, SLOT(OnConnect()));
m_oTimer.setInterval(m_tmMinInterval / 1000);
m_oTimer.start();
}
cRecorderControlAppWindow::~cRecorderControlAppWindow()
{
m_oTimer.stop();
if (m_pSystem)
{
delete m_pSystem;
}
}
void cRecorderControlAppWindow::OnConnect()
{
Connect(true);
}
void cRecorderControlAppWindow::OnTimer()
{
std::list<tRecorderInfo> lstInfo;
bool bIsConnected = false;
if (m_pSystem)
{
bIsConnected = IS_OK(m_pSystem->Ping());
if (bIsConnected)
{
for (auto& oRecorder : GetAllRecorders())
{
tRecorderInfo sInfo;
sInfo.strRecorderName = oRecorder.first.GetPtr();
sInfo.eState = static_cast<adtf::services::IRecorder::tState>(oRecorder.second->GetCurrentState());
sInfo.strFile = oRecorder.second->GetCurrentFileName();
lstInfo.push_back(sInfo);
}
m_oTimer.setInterval(m_tmMinInterval / 1000);
}
else
{
m_oTimer.setInterval(1000);
}
}
else
{
Connect(false);
bIsConnected = IS_OK(m_pSystem->Ping());
}
setUpdatesEnabled(false);
if (bIsConnected)
{
QString strTitle = "Demo Recorder Control App ... connected to ";
strTitle.append(m_strADTFControlURL);
setWindowTitle(strTitle);
}
else
{
QString strTitle = "Demo Recorder Control App ... NOT CONNECTED TO ";
strTitle.append(m_strADTFControlURL);
setWindowTitle(strTitle);
}
m_pWidget->Update(lstInfo);
setUpdatesEnabled(true);
}
tResult cRecorderControlAppWindow::Connect(bool bWithError)
{
m_strADTFControlURL = static_cast<const char*>(m_pURL->toPlainText().toUtf8());
if (m_pSystem)
{
if (m_pSystem->GetHostURL().IsEqual(m_strADTFControlURL))
{
tResult nRes = m_pSystem->Ping();
if (nRes.IsFailed())
{
if (bWithError)
{
show_result(this, nRes);
}
return nRes;
}
}
else
{
delete m_pSystem;
m_pSystem = nullptr;
}
}
m_pSystem = new adtf::remote::cADTFRemoteSystem(m_strADTFControlURL);
if (m_pSystem)
{
tResult nRes = m_pSystem->Ping();
if (nRes.IsFailed())
{
if (bWithError)
{
show_result(this, nRes);
}
return nRes;
}
}
RETURN_NOERROR;
}
void cRecorderControlAppWindow::StartRecording(const QString& strRecorderName)
{
adtf::remote::rpc_object_client_ptr<adtf::remote::IRecorder> pRecorder;
if (GetRecorder(strRecorderName, pRecorder))
{
pRecorder->Start("");
}
}
void cRecorderControlAppWindow::StopRecording(const QString& strRecorderName)
{
adtf::remote::rpc_object_client_ptr<adtf::remote::IRecorder> pRecorder;
if (GetRecorder(strRecorderName, pRecorder))
{
pRecorder->Stop("");
}
}
void cRecorderControlAppWindow::SplitRecording(const QString& strRecorderName)
{
adtf::remote::rpc_object_client_ptr<adtf::remote::IRecorder> pRecorder;
if (GetRecorder(strRecorderName, pRecorder))
{
pRecorder->Split("");
}
}
int main(int argc, char* argv[])
{
adtf::util::cCommandLine oCommand(argc, (const char**) argv);
adtf::util::cString strURL = oCommand.GetProperty("control-url");
if (strURL.IsEmpty())
{
strURL = adtf::remote::cADTFRemoteSystem::DEFAULT_HOST_URL;
}
QApplication app(argc, argv);
cRecorderControlAppWindow oMyApp(strURL);
oMyApp.show();
return app.exec();
}