Radiation-resistantCamera/Vimba_6_0/VimbaCPP/Examples/VimbaViewer/Source/ViewerWindow.cpp
2025-04-30 09:26:04 +08:00

2380 lines
86 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: ViewerWindow.cpp
Description: The viewer window framework.
This contains of dock widgets like camera feature tree, a histogram, a toolbar and MDI window
-------------------------------------------------------------------------------
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.
=============================================================================*/
#include "ViewerWindow.h"
#include <QTimer>
#include "LineEditCompleter.h"
#include "SortFilterProxyModel.h"
#include "SplashScreen.h"
#include "tabextensioninterface.h"
#include "UI/ControllerTreeWindow.h"
#include "UI/DockWidgetWindow.h"
#include "UI/Histogram/HistogramWindow.h"
#include "UI/MainInformationWindow.h"
#include "UI/Viewer.h"
#include "VmbImageTransformHelper.hpp"
using AVT::VmbAPI::Frame;
using AVT::VmbAPI::FramePtr;
#ifndef _WIN32
#include <unistd.h>
#endif
void ViewerWindow::showSplashScreen(const QString& sID,QWidget* parent)
{
bool bIsModelFound = true;
QPixmap pixmap;
// We expect ID to be of format: Modelname (DevicePartNumber)-DeviceID(DEV_MAC@) while MAC@ has 12 digits
if ( sID.startsWith( "1800" ) )
pixmap.load( ":/VimbaViewer/Images/1800U.png" );
else if ( sID.contains( "Mako" ))
pixmap.load( ":/VimbaViewer/Images/mako.png" );
else if(sID.contains("Manta"))
pixmap.load( ":/VimbaViewer/Images/manta.png" );
else if(sID.contains("GT"))
{
if ( sID.contains( "4100 " )
|| sID.contains( "4905" )
|| sID.contains( "4907" )
|| sID.contains( "6600" ))
pixmap.load( ":/VimbaViewer/Images/prosilicagt-large.png" );
else
pixmap.load( ":/VimbaViewer/Images/prosilicagt.png" );
}
else if(sID.contains("GC"))
pixmap.load( ":/VimbaViewer/Images/prosilicagc.png" );
else if(sID.contains("GX"))
pixmap.load( ":/VimbaViewer/Images/prosilicagx.png" );
else if(sID.contains("GE"))
pixmap.load( ":/VimbaViewer/Images/prosilicage.png" );
else if(sID.contains("Marlin"))
pixmap.load( ":/VimbaViewer/Images/marlin.png" );
else if(sID.contains("Guppy"))
{
if ( sID.contains( "PRO" ))
pixmap.load( ":/VimbaViewer/Images/guppy-pro.png" );
else
pixmap.load( ":/VimbaViewer/Images/guppy.png" );
}
else if(sID.contains("Oscar"))
pixmap.load( ":/VimbaViewer/Images/oscar.png" );
else if(sID.contains("Pike"))
pixmap.load( ":/VimbaViewer/Images/pike.png" );
else if(sID.contains("Stingray"))
pixmap.load( ":/VimbaViewer/Images/stingray.png" );
else if(sID.contains("Bigeye"))
pixmap.load( ":/VimbaViewer/Images/bigeye.png" );
else if(sID.contains("Goldeye P"))
pixmap.load( ":/VimbaViewer/Images/goldeye-p.png" );
else if(sID.contains("Goldeye G") || sID.contains("Goldeye CL"))
{
if ( sID.contains( "Cool" ))
pixmap.load( ":/VimbaViewer/Images/goldeye-g-cool.png" );
else
pixmap.load( ":/VimbaViewer/Images/goldeye-g.png" );
}
else
{
pixmap.load( ":/VimbaViewer/Images/stripes_256.png" );
bIsModelFound = false;
}
SplashScreen splashScreen(pixmap, parent, Qt::SplashScreen);
const int posX = (parent->width() - splashScreen.width()) / 2;
const int posY = (parent->height() - splashScreen.height()) / 2;
splashScreen.setGeometry( posX, posY, splashScreen.width(), splashScreen.height() );
splashScreen.show();
if(bIsModelFound)
{
splashScreen.showMessage("" , Qt::AlignHCenter | Qt::AlignVCenter, Qt::white);
}
else
{
splashScreen.showMessage("" , Qt::AlignHCenter | Qt::AlignVCenter, Qt::black);
}
}
ViewerWindow::ViewerWindow ( QWidget *parent, Qt::WindowFlags flag, QString sID, QString sAccess, bool bAutoAdjustPacketSize, CameraPtr pCam )
: QMainWindow( NULL, flag )
, m_DockController( NULL )
, m_DockInformation( NULL )
, m_Controller( NULL )
, m_ScreenViewer( NULL )
, m_InformationWindow( NULL )
, m_bHasJustStarted ( false )
, m_bIsFirstStart ( true )
, m_bIsCameraRunning ( false )
, m_bIsCamOpen ( false )
, m_bIsRedHighlighted ( false )
, m_bIsViewerWindowClosing ( false )
, m_bIsDisplayEveryFrame ( false )
, m_bUseAllocAndAnnounce ( false )
, m_ImageOptionDialog ( NULL )
, m_saveFileDialog ( NULL )
, m_getDirDialog ( NULL )
, m_bIsTriggeredByMultiSaveBtn (false)
, m_nNumberOfFramesToSave (0)
, m_FrameBufferCount (BUFFER_COUNT)
, m_pCam( pCam )
{
showSplashScreen(sID,parent);
VmbError_t errorType;
QTime openTimer;
openTimer.start();
/* setup information window */
m_InformationWindow = new MainInformationWindow(m_DockInformation, 0, m_pCam);
m_InformationWindow->openLoggingWindow();
if( 0 == sAccess.compare(tr("Open FULL ACCESS")))
{
errorType = m_pCam->Open(VmbAccessModeFull);
m_sAccessMode = tr("(FULL ACCESS)");
}
else if( 0 == sAccess.compare(tr("Open READ ONLY")))
{
errorType = m_pCam->Open(VmbAccessModeRead);
m_sAccessMode = tr("(READ ONLY)");
bAutoAdjustPacketSize = false;
}
else if( 0 == sAccess.compare(tr("Open CONFIG")))
{
errorType = m_pCam->Open(VmbAccessModeConfig);
m_sAccessMode = tr("(CONFIG MODE)");
bAutoAdjustPacketSize = false;
}
else if( 0 == sAccess.compare(tr("Open LITE")))
{
errorType = m_pCam->Open(VmbAccessModeLite);
m_sAccessMode = tr("(LITE)");
bAutoAdjustPacketSize = false;
}
else
{
errorType = VmbErrorInvalidAccess;
bAutoAdjustPacketSize = false;
}
m_OpenError = errorType;
if( VmbErrorSuccess != errorType )
{
openTimer.elapsed();
return;
}
m_sCameraID = sID;
/* create ViewerWindow */
setupUi(this);
if(!m_sAccessMode.isEmpty())
{
sID.append(" ");
sID.append(m_sAccessMode);
}
this->setWindowTitle(sID);
ActionFreerun->setEnabled(isStreamingAvailable());
/* add Viewer Widget to ViewerWindow*/
m_pScene = QSharedPointer<QGraphicsScene>(new QGraphicsScene());
m_PixmapItem = new QGraphicsPixmapItem();
m_ScreenViewer = new Viewer(Ui::ViewerWindow::centralWidget);
m_ScreenViewer->setScene(m_pScene.data());
m_pScene->addItem(m_PixmapItem);
this->setCentralWidget( m_ScreenViewer );
QPixmap image( ":/VimbaViewer/Images/stripes_256.png" );
m_PixmapItem->setPixmap(image);
m_ScreenViewer->show();
m_bIsCamOpen = true;
/* add DockWidgets: Controller and Information */
m_DockController = new DockWidgetWindow(tr("Controller for ")+sID, this);
m_DockInformation = new DockWidgetWindow(tr("Information for ")+sID, this);
m_DockHistogram = new DockWidgetWindow(tr("Histogram for ")+sID, this);
m_DockController->setObjectName("Controller");
m_DockInformation->setObjectName("Information");
m_DockHistogram->setObjectName("Histogram");
this->addDockWidget(static_cast<Qt::DockWidgetArea>(2), m_DockController);
this->addDockWidget(Qt::BottomDockWidgetArea, m_DockInformation);
this->addDockWidget(static_cast<Qt::DockWidgetArea>(1), m_DockHistogram);
m_DockHistogram->hide();
/* add Controller Tree */
QWidget *dockWidgetContents = new QWidget();
QVBoxLayout *verticalLayout2 = new QVBoxLayout(dockWidgetContents);
QSplitter *splitter = new QSplitter(dockWidgetContents);
QWidget *verticalLayoutWidget = new QWidget(splitter);
QVBoxLayout *verticalLayout = new QVBoxLayout(verticalLayoutWidget);
QTabWidget *tabWidget = new QTabWidget(verticalLayoutWidget);
QWidget *widgetTree = new QWidget();
QVBoxLayout *verticalLayout3 = new QVBoxLayout(widgetTree);
m_Description = new QTextEdit();
m_Controller = new ControllerTreeWindow(m_sCameraID, widgetTree, bAutoAdjustPacketSize, m_pCam);
if (VmbErrorSuccess != m_Controller->getTreeStatus())
{
onFeedLogger("ERROR: ControllerTree returned: "+QString::number(m_Controller->getTreeStatus()) + " " + Helper::mapReturnCodeToString(m_Controller->getTreeStatus()));
}
m_Description->setLineWrapMode(QTextEdit::NoWrap);
m_Description->setReadOnly(true);
m_Description->setStyleSheet("font: 12px;\n" "font-family: Verdana;\n");
QList<int> listSize;
listSize << 5000;
splitter->setChildrenCollapsible(false);
splitter->setOrientation(Qt::Vertical);
splitter->addWidget(verticalLayoutWidget);
splitter->addWidget(m_Description);
splitter->setSizes(listSize);
/* Filter Pattern */
QHBoxLayout *pattern_HLayout = new QHBoxLayout();
m_FilterPatternLineEdit = new LineEditCompleter(this);
m_FilterPatternLineEdit->setText(tr("Example: Gain|Width"));
m_FilterPatternLineEdit->setToolTip(tr("To filter multiple features, e.g: Width|Gain|xyz|etc"));
m_FilterPatternLineEdit->setCompleter(m_Controller->getListCompleter());
m_FilterPatternLineEdit->setMinimumWidth(200);
QLabel *filterPatternLabel = new QLabel(tr("Filter pattern:"));
filterPatternLabel->setStyleSheet("font-weight: bold;");
QPushButton *patternButton = new QPushButton(tr("Search"));
pattern_HLayout->addWidget(filterPatternLabel);
pattern_HLayout->addWidget(m_FilterPatternLineEdit);
pattern_HLayout->addWidget(patternButton);
verticalLayout3->addLayout(pattern_HLayout);
connect(m_FilterPatternLineEdit, SIGNAL(returnPressed()), this, SLOT(textFilterChanged()));
connect(patternButton, SIGNAL(clicked(bool)), this, SLOT(textFilterChanged()));
verticalLayout->setContentsMargins(0, 0, 0, 0);
verticalLayout->addWidget(tabWidget);
verticalLayout2->addWidget(splitter);
verticalLayout3->addWidget(m_Controller);
tabWidget->setStyleSheet("color: rgb(0, 0, 0);");
// closed source injected
if (loadPlugin())
{
FeaturePtrVector featVec;
pCam->GetFeatures(featVec);
QVector<FeaturePtr> tmpFeatures = QVector<FeaturePtr>::fromStdVector(featVec);
QSharedPointer<QVector<FeaturePtr> > qFeatVec = QFeatureVectorPtr( new QVector<FeaturePtr>(tmpFeatures));
for (int i = 0; i < m_TabPluginCount; i++)
{
QWidget *plugtabWidget = new QWidget();
TabExtensionResult result = m_tabExtensionInterface[i]->get(qFeatVec, *plugtabWidget);
if ( result == TER_OK)
{
m_tabExtensionInterface[i]->connectToResetFps(this, SLOT(onResetFPS()));
m_tabExtensionInterface[i]->connectFromAcquire(this, SIGNAL(acquisitionRunning(bool)));
tabWidget->addTab(plugtabWidget, plugtabWidget->accessibleName());
}
else
{
delete plugtabWidget;
}
}
}
tabWidget->addTab(widgetTree, tr("All"));
m_DockController->setWidget(dockWidgetContents);
connect(tabWidget, SIGNAL(currentChanged(int)), m_Controller, SLOT(closeControls()));
/* tooltip checkbox */
m_ToolTipCheckBox = new QCheckBox();
m_ToolTipCheckBox->setText(tr("Tooltip ON"));
m_ToolTipCheckBox->setChecked(true);
verticalLayout3->addWidget(m_ToolTipCheckBox);
connect( m_ToolTipCheckBox, SIGNAL(clicked(bool)), this, SLOT(onTooltipCheckBoxClick(bool)) );
connect(m_DockController, SIGNAL(topLevelChanged (bool)), this, SLOT(onfloatingDockChanged(bool)));
connect(m_DockInformation, SIGNAL(topLevelChanged (bool)), this, SLOT(onfloatingDockChanged(bool)));
connect(m_DockHistogram, SIGNAL(topLevelChanged (bool)), this, SLOT(onfloatingDockChanged(bool)));
connect(m_DockController, SIGNAL(visibilityChanged(bool)), this, SLOT(onVisibilityChanged(bool)));
connect(m_DockInformation, SIGNAL(visibilityChanged(bool)), this, SLOT(onVisibilityChanged(bool)));
connect(m_DockHistogram, SIGNAL(visibilityChanged(bool)), this, SLOT(onVisibilityChanged(bool)));
connect(m_Controller, SIGNAL(setDescription(const QString &)), this, SLOT(onSetDescription(const QString &)));
connect(m_Controller, SIGNAL(setEventMessage(const QStringList &)), this, SLOT(onSetEventMessage(const QStringList &)), Qt::QueuedConnection);
connect(m_Controller, SIGNAL(acquisitionStartStop(const QString &)), this, SLOT(onAcquisitionStartStop(const QString &)));
connect(m_Controller, SIGNAL(updateBufferSize()), this, SLOT(onPrepareCapture()));
connect(m_Controller, SIGNAL(resetFPS()), this, SLOT(onResetFPS()));
connect(m_Controller, SIGNAL(logging(const QString &)), this, SLOT(onFeedLogger( const QString &)));
connect(m_ScreenViewer, SIGNAL(savingImage()), this, SLOT(on_ActionSaveAs_triggered()));
connect(m_ScreenViewer, SIGNAL(setColorInterpolationState(const bool &)), this, SLOT(onSetColorInterpolation(const bool &)));
/* create FrameObserver to get frames from camera */
SP_SET( m_pFrameObs, new FrameObserver(m_pCam) );
connect(SP_ACCESS( m_pFrameObs ), SIGNAL(frameReadyFromObserver (QImage , const QString&, const QString&, const QString&)),
this, SLOT(onimageReady(QImage , const QString&, const QString&, const QString&)));
connect(SP_ACCESS( m_pFrameObs ), SIGNAL(frameReadyFromObserverFullBitDepth (tFrameInfo)),
this, SLOT(onFullBitDepthImageReady(tFrameInfo)));
connect(SP_ACCESS( m_pFrameObs ), SIGNAL(setCurrentFPS (const QString &)),
this, SLOT(onSetCurrentFPS(const QString &)));
connect(SP_ACCESS( m_pFrameObs ), SIGNAL(setFrameCounter (const unsigned int &)),
this, SLOT(onSetFrameCounter(const unsigned int &)));
/* HISTOGRAM: We need to register QVector<QVector <quint32> > because it is not known to Qt's meta-object system */
qRegisterMetaType< QVector<QVector <quint32> > >("QVector<QVector <quint32> >");
qRegisterMetaType< QVector <QStringList> >("QVector <QStringList>");
connect(m_pFrameObs.get(), SIGNAL(histogramDataFromObserver ( const QVector<QVector <quint32> > &, const QString &, const double &, const double &, const QVector <QStringList>& )),
this, SLOT(onSetHistogramData( const QVector<QVector <quint32> > &, const QString &, const double &, const double & , const QVector <QStringList>&)));
m_DockInformation->setWidget(m_InformationWindow);
int openElapsedTime = openTimer.elapsed();
if( openElapsedTime <= 2500 )
{
#ifdef WIN32
Sleep(2500-openElapsedTime);
#else
usleep( (2500-openElapsedTime) * 1000 );
#endif
}
/* use default setting position and geometry */
QSettings settings("Allied Vision", "Vimba Viewer");
this->restoreGeometry(settings.value("geometry").toByteArray());
this->restoreState( settings.value("state").toByteArray(), 0 );
this->show();
(!m_DockController->isFloating() && !m_DockInformation->isFloating() && m_DockController->isVisible() && m_DockInformation->isVisible()) ? ActionResetPosition->setEnabled(false) : ActionResetPosition->setEnabled(true);
if( VmbErrorSuccess != m_Controller->getTreeStatus())
{
onFeedLogger("ERROR: GetFeatures returned: "+QString::number(m_Controller->getTreeStatus()) + " " + Helper::mapReturnCodeToString(m_Controller->getTreeStatus()));
}
/* Histogram */
m_HistogramWindow = new HistogramWindow(this);
m_DockHistogram->setWidget(m_HistogramWindow);
m_HistogramWindow->createGraphWidgets();
m_DockHistogram->isVisible() ? ActionHistogram->setChecked(true) : ActionHistogram->setChecked(false);
/* Statusbar */
m_OperatingStatusLabel = new QLabel(" Ready ");
m_FormatLabel = new QLabel;
m_ImageSizeLabel = new QLabel;
m_FramesLabel = new QLabel;
m_FramerateLabel = new QLabel;
statusbar->addWidget(m_OperatingStatusLabel);
statusbar->addWidget(m_ImageSizeLabel);
statusbar->addWidget(m_FormatLabel);
statusbar->addWidget(m_FramesLabel);
statusbar->addWidget(m_FramerateLabel);
m_OperatingStatusLabel->setStyleSheet("background-color: rgb(0,0, 0); color: rgb(255,255,255)");
m_TextItem = new QGraphicsTextItem;
QFont serifFont("Arial", 12, QFont::Bold);
m_TextItem->setFont(serifFont);
m_TextItem->setDefaultTextColor(Qt::red);
/*Save Images Option */
m_ImageOptionDialog = new QDialog(this, windowFlags() & ~Qt::WindowContextHelpButtonHint & ~Qt::WindowMinimizeButtonHint & ~Qt::WindowMaximizeButtonHint);
m_SaveImageOption.setupUi(m_ImageOptionDialog);
if(!settings.value(m_sCameraID).toString().isEmpty())
m_SaveImageOption.ImageDestination_Edit->setText (settings.value(m_sCameraID).toString());
else
{
m_SaveImageOption.ImageDestination_Edit->setText( QString(
#ifdef WIN32
"C:\\"
#else
"/home/"
#endif
));
}
connect(m_SaveImageOption.ImageDestinationButton, SIGNAL(clicked()),this, SLOT(getSaveDestinationPath()));
connect(m_ImageOptionDialog, SIGNAL(accepted()),this, SLOT(acceptSaveImagesDlg()));
connect(m_ImageOptionDialog, SIGNAL(rejected()),this, SLOT(rejectSaveImagesDlg()));
if(!settings.value(m_sCameraID+"SaveImageName").toString().isEmpty())
m_SaveImageOption.ImageName_Edit->setText (settings.value(m_sCameraID+"SaveImageName").toString());
else
m_SaveImageOption.ImageName_Edit->setText("VimbaImage");
/* Direct Access */
m_AccessDialog = new QDialog(this, windowFlags() & ~Qt::WindowContextHelpButtonHint & ~Qt::WindowMinimizeButtonHint & ~Qt::WindowMaximizeButtonHint);
m_DirectAccess.setupUi(m_AccessDialog);
m_DirectAccess.RegAdd_Edit->setMaxLength(8);
m_DirectAccess.RegData_Edit->setMaxLength(8);
m_DirectAccess.RegAdd_Edit->setText("FFFFFFFC");
m_DirectAccess.RegData_Edit->setText("00000000");
m_DirectAccess.RegDataDec_Edit->setText("0");
VmbInterfaceType InterfaceType = VmbInterfaceUnknown;
m_DirectAccess.CheckBoxEndianess->setVisible( VmbErrorSuccess == m_pCam->GetInterfaceType(InterfaceType) );
m_DirectAccess.CheckBoxEndianess->setChecked( VmbInterfaceUsb == InterfaceType );
m_DirectAccess.CheckBoxEndianess->setToolTip( m_DirectAccess.CheckBoxEndianess->toolTip() + " (your device was detected to be " + (VmbInterfaceUsb == InterfaceType ? "little" : "big") + " endian)");
m_AccessDialog->setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint & ~Qt::WindowMinimizeButtonHint);
QRegExp rxHex("[0-9A-Fa-f]{1,8}");
m_DirectAccess.RegAdd_Edit->setValidator(new QRegExpValidator(rxHex, m_DirectAccess.RegAdd_Edit));
m_DirectAccess.RegData_Edit->setValidator(new QRegExpValidator(rxHex, m_DirectAccess.RegData_Edit));
QRegExp rxDec("[0-9]{1,10}");
m_DirectAccess.RegDataDec_Edit->setValidator(new QRegExpValidator(rxDec, m_DirectAccess.RegDataDec_Edit));
connect(m_DirectAccess.RegWrite_Button , SIGNAL(clicked()) , this, SLOT(writeRegisterData()));
connect(m_DirectAccess.RegRead_Button , SIGNAL(clicked()) , this, SLOT(readRegisterData()));
connect(m_DirectAccess.RegData_Edit , SIGNAL(textChanged(const QString&)) , this, SLOT(directAccessHexTextChanged(const QString&)));
connect(m_DirectAccess.RegDataDec_Edit , SIGNAL(textChanged(const QString&)) , this, SLOT(directAccessDecTextChanged(const QString&)));
connect(m_DirectAccess.CheckBoxEndianess, SIGNAL(stateChanged(int)) , this, SLOT(endianessChanged(int)));
/*Viewer Option */
m_ViewerOptionDialog = new QDialog(this, windowFlags() & ~Qt::WindowContextHelpButtonHint & ~Qt::WindowMinimizeButtonHint & ~Qt::WindowMaximizeButtonHint);
m_ViewerOption.setupUi(m_ViewerOptionDialog);
m_ViewerOption.lineEdit_FramesCount->setText(QString::number( m_FrameBufferCount ));
VmbInterfaceType interfaceType = VmbInterfaceUnknown;
m_pCam->GetInterfaceType(interfaceType);
m_bUseAllocAndAnnounce = (interfaceType == VmbInterfaceCSI2);
m_ViewerOption.AllocAndAnnounce_CheckBox->setChecked(m_bUseAllocAndAnnounce);
connect( m_ViewerOption.lineEdit_FramesCount, SIGNAL(textChanged(const QString&)),this, SLOT(optionsFrameCountChanged(const QString&)));
connect( m_ViewerOption.DisplayInterval_CheckBox, SIGNAL(clicked(bool)), this, SLOT(displayEveryFrameClick(bool)));
connect( m_ViewerOption.AllocAndAnnounce_CheckBox, SIGNAL(clicked(bool)), this, SLOT(useAllocAndAnnounceClick(bool)));
connect( m_ViewerOption.buttonBox, SIGNAL(accepted()),this, SLOT(optionsAccepted()));
//connect(parent, SIGNAL(closeViewer()), this, SLOT(close()));
if (ActionHistogram->isChecked())
{
m_HistogramWindow->initializeStatistic();
m_pFrameObs->enableHistogram(true);
}
else
m_pFrameObs->enableHistogram(false);
m_Timer = new QTimer(this);
connect(m_Timer, SIGNAL(timeout()), this, SLOT(updateColorInterpolationState()));
/* enable/disable menu */
connect(m_Controller, SIGNAL(enableViewerMenu(bool)), this, SLOT(enableMenuAndToolbar(bool)));
/* saving images */
m_SaveImageThread = QSharedPointer<SaveImageThread>(new SaveImageThread());
connect( m_SaveImageThread.data(), SIGNAL(setPosition(unsigned int)), this, SLOT(onSaving(unsigned int)));
connect( m_SaveImageThread.data(), SIGNAL( LogMessage(const QString&)), this, SLOT(onFeedLogger(const QString&)) );
if (m_TabPluginCount == 0) // All Tab is visible set focus to "search"
{
m_FilterPatternLineEdit->setFocus();
}
m_FilterPatternLineEdit->selectAll();
#ifdef WIN32
m_SelectedExtension = ".bmp";
#else
m_SelectedExtension = ".png";
#endif
// test if the LibTiff library is available on this system
m_LibTiffAvailable = m_TiffWriter.IsAvailable();
ActionAllow16BitTiffSaving->setEnabled(m_LibTiffAvailable);
}
ViewerWindow::~ViewerWindow()
{
/* save setting position and geometry from last session */
QSettings settings("Allied Vision", "Vimba Viewer");
settings.setValue("geometry", saveGeometry());
settings.setValue("state", saveState(0));
/* If cam is open */
if(!m_sCameraID.isEmpty())
{
settings.setValue(m_sCameraID, m_SaveImageOption.ImageDestination_Edit->text());
if(!m_SaveName.isEmpty())
settings.setValue(m_sCameraID +"SaveImageName", m_SaveName);
if( NULL != m_saveFileDialog )
{
delete m_saveFileDialog;
m_saveFileDialog = NULL;
}
releaseBuffer();
m_pCam->Close();
}
}
void ViewerWindow::textFilterChanged()
{
QPixmap pixmap( ":/VimbaViewer/Images/refresh.png" );
SplashScreen splashScreen(pixmap, m_Controller, Qt::SplashScreen);
int nW = ((m_Controller->width()/2) - splashScreen.width()/2);
int nH = ((m_Controller->height()/2) - splashScreen.height()/2);
splashScreen.setGeometry(nW,nH, splashScreen.width(),splashScreen.height());
splashScreen.show();
splashScreen.showMessage("Please wait..." , Qt::AlignHCenter | Qt::AlignVCenter, Qt::red);
QRegExp::PatternSyntax syntax = QRegExp::PatternSyntax(0);
Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive;
QRegExp regExp(m_FilterPatternLineEdit->text(), caseSensitivity, syntax);
m_Controller->m_ProxyModel->setFilterRegExp(regExp);
m_Controller->expandAll();
m_Controller->updateUnRegisterFeature();
m_Controller->updateRegisterFeature();
m_FilterPatternLineEdit->setFocus();
m_FilterPatternLineEdit->selectAll();
}
void ViewerWindow::enableMenuAndToolbar ( bool bValue )
{
menuBarMainWindow->setEnabled(bValue);
toolBar->setEnabled(bValue);
}
void ViewerWindow::onTooltipCheckBoxClick ( bool bValue )
{
m_Controller->showTooltip ( bValue );
}
void ViewerWindow::updateColorInterpolationState()
{
/* update interpolation state after start */
m_ScreenViewer->updateInterpolationState(m_pFrameObs->getColorInterpolation());
m_Timer->stop();
}
void ViewerWindow::onSetColorInterpolation ( const bool &bState )
{
m_pFrameObs->setColorInterpolation(bState);
}
bool ViewerWindow::getCamOpenStatus() const
{
return m_bIsCamOpen;
}
CameraPtr ViewerWindow::getCameraPtr()
{
return m_pCam;
}
bool ViewerWindow::isControlledCamera( const CameraPtr &cam) const
{
return SP_ACCESS( cam) == SP_ACCESS( m_pCam );
}
bool ViewerWindow::getAdjustPacketSizeMessage ( QString &sMessage )
{
if(m_Controller->isGigE())
{
if(VmbErrorSuccess == m_Controller->getTreeStatus())
{
sMessage = "Packet Size Adjusted:\t";
}
else
{
sMessage = "Failed To Adjust Packet Size!";
sMessage.append(" Reason: " + Helper::mapReturnCodeToString(m_Controller->getTreeStatus()));
}
return true;
}
return false;
}
VmbError_t ViewerWindow::getOpenError() const
{
return m_OpenError;
}
QString ViewerWindow::getCameraID() const
{
return m_sCameraID;
}
void ViewerWindow::closeEvent ( QCloseEvent *event )
{
if (m_bIsCameraRunning)
{
m_bIsViewerWindowClosing = true;
onAcquisitionStartStop("AcquisitionStopFreerun");
}
emit closeViewer( m_pCam );
}
void ViewerWindow::displayEveryFrameClick ( bool bValue )
{
m_ViewerOption.Note_Label->setEnabled(bValue);
m_bIsDisplayEveryFrame = bValue;
}
void ViewerWindow::useAllocAndAnnounceClick ( bool bValue )
{
m_bUseAllocAndAnnounce = bValue;
}
/* Viewer Option */
void ViewerWindow::on_ActionDisplayOptions_triggered()
{
m_ViewerOption.lineEdit_FramesCount->setText(QString::number ( m_FrameBufferCount ));
m_ViewerOptionDialog->exec();
}
void ViewerWindow::on_ActionResetPosition_triggered()
{
m_DockController ->setFloating(false);
m_DockInformation->setFloating(false);
m_DockHistogram ->setFloating(false);
m_DockController ->show();
m_DockInformation->show();
m_DockHistogram ->hide();
ActionHistogram ->setChecked(false);
ActionResetPosition->setEnabled(false);
}
/* Direct Register Access */
void ViewerWindow::on_ActionRegister_triggered()
{
m_DirectAccess.RegAccessError_Label->clear();
m_DirectAccess.RegAccessError_Label->setStyleSheet("");
m_DirectAccess.RegAdd_Edit->setFocus();
m_DirectAccess.RegAdd_Edit->selectAll();
m_AccessDialog->show();
}
void ViewerWindow::optionsFrameCountChanged ( const QString &sText )
{
bool bOk;
unsigned int frames = sText.toUInt(&bOk);
if(!bOk)
{
m_ViewerOption.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
return;
}
if( (0 != QString::number(frames).compare(m_ViewerOption.lineEdit_FramesCount->text()))
||(frames < 1))
{
m_ViewerOption.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
return;
}
m_ViewerOption.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
}
void ViewerWindow::optionsAccepted()
{
bool bOk;
unsigned int frames = m_ViewerOption.lineEdit_FramesCount->text().toUInt(&bOk);
if (!bOk)
{
return;
}
m_FrameBufferCount = frames;
}
void ViewerWindow::directAccessHexTextChanged ( const QString &sText )
{
bool bOk;
unsigned int sDec = sText.toUInt(&bOk, 16);
endianessConvert( sDec );
if(0 == QString::number(sDec).compare(m_DirectAccess.RegDataDec_Edit->text()))
return;
else
m_DirectAccess.RegDataDec_Edit->setText(QString::number(sDec));
}
void ViewerWindow::directAccessDecTextChanged ( const QString &sText )
{
unsigned int lDecValue = sText.toUInt();
endianessConvert( lDecValue );
QString sHex;
sHex.setNum(lDecValue,16);
if(0 == sHex.compare(m_DirectAccess.RegData_Edit->text()))
return;
else
m_DirectAccess.RegData_Edit->setText(sHex);
}
void ViewerWindow::writeRegisterData()
{
bool bOk;
qlonglong lRegAddress = m_DirectAccess.RegAdd_Edit->text().toLongLong(&bOk, 16);
qlonglong lRegData = m_DirectAccess.RegData_Edit->text().toLongLong(&bOk, 16);
m_DirectAccess.RegAccessError_Label->clear();
m_DirectAccess.RegAccessError_Label->setStyleSheet("background-color: rgb(240,240,240); color: rgb(0,0,0)");
m_DirectAccess.RegDataDec_Edit->setFocus();
m_DirectAccess.RegDataDec_Edit->selectAll();
std::vector<VmbUint64_t> address;
address.push_back((VmbUint64_t)lRegAddress);
std::vector<VmbUint64_t> data;
data.push_back((VmbUint64_t)lRegData);
VmbError_t errorType = m_pCam->WriteRegisters(address, data);
if( VmbErrorSuccess != errorType )
{
m_DirectAccess.RegAccessError_Label->setStyleSheet("background-color: rgb(0,0,0); color: rgb(255,0,0)");
m_DirectAccess.RegAccessError_Label->setText(" "+tr("Write Register Failed!")+" <"+tr("Error")+": " + QString::number(errorType) + ">");
}
}
void ViewerWindow::readRegisterData()
{
bool bOk;
qlonglong lRegAddress = m_DirectAccess.RegAdd_Edit->text().toLongLong(&bOk, 16);
m_DirectAccess.RegAccessError_Label->clear();
m_DirectAccess.RegAccessError_Label->setStyleSheet("background-color: rgb(240,240,240); color: rgb(0,0,0)");
std::vector<VmbUint64_t> address;
address.push_back((VmbUint64_t)lRegAddress);
std::vector<VmbUint64_t> data;
data.resize(1);
VmbError_t errorType = m_pCam->ReadRegisters(address, data);
if( VmbErrorSuccess != errorType )
{
m_DirectAccess.RegAccessError_Label->setStyleSheet("background-color: rgb(0,0,0); color: rgb(255,0,0)");
m_DirectAccess.RegAccessError_Label->setText(" "+tr("Read Register Failed!")+" <"+tr("Error:")+" " + QString::number(errorType) + ">");
return;
}
QString sData = QString("%1").arg(data[0], 8, 16, QLatin1Char('0'));
m_DirectAccess.RegData_Edit->setText(sData);
}
void ViewerWindow::endianessChanged(int index)
{
emit directAccessDecTextChanged( m_DirectAccess.RegDataDec_Edit->text() );
}
template <typename T>
void ViewerWindow::endianessConvert(T &v)
{
if( Qt::Checked == m_DirectAccess.CheckBoxEndianess->checkState() )
{
v = qFromBigEndian( v );
}
}
/* Saving an image */
void ViewerWindow::on_ActionSaveAs_triggered()
{
// make a copy of the images before save-as dialog appears (image can change during time dialog open)
QImage image = m_PixmapItem->pixmap().toImage();
tFrameInfo imageFullBitdepth = m_FullBitDepthImage;
QString fileExtension;
bool isImageAvailable = true;
if ( image.isNull() )
{
isImageAvailable = false;
}
else
{
/* Get all inputformats */
unsigned int nFilterSize = QImageReader::supportedImageFormats().count();
for (int i = nFilterSize-1; i >= 0; i--)
{
fileExtension += "."; /* Insert wildcard */
fileExtension += QString(QImageReader::supportedImageFormats().at(i)).toLower(); /* Insert the format */
if(0 != i)
fileExtension += ";;"; /* Insert a space */
}
if( NULL != m_saveFileDialog )
{
delete m_saveFileDialog;
m_saveFileDialog = NULL;
}
m_saveFileDialog = new QFileDialog ( this, tr("Save Image"), m_SaveFileDir, fileExtension );
m_saveFileDialog->setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint & ~Qt::WindowMinimizeButtonHint & ~Qt::WindowMaximizeButtonHint);
m_saveFileDialog->selectFilter(m_SelectedExtension);
m_saveFileDialog->setAcceptMode(QFileDialog::AcceptSave);
if(m_saveFileDialog->exec())
{ //OK
m_SelectedExtension = m_saveFileDialog->selectedNameFilter();
m_SaveFileDir = m_saveFileDialog->directory().absolutePath();
QStringList files = m_saveFileDialog->selectedFiles();
if(!files.isEmpty())
{
QString fileName = files.at(0);
if(!fileName.endsWith(m_SelectedExtension))
{
fileName.append(m_SelectedExtension);
}
bool saved = false;
// save image using LibTiff library for 16 Bit
if( m_LibTiffAvailable && ActionAllow16BitTiffSaving->isChecked() && m_SelectedExtension.contains(".tif") && isSupportedPixelFormat())
{
saved = m_TiffWriter.WriteTiff(imageFullBitdepth, fileName.toAscii());
}
// use default QImage save functionality
else
{
if( true == CanReduceBpp() )
{
saved = ReduceBpp( image ).save( fileName );
}
else
{
saved = image.save( fileName );
}
}
if ( true == saved )
{
QMessageBox::information( this, tr( "Vimba Viewer" ), tr( "Image: " ) + fileName + tr( " saved successfully" ));
}
else
{
QMessageBox::warning( this, tr( "Vimba Viewer" ), tr( "Error saving image" ));
}
}
}
}
if ( !isImageAvailable )
{
QMessageBox::warning( this, tr( "Vimba Viewer" ), tr( "No image to save" ));
}
}
/* Saving multiple images */
void ViewerWindow::on_ActionSaveOptions_triggered()
{
QStringList sListFormat;
for (int i = 0; i < QImageReader::supportedImageFormats().count(); i++)
{
QString sTemp;
sTemp.append("."); /* Insert wildcard */
sTemp.append(QString(QImageReader::supportedImageFormats().at(i)).toLower()); /* Insert the format */
sListFormat << sTemp;
}
sListFormat << ".bin";
m_SaveImageOption.ImageFormat_ComboBox->clear();
m_SaveImageOption.ImageFormat_ComboBox->addItems(sListFormat);
// restore previously selected format (if possible)
if ( false == m_SaveFormat.isEmpty() )
{
int index = m_SaveImageOption.ImageFormat_ComboBox->findText(m_SaveFormat);
if( -1 != index )
{
m_SaveImageOption.ImageFormat_ComboBox->setCurrentIndex(index);
}
}
m_ImageOptionDialog->setModal(true);
m_ImageOptionDialog->show();
}
void ViewerWindow::acceptSaveImagesDlg()
{
if( !m_SaveImageOption.ImageDestination_Edit->text().isEmpty() &&
!m_SaveImageOption.ImageName_Edit->text().isEmpty() )
{
m_ImagePath = m_SaveImageOption.ImageDestination_Edit->text();
}
else
{
if(m_SaveImageOption.ImageDestination_Edit->text().isEmpty())
QMessageBox::warning( this, tr("Vimba Viewer"), "<Save Image Options> "+tr("Please choose your destination path!") );
if(m_SaveImageOption.ImageName_Edit->text().isEmpty())
QMessageBox::warning( this, tr("Vimba Viewer"), "<Save Image Options> "+tr("Please give a name!") );
m_ImageOptionDialog->setModal(true);
m_ImageOptionDialog->show();
}
/* name check existing files */
QDir destDir( m_SaveImageOption.ImageDestination_Edit->text());
QStringList filter;
for (int i = 0; i < QImageReader::supportedImageFormats().count(); i++)
{
QString sTemp;
sTemp.append("*."); /* Insert wildcard */
sTemp.append(QString(QImageReader::supportedImageFormats().at(i)).toLower()); /* Insert the format */
filter << sTemp;
}
destDir.setNameFilters(filter);
QStringList files = destDir.entryList();
bool bRes = true;
while(bRes)
{
bRes = checkUsedName(files);
}
if(0 < m_SaveImageOption.NumberOfFrames_SpinBox->value())
ActionSaveImages->setEnabled(true);
else
ActionSaveImages->setEnabled(false);
m_SaveFormat = m_SaveImageOption.ImageFormat_ComboBox->currentText();
}
void ViewerWindow::rejectSaveImagesDlg()
{
QString sPathBefore = m_SaveImageOption.ImageDestination_Edit->text();
m_SaveImageOption.ImageDestination_Edit->setText(sPathBefore);
}
bool ViewerWindow::checkUsedName ( const QStringList &files )
{
for( int nPos = 0; nPos < files.size(); nPos++ )
{
if(0 == files.at(nPos).compare(m_SaveImageOption.ImageName_Edit->text()+"_1"+m_SaveImageOption.ImageFormat_ComboBox->currentText()))
{
m_SaveImageOption.ImageName_Edit->setText(m_SaveImageOption.ImageName_Edit->text()+"_New");
return true;
}
}
return false;
}
bool ViewerWindow::isDestPathWritable()
{
/* check permission of destination
QFileInfo can not be used, because a windows dir can be write protected, but files inside can be created
*/
QString sTmpPath = m_SaveImageOption.ImageDestination_Edit->text().append("/").append("fileTmp.dat");
QFile fileTmp(sTmpPath);
if(!fileTmp.open( QIODevice::ReadWrite|QIODevice::Text))
{
QMessageBox::warning( this, tr("Vimba Viewer"), "<Save Image Options> "+tr("No permission to write to destination path. Please select another one! ") );
return false;
}
fileTmp.close();
QFile::remove(sTmpPath);
return true;
}
/* confirm saving from toolbar */
void ViewerWindow::on_ActionSaveImages_triggered()
{
#ifdef _WIN32 // Do the check always on Windows
if (!isDestPathWritable())
{
ActionSaveImages->setEnabled(false);
return;
}
#else
#ifndef WIN32
if (!isDestPathWritable())
{
ActionSaveImages->setEnabled(false);
return;
}
#endif
#endif
//overwrite existing name
if(0 != m_SaveImageOption.ImageName_Edit->text().compare(m_SaveImageName))
{
m_SaveImageName = m_SaveImageOption.ImageName_Edit->text();
}
m_nImageCounter = 0;
m_nNumberOfFramesToSave = m_SaveImageOption.NumberOfFrames_SpinBox->value();
m_SaveFormat = m_SaveImageOption.ImageFormat_ComboBox->currentText();
m_SaveName = m_SaveImageOption.ImageName_Edit->text();
m_SaveImageThread->SetNumberToSave ( m_nNumberOfFramesToSave );
m_SaveImageThread->SetSaveFormat ( m_SaveFormat );
m_SaveImageThread->SetPath ( m_ImagePath );
m_SaveImageThread->SetBaseName ( m_SaveName );
if( 0 < m_nNumberOfFramesToSave )
{
if( 0 == m_SaveImageOption.ImageFormat_ComboBox->currentText().compare(".bin"))
m_pFrameObs->saveRawData(m_nNumberOfFramesToSave, m_ImagePath, m_SaveName);
// save full bit depth series of images when requested and LibTif is available
if( m_LibTiffAvailable && ActionAllow16BitTiffSaving->isChecked() && m_SaveFormat.contains(".tif") && isSupportedPixelFormat())
{
m_Allow16BitMultiSave = true;
m_SaveImageThread->SetSave16Bit ( true );
// start transferring full bit depth frames from frame observer
m_pFrameObs->enableFullBitDepthTransfer(true);
}
else
{
m_Allow16BitMultiSave = false;
m_SaveImageThread->SetSave16Bit ( false );
m_bIsTriggeredByMultiSaveBtn = true;
m_pFrameObs->enableFullBitDepthTransfer(false);
}
ActionFreerun->setChecked(isStreamingAvailable());
on_ActionFreerun_triggered();
ActionFreerun->setEnabled(false);
}
}
void ViewerWindow::getSaveDestinationPath()
{
if( NULL != m_getDirDialog )
{
delete m_getDirDialog;
m_getDirDialog = NULL;
}
m_getDirDialog = new QFileDialog ( this, tr("Destination"), m_SaveImageOption.ImageDestination_Edit->text());
QFileDialog::Options options = QFileDialog::DontResolveSymlinks | QFileDialog::ShowDirsOnly |QFileDialog::DontUseNativeDialog;
m_getDirDialog->setOptions(options);
m_getDirDialog->setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint & ~Qt::WindowMinimizeButtonHint & ~Qt::WindowMaximizeButtonHint);
m_getDirDialog->setLabelText(QFileDialog::LookIn, tr("Destination Path"));
m_getDirDialog->setLabelText(QFileDialog::FileType, tr("Type"));
m_getDirDialog->setFileMode( QFileDialog::Directory);
QString sDir;
if( m_getDirDialog->exec() )
{ //OK
sDir = m_getDirDialog->directory().absolutePath();
}
if(!sDir.isEmpty())
m_SaveImageOption.ImageDestination_Edit->setText(sDir);
}
void ViewerWindow::on_ActionLeftRotation_triggered()
{
m_ScreenViewer->rotate(-90);
}
void ViewerWindow::on_ActionRightRotation_triggered()
{
m_ScreenViewer->rotate(90);
}
void ViewerWindow::on_ActionZoomOut_triggered()
{
m_ScreenViewer->zoomOut();
}
void ViewerWindow::on_ActionZoomIn_triggered()
{
m_ScreenViewer->zoomIn();
}
void ViewerWindow::on_ActionOriginalSize_triggered()
{
m_ScreenViewer->setDefaultSize();
}
void ViewerWindow::on_ActionFitToWindow_triggered()
{
m_ScreenViewer->setDefaultSize();
if (ActionFitToWindow->isChecked())
{
m_ScreenViewer->setToolTip(tr(""));
m_ScreenViewer->fitInView(m_pScene->itemsBoundingRect(), Qt::IgnoreAspectRatio);
m_ScreenViewer->enableFitToWindow(true);
ActionLeftRotation->setEnabled(false);
ActionRightRotation->setEnabled(false);
ActionOriginalSize->setEnabled(false);
ActionZoomIn->setEnabled(false);
ActionZoomOut->setEnabled(false);
}
else
{
m_ScreenViewer->enableFitToWindow(false);
ActionLeftRotation->setEnabled(true);
ActionRightRotation->setEnabled(true);
ActionOriginalSize->setEnabled(true);
ActionZoomIn->setEnabled(true);
ActionZoomOut->setEnabled(true);
}
}
void ViewerWindow::on_ActionHistogram_triggered()
{
m_HistogramWindow->deinitializeStatistic();
if (ActionHistogram->isChecked())
{
m_HistogramWindow->initializeStatistic();
m_DockHistogram->show();
m_pFrameObs->enableHistogram(true);
}
else
{
m_DockHistogram->hide();
m_pFrameObs->enableHistogram(false);
}
if(!ActionHistogram->isChecked() && m_DockController->isVisible() && m_DockInformation->isVisible())
ActionResetPosition->setEnabled(false);
}
void ViewerWindow::on_ActionLoadCameraSettings_triggered()
{
bool proceedLoading = true;
// create window title
QString windowTitle = tr( "Load Camera Settings" );
// setup message boxes
QMessageBox msgbox;
msgbox.setWindowTitle( windowTitle );
QMessageBox msgbox2;
msgbox2.setStandardButtons( QMessageBox::Yes );
msgbox2.addButton( QMessageBox::No );
msgbox2.setDefaultButton( QMessageBox::No );
// check if camera was opened in 'full access' mode
if( 0 != m_sAccessMode.compare( tr("(FULL ACCESS)") ) )
{
msgbox.setIcon( QMessageBox::Critical );
msgbox.setText( tr("Camera must be opened in FULL ACCESS mode to use this feature") );
msgbox.exec();
return;
}
// check if any file dialog was created already
if( NULL != m_saveFileDialog )
{
delete m_saveFileDialog;
m_saveFileDialog = NULL;
}
// create file dialog
m_saveFileDialog = new QFileDialog( this, windowTitle, QDir::home().absolutePath(), "*.xml" );
m_saveFileDialog->setWindowFlags( windowFlags() & ~Qt::WindowContextHelpButtonHint & ~Qt::WindowMinimizeButtonHint & ~Qt::WindowMaximizeButtonHint );
m_saveFileDialog->selectFilter( "*.xml" );
m_saveFileDialog->setAcceptMode( QFileDialog::AcceptOpen );
m_saveFileDialog->setFileMode( QFileDialog::ExistingFile );
// show dialog
int rval = m_saveFileDialog->exec();
if( 0 == rval )
{
return;
}
// get selected file
m_SaveFileDir = m_saveFileDialog->directory().absolutePath();
QStringList selectedFiles = m_saveFileDialog->selectedFiles();
if( true == selectedFiles.isEmpty() )
{
msgbox.setIcon( QMessageBox::Critical );
msgbox.setText( tr("No file selected") );
msgbox.exec();
return;
}
// delete file dialog
// (to prevent OCT-1870 bug occured with Qt v4.7.1)
delete m_saveFileDialog;
m_saveFileDialog = NULL;
// get selected file
QString selectedFile = selectedFiles.at(0);
// check if xml file is valid
if( false == selectedFile.endsWith( ".xml" ) )
{
msgbox.setIcon( QMessageBox::Critical );
msgbox.setText( tr("Invalid xml file selected.\nFile must be of type '*.xml'") );
msgbox.exec();
return;
}
// create and prepare xml parser
// to check if model name differences between xxml file
// and connected camera exist
QXmlStreamReader xml;
QFile xmlFile( selectedFile );
QString deviceModel = QString( "" );
// open xml file stream
bool check = xmlFile.open( QIODevice::ReadOnly );
if( false == check )
{
msgbox2.setIcon( QMessageBox::Warning );
msgbox2.setText( tr("Could not validate camera model.\nDo you want to proceed loading settings to selected camera ?") );
rval = msgbox2.exec();
if( QMessageBox::No == rval )
{
proceedLoading = false;
}
}
else
{
// connect opened file with xml stream object
xml.setDevice( &xmlFile );
}
// proceed loading camera settings only if flag still true
if( true == proceedLoading )
{
// read xml structure
while( false == xml.atEnd() )
{
// get current xml token
xml.readNext();
QString currentToken = xml.name().toString();
// check if token is named 'CameraSettings'
if( 0 == currentToken.compare( "CameraSettings" ) )
{
// get token attributes and iterate through them
QXmlStreamAttributes attributes = xml.attributes();
for( int i=0; i<attributes.count(); ++i )
{
// get current attribute
QXmlStreamAttribute currentAttribute = attributes.at(i);
// check if current attribute is name 'CameraModel'
QString attributeName = currentAttribute.name().toString();
if( 0 == attributeName.compare( "CameraModel" ) )
{
deviceModel = currentAttribute.value().toString();
break;
}
}
break;
}
}
// close xml file stream
xmlFile.close();
// check if deviceModel was retrieved from xml file
if( true == deviceModel.isEmpty() )
{
msgbox2.setIcon( QMessageBox::Warning );
msgbox2.setText( tr("Could not validate camera model.\nDo you want to proceed loading settings to selected camera ?") );
rval = msgbox2.exec();
if( QMessageBox::No == rval )
{
proceedLoading = false;
}
}
}
// proceed loading camera settings only if flag still true
std::string modelName;
if( true == proceedLoading )
{
// get model name from connected camera
const VmbErrorType err = m_pCam->GetModel( modelName );
if( VmbErrorSuccess != err )
{
msgbox2.setIcon( QMessageBox::Warning );
msgbox2.setText( tr("Could not validate camera model.\nDo you want to proceed loading settings to selected camera ?") );
rval = msgbox2.exec();
if( QMessageBox::No == rval )
{
proceedLoading = false;
}
}
}
// proceed loading camera settings only if flag still true
if( true == proceedLoading )
{
// compare mode names from xml file and from
// connected device with each other
if( 0 != deviceModel.compare( QString(modelName.c_str()) ) )
{
QString msgtext = tr( "Selected camera model is different from xml file.\n");
msgtext.append( tr("[camera: %1]\n").arg( modelName.c_str() ) );
msgtext.append( tr("[xml: %1]\n\n").arg( deviceModel) );
msgtext.append( tr("Do you want to proceed loading operation ?" ) );
msgbox2.setIcon( QMessageBox::Warning );
msgbox2.setText( msgtext );
rval = msgbox2.exec();
if( QMessageBox::No == rval )
{
proceedLoading = false;
}
}
}
// proceed loading camera settings only if flag still true
if( true == proceedLoading )
{
// setup behaviour for loading and saving camera features
m_pCam->LoadSaveSettingsSetup( VmbFeaturePersistNoLUT, 5, 4 );
// call load method from VimbaCPP
const VmbErrorType err = m_pCam->LoadCameraSettings( selectedFile.toStdString() );
if( VmbErrorSuccess != err )
{
QString msgtext = tr( "There have been errors during loading of feature values.\n" );
msgtext.append( tr("[Error code: %1]\n").arg( err ) );
msgtext.append( tr("[file: %1]").arg( selectedFile) );
onFeedLogger( "ERROR: LoadCameraSettings returned: " + QString::number(err) + ". For details activate VimbaC logging and check out VmbCameraSettingsLoad.log" );
msgbox.setIcon( QMessageBox::Warning );
msgbox.setText( msgtext );
msgbox.exec();
return;
}
else
{
msgbox.setIcon( QMessageBox::Information );
QString msgtext = tr( "Successfully loaded device settings\nfrom '%1'" ).arg( selectedFile );
msgbox.setText( msgtext );
msgbox.exec();
}
}
}
void ViewerWindow::on_ActionSaveCameraSettings_triggered()
{
VmbErrorType err = VmbErrorSuccess;
// create window title
QString windowTitle = tr( "Save Camera Settings" );
// create message box
QMessageBox msgbox;
msgbox.setWindowTitle( windowTitle );
// check if camera was opened in 'full access' mode
if( 0 != m_sAccessMode.compare( tr("(FULL ACCESS)") ) )
{
msgbox.setIcon( QMessageBox::Critical );
msgbox.setText( tr("Camera must be opened in FULL ACCESS mode to use this feature") );
msgbox.exec();
return;
}
// check if any file dialog was created already
if( NULL != m_saveFileDialog )
{
delete m_saveFileDialog;
m_saveFileDialog = NULL;
}
// setup file dialog
m_saveFileDialog = new QFileDialog( this, windowTitle, QDir::home().absolutePath(), "*.xml" );
m_saveFileDialog->setWindowFlags( windowFlags() & ~Qt::WindowContextHelpButtonHint & ~Qt::WindowMinimizeButtonHint & ~Qt::WindowMaximizeButtonHint );
m_saveFileDialog->selectFilter( "*.xml" );
m_saveFileDialog->setAcceptMode( QFileDialog::AcceptSave );
// show dialog
int rval = m_saveFileDialog->exec();
if( 0 == rval )
{
return;
}
// get selected file
m_SaveFileDir = m_saveFileDialog->directory().absolutePath();
QStringList selectedFiles = m_saveFileDialog->selectedFiles();
if( true == selectedFiles.isEmpty() )
{
msgbox.setIcon( QMessageBox::Critical );
msgbox.setText( tr("No file selected") );
msgbox.exec();
return;
}
// delete file dialog
// (to prevent OCT-1870 bug occured with Qt v4.7.1)
delete m_saveFileDialog;
m_saveFileDialog = NULL;
// get selected file
QString selectedFile = selectedFiles.at(0);
if( false == selectedFile.endsWith( ".xml" ) )
{
selectedFile.append( ".xml" );
}
// setup behaviour for loading and saving camera features
m_pCam->LoadSaveSettingsSetup( VmbFeaturePersistNoLUT, 5, 4 );
// call VimbaCPP save function
QString msgtext;
err = m_pCam->SaveCameraSettings( selectedFile.toStdString() );
if( VmbErrorSuccess != err )
{
msgtext = tr( "There have been errors during saving feature values.\n" );
msgtext.append( tr("[Error code: %1]\n").arg( err ) );
msgtext.append( tr("[file: %1]").arg( selectedFile) );
onFeedLogger( "ERROR: SaveCameraSettings returned: " + QString::number(err) + ". For details activate VimbaC logging and check out VmbCameraSettingsSave.log" );
msgbox.setIcon( QMessageBox::Warning );
msgbox.setText( msgtext );
msgbox.exec();
return;
}
else
{
msgtext = tr( "Successfully saved device settings to\n'" );
msgtext.append( selectedFile );
msgtext.append( "'" );
msgbox.setIcon( QMessageBox::Information );
msgbox.setText( msgtext );
msgbox.exec();
}
}
void ViewerWindow::on_ActionLoadCameraSettingsMenu_triggered()
{
on_ActionLoadCameraSettings_triggered();
}
void ViewerWindow::on_ActionSaveCameraSettingsMenu_triggered()
{
on_ActionSaveCameraSettings_triggered();
}
void ViewerWindow::on_ActionAllow16BitTiffSaving_triggered()
{
if ( ActionAllow16BitTiffSaving->isChecked() && m_LibTiffAvailable && isSupportedPixelFormat())
{
m_pFrameObs->enableFullBitDepthTransfer(true);
}
else
{
m_pFrameObs->enableFullBitDepthTransfer(false);
}
}
void ViewerWindow::onfloatingDockChanged ( bool bIsFloating )
{
if( (m_DockController->isFloating() || (false == m_DockController->isVisible())) ||
(m_DockInformation->isFloating() || (false == m_DockInformation->isVisible())) )
ActionResetPosition->setEnabled(true);
else
ActionResetPosition->setEnabled(false);
if(m_DockHistogram->isVisible())
ActionHistogram->setChecked(true);
}
void ViewerWindow::onVisibilityChanged ( bool bIsVisible )
{
if( m_DockController->isVisible() && !m_DockController->isFloating() &&
m_DockInformation->isVisible() && !m_DockInformation->isFloating() )
{
ActionResetPosition->setEnabled(false);
}
else
{
ActionResetPosition->setEnabled(true);
}
if(!m_DockHistogram->isVisible())
{
if (ActionHistogram->isChecked() )
{
ActionHistogram->setChecked(false);
}
}
else
{
ActionHistogram->setChecked(true);
}
}
void ViewerWindow::onResetFPS()
{
SP_ACCESS( m_pFrameObs )->resetFrameCounter(false);
}
void ViewerWindow::onSetCurrentFPS( const QString &sFPS )
{
m_FramerateLabel->setText( QString::fromStdString(" Current FPS: ")+ sFPS + " " );
}
void ViewerWindow::onSetFrameCounter( const unsigned int &nNumberOfFrames )
{
m_FramesLabel->setText( "Frames: " + QString::number(nNumberOfFrames) + " " );
}
void ViewerWindow::onSetEventMessage ( const QStringList &sMsg )
{
m_InformationWindow->setEventMessage(sMsg);
}
void ViewerWindow::onSetDescription ( const QString &sDesc )
{
m_Description->setText(sDesc);
}
void ViewerWindow::onSetHistogramData ( const QVector<QVector <quint32> > &histData, const QString &sHistogramTitle,
const double &nMaxHeight_YAxis, const double &nMaxWidth_XAxis, const QVector <QStringList> &statistics )
{
if( ActionHistogram->isChecked() )
{
QStringList ColorComponentList;
QStringList MinimumValueList;
QStringList MaximumValueList;
QStringList AverageValueList;
QString sFormat;
if(sHistogramTitle.contains("Mono8"))
{
sFormat = "Mono8";
ColorComponentList << statistics.at(0).at(0);
MinimumValueList << statistics.at(0).at(1);
MaximumValueList << statistics.at(0).at(2);
AverageValueList << statistics.at(0).at(3);
m_HistogramWindow->setStatistic(ColorComponentList, MinimumValueList, MaximumValueList, AverageValueList, sFormat);
}
if(sHistogramTitle.contains("RGB8") || sHistogramTitle.contains("BGR8") || sHistogramTitle.contains("YUV") || sHistogramTitle.contains("Bayer"))
{
if(sHistogramTitle.contains("RGB8") || sHistogramTitle.contains("BGR8"))
sFormat = "RGB";
if(sHistogramTitle.contains("Bayer"))
sFormat = "Bayer";
if(sHistogramTitle.contains("YUV"))
sFormat = "YUV";
ColorComponentList << statistics.at(0).at(0) << statistics.at(1).at(0) << statistics.at(2).at(0);
MinimumValueList << statistics.at(0).at(1) << statistics.at(1).at(1) << statistics.at(2).at(1);
MaximumValueList << statistics.at(0).at(2) << statistics.at(1).at(2) << statistics.at(2).at(2);
AverageValueList << statistics.at(0).at(3) << statistics.at(1).at(3) << statistics.at(2).at(3);
m_HistogramWindow->setStatistic(ColorComponentList, MinimumValueList, MaximumValueList, AverageValueList, sFormat);
}
m_HistogramWindow->updateHistogram(histData, sHistogramTitle, nMaxHeight_YAxis, nMaxWidth_XAxis);
}
else
m_pFrameObs->enableHistogram(false);
}
/* display frames on viewer */
void ViewerWindow::onimageReady ( QImage image, const QString &sFormat, const QString &sHeight, const QString &sWidth )
{
m_FormatLabel->setText("Pixel Format: " + sFormat + " ");
m_ImageSizeLabel->setText("Size H: " + sHeight + " ,W: "+ sWidth + " ");
if(m_bHasJustStarted)
{
foreach( QGraphicsItem *item, m_pScene->items() )
{
if( item->type() == QGraphicsTextItem::Type )
{
m_pScene->removeItem(m_TextItem);
m_FormatLabel->setStyleSheet("background-color: rgb(195,195,195); color: rgb(0,0,0)");
m_bIsRedHighlighted = false;
continue;
}
m_pScene->removeItem(m_PixmapItem);
}
m_pScene->addItem(m_PixmapItem);
m_bHasJustStarted = false;
}
if( (sFormat.contains("Convert Error")) )
{
if( false == m_bIsRedHighlighted )
{
m_bIsRedHighlighted = true;
m_FormatLabel->setStyleSheet("background-color: rgb(196,0, 0); color: rgb(255,255,255)");
if (sFormat.contains("height") || sFormat.contains("width"))
{
m_TextItem->setPlainText("The Resolution you set is not supported by VimbaImageTransform.\n"
"Please change height or width !");
}
else
{
m_TextItem->setPlainText("PixelFormat transformation not supported.");
}
m_TextItem->setPos(m_pScene->width()/6, m_pScene->height()/2);
m_pScene->addItem(m_TextItem);
}
}
else
{
if( m_bIsRedHighlighted )
{
m_FormatLabel->setStyleSheet("background-color: rgb(195,195,195); color: rgb(0,0,0)");
m_bIsRedHighlighted = false;
if (!m_pScene->items().isEmpty())
{
m_pScene->removeItem(m_TextItem);
}
}
}
/* display it at centre whenever changed */
m_pScene->setSceneRect(0, 0, image.width(), image.height() );
m_PixmapItem->setPixmap(QPixmap::fromImage(image));
m_ScreenViewer->show();
/* save series of images */
if( (0 < m_nNumberOfFramesToSave) && m_bIsTriggeredByMultiSaveBtn )
{
++m_nImageCounter;
if(m_nImageCounter <= m_nNumberOfFramesToSave)
{
m_SaveImageThread->start();
try
{
static bool bCanReduceBpp;
// Test only once for every batch to save
if ( 1 == m_nImageCounter )
{
bCanReduceBpp = CanReduceBpp();
}
// Save with 8 bpp
if ( true == bCanReduceBpp )
{
m_SaveImageThread->Enqueue( ReduceBpp( image ), m_nImageCounter );
}
// Save as is
else
{
m_SaveImageThread->Enqueue( image, m_nImageCounter );
}
// Reset at end of batch
if ( m_nImageCounter == m_nNumberOfFramesToSave )
{
bCanReduceBpp = false;
}
}
catch( const std::bad_alloc &/*bex*/)
{
m_bIsRedHighlighted = false;
ActionFreerun->setChecked(false);
on_ActionFreerun_triggered();
ActionFreerun->setEnabled(isStreamingAvailable());
m_SaveImagesDialog->hide();
delete m_SaveImagesDialog;
m_SaveImagesDialog = NULL;
m_SaveImageThread->StopProcessing();
m_SaveImageThread->wait();
m_bIsTriggeredByMultiSaveBtn = false;
m_Allow16BitMultiSave = false;
}
}
}
}
void ViewerWindow::onFullBitDepthImageReady(tFrameInfo mFullImageInfo)
{
// store a full bit depth image frame in case user wants to save to file
m_FullBitDepthImage = mFullImageInfo;
// save series of TIFF images using LibTif
if( (0 < m_nNumberOfFramesToSave) && m_Allow16BitMultiSave )
{
m_SaveImageThread->start();
++m_nImageCounter;
if(m_nImageCounter <= m_nNumberOfFramesToSave)
{
try
{
m_SaveImageThread->Enqueue( mFullImageInfo, m_nImageCounter );
}
catch( const std::bad_alloc &bex)
{
m_bIsRedHighlighted = false;
ActionFreerun->setChecked(false);
on_ActionFreerun_triggered();
ActionFreerun->setEnabled(isStreamingAvailable());
m_SaveImagesDialog->hide();
delete m_SaveImagesDialog;
m_SaveImagesDialog = NULL;
m_SaveImageThread->StopProcessing();
m_SaveImageThread->wait();
m_bIsTriggeredByMultiSaveBtn = false;
m_Allow16BitMultiSave = false;
}
}
}
}
void ViewerWindow::onSaving ( unsigned int nPos )
{
if( 1 == nPos )
{
//Start Progressbar
m_SaveImagesDialog = new QDialog(0, Qt::CustomizeWindowHint|Qt::WindowTitleHint);
m_SaveImagesUIDialog.setupUi(m_SaveImagesDialog);
m_SaveImagesUIDialog.saveImagesProgress->setMaximum(m_nNumberOfFramesToSave);
m_SaveImagesUIDialog.saveImagesProgress->setMinimum(1);
m_SaveImagesDialog->show();
}
m_SaveImagesUIDialog.saveImagesProgress->setValue(nPos);
if (m_nNumberOfFramesToSave == nPos)
{
m_FormatLabel->setStyleSheet("background-color: rgb(195,195,195); color: rgb(0,0,0)");
m_bIsRedHighlighted = false;
ActionFreerun->setChecked(false);
on_ActionFreerun_triggered();
ActionFreerun->setEnabled(isStreamingAvailable());
foreach( QGraphicsItem *item, m_pScene->items() )
{
if( item->type() == QGraphicsTextItem::Type )
{
m_pScene->removeItem(m_TextItem);
break;
}
}
m_SaveImagesDialog->hide();
delete m_SaveImagesDialog;
m_SaveImagesDialog = NULL;
m_SaveImageThread->StopProcessing();
m_SaveImageThread->wait();
m_nImageCounter = 0;
m_bIsTriggeredByMultiSaveBtn = false;
m_Allow16BitMultiSave = false;
// restore state of full bit depth image transfer flag
on_ActionAllow16BitTiffSaving_triggered();
}
}
void ViewerWindow::onAcquisitionStartStop ( const QString &sThisFeature )
{
QIcon icon;
/* this is intended to stop and start the camera again since PixelFormat, Height and Width have been changed while camera running
* ignore this when the changing has been made while camera not running
*/
if( ((0 == sThisFeature.compare("AcquisitionStart")) && (m_bIsCameraRunning)) )
{
ActionFreerun->setChecked(true);
on_ActionFreerun_triggered();
}
else if( sThisFeature.contains("AcquisitionStartFreerun") )
{
SP_ACCESS( m_pFrameObs )->resetFrameCounter(true);
if(!m_bIsCameraRunning)
{
icon.addFile(QString::fromUtf8(":/VimbaViewer/Images/stop.png"), QSize(), QIcon::Normal, QIcon::On);
ActionFreerun->setIcon(icon);
checkDisplayInterval();
releaseBuffer();
onPrepareCapture();
ActionFreerun->setChecked(true);
m_bIsCameraRunning = true;
m_bHasJustStarted = true;
emit acquisitionRunning(true);
if(ActionDisplayOptions->isEnabled())
ActionDisplayOptions->setEnabled(false);
if(ActionSaveOptions->isEnabled())
ActionSaveOptions->setEnabled(false);
/* if save images settings set, and acquisition starts */
if( (0 < m_SaveImageOption.NumberOfFrames_SpinBox->value()) && ActionSaveImages->isEnabled() )
{
ActionSaveImages->setEnabled(false);
m_nImageCounter = 0;
m_nNumberOfFramesToSave = 0;
}
m_OperatingStatusLabel->setText( " Running... " );
m_OperatingStatusLabel->setStyleSheet("background-color: rgb(0,128, 0); color: rgb(255,255,255)");
}
}
else if( sThisFeature.contains("AcquisitionStopFreerun") )
{
if(m_bIsCameraRunning)
{
icon.addFile(QString::fromUtf8(":/VimbaViewer/Images/play.png"), QSize(), QIcon::Normal, QIcon::Off);
ActionFreerun->setIcon(icon);
releaseBuffer();
ActionFreerun->setChecked(false);
if (m_bIsViewerWindowClosing)
on_ActionFreerun_triggered();
m_bIsCameraRunning = false;
emit acquisitionRunning(false);
if(!ActionSaveOptions->isEnabled())
ActionSaveOptions->setEnabled(true);
if(!ActionFreerun->isEnabled())
ActionFreerun->setEnabled(isStreamingAvailable());
if(!ActionDisplayOptions->isEnabled())
ActionDisplayOptions->setEnabled(true);
/* if save images running, and acquisition stops */
if( (0 < m_SaveImageOption.NumberOfFrames_SpinBox->value()) && !ActionSaveImages->isEnabled() )
{
ActionSaveImages->setEnabled(true);
}
m_Controller->synchronizeEventFeatures();
}
m_OperatingStatusLabel->setText( " Ready " );
m_OperatingStatusLabel->setStyleSheet("background-color: rgb(0,0, 0); color: rgb(255,255,255)");
}
else if( ((0 == sThisFeature.compare("AcquisitionStop")) && (m_bIsCameraRunning)) ||
(sThisFeature.contains("AcquisitionStopWidthHeight")))
{
if(m_bIsCameraRunning)
{
ActionFreerun->setChecked(false);
on_ActionFreerun_triggered();
/* use this for GigE, so you can change the W/H "on the fly" */
if(0 == sThisFeature.compare("AcquisitionStopWidthHeight"))
{
m_bIsCameraRunning = true;
emit acquisitionRunning(true);
}
}
// update state of full bit depth image transfer flag in case pixel format has changed
on_ActionAllow16BitTiffSaving_triggered();
}
// update state of full bit depth image transfer flag in case pixel format has changed
on_ActionAllow16BitTiffSaving_triggered();
}
void ViewerWindow::checkDisplayInterval()
{
FeaturePtr pFeatMode;
if(VmbErrorSuccess == m_pCam->GetFeatureByName( "AcquisitionMode", pFeatMode ))
{
std::string sValue("");
if( VmbErrorSuccess == pFeatMode->GetValue(sValue) )
{
/* display all received frames for SingleFrame and MultiFrame mode or if the user wants to have it */
if( 0 == sValue.compare("SingleFrame") || 0 == sValue.compare("MultiFrame") || m_bIsDisplayEveryFrame )
SP_ACCESS( m_pFrameObs )->setDisplayInterval( 0 );
/* display frame in a certain interval to save CPU consumption for continuous mode */
else
SP_ACCESS( m_pFrameObs )->setDisplayInterval( 1 );
}
}
}
void ViewerWindow::on_ActionFreerun_triggered()
{
VmbError_t error;
FeaturePtr pFeat;
checkDisplayInterval();
/* update interpolation state after start */
if( !m_Timer->isActive())
{
m_Timer->start(200);
}
QIcon icon;
/* ON */
if( ActionFreerun->isChecked() )
{
icon.addFile(QString::fromUtf8(":/VimbaViewer/Images/stop.png"), QSize(), QIcon::Normal, QIcon::On);
ActionFreerun->setIcon(icon);
error = onPrepareCapture();
if( VmbErrorSuccess != error )
{
m_bIsCameraRunning = false;
emit acquisitionRunning(false);
m_OperatingStatusLabel->setText( " Failed to start! Error: " + QString::number(error)+" "+Helper::mapReturnCodeToString(error) );
m_OperatingStatusLabel->setStyleSheet("background-color: rgb(196,0, 0); color: rgb(255,255,255)");
icon.addFile(QString::fromUtf8(":/VimbaViewer/Images/play.png"), QSize(), QIcon::Normal, QIcon::Off);
ActionFreerun->setIcon(icon);
ActionFreerun->setChecked(false);
return;
}
error = m_pCam->GetFeatureByName( "AcquisitionStart", pFeat );
int nResult = m_sAccessMode.compare(tr("(READ ONLY)")) ;
if ( (VmbErrorSuccess == error) && ( 0 != nResult ) )
{
SP_ACCESS( m_pFrameObs )->resetFrameCounter(true);
// Do some GUI-related preparations before really starting (to avoid timing problems)
m_OperatingStatusLabel->setText( " Running... " );
m_OperatingStatusLabel->setStyleSheet("background-color: rgb(0,128, 0); color: rgb(255,255,255)");
if(ActionDisplayOptions->isEnabled())
ActionDisplayOptions->setEnabled(false);
if(ActionSaveOptions->isEnabled())
ActionSaveOptions->setEnabled(false);
if( ActionSaveImages->isEnabled() && (0 < m_SaveImageOption.NumberOfFrames_SpinBox->value()) )
ActionSaveImages->setEnabled(false);
error = pFeat->RunCommand();
if(VmbErrorSuccess == error)
{
if(m_bIsFirstStart)
{
m_bIsFirstStart = false;
}
m_bHasJustStarted = true;
m_bIsCameraRunning = true;
emit acquisitionRunning(true);
}
else
{
m_bIsCameraRunning = false;
emit acquisitionRunning(false);
m_OperatingStatusLabel->setText( " Failed to execute AcquisitionStart! Error: " + QString::number(error)+" "+Helper::mapReturnCodeToString(error) );
m_OperatingStatusLabel->setStyleSheet("background-color: rgb(196,0, 0); color: rgb(255,255,255)");
m_InformationWindow->feedLogger("Logging", QString(QTime::currentTime().toString("hh:mm:ss:zzz")+"\t" +
" RunCommand [AcquisitionStart] Failed! Error: " + QString::number(error)+" "+
Helper::mapReturnCodeToString(error)), VimbaViewerLogCategory_ERROR);
if(ActionDisplayOptions->isEnabled())
ActionDisplayOptions->setEnabled(true);
if(ActionSaveOptions->isEnabled())
ActionSaveOptions->setEnabled(true);
if( ActionSaveImages->isEnabled() && (0 < m_SaveImageOption.NumberOfFrames_SpinBox->value()) )
ActionSaveImages->setEnabled(true);
}
}
}
/* OFF */
else
{
error = m_pCam->GetFeatureByName("AcquisitionStop", pFeat);
if ( (VmbErrorSuccess == error) )
{
if(0 != m_sAccessMode.compare(tr("(READ ONLY)")))
error = pFeat->RunCommand();
icon.addFile(QString::fromUtf8(":/VimbaViewer/Images/play.png"), QSize(), QIcon::Normal, QIcon::Off);
ActionFreerun->setIcon(icon);
if(VmbErrorSuccess == error)
{
m_bIsCameraRunning = false;
emit acquisitionRunning(false);
m_OperatingStatusLabel->setText( " Ready " );
m_OperatingStatusLabel->setStyleSheet("background-color: rgb(0,0, 0); color: rgb(255,255,255)");
releaseBuffer();
}
else
{
m_InformationWindow->feedLogger("Logging", QString(QTime::currentTime().toString("hh:mm:ss:zzz")+"\t" +
" RunCommand [AcquisitionStop] Failed! Error: " + QString::number(error) + " " +
Helper::mapReturnCodeToString(error) ), VimbaViewerLogCategory_ERROR);
}
}
if(!ActionDisplayOptions->isEnabled())
ActionDisplayOptions->setEnabled(true);
if(!ActionSaveOptions->isEnabled())
ActionSaveOptions->setEnabled(true);
if( !ActionSaveImages->isEnabled() && (0 < m_SaveImageOption.NumberOfFrames_SpinBox->value()))
ActionSaveImages->setEnabled(true);
m_Controller->synchronizeEventFeatures();
}
}
VmbError_t ViewerWindow::releaseBuffer()
{
m_pFrameObs->Stopping();
VmbError_t error = m_pCam->EndCapture();
if( VmbErrorSuccess == error )
error = m_pCam->FlushQueue();
if( VmbErrorSuccess == error )
error = m_pCam->RevokeAllFrames();
return error;
}
VmbError_t ViewerWindow::onPrepareCapture()
{
FeaturePtr pFeature;
VmbInt64_t nPayload = 0;
QVector <FramePtr> frames;
VmbError_t error = m_pCam->GetFeatureByName("PayloadSize", pFeature);
VmbUint32_t nCounter = 0;
if( VmbErrorSuccess == error )
{
error = pFeature->GetValue(nPayload);
if(VmbErrorSuccess == error)
{
frames.resize(m_FrameBufferCount);
bool bIsStreamingAvailable = isStreamingAvailable();
if (bIsStreamingAvailable)
{
for (int i=0; i<frames.size(); i++)
{
try
{
frames[i] = FramePtr(new Frame(nPayload, (m_bUseAllocAndAnnounce) ? AVT::VmbAPI::FrameAllocation_AllocAndAnnounceFrame : AVT::VmbAPI::FrameAllocation_AnnounceFrame ));
nCounter++;
}
catch(std::bad_alloc& )
{
frames.resize((VmbInt64_t) (nCounter * 0.7));
break;
}
m_pFrameObs->Starting();
error = frames[i]->RegisterObserver(m_pFrameObs);
if( VmbErrorSuccess != error )
{
m_InformationWindow->feedLogger("Logging",
QString(QTime::currentTime().toString("hh:mm:ss:zzz")+"\t" + " RegisterObserver frame["+ QString::number(i)+ "] Failed! Error: " + QString::number(error)+" "+ Helper::mapReturnCodeToString(error)),
VimbaViewerLogCategory_ERROR);
return error;
}
}
for (int i=0; i<frames.size(); i++)
{
error = m_pCam->AnnounceFrame( frames[i] );
VmbUchar_t* pBuffer;
frames[i]->GetBuffer(pBuffer);
if( VmbErrorSuccess != error )
{
m_InformationWindow->feedLogger("Logging",
QString(QTime::currentTime().toString("hh:mm:ss:zzz")+"\t" + " AnnounceFrame ["+ QString::number(i)+ "] Failed! Error: " + QString::number(error)+" "+ Helper::mapReturnCodeToString(error)),
VimbaViewerLogCategory_ERROR);
return error;
}
}
}
if(VmbErrorSuccess == error)
{
error = m_pCam->StartCapture();
if( VmbErrorSuccess != error )
{
QString sMessage = " StartCapture Failed! Error: ";
if(0 != m_sAccessMode.compare(tr("(READ ONLY)")))
m_InformationWindow->feedLogger("Logging",
QString(QTime::currentTime().toString("hh:mm:ss:zzz")+"\t" + sMessage + QString::number(error)+" "+ Helper::mapReturnCodeToString(error)),
VimbaViewerLogCategory_ERROR);
return error;
}
}
if (bIsStreamingAvailable)
{
for (int i=0; i<frames.size(); i++)
{
error = m_pCam->QueueFrame( frames[i] );
if( VmbErrorSuccess != error )
{
m_InformationWindow->feedLogger("Logging",
QString(QTime::currentTime().toString("hh:mm:ss:zzz")+"\t" + " QueueFrame ["+ QString::number(i)+ "] Failed! Error: " + QString::number(error)+" "+ Helper::mapReturnCodeToString(error)),
VimbaViewerLogCategory_ERROR);
return error;
}
}
}
}
else
{
m_InformationWindow->feedLogger("Logging",
QString(QTime::currentTime().toString("hh:mm:ss:zzz")+"\t" + " GetValue [PayloadSize] Failed! Error: " + QString::number(error)+" "+ Helper::mapReturnCodeToString(error)),
VimbaViewerLogCategory_ERROR);
return error;
}
}
else
{
m_InformationWindow->feedLogger("Logging",
QString(QTime::currentTime().toString("hh:mm:ss:zzz")+"\t" + " GetFeatureByName [PayloadSize] Failed! Error: " + QString::number(error)+" "+ Helper::mapReturnCodeToString(error)),
VimbaViewerLogCategory_ERROR);
return error;
}
return error;
}
void ViewerWindow::onFeedLogger ( const QString &sMessage )
{
m_InformationWindow->feedLogger("Logging", QString(QTime::currentTime().toString("hh:mm:ss:zzz")+"\t" + sMessage), VimbaViewerLogCategory_ERROR);
}
void ViewerWindow::changeEvent ( QEvent * event )
{
if( event->type() == QEvent::WindowStateChange )
{
if( isMinimized() )
m_Controller->showControl(false);
else if( isMaximized() )
m_Controller->showControl(true);
}
}
bool ViewerWindow::loadPlugin()
{
const QDir pluginsDir(qApp->applicationDirPath() + "/plugins");
m_TabPluginCount = 0;
foreach ( const QString fileName, pluginsDir.entryList(QDir::Files))
{
QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
QObject* const plugin = pluginLoader.instance();
if (plugin)
{
TabExtensionInterface* const tabInterface = qobject_cast<TabExtensionInterface *>(plugin);
m_tabExtensionInterface.push_back(tabInterface);
if (m_tabExtensionInterface[m_TabPluginCount])
{
m_TabPluginCount++;
}
}
}
return m_TabPluginCount > 0;
}
bool ViewerWindow::CanReduceBpp()
{
bool res = false;
FeaturePtr pFeature;
// TODO: Persist pixel format in viewer. Pixel format might be altered in between capture and save. Then color would be transformed to mono.
// Bug or feature?
VmbError_t error = m_pCam->GetFeatureByName( "PixelFormat", pFeature );
if( VmbErrorSuccess == error )
{
VmbInt64_t nFormat;
error = pFeature->GetValue( nFormat );
if( VmbErrorSuccess == error )
{
res = Helper::convertFormatToString(static_cast<VmbPixelFormatType>(nFormat)).contains("Mono");
}
}
return res;
}
// Reduces bpp to 8
QImage ViewerWindow::ReduceBpp( QImage image )
{
// Create 8 bit grey scale color table
if ( 0 == m_ColorTable.size() )
{
for ( int i = 0; i < 256; ++i )
{
m_ColorTable.push_back( QColor( i, i, i ).rgb() );
}
}
// Convert to 8 bit grey scale
return image.convertToFormat( QImage::Format_Indexed8, m_ColorTable );
}
// Check if the TL supports streaming
bool ViewerWindow::isStreamingAvailable()
{
AVT::VmbAPI::FeaturePtr pStreamIDFeature;
m_pCam->GetFeatureByName("StreamID", pStreamIDFeature);
return (NULL == pStreamIDFeature) ? false : true;
}
// test if the current pixel format is supported and should use LibTiff to save image
bool ViewerWindow::isSupportedPixelFormat()
{
bool result = false;
FeaturePtr pFeature;
VmbError_t error = m_pCam->GetFeatureByName( "PixelFormat", pFeature );
if( VmbErrorSuccess == error )
{
VmbInt64_t nFormat;
error = pFeature->GetValue( nFormat );
if( VmbErrorSuccess == error )
{
switch(nFormat)
{
// supported images formats:
case VmbPixelFormatMono10:
case VmbPixelFormatMono10p:
case VmbPixelFormatMono12:
case VmbPixelFormatMono12p:
case VmbPixelFormatMono12Packed:
case VmbPixelFormatMono14:
case VmbPixelFormatMono16:
case VmbPixelFormatBayerGR10:
case VmbPixelFormatBayerRG10:
case VmbPixelFormatBayerGB10:
case VmbPixelFormatBayerBG10:
case VmbPixelFormatBayerGR10p:
case VmbPixelFormatBayerRG10p:
case VmbPixelFormatBayerGB10p:
case VmbPixelFormatBayerBG10p:
case VmbPixelFormatBayerGR12:
case VmbPixelFormatBayerRG12:
case VmbPixelFormatBayerGB12:
case VmbPixelFormatBayerBG12:
case VmbPixelFormatBayerGR12Packed:
case VmbPixelFormatBayerRG12Packed:
case VmbPixelFormatBayerGB12Packed:
case VmbPixelFormatBayerBG12Packed:
case VmbPixelFormatBayerGR12p:
case VmbPixelFormatBayerRG12p:
case VmbPixelFormatBayerGB12p:
case VmbPixelFormatBayerBG12p:
case VmbPixelFormatBayerGR16:
case VmbPixelFormatBayerRG16:
case VmbPixelFormatBayerGB16:
case VmbPixelFormatBayerBG16:
result = true;
break;
default:
result = false;
}
}
}
return result;
}
void SaveImageThread::run()
{
m_Images.StartProcessing();
m_16BitImages.StartProcessing();
// save 16 bit depth images if requested
if(m_bSave16BitImages)
{
ImageWriter tiffWriter;
if( !tiffWriter.IsAvailable() )
{
return;
}
FramePair tmpInfo;
while( m_16BitImages.WaitData(tmpInfo) )
{
QString sFullPath = m_sImagePath;
sFullPath.append("//").append(m_sSaveName);
sFullPath.append("_"+QString::number(tmpInfo.first)).append(m_sSaveFormat);
// save image using LibTif
if( ! tiffWriter.WriteTiff( tmpInfo.second, sFullPath.toAscii(),this) )
{
emit LogMessage(QString("error could not write TIFF image ") +sFullPath );
}
emit setPosition ( tmpInfo.first );
if( tmpInfo.first >= m_nTNumber2Save )
{
break;
}
}
}
// save standard QImage format
else
{
ImagePair tmpImage;
while( m_Images.WaitData( tmpImage ) )
{
QString sFullPath = m_sImagePath;
sFullPath.append("//").append(m_sSaveName);
sFullPath.append("_"+QString::number(tmpImage.first)).append(m_sSaveFormat);
// save image
if( ! tmpImage.second.save(sFullPath) )
{
emit LogMessage(QString("error could not write image ") +sFullPath );
}
emit setPosition ( tmpImage.first);
if( tmpImage.first >= m_nTNumber2Save )
{
break;
}
}
}
}