2643 lines
92 KiB
C++
2643 lines
92 KiB
C++
![]() |
/*=============================================================================
|
|||
|
Copyright (C) 2012-2019 Allied Vision Technologies. All Rights Reserved.
|
|||
|
|
|||
|
Redistribution of this file, in original or modified form, without
|
|||
|
prior written consent of Allied Vision Technologies is prohibited.
|
|||
|
|
|||
|
-------------------------------------------------------------------------------
|
|||
|
|
|||
|
File: ControllerTreeWindow.cpp
|
|||
|
|
|||
|
Description: All about features control tree
|
|||
|
|
|||
|
-------------------------------------------------------------------------------
|
|||
|
|
|||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
|
|||
|
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF TITLE,
|
|||
|
NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|||
|
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
|||
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|||
|
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
|||
|
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
|
|||
|
=============================================================================*/
|
|||
|
|
|||
|
/* define this to use std::numeric_limits */
|
|||
|
#define NOMINMAX
|
|||
|
|
|||
|
#include <limits>
|
|||
|
#include <iostream>
|
|||
|
|
|||
|
#include <QCheckBox>
|
|||
|
#include <QItemDelegate>
|
|||
|
#include <QLabel>
|
|||
|
#include <QLineEdit>
|
|||
|
#include <QPushButton>
|
|||
|
#include <QStandardItemModel>
|
|||
|
#include <QtConcurrentRun>
|
|||
|
|
|||
|
#include "../ExternLib/qwt/qwt_slider.h"
|
|||
|
#include "../ExternLib/qwt/qwt_scale_engine.h"
|
|||
|
|
|||
|
#include "ControllerTreeWindow.h"
|
|||
|
#include "ExComboBox.h"
|
|||
|
#include "Helper.h"
|
|||
|
#include "HexEditor/HexMainWindow.h"
|
|||
|
#include "IntSpinBox.h"
|
|||
|
#include "MultiCompleter.h"
|
|||
|
#include "SortFilterProxyModel.h"
|
|||
|
#include "SplashScreen.h"
|
|||
|
|
|||
|
#include <FeatureObserver.h>
|
|||
|
|
|||
|
using AVT::VmbAPI::StringVector;
|
|||
|
|
|||
|
#ifdef WIN32
|
|||
|
#include <windows.h>
|
|||
|
#else
|
|||
|
#include <unistd.h>
|
|||
|
#include <cstring>
|
|||
|
#endif
|
|||
|
|
|||
|
/* controlling row/height size in tree */
|
|||
|
class ItemDelegate: public QItemDelegate
|
|||
|
{
|
|||
|
public:
|
|||
|
ItemDelegate() {}
|
|||
|
QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
|||
|
{
|
|||
|
QSize s = QItemDelegate::sizeHint( option, index );
|
|||
|
s.setHeight( row_height );
|
|||
|
return s;
|
|||
|
}
|
|||
|
|
|||
|
void setRowHeight( const unsigned char height )
|
|||
|
{
|
|||
|
row_height = height;
|
|||
|
}
|
|||
|
|
|||
|
protected:
|
|||
|
unsigned char row_height;
|
|||
|
};
|
|||
|
|
|||
|
ControllerTreeWindow::ControllerTreeWindow ( QString sID, QWidget *parent, bool bAutoAdjustPacketSize, CameraPtr pCam ): QTreeView ( parent ), m_TreeDelegate ( NULL ),
|
|||
|
m_HBooleanLayout ( NULL ), m_HBooleanLayout2 ( NULL ), m_BooleanWidget ( NULL ), m_CheckBox_Bool ( NULL ),
|
|||
|
m_HEditLayout ( NULL ), m_HEditLayout2 ( NULL ), m_EditWidget ( NULL ), m_TextEdit_String ( NULL ),
|
|||
|
m_HButtonLayout ( NULL ), m_HButtonLayout2 ( NULL ), m_ButtonWidget ( NULL ), m_CmdButton ( NULL ),
|
|||
|
m_HComboLayout ( NULL ), m_HComboLayout2 ( NULL ), m_ComboWidget ( NULL ), m_EnumComboBox ( NULL ),
|
|||
|
m_HLineEditLayout ( NULL ), m_HLineEditLayout2 ( NULL ), m_LineEditWidget ( NULL ), m_LineEdit ( NULL ), m_HexLabel ( NULL ),
|
|||
|
m_HSpinSliderLayout_Int ( NULL ), m_HSpinSliderLayout_Int2 ( NULL ), m_IntSpinSliderWidget ( NULL ), m_SpinBox_Int ( NULL ), m_Slider_Int ( NULL ),
|
|||
|
m_HSpinSliderLayout_Float ( NULL ), m_HSliderEditLayout_Float2 ( NULL ), m_FloatSliderEditWidget ( NULL ), m_EditBox_Float ( NULL ), m_Slider_Float ( NULL ),
|
|||
|
m_HexWindow ( NULL ), m_LogSliderWidget ( NULL ), m_FeaturesPollingTimer ( NULL ),
|
|||
|
m_nSliderStep ( 0 ), m_dMinimum ( 0 ), m_dMaximum ( 0 ), m_dIncrement ( 0 ), m_nIntSliderOldValue ( 0 ), m_bIsGigE ( false ), m_bIsTimeout ( false ),
|
|||
|
m_pFeatureObs( new FeatureObserver(pCam)), m_ListTreeError ( VmbErrorOther ), m_bIsTooltipOn ( true ), m_bIsJobDone ( true ), m_bIsMousePressed ( false ), m_bIsBusy ( false )
|
|||
|
{
|
|||
|
m_pCam = pCam;
|
|||
|
m_sCameraID = sID;
|
|||
|
setupTree();
|
|||
|
connect((FeatureObserver*)(SP_ACCESS(m_pFeatureObs)), SIGNAL(setEventMessage(const QStringList &)), this, SLOT(onSetEventMsg(const QStringList &)));
|
|||
|
this->setStyleSheet(QString::fromUtf8("QToolTip {""}"));
|
|||
|
|
|||
|
m_Level.append(m_Level0Map);
|
|||
|
m_Level.append(m_Level1Map);
|
|||
|
m_Level.append(m_Level2Map);
|
|||
|
m_Level.append(m_Level3Map);
|
|||
|
m_Level.append(m_Level4Map);
|
|||
|
m_Level.append(m_Level5Map);
|
|||
|
m_Level.append(m_Level6Map);
|
|||
|
m_Level.append(m_Level7Map);
|
|||
|
m_Level.append(m_Level8Map);
|
|||
|
m_Level.append(m_Level9Map);
|
|||
|
|
|||
|
QStringList CompletionList;
|
|||
|
|
|||
|
VmbError_t error = m_pCam->GetFeatures(m_featPtrVec);
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
for( unsigned int i=0; i < m_featPtrVec.size(); i++ )
|
|||
|
{
|
|||
|
VmbFeatureVisibilityType visibilityType;
|
|||
|
m_featPtrVec.at(i)->GetVisibility(visibilityType);
|
|||
|
|
|||
|
std::string sDisplayName;
|
|||
|
m_featPtrVec.at(i)->GetDisplayName(sDisplayName);
|
|||
|
|
|||
|
/* Save DisplayName for filter completer */
|
|||
|
CompletionList << QString::fromStdString(sDisplayName);
|
|||
|
|
|||
|
if((VmbFeatureVisibilityBeginner == visibilityType) || (VmbFeatureVisibilityExpert == visibilityType) || (VmbFeatureVisibilityGuru == visibilityType))
|
|||
|
{
|
|||
|
sortCategoryAndAttribute(m_featPtrVec.at(i), m_ModelGuru);
|
|||
|
mapInformation(QString::fromStdString(sDisplayName), m_featPtrVec.at(i));
|
|||
|
m_featPtrMap[QString::fromStdString(sDisplayName)] = m_featPtrVec.at(i);
|
|||
|
std::string sFeatureName;
|
|||
|
m_featPtrVec.at(i)->GetName(sFeatureName);
|
|||
|
m_DisplayFeatureNameMap[QString::fromStdString(sDisplayName)] = QString::fromStdString(sFeatureName);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* Features string completer for filter */
|
|||
|
m_StringCompleter = new MultiCompleter(CompletionList, this);
|
|||
|
m_StringCompleter->setCaseSensitivity(Qt::CaseInsensitive);
|
|||
|
|
|||
|
m_ListTreeError = error;
|
|||
|
m_Model = m_ModelGuru;
|
|||
|
|
|||
|
m_ProxyModel = new SortFilterProxyModel(this);
|
|||
|
m_ProxyModel->setDynamicSortFilter(true);
|
|||
|
setModel(m_ProxyModel);
|
|||
|
m_ProxyModel->setSourceModel(m_Model);
|
|||
|
|
|||
|
resizeColumnToContents(0);
|
|||
|
/* used to set the maximum height of the row in tree */
|
|||
|
m_TreeDelegate = new ItemDelegate();
|
|||
|
m_TreeDelegate->setRowHeight(20);
|
|||
|
setItemDelegate(m_TreeDelegate);
|
|||
|
|
|||
|
connect( this, SIGNAL( expanded(const QModelIndex &) ), this, SLOT( expand(const QModelIndex &) ) );
|
|||
|
connect( this, SIGNAL( expanded(const QModelIndex &) ), this, SLOT( updateColWidth()) );
|
|||
|
connect( this, SIGNAL( collapsed(const QModelIndex &) ), this, SLOT( collapse(const QModelIndex &) ) );
|
|||
|
connect((FeatureObserver*)(SP_ACCESS(m_pFeatureObs)), SIGNAL(setChangedFeature(const QString &, const QString &, const bool &)),
|
|||
|
this, SLOT(onSetChangedFeature(const QString &, const QString &, const bool &)));
|
|||
|
connect( this, SIGNAL( clicked(const QModelIndex &) ), this, SLOT( onClicked(const QModelIndex &) ) );
|
|||
|
|
|||
|
sortByColumn(0, Qt::AscendingOrder);
|
|||
|
setSelectionMode(QAbstractItemView::SingleSelection);
|
|||
|
|
|||
|
/* Auto Adjust Packet Size */
|
|||
|
m_bAutoAdjustPacketSize = bAutoAdjustPacketSize;
|
|||
|
if(m_bIsGigE && m_bAutoAdjustPacketSize)
|
|||
|
{
|
|||
|
FeaturePtr FeatPtr = getFeaturePtr("GVSP Adjust Packet Size");
|
|||
|
if( NULL == FeatPtr)
|
|||
|
return;
|
|||
|
|
|||
|
error = FeatPtr->RunCommand();
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
QTimer::singleShot(7000, this, SLOT(setAdjustPacketSizeTimeout()));
|
|||
|
|
|||
|
bool bIsDone = false;
|
|||
|
while((!bIsDone) && (VmbErrorSuccess == error))
|
|||
|
{
|
|||
|
QCoreApplication::processEvents();
|
|||
|
if(m_bIsTimeout)
|
|||
|
{
|
|||
|
m_ListTreeError = 7000; //7000: "Timeout"
|
|||
|
return;
|
|||
|
}
|
|||
|
error = FeatPtr->IsCommandDone(bIsDone);
|
|||
|
}
|
|||
|
|
|||
|
m_ListTreeError = error;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
m_FeaturesPollingTimer = new QTimer ( this );
|
|||
|
connect (m_FeaturesPollingTimer, SIGNAL(timeout()), this, SLOT(runPollingFeaturesValue()));
|
|||
|
m_FeaturesPollingTimer->start(500);
|
|||
|
}
|
|||
|
|
|||
|
ControllerTreeWindow::~ControllerTreeWindow()
|
|||
|
{
|
|||
|
if (VmbErrorSuccess == getTreeStatus())
|
|||
|
m_FeaturesPollingTimer->stop();
|
|||
|
resetControl();
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::showEvent(QShowEvent *event)
|
|||
|
{
|
|||
|
updateRegisterFeature();
|
|||
|
if (m_sCurrentSelectedFeature != "")
|
|||
|
{
|
|||
|
FeaturePtr pFeature = getFeaturePtr( m_sCurrentSelectedFeature );
|
|||
|
/* make sure to update the info */
|
|||
|
mapInformation(m_sCurrentSelectedFeature, pFeature);
|
|||
|
showIt(this->currentIndex(), "Description");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::hideEvent(QHideEvent *event)
|
|||
|
{
|
|||
|
updateUnRegisterFeature();
|
|||
|
this->setToolTip("");
|
|||
|
emit setDescription("");
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void ControllerTreeWindow::saveFeaturesToTextFile ( const QString &sDestPathAndFileName )
|
|||
|
{
|
|||
|
QFile file(sDestPathAndFileName);
|
|||
|
file.open(QIODevice::WriteOnly | QIODevice::Text);
|
|||
|
QTextStream outputstream (&file);
|
|||
|
|
|||
|
QMap<QString, FeaturePtr>::iterator i;
|
|||
|
|
|||
|
for (i = m_featPtrMap.begin(); i != m_featPtrMap.end(); ++i)
|
|||
|
{
|
|||
|
QString sFeatureDisplayName = i.key();
|
|||
|
outputstream << sFeatureDisplayName << " = " << getFeatureValue ( i.value()) << "\n";
|
|||
|
}
|
|||
|
|
|||
|
file.close();
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::setAdjustPacketSizeTimeout()
|
|||
|
{
|
|||
|
m_bIsTimeout = true;
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::runPollingFeaturesValue()
|
|||
|
{
|
|||
|
// possible improvement: Check if the method is already running here (instead of in
|
|||
|
// pollingFeaturesValue via a mutex) to prevent unnecessary spawning of a thread
|
|||
|
QtConcurrent::run(this, &ControllerTreeWindow::pollingFeaturesValue);
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::pollingFeaturesValue()
|
|||
|
{
|
|||
|
// Only run if no other thred is currently polling camera features via this method
|
|||
|
if (m_FeaturesPollingMutex.tryLock())
|
|||
|
{
|
|||
|
for (int i = 0; i < m_FeaturesPollingName.size(); i++)
|
|||
|
{
|
|||
|
FeaturePtr FeatPtr = getFeaturePtr(m_FeaturesPollingName.at(i));
|
|||
|
|
|||
|
VmbUint32_t nPollValue = 0;
|
|||
|
if (VmbErrorSuccess == FeatPtr->GetPollingTime( nPollValue ))
|
|||
|
{
|
|||
|
if(0 == nPollValue)
|
|||
|
{
|
|||
|
updateExpandedTreeValue(FeatPtr, m_FeaturesPollingName.at(i));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
m_FeaturesPollingMutex.unlock();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
bool ControllerTreeWindow::isGigE() const
|
|||
|
{
|
|||
|
return (m_bIsGigE && m_bAutoAdjustPacketSize);
|
|||
|
}
|
|||
|
|
|||
|
VmbError_t ControllerTreeWindow::getTreeStatus() const
|
|||
|
{
|
|||
|
return m_ListTreeError;
|
|||
|
}
|
|||
|
|
|||
|
MultiCompleter *ControllerTreeWindow::getListCompleter() const
|
|||
|
{
|
|||
|
return m_StringCompleter;
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::showTooltip ( const bool bIsChecked )
|
|||
|
{
|
|||
|
m_bIsTooltipOn = bIsChecked;
|
|||
|
setToolTip( m_bIsTooltipOn ? m_sTooltip : "" );
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::mapInformation(const QString sName, const FeaturePtr &featPtr)
|
|||
|
{
|
|||
|
if( NULL == featPtr)
|
|||
|
return;
|
|||
|
|
|||
|
std::string sDescription;
|
|||
|
featPtr->GetDescription(sDescription);
|
|||
|
|
|||
|
QString sQDescription = "<br/>";
|
|||
|
sQDescription.append(QString::fromUtf8(sDescription.c_str()));
|
|||
|
sQDescription = sQDescription.replace(".", ".<br/>");
|
|||
|
|
|||
|
QString sInfo = getFeatureInformation(featPtr);
|
|||
|
if(sInfo.isEmpty())
|
|||
|
{
|
|||
|
m_DescriptonMap[sName] = sQDescription;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if(sDescription.empty())
|
|||
|
m_DescriptonMap[sName] = "<b>DESCRIPTION:</b> N/A<br/>" + sInfo;
|
|||
|
else
|
|||
|
m_DescriptonMap[sName] = "<b>DESCRIPTION:</b>" + sQDescription.append("<br/>").append(sInfo);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
QString ControllerTreeWindow::getFeatureInformation(const FeaturePtr &featPtr)
|
|||
|
{
|
|||
|
QString sInformation;
|
|||
|
VmbInt64_t nMin = 0, nMax = 0, nInc = 0;
|
|||
|
double dMin = 0, dMax = 0, dInc = 0;
|
|||
|
|
|||
|
std::string sFeatureName;
|
|||
|
featPtr->GetName(sFeatureName);
|
|||
|
sInformation.append("<b>FEATURE NAME:</b> ").append(QString::fromStdString(sFeatureName)).append("<br/>");
|
|||
|
|
|||
|
VmbFeatureVisibilityType visibility = VmbFeatureVisibilityUnknown;
|
|||
|
featPtr->GetVisibility(visibility);
|
|||
|
sInformation.append("<b>VISIBILITY:</b> ");
|
|||
|
switch(visibility)
|
|||
|
{
|
|||
|
case VmbFeatureVisibilityUnknown: sInformation.append("UNKNOWN<br/>"); break;
|
|||
|
case VmbFeatureVisibilityBeginner: sInformation.append("BEGINNER<br/>"); break;
|
|||
|
case VmbFeatureVisibilityExpert: sInformation.append("EXPERT<br/>"); break;
|
|||
|
case VmbFeatureVisibilityGuru: sInformation.append("GURU<br/>"); break;
|
|||
|
case VmbFeatureVisibilityInvisible: sInformation.append("INVISIBLE<br/>"); break;
|
|||
|
default: sInformation.append("N/A<br/>"); break;
|
|||
|
}
|
|||
|
|
|||
|
/* get feature type and type-specific info */
|
|||
|
VmbFeatureDataType dataType = VmbFeatureDataUnknown;
|
|||
|
VmbFeatureFlagsType flags;
|
|||
|
VmbError_t error = featPtr->GetDataType(dataType);
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
switch(dataType)
|
|||
|
{
|
|||
|
case VmbFeatureDataInt:
|
|||
|
{
|
|||
|
/* only show range and increment for integer features that might change */
|
|||
|
if ((VmbErrorSuccess == featPtr->GetFlags(flags)) && ((((VmbFeatureFlagsVolatile|VmbFeatureFlagsWrite|VmbFeatureFlagsModifyWrite) & flags)!=0)||(VmbFeatureFlagsRead == flags)))
|
|||
|
{
|
|||
|
if( VmbErrorSuccess == featPtr->GetRange(nMin, nMax))
|
|||
|
sInformation.append("<b>TYPE:</b> Integer<br/><b>MINIMUM:</b> ").append(QString::number(nMin)).append("<br/><b>MAXIMUM:</b> ").append(QString::number(nMax).append("<br/>"));
|
|||
|
if( (VmbErrorSuccess == featPtr->GetIncrement(nInc)) && (1!=nInc))
|
|||
|
sInformation.append("<b>INTERVAL:</b> ").append(QString::number(nInc)).append("<br/>");
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
case VmbFeatureDataFloat:
|
|||
|
{
|
|||
|
/* only show range and increment for float features that might change */
|
|||
|
VmbFeatureFlagsType flags;
|
|||
|
if ((VmbErrorSuccess == featPtr->GetFlags(flags)) && ((((VmbFeatureFlagsVolatile|VmbFeatureFlagsWrite|VmbFeatureFlagsModifyWrite) & flags)!=0)||(VmbFeatureFlagsRead == flags)))
|
|||
|
{
|
|||
|
if( VmbErrorSuccess == featPtr->GetRange(dMin, dMax))
|
|||
|
sInformation.append("<b>TYPE:</b> Float<br/><b>MINIMUM:</b> ").append(QString::number(dMin,'g',9)).append("<br/><b>MAXIMUM:</b> ").append(QString::number(dMax,'g',12)).append("<br/>");
|
|||
|
|
|||
|
if( VmbErrorSuccess == featPtr->GetIncrement(dInc))
|
|||
|
sInformation.append("<b>INTERVAL:</b> ").append(QString::number(dInc,'f',10)).append("<br/>");
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
case VmbFeatureDataEnum: sInformation.append("<b>TYPE:</b> Enumeration<br/>"); break;
|
|||
|
case VmbFeatureDataString: sInformation.append("<b>TYPE:</b> String<br/>"); break;
|
|||
|
case VmbFeatureDataBool: sInformation.append("<b>TYPE:</b> Boolean<br/>"); break;
|
|||
|
case VmbFeatureDataCommand: sInformation.append("<b>TYPE:</b> Command<br/>"); break;
|
|||
|
case VmbFeatureDataRaw: sInformation.append("<b>TYPE:</b> Raw<br/>"); break;
|
|||
|
default: break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
std::string sCategory;
|
|||
|
featPtr->GetCategory(sCategory);
|
|||
|
sInformation.append("<b>CATEGORY:</b> ").append(QString::fromStdString(sCategory)).append("<br/>");
|
|||
|
|
|||
|
FeaturePtrVector featPtrVec;
|
|||
|
|
|||
|
sInformation.append("<br/><b>AFFECTED FEATURE(S):</b> ");
|
|||
|
featPtr->GetAffectedFeatures(featPtrVec);
|
|||
|
for(unsigned int i=0; i < featPtrVec.size(); i++)
|
|||
|
{
|
|||
|
std::string sName;
|
|||
|
featPtrVec.at(i)->GetName(sName);
|
|||
|
|
|||
|
if(0 == i)
|
|||
|
sInformation.append("<br/>");
|
|||
|
|
|||
|
sInformation.append(QString::fromStdString(sName));
|
|||
|
if(i+1 != featPtrVec.size())
|
|||
|
{
|
|||
|
sInformation.append(", ");
|
|||
|
if(0 == ((i+1) % 4) && (i != 0) )
|
|||
|
sInformation.append("<br/>");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if(0 == featPtrVec.size())
|
|||
|
sInformation.append("N/A");
|
|||
|
|
|||
|
sInformation.append("<br/>");
|
|||
|
return sInformation;
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::onClicked ( const QModelIndex & current )
|
|||
|
{
|
|||
|
setCursor(Qt::ArrowCursor);
|
|||
|
scrollTo(current, QAbstractItemView::EnsureVisible);
|
|||
|
|
|||
|
if( m_bIsBusy )
|
|||
|
return;
|
|||
|
|
|||
|
m_bIsBusy = true;
|
|||
|
|
|||
|
if( !current.isValid())
|
|||
|
{
|
|||
|
m_bIsBusy = false;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
/* check what feature is that */
|
|||
|
FeaturePtr FeatPtr;
|
|||
|
QString sFeature = getFeatureName(current);
|
|||
|
FeatPtr = getFeaturePtr(sFeature);
|
|||
|
|
|||
|
/* make sure to update the info */
|
|||
|
mapInformation(sFeature, FeatPtr);
|
|||
|
showIt(current, "Description");
|
|||
|
|
|||
|
if (( NULL == FeatPtr) || !isFeatureWritable(sFeature) || 0 == current.column())
|
|||
|
{
|
|||
|
m_bIsBusy = false;
|
|||
|
m_sCurrentSelectedFeature = sFeature;
|
|||
|
resetControl();
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
VmbFeatureDataType dataType = VmbFeatureDataUnknown;
|
|||
|
if(VmbErrorSuccess == FeatPtr->GetDataType(dataType))
|
|||
|
{
|
|||
|
switch(dataType)
|
|||
|
{
|
|||
|
case VmbFeatureDataInt: createIntSliderSpinBox(current); break;
|
|||
|
case VmbFeatureDataFloat: createFloatSliderEditBox(current); break;
|
|||
|
case VmbFeatureDataEnum: createEnumComboBox(current); break;
|
|||
|
case VmbFeatureDataString: createStringEditBox(current); break;
|
|||
|
case VmbFeatureDataBool: createBooleanCheckBox(current); break;
|
|||
|
case VmbFeatureDataCommand: createCommandButton(current); break;
|
|||
|
case VmbFeatureDataRaw: createHexEditor(current); break;
|
|||
|
default: break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
m_bIsBusy = false;
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::collapse ( const QModelIndex & index )
|
|||
|
{
|
|||
|
QVariant varData = index.data();
|
|||
|
int nrow = 0;
|
|||
|
QVariant varChild = 1;
|
|||
|
|
|||
|
while(0 != varChild.type())
|
|||
|
{
|
|||
|
QModelIndex child = index.child(nrow++, 0);
|
|||
|
|
|||
|
if (0 == child.data().type())
|
|||
|
break;
|
|||
|
|
|||
|
varChild = child.data();
|
|||
|
|
|||
|
if ( !isEventFeature(getFeaturePtr( varChild.toString() )))
|
|||
|
{
|
|||
|
unregisterFeatureObserver(varChild.toString());
|
|||
|
|
|||
|
for (int i = 0; i < m_FeaturesPollingName.size(); i++)
|
|||
|
{
|
|||
|
if (m_FeaturesPollingName.at(i) == varChild.toString())
|
|||
|
{
|
|||
|
m_FeaturesPollingName.removeAt(i);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
collapse(child);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::expand( const QModelIndex & index )
|
|||
|
{
|
|||
|
QVariant varData = index.data();
|
|||
|
int nrow = 0;
|
|||
|
QVariant varChild = 1;
|
|||
|
|
|||
|
while(0 != varChild.type())
|
|||
|
{
|
|||
|
QModelIndex child = index.child(nrow++, 0);
|
|||
|
if (0 == child.data().type())
|
|||
|
break;
|
|||
|
varChild = child.data();
|
|||
|
|
|||
|
if(isExpanded(child))
|
|||
|
expand(child);
|
|||
|
|
|||
|
FeaturePtr pFeature = getFeaturePtr( varChild.toString() );
|
|||
|
|
|||
|
if( !isEventFeature( pFeature ))
|
|||
|
{
|
|||
|
if ( !SP_ISNULL( pFeature ))
|
|||
|
{
|
|||
|
VmbFeatureFlagsType flags = (VmbFeatureFlagsType)0UL;
|
|||
|
VmbUint32_t pollingTime = 0;
|
|||
|
if ( VmbErrorSuccess == pFeature->GetFlags( flags )
|
|||
|
&& VmbFeatureFlagsVolatile & flags
|
|||
|
&& VmbErrorSuccess == pFeature->GetPollingTime( pollingTime )
|
|||
|
&& 0 == pollingTime )
|
|||
|
m_FeaturesPollingName.push_back( varChild.toString() );
|
|||
|
else
|
|||
|
registerFeatureObserver( varChild.toString() );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::updateColWidth()
|
|||
|
{
|
|||
|
resizeColumnToContents(0);
|
|||
|
resizeColumnToContents(1);
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::updateRegisterFeature()
|
|||
|
{
|
|||
|
for(int i=0; i < model()->rowCount(); i++)
|
|||
|
{
|
|||
|
if (isExpanded(model()->index(i, 0)))
|
|||
|
{
|
|||
|
expand(model()->index(i, 0));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
updateColWidth();
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::updateUnRegisterFeature()
|
|||
|
{
|
|||
|
for(int i=0; i < model()->rowCount(); i++)
|
|||
|
{
|
|||
|
collapse(model()->index(i, 0));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
bool ControllerTreeWindow::isEventFeature( const FeaturePtr pFeature ) const
|
|||
|
{
|
|||
|
std::string sCategory;
|
|||
|
if ( !SP_ISNULL( pFeature )
|
|||
|
&& VmbErrorSuccess == SP_ACCESS( pFeature )->GetCategory( sCategory )
|
|||
|
&& std::strstr( sCategory.c_str(), "/EventID" ))
|
|||
|
{
|
|||
|
return true;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::setupTree()
|
|||
|
{
|
|||
|
m_ModelGuru = new QStandardItemModel();
|
|||
|
m_Model = new QStandardItemModel();
|
|||
|
QStringList sHeader;
|
|||
|
sHeader << tr("Feature ") << tr("Value ");
|
|||
|
m_Model->setHorizontalHeaderLabels( sHeader );
|
|||
|
m_ModelGuru->setHorizontalHeaderLabels( sHeader );
|
|||
|
}
|
|||
|
|
|||
|
bool ControllerTreeWindow::findCategory ( const QMap <QString, QString>& map, const QString& sName ) const
|
|||
|
{
|
|||
|
QMap<QString, QString>::const_iterator itr = map.find(sName);
|
|||
|
while (itr != map.constEnd())
|
|||
|
{
|
|||
|
if(0 == itr.key().compare(sName))
|
|||
|
{
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
++itr;
|
|||
|
}
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::sortCategoryAndAttribute ( const FeaturePtr &featPtr, QStandardItemModel *Model )
|
|||
|
{
|
|||
|
QFont categoryFont;
|
|||
|
categoryFont.setBold(true);
|
|||
|
|
|||
|
QList<QStandardItem *> items;
|
|||
|
QList<QStandardItem *> pParent;
|
|||
|
QString sLastNode;
|
|||
|
bool bHasLastNode = false;
|
|||
|
int nLevel = 0;
|
|||
|
|
|||
|
std::string sCategory, sFeatureName;
|
|||
|
QString sFeatureValue;
|
|||
|
bool bIsWritable = false;
|
|||
|
VmbFeatureVisibilityType visibilityType;
|
|||
|
VmbError_t error;
|
|||
|
|
|||
|
error = featPtr->GetDisplayName(sFeatureName);
|
|||
|
|
|||
|
if( VmbErrorSuccess == featPtr->GetCategory(sCategory) &&
|
|||
|
VmbErrorSuccess == error )
|
|||
|
{
|
|||
|
/* TODO check return value */
|
|||
|
sFeatureValue = getFeatureValue(featPtr);
|
|||
|
error = featPtr->IsWritable(bIsWritable);
|
|||
|
featPtr->GetVisibility(visibilityType);
|
|||
|
|
|||
|
/* is it a GigE? : temporarily use to handle floating gain */
|
|||
|
if(0 == sCategory.compare("/GigE"))
|
|||
|
{
|
|||
|
m_bIsGigE = true;
|
|||
|
}
|
|||
|
|
|||
|
/* Feature directly in root category */
|
|||
|
if ( 0 == sCategory.length() )
|
|||
|
{
|
|||
|
sCategory = "/";
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
QString sPath = QString::fromStdString(sCategory);
|
|||
|
|
|||
|
int nCount = sPath.count('/');
|
|||
|
|
|||
|
while((nLevel < nCount))
|
|||
|
{
|
|||
|
nLevel++;
|
|||
|
QString sPart = sPath.section('/', nLevel, nLevel);
|
|||
|
/* Feature directly in root category */
|
|||
|
if ( 0 == sPart.length() )
|
|||
|
{
|
|||
|
sPart = "/";
|
|||
|
}
|
|||
|
bool bNodeExists = false;
|
|||
|
if( 0 < sPart.length())
|
|||
|
{
|
|||
|
/* check if category in level already available */
|
|||
|
if(!findCategory ( m_Level.at(nLevel-1), sPart ))
|
|||
|
{
|
|||
|
bNodeExists = false;
|
|||
|
switch(nLevel-1)
|
|||
|
{
|
|||
|
case 0: m_Level0Map[sPart] = "true"; /* TOP LEVEL */
|
|||
|
m_Level[0] = m_Level0Map;
|
|||
|
break;
|
|||
|
case 1:m_Level1Map[sPart] = "true";
|
|||
|
m_Level[1] = m_Level1Map;
|
|||
|
break;
|
|||
|
case 2:m_Level2Map[sPart] = "true";
|
|||
|
m_Level[2] = m_Level2Map;
|
|||
|
break;
|
|||
|
case 3:m_Level3Map[sPart] = "true";
|
|||
|
m_Level[3] = m_Level3Map;
|
|||
|
break;
|
|||
|
case 4:m_Level4Map[sPart] = "true";
|
|||
|
m_Level[4] = m_Level4Map;
|
|||
|
break;
|
|||
|
case 5:m_Level5Map[sPart] = "true";
|
|||
|
m_Level[5] = m_Level5Map;
|
|||
|
break;
|
|||
|
case 6:m_Level6Map[sPart] = "true";
|
|||
|
m_Level[6] = m_Level6Map;
|
|||
|
break;
|
|||
|
case 7:m_Level7Map[sPart] = "true";
|
|||
|
m_Level[7] = m_Level7Map;
|
|||
|
break;
|
|||
|
case 8:m_Level8Map[sPart] = "true";
|
|||
|
m_Level[8] = m_Level8Map;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
bNodeExists = true;
|
|||
|
}
|
|||
|
|
|||
|
/* if category/feature not available in tree yet, then fill it */
|
|||
|
if( !bNodeExists )
|
|||
|
{
|
|||
|
QList<QStandardItem *> currentItem;
|
|||
|
|
|||
|
currentItem << new QStandardItem(sPart) << new QStandardItem("");
|
|||
|
currentItem.at(0)->setEditable(false);
|
|||
|
currentItem.at(1)->setEditable(false);
|
|||
|
|
|||
|
if(bHasLastNode)
|
|||
|
{
|
|||
|
/* get the pointer of list items */
|
|||
|
items = Model->findItems(sLastNode, Qt::MatchRecursive);
|
|||
|
if(0 != items.size())
|
|||
|
{
|
|||
|
/* find the right parent level, and add the attribute item there*/
|
|||
|
QString sGrandParent = sPath.section('/', nLevel-1, nLevel-1);
|
|||
|
items.at(getGrandParentLevel(items, sGrandParent))->appendRow(currentItem);
|
|||
|
sLastNode = sPart;
|
|||
|
continue;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if(pParent.isEmpty())
|
|||
|
{
|
|||
|
pParent << new QStandardItem(sPart) << new QStandardItem("");
|
|||
|
pParent.at(0)->setFont(categoryFont);
|
|||
|
pParent.at(0)->setEditable(false);
|
|||
|
pParent.at(1)->setEditable(false);
|
|||
|
|
|||
|
Model->appendRow(pParent);
|
|||
|
|
|||
|
sLastNode = sPart;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
/* use the last node as parent if available */
|
|||
|
items = Model->findItems(sLastNode, Qt::MatchRecursive);
|
|||
|
if(0 != items.size())
|
|||
|
{
|
|||
|
/* find the right parent level, and add the attribute item there*/
|
|||
|
QString sGrandParent = sPath.section('/', nLevel-1, nLevel-1);
|
|||
|
items.at(getGrandParentLevel(items, sGrandParent))->appendRow(currentItem);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pParent.at(0)->appendRow(currentItem);
|
|||
|
}
|
|||
|
}
|
|||
|
/* if already available use it as parent node */
|
|||
|
else
|
|||
|
{
|
|||
|
bHasLastNode = true;
|
|||
|
}
|
|||
|
|
|||
|
sLastNode = sPart;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* get the pointer of list items */
|
|||
|
items = Model->findItems(sLastNode, Qt::MatchWrap|Qt::MatchRecursive);
|
|||
|
|
|||
|
if(0 != items.size() && (VmbFeatureVisibilityInvisible != visibilityType))
|
|||
|
{
|
|||
|
QList<QStandardItem *> attributeItems;
|
|||
|
|
|||
|
std::string sStdName;
|
|||
|
featPtr->GetName(sStdName);
|
|||
|
QString sName = QString::fromStdString(sStdName);
|
|||
|
std::string sRepresentation;
|
|||
|
featPtr->GetRepresentation(sRepresentation);
|
|||
|
|
|||
|
if( Helper::needsIPv4Format(sName, sRepresentation))
|
|||
|
{
|
|||
|
sFeatureValue = Helper::displayValueToIPv4(sFeatureValue);
|
|||
|
}
|
|||
|
|
|||
|
attributeItems << new QStandardItem(QString::fromStdString(sFeatureName)) << new QStandardItem(sFeatureValue);
|
|||
|
|
|||
|
attributeItems.at(0)->setEditable(false);
|
|||
|
attributeItems.at(1)->setEditable(false);
|
|||
|
|
|||
|
bIsWritable ? attributeItems.at(0)->setForeground(QColor(0,128, 0))/* green */ : attributeItems.at(0)->setForeground(QColor(135,135, 135)) /* grey */;
|
|||
|
|
|||
|
/* find the right parent level, and add the attribute item there*/
|
|||
|
QString sGrandParent = sPath.section('/', nCount-1, nCount-1);
|
|||
|
items.at(getGrandParentLevel(items, sGrandParent))->appendRow(attributeItems);
|
|||
|
|
|||
|
/* register Events */
|
|||
|
if( isEventFeature( featPtr ))
|
|||
|
{
|
|||
|
featPtr->RegisterObserver(m_pFeatureObs);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
unsigned int ControllerTreeWindow::getGrandParentLevel( const QList<QStandardItem *>& items, const QString &sGrandParent) const
|
|||
|
{
|
|||
|
unsigned int nLevel = 0;
|
|||
|
for (int i=0; i<items.size(); i++ )
|
|||
|
{
|
|||
|
QStandardItem *parent = items.at(i)->parent();
|
|||
|
|
|||
|
if(0 == parent)
|
|||
|
continue;
|
|||
|
|
|||
|
if(0 == sGrandParent.compare(parent->text()) )
|
|||
|
{
|
|||
|
nLevel = i;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return nLevel;
|
|||
|
}
|
|||
|
|
|||
|
bool ControllerTreeWindow::registerFeatureObserver ( const QString &sFeatureName )
|
|||
|
{
|
|||
|
/* register all features to the observer, so you will get notification in case any features value has been changed */
|
|||
|
QMap<QString, FeaturePtr>::iterator find_pos = m_featPtrMap.find( sFeatureName);
|
|||
|
if( find_pos != m_featPtrMap.end() )
|
|||
|
{
|
|||
|
VmbError_t error = find_pos.value()->RegisterObserver(m_pFeatureObs);
|
|||
|
if( VmbErrorSuccess != error)
|
|||
|
{
|
|||
|
emit logging( "ERROR Register Observer - Feature: " + sFeatureName + " returned "+QString::number(error)+
|
|||
|
" "+ Helper::mapReturnCodeToString(error)) ;
|
|||
|
}
|
|||
|
updateExpandedTreeValue(find_pos.value(), sFeatureName);
|
|||
|
return true;
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::unregisterFeatureObserver ( const QString &sFeatureName )
|
|||
|
{
|
|||
|
QMap<QString, FeaturePtr>::iterator find_pos = m_featPtrMap.find( sFeatureName);
|
|||
|
|
|||
|
if( find_pos != m_featPtrMap.end() )
|
|||
|
{
|
|||
|
VmbError_t error = find_pos.value()->UnregisterObserver(m_pFeatureObs);
|
|||
|
if( VmbErrorSuccess != error)
|
|||
|
{
|
|||
|
if(VmbErrorNotFound != error )
|
|||
|
emit logging( "ERROR Unregister Observer - Feature: " + find_pos.key() + " returned "+QString::number(error)+" "+
|
|||
|
Helper::mapReturnCodeToString(error)) ;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::updateExpandedTreeValue ( const FeaturePtr &featPtr, const QString &sName )
|
|||
|
{
|
|||
|
QString sValue = getFeatureValue(featPtr);
|
|||
|
bool bIsWritable = false;
|
|||
|
if( VmbErrorSuccess == featPtr->IsWritable(bIsWritable) )
|
|||
|
onSetChangedFeature(sName, sValue, bIsWritable);
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::onSetEventMsg ( const QStringList &sMsg )
|
|||
|
{
|
|||
|
setEventMessage(sMsg);
|
|||
|
}
|
|||
|
|
|||
|
/* synchronize the event information in tree and event window
|
|||
|
make sure to collect last information for event window when acquisition stops */
|
|||
|
void ControllerTreeWindow::synchronizeEventFeatures()
|
|||
|
{
|
|||
|
if(m_bIsGigE)
|
|||
|
{
|
|||
|
FeatureObserverPtr p = SP_DYN_CAST(m_pFeatureObs,FeatureObserver);
|
|||
|
if( NULL != p)
|
|||
|
{
|
|||
|
if(SP_ACCESS(p)->isEventRunning())
|
|||
|
{
|
|||
|
SP_ACCESS(p)->startObserverTimer();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* put the value to related features changed
|
|||
|
keep tree features value up-to-date */
|
|||
|
void ControllerTreeWindow::onSetChangedFeature ( const QString &sFeature, const QString &sValue, const bool &bIsWritable )
|
|||
|
{
|
|||
|
QModelIndexList currentItems = m_Model->match( m_Model->index(0,0), Qt::DisplayRole, QVariant::fromValue(sFeature), 1, Qt::MatchWrap|Qt::MatchRecursive);
|
|||
|
|
|||
|
if( 0 == currentItems.size() )
|
|||
|
return;
|
|||
|
|
|||
|
QString sFeatureValue = sValue;
|
|||
|
|
|||
|
if( Helper::needsIPv4Format(sFeature) )
|
|||
|
{
|
|||
|
sFeatureValue = Helper::displayValueToIPv4(sValue);
|
|||
|
}
|
|||
|
else if( sFeature == "Device MAC Address")
|
|||
|
{
|
|||
|
sFeatureValue = Helper::displayValueToMAC(sValue);
|
|||
|
}
|
|||
|
|
|||
|
QModelIndex newIndex = m_Model->index( currentItems.at(0).row(), 1, currentItems.at(0).parent());
|
|||
|
m_Model->setData( newIndex, QVariant(sFeatureValue), Qt::EditRole );
|
|||
|
|
|||
|
//TLParamsLock?
|
|||
|
QList<QStandardItem *> itemsCol1 = m_Model->findItems(sFeature, Qt::MatchWrap|Qt::MatchRecursive, 0) ;
|
|||
|
|
|||
|
if(!itemsCol1.empty())
|
|||
|
{
|
|||
|
bIsWritable ? itemsCol1.at(0)->setForeground(QColor(0,128, 0))/*green*/ : itemsCol1.at(0)->setForeground(QColor(135,135, 135))/*grey*/;
|
|||
|
if( 0 == m_sCurrentSelectedFeature.compare(sFeature))
|
|||
|
updateWidget(bIsWritable, QVariant(sFeatureValue));
|
|||
|
}
|
|||
|
|
|||
|
if ( !m_FeaturePtr_EnumComboBox || !m_EnumComboBox )
|
|||
|
return;
|
|||
|
|
|||
|
/* update Exposure-/Gain-/BalanceWhite- Auto when "Once" clicked */
|
|||
|
if( Helper::isAutoFeature( m_sCurrentSelectedFeature)
|
|||
|
&& Helper::isAutoFeature( sFeature)
|
|||
|
&& m_sCurrentSelectedFeature == sFeature
|
|||
|
&& sFeatureValue == "Off"
|
|||
|
&& m_EnumComboBox->currentText() == "Once" )
|
|||
|
{
|
|||
|
const int nIndex = m_EnumComboBox->findText("Off");
|
|||
|
if(-1 != nIndex)
|
|||
|
m_EnumComboBox->setCurrentIndex(nIndex);
|
|||
|
}
|
|||
|
|
|||
|
if( m_sCurrentSelectedFeature == sFeature && sValue.isEmpty() )
|
|||
|
{
|
|||
|
m_EnumComboBox->setItemText(m_EnumComboBox->count(), sValue);
|
|||
|
m_EnumComboBox->setCurrentIndex(m_EnumComboBox->count());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
template <typename COMPOUND_WIDGET>
|
|||
|
void updateEditWidget(COMPOUND_WIDGET *w, const QVariant &value, bool bIsWritable)
|
|||
|
{
|
|||
|
w->setEnabled(bIsWritable);
|
|||
|
if(bIsWritable)
|
|||
|
{
|
|||
|
QLineEdit * pChild= w-> template findChild<QLineEdit *>(QString("value"));
|
|||
|
if ( NULL != pChild
|
|||
|
&& !pChild->isModified()
|
|||
|
)
|
|||
|
{
|
|||
|
const QString newValue = value.toString();
|
|||
|
if( pChild->text() != newValue)
|
|||
|
{
|
|||
|
pChild->setText(newValue);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::updateWidget ( const bool bIsWritable, const QVariant &value )
|
|||
|
{
|
|||
|
if( NULL != m_IntSpinSliderWidget )
|
|||
|
{
|
|||
|
m_IntSpinSliderWidget->setEnabled(bIsWritable);
|
|||
|
if(bIsWritable)
|
|||
|
{
|
|||
|
IntSpinBox * spinBox = m_IntSpinSliderWidget->findChild<IntSpinBox *>(QString("value"));
|
|||
|
if( NULL != spinBox )
|
|||
|
{
|
|||
|
int newValue = value.toInt();
|
|||
|
if( spinBox->value() != newValue
|
|||
|
&& !spinBox->hasFocus())
|
|||
|
{
|
|||
|
spinBox->setValue( newValue );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
else if( NULL != m_ButtonWidget )
|
|||
|
m_ButtonWidget->setEnabled(bIsWritable);
|
|||
|
|
|||
|
else if( NULL != m_ComboWidget )
|
|||
|
m_ComboWidget->setEnabled(bIsWritable);
|
|||
|
|
|||
|
else if( NULL != m_FloatSliderEditWidget )
|
|||
|
{
|
|||
|
updateEditWidget( m_FloatSliderEditWidget, value, bIsWritable );
|
|||
|
}
|
|||
|
|
|||
|
else if( NULL != m_BooleanWidget )
|
|||
|
{
|
|||
|
m_BooleanWidget->setEnabled(bIsWritable);
|
|||
|
if(bIsWritable)
|
|||
|
m_BooleanWidget->findChild<QCheckBox *>(QString("value"))->setChecked(value.toBool());
|
|||
|
}
|
|||
|
|
|||
|
else if( NULL != m_EditWidget )
|
|||
|
{
|
|||
|
updateEditWidget( m_EditWidget, value, bIsWritable );
|
|||
|
}
|
|||
|
|
|||
|
else if( NULL != m_LineEditWidget )
|
|||
|
{
|
|||
|
updateEditWidget(m_LineEditWidget, value, bIsWritable );
|
|||
|
}
|
|||
|
|
|||
|
else if( NULL != m_LogSliderWidget )
|
|||
|
{
|
|||
|
updateEditWidget( m_LogSliderWidget, value, bIsWritable );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
QString ControllerTreeWindow::getFeatureValue ( const FeaturePtr &featPtr ) const
|
|||
|
{
|
|||
|
VmbInt64_t nValue64 = 0;
|
|||
|
double dValue = 0;
|
|||
|
bool bValue = false;
|
|||
|
|
|||
|
std::string stdValue;
|
|||
|
QString sValue("");
|
|||
|
|
|||
|
VmbFeatureDataType dataType = VmbFeatureDataUnknown;
|
|||
|
|
|||
|
VmbError_t error = featPtr->GetDataType(dataType);
|
|||
|
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
switch(dataType)
|
|||
|
{
|
|||
|
case VmbFeatureDataInt:
|
|||
|
if(VmbErrorSuccess == featPtr->GetValue(nValue64))
|
|||
|
sValue = QString::number(nValue64);
|
|||
|
break;
|
|||
|
|
|||
|
case VmbFeatureDataFloat:
|
|||
|
if(VmbErrorSuccess == featPtr->GetValue(dValue))
|
|||
|
sValue = QString::number(dValue);
|
|||
|
break;
|
|||
|
|
|||
|
case VmbFeatureDataEnum:
|
|||
|
if(VmbErrorSuccess == featPtr->GetValue(stdValue))
|
|||
|
sValue = QString::fromStdString(stdValue);
|
|||
|
break;
|
|||
|
|
|||
|
case VmbFeatureDataString:
|
|||
|
if(VmbErrorSuccess == featPtr->GetValue(stdValue))
|
|||
|
sValue = QString::fromStdString (stdValue);
|
|||
|
break;
|
|||
|
|
|||
|
case VmbFeatureDataBool:
|
|||
|
if(VmbErrorSuccess == featPtr->GetValue(bValue))
|
|||
|
bValue ? sValue = "true" : sValue = "false";
|
|||
|
break;
|
|||
|
|
|||
|
case VmbFeatureDataCommand:
|
|||
|
sValue = "[COMMAND]";
|
|||
|
break;
|
|||
|
|
|||
|
case VmbFeatureDataRaw:
|
|||
|
sValue = "Click here to open";
|
|||
|
break;
|
|||
|
default: break;
|
|||
|
}
|
|||
|
}
|
|||
|
return sValue;
|
|||
|
}
|
|||
|
|
|||
|
QString ControllerTreeWindow::getFeatureName ( const QModelIndex& item ) const
|
|||
|
{
|
|||
|
QString sAttrName("");
|
|||
|
if(item.isValid())
|
|||
|
{
|
|||
|
QModelIndex indexFirstCol = item.sibling(item.row(), 0);
|
|||
|
sAttrName = indexFirstCol.model()->data( indexFirstCol, Qt::DisplayRole ).toString();
|
|||
|
}
|
|||
|
return sAttrName;
|
|||
|
}
|
|||
|
|
|||
|
FeaturePtr ControllerTreeWindow::getFeaturePtr ( const QString &sFeature )
|
|||
|
{
|
|||
|
QMap<QString, FeaturePtr>::iterator i = m_featPtrMap.find(sFeature);
|
|||
|
|
|||
|
if ( m_featPtrMap.end() != i )
|
|||
|
{
|
|||
|
return i.value();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return FeaturePtr();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::showIt ( const QModelIndex item, const QString &sWhat )
|
|||
|
{
|
|||
|
QString sAttrName = getFeatureName(item);
|
|||
|
|
|||
|
QMap<QString, QString>::const_iterator i;
|
|||
|
|
|||
|
if( 0 == sWhat.compare("Description"))
|
|||
|
i = m_DescriptonMap.find(sAttrName);
|
|||
|
|
|||
|
while (i != m_DescriptonMap.constEnd())
|
|||
|
{
|
|||
|
if(0 == i.key().compare(sAttrName))
|
|||
|
{
|
|||
|
m_sTooltip = i.value();
|
|||
|
if(m_bIsTooltipOn)
|
|||
|
{
|
|||
|
this->setToolTip(i.value());
|
|||
|
}
|
|||
|
else
|
|||
|
this->setToolTip("");
|
|||
|
|
|||
|
emit setDescription(i.value());
|
|||
|
return;
|
|||
|
}
|
|||
|
++i;
|
|||
|
}
|
|||
|
/* no feature description has been found */
|
|||
|
this->setToolTip("");
|
|||
|
emit setDescription("");
|
|||
|
}
|
|||
|
|
|||
|
QString ControllerTreeWindow::getFeatureNameFromMap ( const QString &sDisplayName ) const
|
|||
|
{
|
|||
|
QString sFeature;
|
|||
|
QMap<QString, QString>::const_iterator itr = m_DisplayFeatureNameMap.find(sDisplayName);
|
|||
|
if (itr != m_DisplayFeatureNameMap.constEnd())
|
|||
|
{
|
|||
|
sFeature = itr.value();
|
|||
|
}
|
|||
|
|
|||
|
return sFeature;
|
|||
|
}
|
|||
|
|
|||
|
bool ControllerTreeWindow::isFeatureWritable ( const QString & sFeature )
|
|||
|
{
|
|||
|
bool bIsWritable = false;
|
|||
|
FeaturePtr FeatPtr;
|
|||
|
|
|||
|
FeatPtr = getFeaturePtr(sFeature);
|
|||
|
if(FeaturePtr() == FeatPtr)
|
|||
|
return bIsWritable;
|
|||
|
|
|||
|
FeatPtr->IsWritable(bIsWritable);
|
|||
|
|
|||
|
return bIsWritable;
|
|||
|
}
|
|||
|
|
|||
|
/* VmbFeatureDataRaw */
|
|||
|
void ControllerTreeWindow::createHexEditor ( const QModelIndex item )
|
|||
|
{
|
|||
|
FeaturePtr FeatPtr;
|
|||
|
QString sFeature = getFeatureName(item);
|
|||
|
|
|||
|
bool bIsReadOnly = true;
|
|||
|
if (isFeatureWritable(sFeature))
|
|||
|
{
|
|||
|
bIsReadOnly = false;
|
|||
|
}
|
|||
|
FeatPtr = getFeaturePtr(sFeature);
|
|||
|
if( NULL == FeatPtr)
|
|||
|
return;
|
|||
|
|
|||
|
if( VmbErrorSuccess == FeatPtr->GetValue(m_RawData) )
|
|||
|
{
|
|||
|
m_HexWindow = new HexMainWindow(this, NULL, "Raw Data Editor", bIsReadOnly, FeatPtr);
|
|||
|
unsigned char * c = &(m_RawData[0]);
|
|||
|
QByteArray data = QByteArray::fromRawData((char*)c, m_RawData.size());
|
|||
|
m_HexWindow->setData(data);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* VmbFeatureDataCommand */
|
|||
|
void ControllerTreeWindow::createCommandButton ( const QModelIndex item )
|
|||
|
{
|
|||
|
QString sFeature_Command = getFeatureName(item);
|
|||
|
|
|||
|
if (isFeatureWritable(sFeature_Command))
|
|||
|
{
|
|||
|
m_sCurrentSelectedFeature = m_sFeature_Command = sFeature_Command;
|
|||
|
|
|||
|
m_FeaturePtr_Command = getFeaturePtr(sFeature_Command);
|
|||
|
if(NULL == m_FeaturePtr_Command)
|
|||
|
return;
|
|||
|
|
|||
|
resetControl();
|
|||
|
|
|||
|
m_ButtonWidget = new QWidget(this);
|
|||
|
m_HButtonLayout = new QHBoxLayout(m_ButtonWidget);
|
|||
|
m_CmdButton = new QPushButton(QIcon(":/VimbaViewer/Images/execute.png"), QString("Execute..."), m_ButtonWidget);
|
|||
|
|
|||
|
m_HButtonLayout2 = new QHBoxLayout();
|
|||
|
m_HButtonLayout2->addWidget(m_CmdButton);
|
|||
|
m_HButtonLayout->addLayout(m_HButtonLayout2);
|
|||
|
|
|||
|
QPoint p = QCursor::pos();
|
|||
|
m_ButtonWidget->setFixedSize(m_sCurrentSelectedFeature.length()*10, 60);
|
|||
|
m_ButtonWidget->setWindowFlags( Qt::Tool | Qt::WindowCloseButtonHint );
|
|||
|
m_ButtonWidget->setWindowTitle(m_sCurrentSelectedFeature);
|
|||
|
AdjustOffscreenPosition(p, *m_ButtonWidget );
|
|||
|
m_ButtonWidget->move(p.x(), p.y());
|
|||
|
m_ButtonWidget->show();
|
|||
|
|
|||
|
QObject::connect( m_CmdButton, SIGNAL(clicked()), this, SLOT(onCmdButtonClick()) );
|
|||
|
setCursor(Qt::PointingHandCursor);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* run command when feature button clicked */
|
|||
|
void ControllerTreeWindow::onCmdButtonClick()
|
|||
|
{
|
|||
|
VmbError_t error;
|
|||
|
|
|||
|
if( (0 == m_sFeature_Command.compare("AcquisitionStop"))
|
|||
|
|| (0 == m_sFeature_Command.compare("Acquisition Stop"))
|
|||
|
|| (0 == m_sFeature_Command.compare("AcquisitionAbort"))
|
|||
|
|| (0 == m_sFeature_Command.compare("Acquisition Abort")))
|
|||
|
{
|
|||
|
error = m_FeaturePtr_Command->RunCommand();
|
|||
|
emit acquisitionStartStop("AcquisitionStopFreerun");
|
|||
|
}
|
|||
|
else if( (0 == m_sFeature_Command.compare("AcquisitionStart"))
|
|||
|
|| (0 == m_sFeature_Command.compare("Acquisition Start")))
|
|||
|
{
|
|||
|
emit acquisitionStartStop("AcquisitionStartFreerun");
|
|||
|
}
|
|||
|
|
|||
|
if( (0 != m_sFeature_Command.compare("AcquisitionStop"))
|
|||
|
&& (0 != m_sFeature_Command.compare("Acquisition Stop"))
|
|||
|
&& (0 != m_sFeature_Command.compare("AcquisitionAbort"))
|
|||
|
&& (0 != m_sFeature_Command.compare("Acquisition Abort")))
|
|||
|
{
|
|||
|
error = m_FeaturePtr_Command->RunCommand();
|
|||
|
}
|
|||
|
|
|||
|
if( VmbErrorSuccess != error)
|
|||
|
{
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " returned "+QString::number(error)+
|
|||
|
" "+ Helper::mapReturnCodeToString(error)) ;
|
|||
|
}
|
|||
|
else if( 0 == m_sFeature_Command.compare("GVSP Adjust Packet Size"))
|
|||
|
{
|
|||
|
bool bIsDone = false;
|
|||
|
this->setEnabled(false);
|
|||
|
emit enableViewerMenu (false);
|
|||
|
QPixmap Pixmap( ":/VimbaViewer/Images/refresh.png" );
|
|||
|
SplashScreen Splash(Pixmap, this, Qt::SplashScreen);
|
|||
|
int nW = ((this->width()/2) - Splash.width()/2);
|
|||
|
int nH = ((this->height()/2) - Splash.height()/2);
|
|||
|
Splash.setGeometry(nW,nH, Splash.width(),Splash.height());
|
|||
|
Splash.show();
|
|||
|
Splash.showMessage("Please wait ..." , Qt::AlignHCenter | Qt::AlignVCenter, Qt::red);
|
|||
|
|
|||
|
while((!bIsDone) && (VmbErrorSuccess == error))
|
|||
|
{
|
|||
|
error = m_FeaturePtr_Command->IsCommandDone(bIsDone);
|
|||
|
}
|
|||
|
|
|||
|
this->setEnabled(true);
|
|||
|
emit enableViewerMenu (true);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* VmbFeatureDataEnum */
|
|||
|
void ControllerTreeWindow::createEnumComboBox ( const QModelIndex item )
|
|||
|
{
|
|||
|
VmbError_t error;
|
|||
|
QString sFeature_EnumComboBox = getFeatureName(item);
|
|||
|
|
|||
|
// Don't create drop down for read only features
|
|||
|
if (isFeatureWritable(sFeature_EnumComboBox))
|
|||
|
{
|
|||
|
m_sCurrentSelectedFeature = m_sFeature_EnumComboBox = sFeature_EnumComboBox;
|
|||
|
|
|||
|
// Set FeaturePtr member to currently selected enum feature
|
|||
|
m_FeaturePtr_EnumComboBox = getFeaturePtr(m_sFeature_EnumComboBox);
|
|||
|
if(FeaturePtr() == m_FeaturePtr_EnumComboBox)
|
|||
|
return;
|
|||
|
|
|||
|
resetControl();
|
|||
|
m_ComboWidget = new QWidget(this);
|
|||
|
m_HComboLayout = new QHBoxLayout(m_ComboWidget);
|
|||
|
m_EnumComboBox = new ExComboBox( );
|
|||
|
m_HComboLayout2 = new QHBoxLayout();
|
|||
|
m_HComboLayout2->addWidget(m_EnumComboBox);
|
|||
|
m_HComboLayout->addLayout(m_HComboLayout2);
|
|||
|
|
|||
|
// Get all possible enumerations as string
|
|||
|
StringVector sEnumEntries;
|
|||
|
error = m_FeaturePtr_EnumComboBox->GetValues(sEnumEntries);
|
|||
|
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
std::string sCurrentValue;
|
|||
|
unsigned int nPos = 0;
|
|||
|
// Get currently selected enumeration
|
|||
|
if(VmbErrorSuccess == m_FeaturePtr_EnumComboBox->GetValue(sCurrentValue) || VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
for(unsigned int i=0; i < sEnumEntries.size(); i++)
|
|||
|
{
|
|||
|
// Check each enumeration if it is currently applicable
|
|||
|
bool bIsAvailable = false;
|
|||
|
m_FeaturePtr_EnumComboBox->IsValueAvailable(sEnumEntries.at(i).c_str(), bIsAvailable );
|
|||
|
|
|||
|
if(bIsAvailable)
|
|||
|
{
|
|||
|
// Add all applicable enumerations to drop down
|
|||
|
m_EnumComboBox->addItem(QString::fromStdString(sEnumEntries.at(i)));
|
|||
|
// Is this currently selected enumeration?
|
|||
|
if(0 == sEnumEntries.at(i).compare(sCurrentValue))
|
|||
|
// Set drop down index
|
|||
|
m_EnumComboBox->setCurrentIndex(nPos);
|
|||
|
nPos++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if(sCurrentValue.empty())
|
|||
|
{
|
|||
|
m_EnumComboBox->setItemText(nPos, QString::fromStdString(sCurrentValue));
|
|||
|
m_EnumComboBox->setCurrentIndex(nPos);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
QPoint p = QCursor::pos();
|
|||
|
m_ComboWidget->setFixedSize(m_sCurrentSelectedFeature.length()*13, 60);
|
|||
|
m_ComboWidget->setWindowFlags( Qt::Tool | Qt::WindowCloseButtonHint );
|
|||
|
m_ComboWidget->setWindowTitle(m_sCurrentSelectedFeature);
|
|||
|
AdjustOffscreenPosition(p, *m_ComboWidget );
|
|||
|
m_ComboWidget->move(p.x(), p.y());
|
|||
|
m_ComboWidget->show();
|
|||
|
|
|||
|
QObject::connect( m_EnumComboBox, SIGNAL(activated(const QString &)), this, SLOT(onEnumComboBoxClick(const QString &)) );
|
|||
|
setCursor(Qt::PointingHandCursor);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " (GetEnumRange) returned "+QString::number(error)+
|
|||
|
" "+ Helper::mapReturnCodeToString(error)) ;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::onEnumComboBoxClick ( const QString &sSelected )
|
|||
|
{
|
|||
|
std::string sCurrentValue;
|
|||
|
VmbError_t error;
|
|||
|
int nIndex = 0;
|
|||
|
int nIndexOld = 0;
|
|||
|
|
|||
|
error = m_FeaturePtr_EnumComboBox->GetValue(sCurrentValue);
|
|||
|
if( VmbErrorSuccess == error )
|
|||
|
{
|
|||
|
nIndexOld = m_EnumComboBox->findText(QString::fromStdString(sCurrentValue));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " (GetEnumValue) " + sSelected +" returned "+QString::number(error)+
|
|||
|
" "+ Helper::mapReturnCodeToString(error)) ;
|
|||
|
}
|
|||
|
|
|||
|
if( (0 == m_sFeature_EnumComboBox.compare("PixelFormat")) || (0 == m_sFeature_EnumComboBox.compare("Pixel Format")) ||
|
|||
|
(0 == m_sFeature_EnumComboBox.compare("AcquisitionMode")) || (0 == m_sFeature_EnumComboBox.compare("Acquisition Mode")) )
|
|||
|
{
|
|||
|
/* stop Acquisition */
|
|||
|
emit acquisitionStartStop("AcquisitionStop");
|
|||
|
|
|||
|
/* give a bit time to make sure that camera is stopped */
|
|||
|
#ifdef WIN32
|
|||
|
::Sleep(5);
|
|||
|
#else
|
|||
|
::usleep(5000);
|
|||
|
#endif
|
|||
|
|
|||
|
error = m_FeaturePtr_EnumComboBox->SetValue(sSelected.toAscii().data());
|
|||
|
if(VmbErrorSuccess != error)
|
|||
|
{
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " (SetEnumValue) " + sSelected +" returned "+QString::number(error)+
|
|||
|
" "+ Helper::mapReturnCodeToString(error)) ;
|
|||
|
}
|
|||
|
|
|||
|
if(VmbErrorSuccess == m_FeaturePtr_EnumComboBox->GetValue(sCurrentValue))
|
|||
|
{
|
|||
|
/* make sure to set back the valid value from the camera to combobox */
|
|||
|
nIndex = m_EnumComboBox->findText(QString::fromStdString(sCurrentValue));
|
|||
|
m_EnumComboBox->setCurrentIndex(nIndex);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_EnumComboBox->setCurrentIndex(nIndexOld);
|
|||
|
{
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " (GetEnumValue) " + sSelected +" returned "+QString::number(error)+
|
|||
|
" "+ Helper::mapReturnCodeToString(error)) ;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#ifdef WIN32
|
|||
|
::Sleep(5);
|
|||
|
#else
|
|||
|
::usleep(5000);
|
|||
|
#endif
|
|||
|
|
|||
|
/*start Acquisition */
|
|||
|
emit acquisitionStartStop("AcquisitionStart");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
error = m_FeaturePtr_EnumComboBox->SetValue(sSelected.toAscii().data());
|
|||
|
|
|||
|
if(VmbErrorSuccess != error)
|
|||
|
{
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " (SetEnumValue) " + sSelected +" returned "+QString::number(error)+
|
|||
|
" "+ Helper::mapReturnCodeToString(error)) ;
|
|||
|
}
|
|||
|
|
|||
|
if( VmbErrorSuccess == m_FeaturePtr_EnumComboBox->GetValue(sCurrentValue) )
|
|||
|
{
|
|||
|
/* make sure to set back the valid value from the camera to combobox */
|
|||
|
nIndex = m_EnumComboBox->findText(QString::fromStdString(sCurrentValue));
|
|||
|
m_EnumComboBox->setCurrentIndex(nIndex);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_EnumComboBox->setCurrentIndex(nIndexOld);
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " (GetEnumValue) " + sSelected +" returned "+QString::number(error)+
|
|||
|
" "+ Helper::mapReturnCodeToString(error)) ;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* VmbFeatureDataInt */
|
|||
|
void ControllerTreeWindow::createIntSliderSpinBox ( const QModelIndex item )
|
|||
|
{
|
|||
|
VmbError_t error;
|
|||
|
QString sFeature_IntSpinBox = getFeatureName(item);
|
|||
|
|
|||
|
if (isFeatureWritable(sFeature_IntSpinBox))
|
|||
|
{
|
|||
|
m_sCurrentSelectedFeature = m_sFeature_IntSpinBox = sFeature_IntSpinBox;
|
|||
|
|
|||
|
m_FeaturePtr_IntSpinBox = getFeaturePtr(m_sFeature_IntSpinBox);
|
|||
|
|
|||
|
std::string sRepresentation;
|
|||
|
m_FeaturePtr_IntSpinBox->GetRepresentation(sRepresentation);
|
|||
|
|
|||
|
VmbInt64_t nMin = 0, nMax = 0, nInc = 1, nValue = 0;
|
|||
|
error = m_FeaturePtr_IntSpinBox->GetRange(nMin, nMax);
|
|||
|
|
|||
|
/* use a line edit to show reg add in Hex */
|
|||
|
QString sName = getFeatureNameFromMap(m_sCurrentSelectedFeature);
|
|||
|
if( VmbErrorSuccess == error &&
|
|||
|
( sRepresentation == "HexNumber" ||
|
|||
|
Helper::needsIPv4Format(sName, sRepresentation) ||
|
|||
|
nMax > 9999
|
|||
|
)
|
|||
|
)
|
|||
|
{
|
|||
|
createLineEdit(item);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if(NULL == m_FeaturePtr_IntSpinBox)
|
|||
|
return;
|
|||
|
|
|||
|
resetControl();
|
|||
|
|
|||
|
m_IntSpinSliderWidget = new QWidget(this);
|
|||
|
m_HSpinSliderLayout_Int = new QHBoxLayout( m_IntSpinSliderWidget );
|
|||
|
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
if( nMin < std::numeric_limits<int>::min() )
|
|||
|
{
|
|||
|
nMin = std::numeric_limits<int>::min();
|
|||
|
}
|
|||
|
|
|||
|
if( nMax > std::numeric_limits<int>::max() )
|
|||
|
{
|
|||
|
nMax = std::numeric_limits<int>::max();
|
|||
|
if(VmbErrorSuccess == m_FeaturePtr_IntSpinBox->GetValue(nValue))
|
|||
|
{
|
|||
|
if( nMax < nValue )
|
|||
|
m_FeaturePtr_IntSpinBox->SetValue(nMax);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
m_SpinBox_Int = new IntSpinBox(0);
|
|||
|
m_SpinBox_Int->setObjectName("value"); //mark as the element of this dialog that contains the value, used in "updateWidget()"
|
|||
|
m_Slider_Int = new QSlider(Qt::Horizontal);
|
|||
|
m_Slider_Int->installEventFilter(this);
|
|||
|
|
|||
|
error = m_FeaturePtr_IntSpinBox->GetIncrement(nInc);
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
m_SpinBox_Int->setSingleStep(nInc);
|
|||
|
m_Slider_Int->setTickInterval(nInc);
|
|||
|
m_Slider_Int->setSingleStep(nInc);
|
|||
|
}
|
|||
|
|
|||
|
nMax = nMax - ((nMax-nMin) % nInc);
|
|||
|
m_SpinBox_Int->setRange(nMin, nMax);
|
|||
|
m_Slider_Int->setRange( nMin, nMax);
|
|||
|
|
|||
|
m_nSliderStep = nInc;
|
|||
|
|
|||
|
error = m_FeaturePtr_IntSpinBox->GetValue(nValue);
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
if( nValue > std::numeric_limits<int>::max() )
|
|||
|
{
|
|||
|
nValue = std::numeric_limits<int>::max();
|
|||
|
}
|
|||
|
|
|||
|
m_SpinBox_Int->setValue(nValue);
|
|||
|
m_Slider_Int->setValue(nValue);
|
|||
|
m_nIntSliderOldValue = nValue;
|
|||
|
}
|
|||
|
|
|||
|
m_Slider_Int->setPageStep((nMax-nMin)/5/nInc);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " (GetRange) returned "+QString::number(error)+
|
|||
|
" "+ Helper::mapReturnCodeToString(error)) ;
|
|||
|
}
|
|||
|
|
|||
|
m_HSpinSliderLayout_Int2 = new QHBoxLayout( );
|
|||
|
m_HSpinSliderLayout_Int2->addWidget(m_Slider_Int);
|
|||
|
m_HSpinSliderLayout_Int2->addWidget(m_SpinBox_Int);
|
|||
|
m_HSpinSliderLayout_Int->addLayout(m_HSpinSliderLayout_Int2);
|
|||
|
|
|||
|
QPoint p = QCursor::pos();
|
|||
|
m_IntSpinSliderWidget->setFixedHeight(60);
|
|||
|
m_IntSpinSliderWidget->setWindowFlags( Qt::Tool | Qt::WindowCloseButtonHint );
|
|||
|
m_IntSpinSliderWidget->setWindowTitle(m_sCurrentSelectedFeature);
|
|||
|
AdjustOffscreenPosition(p, *m_IntSpinSliderWidget );
|
|||
|
m_IntSpinSliderWidget->move(p.x(), p.y());
|
|||
|
m_IntSpinSliderWidget->show();
|
|||
|
|
|||
|
connect( m_Slider_Int, SIGNAL(valueChanged(int)), this, SLOT(onIntSliderChanged(int)) );
|
|||
|
connect( m_SpinBox_Int, SIGNAL(editingFinished()), this, SLOT(onIntSpinBoxClick()) );
|
|||
|
setCursor(Qt::PointingHandCursor);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::onIntSliderReleased()
|
|||
|
{
|
|||
|
onIntSliderChanged(m_Slider_Int->value());
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::onIntSliderChanged ( int nValue )
|
|||
|
{
|
|||
|
/* ignore it while pressing mouse and when slider still busy */
|
|||
|
if(m_bIsMousePressed || !m_bIsJobDone )
|
|||
|
return;
|
|||
|
|
|||
|
m_bIsJobDone = false;
|
|||
|
int nCurrentValue = nValue;
|
|||
|
|
|||
|
if( (m_nIntSliderOldValue > nValue) && (m_Slider_Int->minimum() != nValue) )
|
|||
|
{
|
|||
|
int nMod = nValue%m_nSliderStep;
|
|||
|
nValue = nValue - nMod;
|
|||
|
}
|
|||
|
|
|||
|
if( (0 != (nValue%m_nSliderStep)) && ( m_Slider_Int->minimum() != nValue) && ( m_Slider_Int->maximum() != nValue) )
|
|||
|
{
|
|||
|
nValue = nValue + (m_nSliderStep - (nValue%m_nSliderStep));
|
|||
|
}
|
|||
|
|
|||
|
if(m_Slider_Int->hasFocus())
|
|||
|
{
|
|||
|
setIntegerValue (nValue);
|
|||
|
}
|
|||
|
|
|||
|
m_nIntSliderOldValue = nCurrentValue;
|
|||
|
m_bIsJobDone = true;
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::onIntSpinBoxClick()
|
|||
|
{
|
|||
|
int nValue = m_SpinBox_Int->value();
|
|||
|
|
|||
|
if( (0 != (nValue%m_nSliderStep)) && ( m_SpinBox_Int->minimum() != nValue) && ( m_SpinBox_Int->maximum() != nValue) )
|
|||
|
{
|
|||
|
nValue = (nValue + (m_nSliderStep - (nValue%m_nSliderStep)) );
|
|||
|
}
|
|||
|
|
|||
|
setIntegerValue (nValue);
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::setIntegerValue ( const int &nValue )
|
|||
|
{
|
|||
|
VmbError_t error;
|
|||
|
|
|||
|
if( 0 == m_sFeature_IntSpinBox.compare("Width") ||0 == m_sFeature_IntSpinBox.compare("Height") )
|
|||
|
{
|
|||
|
/* stop Acquisition */
|
|||
|
emit acquisitionStartStop("AcquisitionStopWidthHeight");
|
|||
|
|
|||
|
error = m_FeaturePtr_IntSpinBox->SetValue(nValue);
|
|||
|
if( VmbErrorSuccess != error )
|
|||
|
{
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " (SetValue) "+ QString::number(nValue)+" returned "+QString::number(error)+
|
|||
|
" "+ Helper::mapReturnCodeToString(error)) ;
|
|||
|
}
|
|||
|
|
|||
|
updateCurrentIntValue();
|
|||
|
|
|||
|
/*start Acquisition */
|
|||
|
emit acquisitionStartStop("AcquisitionStart");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
error = m_FeaturePtr_IntSpinBox->SetValue(nValue);
|
|||
|
if( VmbErrorSuccess != error )
|
|||
|
{
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " (SetValue) "+ QString::number(nValue)+" returned "+QString::number(error)+
|
|||
|
" "+ Helper::mapReturnCodeToString(error)) ;
|
|||
|
}
|
|||
|
|
|||
|
updateCurrentIntValue();
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::updateCurrentIntValue()
|
|||
|
{
|
|||
|
VmbInt64_t nCurrentValue = 0;
|
|||
|
|
|||
|
VmbError_t error = m_FeaturePtr_IntSpinBox->GetValue(nCurrentValue);
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
/* make sure to set back the valid value from the camera to slider and spinbox */
|
|||
|
m_SpinBox_Int->setValue(nCurrentValue);
|
|||
|
m_Slider_Int->setValue(nCurrentValue);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " (GetValue) "+ QString::number(nCurrentValue)+" returned "+QString::number(error)+
|
|||
|
" "+ Helper::mapReturnCodeToString(error)) ;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* VmbFeatureDataFloat */
|
|||
|
void ControllerTreeWindow::createFloatSliderEditBox ( const QModelIndex item )
|
|||
|
{
|
|||
|
VmbError_t error;
|
|||
|
QString sFeature_FloatSliderEditBox = getFeatureName(item);
|
|||
|
|
|||
|
if (isFeatureWritable(sFeature_FloatSliderEditBox))
|
|||
|
{
|
|||
|
m_sCurrentSelectedFeature = m_sFeature_FloatSliderSpinBox = sFeature_FloatSliderEditBox;
|
|||
|
m_FeaturePtr_FloatSliderSpinBox = getFeaturePtr(sFeature_FloatSliderEditBox);
|
|||
|
if(NULL == m_FeaturePtr_FloatSliderSpinBox)
|
|||
|
return;
|
|||
|
|
|||
|
resetControl();
|
|||
|
|
|||
|
error = m_FeaturePtr_FloatSliderSpinBox->GetRange(m_dMinimum, m_dMaximum);
|
|||
|
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
/* if there's an increment, compute the correct maximum (allowing some float uncertainty) */
|
|||
|
if(VmbErrorSuccess == m_FeaturePtr_FloatSliderSpinBox->GetIncrement(m_dIncrement))
|
|||
|
{
|
|||
|
double dSteps = floor((m_dMaximum-m_dMinimum)/m_dIncrement*1.000000000001);
|
|||
|
double dMaximum = m_dMinimum + dSteps*m_dIncrement*1.000000000001;
|
|||
|
if (dMaximum < m_dMaximum)
|
|||
|
m_dMaximum = dMaximum;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_dIncrement = 0.0;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " (GetRange) "+" returned "+QString::number(error)+
|
|||
|
" "+ Helper::mapReturnCodeToString(error)) ;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
std::string sRepresentation;
|
|||
|
m_FeaturePtr_FloatSliderSpinBox->GetRepresentation(sRepresentation);
|
|||
|
|
|||
|
/* use a logarithmic slider for exposure */
|
|||
|
if( 0 == sFeature_FloatSliderEditBox.compare("Exposure Time") || 0 == sFeature_FloatSliderEditBox.compare("ExposureTimeAbs")
|
|||
|
|| 0 == sRepresentation.compare("Logarithmic"))
|
|||
|
{
|
|||
|
createLogarithmicSlider(item);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
m_FloatSliderEditWidget = new QWidget(this);
|
|||
|
m_HSpinSliderLayout_Float = new QHBoxLayout( m_FloatSliderEditWidget );
|
|||
|
|
|||
|
/* Line Edit */
|
|||
|
m_EditBox_Float = new QLineEdit(0);
|
|||
|
m_EditBox_Float->setObjectName("value"); //mark as the element of this dialog that contains the value, used in "updateWidget()"
|
|||
|
|
|||
|
/* GigE: Gain, Hue
|
|||
|
* 1394: Trigger Delay
|
|||
|
* They will be treated as Floating in fact they are int
|
|||
|
*/
|
|||
|
double dValue = 0;
|
|||
|
error = m_FeaturePtr_FloatSliderSpinBox->GetValue(dValue);
|
|||
|
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
m_EditBox_Float->setText( QString::number( dValue ));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " (GetValue) "+ QString::number(dValue,'g',16)+" returned "+QString::number(error)+
|
|||
|
" "+ Helper::mapReturnCodeToString(error)) ;
|
|||
|
}
|
|||
|
|
|||
|
/* Slider */
|
|||
|
m_Slider_Float = new QwtSlider(Qt::Horizontal, m_FloatSliderEditWidget);
|
|||
|
m_Slider_Float->setGroove(true);
|
|||
|
m_Slider_Float->setTrough(false);
|
|||
|
m_Slider_Float->setScalePosition(static_cast<QwtSlider::ScalePosition>(0) /*::NoScale*/); // Unfortunately older g++ compiler does not support enum as namespace or class
|
|||
|
m_Slider_Float->setScaleEngine( new QwtLinearScaleEngine );
|
|||
|
m_Slider_Float->setHandleSize(QSize( 12, 18 ));
|
|||
|
m_Slider_Float->setFocusPolicy( Qt::StrongFocus);
|
|||
|
m_Slider_Float->installEventFilter(this);
|
|||
|
|
|||
|
if (abs(m_dIncrement) > 0.0000001)
|
|||
|
{
|
|||
|
m_Slider_Float->setTotalSteps(ceil((m_dMaximum-m_dMinimum)/m_dIncrement));
|
|||
|
}
|
|||
|
|
|||
|
m_Slider_Float->setScale( m_dMinimum, m_dMaximum );
|
|||
|
m_Slider_Float->setValue( dValue );
|
|||
|
|
|||
|
m_HSliderEditLayout_Float2 = new QHBoxLayout();
|
|||
|
m_HSliderEditLayout_Float2->addWidget(m_Slider_Float);
|
|||
|
m_Slider_Float->setMinimumWidth(200);
|
|||
|
m_EditBox_Float->setMinimumWidth(60);
|
|||
|
m_EditBox_Float->setMaximumWidth(80);
|
|||
|
m_HSliderEditLayout_Float2->addWidget(m_EditBox_Float);
|
|||
|
m_EditBox_Float->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
|||
|
m_HSpinSliderLayout_Float->addLayout(m_HSliderEditLayout_Float2);
|
|||
|
|
|||
|
QPoint p = QCursor::pos();
|
|||
|
m_FloatSliderEditWidget->setFixedHeight(60);
|
|||
|
m_FloatSliderEditWidget->setWindowFlags( Qt::Tool | Qt::WindowCloseButtonHint );
|
|||
|
m_FloatSliderEditWidget->setWindowTitle(m_sCurrentSelectedFeature);
|
|||
|
AdjustOffscreenPosition(p, *m_FloatSliderEditWidget );
|
|||
|
m_FloatSliderEditWidget->move(p.x(), p.y());
|
|||
|
m_FloatSliderEditWidget->show();
|
|||
|
|
|||
|
/* As of Vimba >= 1.4, float features other than ExposureTime don't use spin box anymore */
|
|||
|
connect( m_Slider_Float, SIGNAL( valueChanged( double ) ), this, SLOT( onFloatSliderChanged( double ) ) );
|
|||
|
connect( m_EditBox_Float, SIGNAL(editingFinished()), this, SLOT(onFloatEditFinished()) );
|
|||
|
setCursor(Qt::PointingHandCursor);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::onFloatSliderReleased()
|
|||
|
{
|
|||
|
onFloatSliderChanged(m_Slider_Float->value());
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::onFloatSliderChanged( double dValue )
|
|||
|
{
|
|||
|
/* ignore it while pressing mouse and when slider still busy */
|
|||
|
if(m_bIsMousePressed || !m_bIsJobDone )
|
|||
|
return;
|
|||
|
|
|||
|
m_bIsJobDone = false;
|
|||
|
|
|||
|
if( dValue > (m_dMaximum * 0.995) )
|
|||
|
dValue = m_dMaximum;
|
|||
|
|
|||
|
if(m_Slider_Float->hasFocus())
|
|||
|
{
|
|||
|
m_EditBox_Float->setText( QString::number(dValue));
|
|||
|
/* As of Vimba >= 1.4, float features other than ExposureTime don't use spin box anymore */
|
|||
|
onFloatEditFinished();
|
|||
|
}
|
|||
|
|
|||
|
m_bIsJobDone = true;
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::onFloatEditFinished()
|
|||
|
{
|
|||
|
double dValue = m_EditBox_Float->text().toDouble()*1.0000000000001; // allow some float imprecision
|
|||
|
setFloatingValue (dValue);
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::setFloatingValue ( const double &dValue )
|
|||
|
{
|
|||
|
double dCurrentValue = dValue;
|
|||
|
VmbError_t error;
|
|||
|
|
|||
|
/* restrict to the allowed values */
|
|||
|
if( m_dMaximum < dValue )
|
|||
|
{
|
|||
|
dCurrentValue = m_dMaximum;
|
|||
|
}
|
|||
|
else if( m_dMinimum > dValue )
|
|||
|
{
|
|||
|
dCurrentValue = m_dMinimum;
|
|||
|
}
|
|||
|
// removed handling for increment because of rounding errors
|
|||
|
// else if ( m_dIncrement != 0.0 )
|
|||
|
// {
|
|||
|
// dCurrentValue = floor((dValue-m_dMinimum)/m_dIncrement)*m_dIncrement + m_dMinimum;
|
|||
|
// }
|
|||
|
error = m_FeaturePtr_FloatSliderSpinBox->SetValue(dCurrentValue);
|
|||
|
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
error = m_FeaturePtr_FloatSliderSpinBox->GetValue(dCurrentValue);
|
|||
|
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
const QString newValue = QString::number(dCurrentValue);
|
|||
|
if( m_EditBox_Float->text() != newValue )
|
|||
|
{
|
|||
|
m_EditBox_Float->setText( newValue );
|
|||
|
}
|
|||
|
|
|||
|
if(!m_Slider_Float->hasFocus() || (!m_bIsGigE) || ( 0 == m_sCurrentSelectedFeature.compare("ColorTransformationValue")) )
|
|||
|
{ /* Not GigE (except ColorTransformationValue), especially to handle Gamma feature. Make sure to set the current feature value back to slider */
|
|||
|
m_Slider_Float->setValue(dCurrentValue);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* reset all fps counters whenever shutter value has been changed */
|
|||
|
if( 0 == m_sFeature_FloatSliderSpinBox.compare("Exposure Time") ||
|
|||
|
0 == m_sFeature_FloatSliderSpinBox.compare("ExposureTimeAbs"))
|
|||
|
{
|
|||
|
emit resetFPS();
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " (SetValue) "+ QString::number(dValue)+" returned "+QString::number(error)+
|
|||
|
" "+ Helper::mapReturnCodeToString(error)) ;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* Logarithmic slider */
|
|||
|
void ControllerTreeWindow::createLogarithmicSlider ( const QModelIndex &item )
|
|||
|
{
|
|||
|
QString sFeature_FloatSliderSpinBox = getFeatureName(item);
|
|||
|
|
|||
|
if (isFeatureWritable(sFeature_FloatSliderSpinBox))
|
|||
|
{
|
|||
|
m_sFeature_FloatSliderSpinBox = sFeature_FloatSliderSpinBox;
|
|||
|
|
|||
|
m_LogSliderWidget = new QWidget(this);
|
|||
|
m_HLogSliderLayout = new QHBoxLayout( m_LogSliderWidget );
|
|||
|
m_LogSliderWidget->setFixedHeight(80);
|
|||
|
m_LogSliderWidget->setMinimumWidth(400);
|
|||
|
|
|||
|
/* LogSlider */
|
|||
|
m_LogSlider = new QwtSlider( Qt::Horizontal, m_LogSliderWidget);
|
|||
|
m_LogSlider->setGroove(true);
|
|||
|
m_LogSlider->setTrough(false);
|
|||
|
m_LogSlider->setScalePosition(static_cast<QwtSlider::ScalePosition>(2) /*::TrailingScale*/); // Unfortunately oder g++ compiler does not support enum as namespace or class
|
|||
|
m_LogSlider->setScaleEngine(new QwtLogScaleEngine(10));
|
|||
|
m_LogSlider->setHandleSize(QSize(12, 18 ));
|
|||
|
m_LogSlider->setScale( m_dMinimum, m_dMaximum );
|
|||
|
|
|||
|
m_LogSlider->setScaleMaxMinor( 10 );
|
|||
|
m_HLogSliderLayout->addWidget(m_LogSlider);
|
|||
|
m_LogSlider->setFocusPolicy( Qt::StrongFocus);
|
|||
|
connect( m_LogSlider, SIGNAL( valueChanged( double ) ), this, SLOT( setLogarithmicSliderValue( double ) ) );
|
|||
|
|
|||
|
m_EditBox_Float = new QLineEdit(0);
|
|||
|
m_EditBox_Float->setObjectName("value"); //mark as the element of this dialog that contains the value, used in "updateWidget()"
|
|||
|
m_EditBox_Float->setMinimumWidth(60);
|
|||
|
m_EditBox_Float->setMaximumWidth(90);
|
|||
|
m_HLogSliderLayout->addWidget(m_EditBox_Float);
|
|||
|
m_EditBox_Float->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
|||
|
m_EditBox_Float->setFocusPolicy( Qt::StrongFocus);
|
|||
|
connect( m_EditBox_Float, SIGNAL(editingFinished()), this, SLOT(onLogarithmicFloatSpinBoxClick()) );
|
|||
|
|
|||
|
double dCurrentValue = 0;
|
|||
|
m_FeaturePtr_FloatSliderSpinBox->GetValue(dCurrentValue);
|
|||
|
if (abs(m_dIncrement) > 0.0001)
|
|||
|
{
|
|||
|
dCurrentValue = floor((dCurrentValue-m_dMinimum)/m_dIncrement+0.00000001)*m_dIncrement + m_dMinimum;
|
|||
|
m_LogSlider->setTotalSteps(ceil((m_dMaximum-m_dMinimum)/m_dIncrement));
|
|||
|
}
|
|||
|
m_EditBox_Float->setText( QString::number( dCurrentValue ));
|
|||
|
m_LogSlider->setValue(dCurrentValue);
|
|||
|
m_LogSlider->installEventFilter(this);
|
|||
|
|
|||
|
m_LogSliderWidget->setWindowTitle( sFeature_FloatSliderSpinBox + " (Min: " + QString::number(m_dMinimum,'g',6) + ", Max: " + QString::number(m_dMaximum,'g', 10) + ") "+ m_sCameraID );
|
|||
|
m_LogSliderWidget->setWindowFlags(Qt::WindowTitleHint);
|
|||
|
QPoint p = QCursor::pos();
|
|||
|
m_LogSliderWidget->setWindowFlags( Qt::Tool );
|
|||
|
AdjustOffscreenPosition(p, *m_LogSliderWidget );
|
|||
|
m_LogSliderWidget->move(p.x(), p.y());
|
|||
|
m_LogSliderWidget->show();
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::onLogarithmicFloatSpinBoxClick()
|
|||
|
{
|
|||
|
setLogarithmicFloatingValue ( m_EditBox_Float->text().toDouble() );
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::onLogarithmicSliderReleased()
|
|||
|
{
|
|||
|
setLogarithmicSliderValue(m_LogSlider->value());
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::setLogarithmicSliderValue( double v )
|
|||
|
{
|
|||
|
/* ignore it while pressing mouse and when slider still busy */
|
|||
|
if(m_bIsMousePressed || !m_bIsJobDone )
|
|||
|
return;
|
|||
|
|
|||
|
m_bIsJobDone = false;
|
|||
|
|
|||
|
double dValue = v;
|
|||
|
|
|||
|
if( dValue > (m_dMaximum * 0.95) )
|
|||
|
dValue = m_dMaximum;
|
|||
|
|
|||
|
if(m_LogSlider->hasFocus())
|
|||
|
setLogarithmicFloatingValue ( dValue );
|
|||
|
|
|||
|
m_bIsJobDone = true;
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::setLogarithmicFloatingValue ( const double &dValue )
|
|||
|
{
|
|||
|
VmbError_t Result;
|
|||
|
double dValueToWrite = dValue;
|
|||
|
if(dValue < m_dMinimum)
|
|||
|
{
|
|||
|
dValueToWrite = m_dMinimum;
|
|||
|
}
|
|||
|
else if(dValue > m_dMaximum)
|
|||
|
{
|
|||
|
dValueToWrite = m_dMaximum;
|
|||
|
}
|
|||
|
// removed adjustments for increments due to rounding problems
|
|||
|
// else if ( m_dIncrement != 0.0 )
|
|||
|
// {
|
|||
|
// dValueToWrite = floor((dValueToWrite + 0.00001-m_dMinimum)/m_dIncrement)*m_dIncrement + m_dMinimum;
|
|||
|
// }
|
|||
|
|
|||
|
Result = m_FeaturePtr_FloatSliderSpinBox->SetValue(dValueToWrite);
|
|||
|
if( Result != VmbErrorSuccess)
|
|||
|
{
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " (SetValue) "+ " returned "+QString::number(Result)+
|
|||
|
" "+ Helper::mapReturnCodeToString(Result)) ;
|
|||
|
return;
|
|||
|
}
|
|||
|
double dCurrentValue = dValueToWrite;
|
|||
|
Result = m_FeaturePtr_FloatSliderSpinBox->GetValue(dCurrentValue);
|
|||
|
if( Result != VmbErrorSuccess)
|
|||
|
{
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " (GetValue) "+ " returned "+QString::number(Result)+
|
|||
|
" "+ Helper::mapReturnCodeToString(Result)) ;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
m_LogSlider->setValue(dCurrentValue);
|
|||
|
|
|||
|
m_EditBox_Float->setText( QString::number( dCurrentValue ));
|
|||
|
m_LogSlider->setToolTip(QString::number(dCurrentValue,'g',16));
|
|||
|
|
|||
|
emit resetFPS();
|
|||
|
}
|
|||
|
|
|||
|
/* VmbFeatureDataBool */
|
|||
|
void ControllerTreeWindow::createBooleanCheckBox ( const QModelIndex item )
|
|||
|
{
|
|||
|
QString sFeature_CheckBox = getFeatureName(item);
|
|||
|
|
|||
|
if (isFeatureWritable(sFeature_CheckBox))
|
|||
|
{
|
|||
|
m_sCurrentSelectedFeature = m_sFeature_CheckBox = sFeature_CheckBox;
|
|||
|
|
|||
|
m_FeaturePtr_CheckBox = getFeaturePtr(m_sFeature_CheckBox);
|
|||
|
if(NULL == m_FeaturePtr_CheckBox)
|
|||
|
return;
|
|||
|
|
|||
|
resetControl();
|
|||
|
|
|||
|
m_BooleanWidget = new QWidget(this);
|
|||
|
m_HBooleanLayout = new QHBoxLayout (m_BooleanWidget);
|
|||
|
m_CheckBox_Bool = new QCheckBox (QString(""));
|
|||
|
m_CheckBox_Bool->setMaximumHeight(20);
|
|||
|
m_CheckBox_Bool->setObjectName("value"); //mark as the element of this dialog that contains the value, used in "updateWidget()"
|
|||
|
m_HBooleanLayout2 = new QHBoxLayout();
|
|||
|
m_HBooleanLayout2->addWidget(m_CheckBox_Bool);
|
|||
|
m_HBooleanLayout->addLayout(m_HBooleanLayout2);
|
|||
|
|
|||
|
bool bValue = false;
|
|||
|
VmbError_t error = m_FeaturePtr_CheckBox->GetValue(bValue);
|
|||
|
if (VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
m_CheckBox_Bool->setChecked(bValue);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_CheckBox_Bool->setChecked(false);
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " (GetValue) "+ " returned "+QString::number(error)+
|
|||
|
" "+ Helper::mapReturnCodeToString(error)) ;
|
|||
|
}
|
|||
|
|
|||
|
QPoint p = QCursor::pos();
|
|||
|
m_BooleanWidget->setFixedHeight(60);
|
|||
|
m_CheckBox_Bool->setText(m_sCurrentSelectedFeature);
|
|||
|
|
|||
|
m_BooleanWidget->setWindowFlags( Qt::Tool | Qt::WindowCloseButtonHint );
|
|||
|
m_BooleanWidget->setWindowTitle(m_sCurrentSelectedFeature);
|
|||
|
AdjustOffscreenPosition(p, *m_BooleanWidget );
|
|||
|
m_BooleanWidget->move(p.x(), p.y());
|
|||
|
m_BooleanWidget->show();
|
|||
|
|
|||
|
connect( m_CheckBox_Bool, SIGNAL(clicked(bool)), this, SLOT(onBoolCheckBoxClick(bool)) );
|
|||
|
setCursor(Qt::PointingHandCursor);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::onBoolCheckBoxClick ( bool bValue )
|
|||
|
{
|
|||
|
bool bCurrentValue = false;
|
|||
|
|
|||
|
VmbError_t error = m_FeaturePtr_CheckBox->SetValue(bValue);
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
error = m_FeaturePtr_CheckBox->GetValue(bCurrentValue);
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
QString sValue = "false";
|
|||
|
(true == bCurrentValue) ? sValue = "true" : sValue = "false";
|
|||
|
m_CheckBox_Bool->setChecked(bCurrentValue);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " (GetValue) "+ " returned "+QString::number(error)+
|
|||
|
" "+ Helper::mapReturnCodeToString(error)) ;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " (SetValue) "+ QString::number(bValue) + " returned "+QString::number(error)+
|
|||
|
" "+ Helper::mapReturnCodeToString(error)) ;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* VmbFeatureDataString */
|
|||
|
void ControllerTreeWindow::createStringEditBox ( const QModelIndex item )
|
|||
|
{
|
|||
|
QString sFeature_StringEditBox = getFeatureName(item);
|
|||
|
|
|||
|
if (isFeatureWritable(sFeature_StringEditBox))
|
|||
|
{
|
|||
|
m_sCurrentSelectedFeature = m_sFeature_StringEditBox = sFeature_StringEditBox;
|
|||
|
|
|||
|
m_FeaturePtr_StringEditBox = getFeaturePtr(m_sFeature_StringEditBox);
|
|||
|
if(NULL == m_FeaturePtr_StringEditBox)
|
|||
|
return;
|
|||
|
|
|||
|
resetControl();
|
|||
|
|
|||
|
m_EditWidget = new QWidget (this);
|
|||
|
m_HEditLayout = new QHBoxLayout(m_EditWidget);
|
|||
|
m_TextEdit_String = new QLineEdit();
|
|||
|
m_TextEdit_String->setObjectName("value"); //mark as the element of this dialog that contains the value, used in "updateWidget()"
|
|||
|
m_TextEdit_String->setMaximumHeight(20);
|
|||
|
m_HEditLayout2 = new QHBoxLayout();
|
|||
|
m_HEditLayout2->addWidget(m_TextEdit_String);
|
|||
|
m_HEditLayout->addLayout(m_HEditLayout2);
|
|||
|
|
|||
|
std::string sValue;
|
|||
|
VmbError_t error = m_FeaturePtr_StringEditBox->GetValue(sValue);
|
|||
|
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
m_TextEdit_String->setText(QString::fromUtf8(sValue.c_str()));
|
|||
|
else
|
|||
|
m_TextEdit_String->setText(QString::fromStdString(" "));
|
|||
|
|
|||
|
QPoint p = QCursor::pos();
|
|||
|
m_EditWidget->setFixedHeight(60);
|
|||
|
m_EditWidget->setWindowFlags( Qt::Tool | Qt::WindowCloseButtonHint );
|
|||
|
m_EditWidget->setWindowTitle(m_sCurrentSelectedFeature);
|
|||
|
AdjustOffscreenPosition(p, *m_EditWidget );
|
|||
|
m_EditWidget->move(p.x(), p.y());
|
|||
|
m_EditWidget->show();
|
|||
|
|
|||
|
connect( m_TextEdit_String, SIGNAL(returnPressed()), this, SLOT(onEditText()) );
|
|||
|
setCursor(Qt::PointingHandCursor);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::onEditText()
|
|||
|
{
|
|||
|
QString sText = m_TextEdit_String->text();
|
|||
|
VmbError_t error = m_FeaturePtr_StringEditBox->SetValue((const char*)sText.toAscii());
|
|||
|
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
std::string sCurrentValue;
|
|||
|
error = m_FeaturePtr_StringEditBox->GetValue(sCurrentValue);
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
m_TextEdit_String->setText(QString::fromStdString(sCurrentValue));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_TextEdit_String->setText("");
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " (GetStringValue) "+ " returned "+QString::number(error)+
|
|||
|
" "+ Helper::mapReturnCodeToString(error)) ;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
emit logging( "ERROR Feature: " + m_sCurrentSelectedFeature + " (SetStringValue) "+ sText + " returned "+QString::number(error)+
|
|||
|
" "+ Helper::mapReturnCodeToString(error)) ;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::createLineEdit ( const QModelIndex &item )
|
|||
|
{
|
|||
|
QString sFeature = getFeatureName(item);
|
|||
|
|
|||
|
if (isFeatureWritable(sFeature))
|
|||
|
{
|
|||
|
m_sCurrentSelectedFeature = m_sFeature_StringLineEdit = sFeature;
|
|||
|
m_FeaturePtr_LineEdit = getFeaturePtr(m_sFeature_StringLineEdit);
|
|||
|
if(NULL == m_FeaturePtr_LineEdit)
|
|||
|
return;
|
|||
|
VmbFeatureDataType dt = VmbFeatureDataUnknown;
|
|||
|
VmbError_t error = m_FeaturePtr_LineEdit->GetDataType( dt );
|
|||
|
|
|||
|
resetControl();
|
|||
|
|
|||
|
QString sName = getFeatureNameFromMap(m_sCurrentSelectedFeature);
|
|||
|
std::string sRepresentation;
|
|||
|
m_FeaturePtr_LineEdit->GetRepresentation( sRepresentation );
|
|||
|
|
|||
|
m_LineEditWidget = new QWidget(this);
|
|||
|
m_HLineEditLayout = new QHBoxLayout( m_LineEditWidget );
|
|||
|
|
|||
|
/* add LineEdit that allows 0-255 */
|
|||
|
/* add Hex Label */
|
|||
|
m_LineEdit = new QLineEdit (m_LineEditWidget);
|
|||
|
m_LineEdit->setObjectName("value"); //mark as the element of this dialog that contains the value, used in "updateWidget()"
|
|||
|
|
|||
|
if ( VmbFeatureDataInt == dt )
|
|||
|
{
|
|||
|
if( Helper::needsIPv4Format(sName, sRepresentation))
|
|||
|
{
|
|||
|
m_HexLabel = new QLabel ("", m_LineEditWidget);
|
|||
|
QRegExp rxIp("(([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\\.){3}([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])");
|
|||
|
m_LineEdit->setValidator(new QRegExpValidator(rxIp, m_LineEdit));
|
|||
|
m_LineEdit->setMinimumWidth(20);
|
|||
|
}
|
|||
|
else if ( sRepresentation == "HexNumber" )
|
|||
|
{
|
|||
|
m_HexLabel = new QLabel (" 0x", m_LineEditWidget);
|
|||
|
QString s;
|
|||
|
|
|||
|
QRegExp rxIp("([0-9a-fA-F]){1,8}");
|
|||
|
m_LineEdit->setValidator(new QRegExpValidator(rxIp, m_LineEdit));
|
|||
|
m_LineEdit->setMaxLength(8);
|
|||
|
}
|
|||
|
else // > sint32
|
|||
|
{
|
|||
|
m_HexLabel = new QLabel ("", m_LineEditWidget);
|
|||
|
QRegExp rxIp("-?[0-9]*");
|
|||
|
m_LineEdit->setValidator(new QRegExpValidator(rxIp, m_LineEdit));
|
|||
|
m_LineEdit->setMinimumWidth(20);
|
|||
|
}
|
|||
|
}
|
|||
|
else if( VmbFeatureDataFloat == dt )
|
|||
|
{
|
|||
|
m_HexLabel = new QLabel ("", m_LineEditWidget);
|
|||
|
m_LineEdit->setValidator(new QDoubleValidator(NULL));
|
|||
|
m_LineEdit->setMinimumWidth(20);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
m_HexLabel->setMaximumHeight(20);
|
|||
|
m_LineEdit->setMaximumHeight(20);
|
|||
|
|
|||
|
m_HLineEditLayout2 = new QHBoxLayout( );
|
|||
|
m_HLineEditLayout2->addWidget(m_HexLabel);
|
|||
|
m_HLineEditLayout2->addWidget(m_LineEdit);
|
|||
|
m_HLineEditLayout->addLayout(m_HLineEditLayout2);
|
|||
|
|
|||
|
if ( VmbFeatureDataInt == dt )
|
|||
|
{
|
|||
|
VmbInt64_t nValue64 = 0;
|
|||
|
error = m_FeaturePtr_LineEdit->GetValue(nValue64);
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
if( Helper::needsIPv4Format(sName, sRepresentation))
|
|||
|
{
|
|||
|
m_LineEdit->insert(Helper::IPv4ToString(nValue64));
|
|||
|
}
|
|||
|
/* Handling of features like DeviceAccessRegisterValue or DeviceAccessRegisterAddress */
|
|||
|
else if ( sRepresentation == "HexNumber" )
|
|||
|
{
|
|||
|
std::string sHexValue("");
|
|||
|
QString sQHexValue;
|
|||
|
error = m_FeaturePtr_LineEdit->GetValue(sHexValue);
|
|||
|
if (!sHexValue.empty())
|
|||
|
{
|
|||
|
sQHexValue.fromStdString(sHexValue);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
sQHexValue.sprintf("%x", nValue64);
|
|||
|
}
|
|||
|
m_LineEdit->insert(sQHexValue);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_LineEdit->insert(QString::number( nValue64 ));
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_LineEdit->insert("Read Error");
|
|||
|
}
|
|||
|
}
|
|||
|
else if ( VmbFeatureDataFloat == dt )
|
|||
|
{
|
|||
|
double dValue = 0;
|
|||
|
error = m_FeaturePtr_LineEdit->GetValue( dValue );
|
|||
|
if( VmbErrorSuccess == error )
|
|||
|
{
|
|||
|
m_LineEdit->insert(QString::number( dValue ));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_LineEdit->insert("Read Error");
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_LineEdit->insert("Read Error");
|
|||
|
}
|
|||
|
|
|||
|
QPoint p = QCursor::pos();
|
|||
|
m_LineEditWidget->setFixedHeight(60);
|
|||
|
m_LineEditWidget->setWindowFlags( Qt::Tool | Qt::WindowCloseButtonHint );
|
|||
|
m_LineEditWidget->setWindowTitle(m_sCurrentSelectedFeature);
|
|||
|
AdjustOffscreenPosition(p, *m_LineEditWidget );
|
|||
|
m_LineEditWidget->move(p.x(), p.y());
|
|||
|
m_LineEditWidget->show();
|
|||
|
|
|||
|
bool success=false;
|
|||
|
success = connect(m_LineEdit, SIGNAL(returnPressed()), this, SLOT(onConfirmClick()) );
|
|||
|
setCursor(Qt::PointingHandCursor);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::onConfirmClick()
|
|||
|
{
|
|||
|
m_HexLabel->clear();
|
|||
|
VmbError_t error;
|
|||
|
bool bOk;
|
|||
|
|
|||
|
QString sName = getFeatureNameFromMap(m_sCurrentSelectedFeature);
|
|||
|
|
|||
|
std::string sRepresentation;
|
|||
|
FeaturePtr pFeature = getFeaturePtr( m_sCurrentSelectedFeature );
|
|||
|
error = pFeature->GetRepresentation( sRepresentation );
|
|||
|
VmbFeatureDataType dt = VmbFeatureDataUnknown;
|
|||
|
pFeature->GetDataType( dt );
|
|||
|
|
|||
|
if( VmbFeatureDataInt == dt )
|
|||
|
{
|
|||
|
qlonglong lValue = 0;
|
|||
|
|
|||
|
if( Helper::needsIPv4Format(sName, sRepresentation))
|
|||
|
{
|
|||
|
m_HexLabel->setText("");
|
|||
|
lValue = Helper::StringToIPv4(m_LineEdit->displayText());
|
|||
|
}
|
|||
|
else if ( sRepresentation == "HexNumber")
|
|||
|
{
|
|||
|
m_HexLabel->setText(" 0x");
|
|||
|
/* convert hex to qlonglong */
|
|||
|
lValue = m_LineEdit->text().toLongLong(&bOk, 16);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_HexLabel->setText("");
|
|||
|
lValue = m_LineEdit->text().toLongLong(&bOk);
|
|||
|
if ( !bOk && !lValue )
|
|||
|
{
|
|||
|
lValue = m_LineEdit->text().contains('-') ? std::numeric_limits<long long>::min() : std::numeric_limits<long long>::max();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
VmbInt64_t nCurrentValue64 = 0, nMin = 0, nMax = 0;
|
|||
|
VmbInt64_t nValue64 = (VmbInt64_t)lValue;
|
|||
|
error = pFeature->GetRange(nMin, nMax);
|
|||
|
if ( VmbErrorSuccess == error )
|
|||
|
{
|
|||
|
if ( nMin > nValue64 )
|
|||
|
{
|
|||
|
nValue64 = nMin;
|
|||
|
}
|
|||
|
if ( nMax < nValue64 )
|
|||
|
{
|
|||
|
nValue64 = nMax;
|
|||
|
}
|
|||
|
error = m_FeaturePtr_LineEdit->SetValue(nValue64);
|
|||
|
}
|
|||
|
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
/* if set is ok, read the value again and put it to GUI */
|
|||
|
error = m_FeaturePtr_LineEdit->GetValue(nCurrentValue64);
|
|||
|
if(VmbErrorSuccess != error)
|
|||
|
{
|
|||
|
if( Helper::needsIPv4Format(sName, sRepresentation))
|
|||
|
{
|
|||
|
m_HexLabel->setText(tr("READ ERROR!!!"));
|
|||
|
}
|
|||
|
else if ( sRepresentation == "HexNumber" )
|
|||
|
{
|
|||
|
m_HexLabel->setText(tr("READ ERROR!!!")+" 0x");
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_HexLabel->setText(tr("READ ERROR!!!"));
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
m_LineEdit->clear();
|
|||
|
|
|||
|
if( Helper::needsIPv4Format(sName, sRepresentation))
|
|||
|
{
|
|||
|
m_LineEdit->insert(Helper::IPv4ToString(nCurrentValue64) );
|
|||
|
}
|
|||
|
else if ( sRepresentation == "HexNumber" )
|
|||
|
{
|
|||
|
m_LineEdit->insert(QString::number(nCurrentValue64, 16));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_LineEdit->insert(QString::number(nCurrentValue64));
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if( Helper::needsIPv4Format(sName, sRepresentation))
|
|||
|
{
|
|||
|
m_HexLabel->setText(tr("WRITE ERROR!!!"));
|
|||
|
}
|
|||
|
else if ( sRepresentation == "HexNumber" )
|
|||
|
{
|
|||
|
m_HexLabel->setText(tr("WRITE ERROR!!!")+" 0x");
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_HexLabel->setText(tr("WRITE ERROR!!!"));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else if ( VmbFeatureDataFloat == dt )
|
|||
|
{
|
|||
|
double dValue = m_LineEdit->text().toDouble( &bOk );
|
|||
|
double dCurrentValue = 0.0, dMin = 0.0, dMax = 0.0;
|
|||
|
|
|||
|
if ( !bOk && !dValue )
|
|||
|
{
|
|||
|
m_HexLabel->setText(tr("ERROR!!!"));
|
|||
|
return;
|
|||
|
}
|
|||
|
error = pFeature->GetRange( dMin, dMax );
|
|||
|
if ( VmbErrorSuccess == error )
|
|||
|
{
|
|||
|
if ( dMin > dValue )
|
|||
|
{
|
|||
|
dValue = dMin;
|
|||
|
}
|
|||
|
if ( dMax < dValue )
|
|||
|
{
|
|||
|
dValue = dMax;
|
|||
|
}
|
|||
|
error = m_FeaturePtr_LineEdit->SetValue(dValue);
|
|||
|
}
|
|||
|
|
|||
|
if(VmbErrorSuccess == error)
|
|||
|
{
|
|||
|
/* if set is ok, read the value again and put it to GUI */
|
|||
|
error = m_FeaturePtr_LineEdit->GetValue( dCurrentValue );
|
|||
|
if( VmbErrorSuccess != error )
|
|||
|
{
|
|||
|
{
|
|||
|
m_HexLabel->setText(tr("READ ERROR!!!"));
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
m_LineEdit->clear();
|
|||
|
|
|||
|
m_LineEdit->insert( QString::number( dCurrentValue ));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
m_HexLabel->setText(tr("WRITE ERROR!!!"));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
bool ControllerTreeWindow::eventFilter(QObject *object, QEvent *event)
|
|||
|
{
|
|||
|
/* set the slider focus back when loosing on scrolling, e.g scrolling right after changing spinbox */
|
|||
|
if (event->type() == QEvent::Wheel)
|
|||
|
{
|
|||
|
if (object == m_Slider_Int)
|
|||
|
{
|
|||
|
if(!m_Slider_Int->hasFocus())
|
|||
|
m_Slider_Int->setFocus();
|
|||
|
}
|
|||
|
|
|||
|
if (object == m_Slider_Float)
|
|||
|
{
|
|||
|
if(!m_Slider_Float->hasFocus())
|
|||
|
m_Slider_Float->setFocus();
|
|||
|
}
|
|||
|
|
|||
|
if (object == m_LogSlider)
|
|||
|
{
|
|||
|
if(!m_LogSlider->hasFocus())
|
|||
|
m_LogSlider->setFocus();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (event->type() == QEvent::MouseButtonPress)
|
|||
|
{
|
|||
|
m_bIsMousePressed = true;
|
|||
|
}
|
|||
|
|
|||
|
if (event->type() == QEvent::MouseButtonRelease)
|
|||
|
{
|
|||
|
m_bIsMousePressed = false;
|
|||
|
|
|||
|
if (object == m_Slider_Int)
|
|||
|
onIntSliderReleased();
|
|||
|
|
|||
|
if (object == m_Slider_Float)
|
|||
|
onFloatSliderReleased();
|
|||
|
|
|||
|
if (object == m_LogSlider)
|
|||
|
onLogarithmicSliderReleased();
|
|||
|
}
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::resetControl()
|
|||
|
{
|
|||
|
/* delete button */
|
|||
|
if( NULL != m_ButtonWidget )
|
|||
|
{
|
|||
|
disconnect( m_CmdButton, SIGNAL(clicked()), this, SLOT(onCmdButtonClick()) );
|
|||
|
delete m_ButtonWidget;
|
|||
|
|
|||
|
m_ButtonWidget = NULL;
|
|||
|
m_CmdButton = NULL;
|
|||
|
m_HButtonLayout = NULL;
|
|||
|
m_HButtonLayout2 = NULL;
|
|||
|
}
|
|||
|
|
|||
|
/* delete ComboBox */
|
|||
|
if( NULL != m_EnumComboBox )
|
|||
|
{
|
|||
|
disconnect( m_EnumComboBox, SIGNAL(activated(const QString &)), this, SLOT(onEnumComboBoxClick(const QString &)) );
|
|||
|
delete m_ComboWidget;
|
|||
|
|
|||
|
m_ComboWidget = NULL;
|
|||
|
m_EnumComboBox = NULL;
|
|||
|
m_HComboLayout = NULL;
|
|||
|
m_HComboLayout2 = NULL;
|
|||
|
}
|
|||
|
|
|||
|
/* delete SpinBox+Slider Int */
|
|||
|
if( ( NULL != m_SpinBox_Int ) && ( NULL != m_Slider_Int ) &&
|
|||
|
( NULL != m_HSpinSliderLayout_Int ) && ( NULL != m_IntSpinSliderWidget))
|
|||
|
{
|
|||
|
removeEventFilter(m_Slider_Int);
|
|||
|
disconnect( m_Slider_Int, SIGNAL(valueChanged(int)), this, SLOT(onIntSliderChanged(int)) );
|
|||
|
disconnect( m_SpinBox_Int, SIGNAL(editingFinished()), this, SLOT(onIntSpinBoxClick()) );
|
|||
|
delete m_IntSpinSliderWidget;
|
|||
|
|
|||
|
m_IntSpinSliderWidget = NULL;
|
|||
|
m_SpinBox_Int = NULL;
|
|||
|
m_Slider_Int = NULL;
|
|||
|
m_HSpinSliderLayout_Int = NULL;
|
|||
|
m_HSpinSliderLayout_Int2 = NULL;
|
|||
|
}
|
|||
|
|
|||
|
/* delete SpinBox+Slider Float */
|
|||
|
if( ( NULL != m_EditBox_Float ) && ( NULL != m_Slider_Float ) &&
|
|||
|
( NULL != m_HSpinSliderLayout_Float ) && ( NULL != m_FloatSliderEditWidget))
|
|||
|
{
|
|||
|
removeEventFilter(m_Slider_Float);
|
|||
|
disconnect( m_Slider_Float, SIGNAL(valueChanged(double)), this, SLOT(onFloatSliderChanged(double)) );
|
|||
|
/* As of Vimba >= 1.4, float features other than ExposureTime don't use spin box anymore */
|
|||
|
disconnect( m_EditBox_Float, SIGNAL(editingFinished()), this, SLOT(onFloatEditFinished()) );
|
|||
|
delete m_FloatSliderEditWidget;
|
|||
|
|
|||
|
m_FloatSliderEditWidget = NULL;
|
|||
|
m_EditBox_Float = NULL;
|
|||
|
m_Slider_Float = NULL;
|
|||
|
m_HSpinSliderLayout_Float = NULL;
|
|||
|
m_HSliderEditLayout_Float2 = NULL;
|
|||
|
}
|
|||
|
|
|||
|
/* delete bool CheckBox */
|
|||
|
if( NULL != m_CheckBox_Bool )
|
|||
|
{
|
|||
|
disconnect( m_CheckBox_Bool, SIGNAL(clicked(bool)), this, SLOT(onBoolCheckBoxClick(bool)) );
|
|||
|
delete m_BooleanWidget;
|
|||
|
|
|||
|
m_BooleanWidget = NULL;
|
|||
|
m_CheckBox_Bool = NULL;
|
|||
|
m_HBooleanLayout = NULL;
|
|||
|
m_HBooleanLayout2 = NULL;
|
|||
|
}
|
|||
|
|
|||
|
/* delete TextEdit */
|
|||
|
if( NULL != m_TextEdit_String )
|
|||
|
{
|
|||
|
disconnect( m_TextEdit_String, SIGNAL(returnPressed()), this, SLOT(onEditText()) );
|
|||
|
delete m_EditWidget;
|
|||
|
|
|||
|
m_EditWidget = NULL;
|
|||
|
m_TextEdit_String = NULL;
|
|||
|
m_HEditLayout = NULL;
|
|||
|
m_HEditLayout2 = NULL;
|
|||
|
}
|
|||
|
|
|||
|
/* delete LineEdit for REG ADD or Multicast IP Address*/
|
|||
|
if( NULL != m_LineEdit )
|
|||
|
{
|
|||
|
disconnect( m_LineEdit, SIGNAL(returnPressed()), this, SLOT(onConfirmClick()) );
|
|||
|
delete m_LineEditWidget;
|
|||
|
|
|||
|
m_LineEditWidget = NULL;
|
|||
|
m_LineEdit = NULL;
|
|||
|
m_HexLabel = NULL;
|
|||
|
m_HLineEditLayout = NULL;
|
|||
|
m_HLineEditLayout2 = NULL;
|
|||
|
}
|
|||
|
|
|||
|
if ( NULL != m_HexWindow )
|
|||
|
{
|
|||
|
/* windows has been closed , just reset it */
|
|||
|
m_HexWindow = NULL;
|
|||
|
m_RawData.clear();
|
|||
|
}
|
|||
|
|
|||
|
/* delete Logarithmic Slider */
|
|||
|
if( NULL != m_LogSliderWidget )
|
|||
|
{
|
|||
|
removeEventFilter(m_LogSlider);
|
|||
|
disconnect( m_LogSlider, SIGNAL( valueChanged( double ) ), this, SLOT( setLogarithmicSliderValue( double ) ) );
|
|||
|
delete m_LogSliderWidget;
|
|||
|
|
|||
|
m_LogSliderWidget = NULL;
|
|||
|
m_LogSlider = NULL;
|
|||
|
m_HLogSliderLayout = NULL;
|
|||
|
m_EditBox_Float = NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::showControl( const bool bIsShow )
|
|||
|
{
|
|||
|
if ( m_IntSpinSliderWidget )
|
|||
|
m_IntSpinSliderWidget->setVisible( bIsShow );
|
|||
|
else if ( m_ButtonWidget )
|
|||
|
m_ButtonWidget->setVisible( bIsShow );
|
|||
|
else if ( m_ComboWidget )
|
|||
|
m_ComboWidget->setVisible( bIsShow );
|
|||
|
else if ( m_FloatSliderEditWidget )
|
|||
|
m_FloatSliderEditWidget->setVisible( bIsShow );
|
|||
|
else if ( m_BooleanWidget )
|
|||
|
m_BooleanWidget->setVisible( bIsShow );
|
|||
|
else if ( m_EditWidget )
|
|||
|
m_EditWidget->setVisible( bIsShow );
|
|||
|
else if ( m_LineEditWidget )
|
|||
|
m_LineEditWidget->setVisible( bIsShow );
|
|||
|
else if ( m_LogSliderWidget )
|
|||
|
m_LogSliderWidget->setVisible( bIsShow );
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::AdjustOffscreenPosition(QPoint &p, QWidget &parentWidget)
|
|||
|
{
|
|||
|
Q_ASSERT( &parentWidget && "parentWidget is NULL reference" );
|
|||
|
|
|||
|
/* out of screen? first identify the current screen */
|
|||
|
QDesktopWidget desktop;
|
|||
|
const QRect currentScreenGeometry = desktop.screenGeometry(desktop.screenNumber(p));
|
|||
|
|
|||
|
parentWidget.adjustSize();
|
|||
|
|
|||
|
/* target position: above and to the right of the targeted position p.x/p.y. */
|
|||
|
p.setY(p.y() - 10 - parentWidget.frameGeometry().height());
|
|||
|
|
|||
|
|
|||
|
/* if parts of the window would appear offscreen, move to the left */
|
|||
|
int horizontalCorrection = (p.x() - currentScreenGeometry.right()) + parentWidget.frameGeometry().width();
|
|||
|
if( horizontalCorrection > 0 )
|
|||
|
p.setX (p.x() - horizontalCorrection);
|
|||
|
|
|||
|
/* if vertical position would be offscreen, show below the current line */
|
|||
|
if( currentScreenGeometry.top() - p.y() > 0 )
|
|||
|
p.setY (p.y() + 24 + parentWidget.frameGeometry().height());
|
|||
|
}
|
|||
|
|
|||
|
void ControllerTreeWindow::closeControls()
|
|||
|
{
|
|||
|
resetControl();
|
|||
|
}
|