2015-03-02 02:53:29 +00:00
/*
Copyright ( C ) 2001 The Kompany
2021-07-13 00:07:12 +03:00
2002 - 2003 Ilya Konstantinov < kde - devel @ future . shiny . co . il >
2002 - 2003 Marcus Meissner < marcus @ jet . franken . de >
2003 Nadeem Hasan < nhasan @ nadmm . com >
2015-03-02 02:53:29 +00:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*/
# include <QtGui/QComboBox>
# include <QtGui/QGroupBox>
# include <QtGui/QHBoxLayout>
# include <QtGui/QLabel>
# include <QtGui/QListView>
# include <QtGui/QRadioButton>
# include <QtGui/QStackedWidget>
# include <QtGui/QVBoxLayout>
# include <QStandardItemModel>
# include <KLocale>
# include <KConfig>
# include <KMessageBox>
# include "config-kamera.h"
extern " C " {
# include <gphoto2.h>
}
# include "kamera.h"
# include "kameraconfigdialog.h"
# include "moc_kameradevice.cpp"
// Define some parts of the old API
# define GP_PROMPT_OK 0
# define GP_PROMPT_CANCEL -1
static const int INDEX_NONE = 0 ;
static const int INDEX_SERIAL = 1 ;
static const int INDEX_USB = 2 ;
static GPContext * glob_context = 0 ;
KCamera : : KCamera ( const QString & name , const QString & path )
{
2021-07-12 23:46:14 +03:00
m_name = name ;
m_model = name ;
m_path = path ;
m_camera = NULL ;
m_abilitylist = NULL ;
2015-03-02 02:53:29 +00:00
}
KCamera : : ~ KCamera ( )
{
2021-07-12 23:46:14 +03:00
if ( m_camera ) {
gp_camera_free ( m_camera ) ;
}
if ( m_abilitylist ) {
gp_abilities_list_free ( m_abilitylist ) ;
}
2015-03-02 02:53:29 +00:00
}
bool KCamera : : initInformation ( )
{
2021-07-12 23:55:00 +03:00
if ( m_model . isNull ( ) ) {
return false ;
}
2021-07-12 23:46:14 +03:00
if ( gp_abilities_list_new ( & m_abilitylist ) ! = GP_OK ) {
emit error ( i18n ( " Could not allocate memory for the abilities list. " ) ) ;
return false ;
}
if ( gp_abilities_list_load ( m_abilitylist , glob_context ) ! = GP_OK ) {
emit error ( i18n ( " Could not load ability list. " ) ) ;
return false ;
}
int index = gp_abilities_list_lookup_model ( m_abilitylist , m_model . toLocal8Bit ( ) . data ( ) ) ;
if ( index < 0 ) {
emit error ( i18n ( " Description of abilities for camera %1 is not available. "
" Configuration options may be incorrect. " , m_model ) ) ;
return false ;
}
gp_abilities_list_get_abilities ( m_abilitylist , index , & m_abilities ) ;
return true ;
2015-03-02 02:53:29 +00:00
}
bool KCamera : : initCamera ( )
{
2021-07-12 23:46:14 +03:00
if ( m_camera ) {
return m_camera ;
} else {
int result ;
initInformation ( ) ;
if ( m_model . isNull ( ) | | m_path . isNull ( ) ) {
return false ;
}
result = gp_camera_new ( & m_camera ) ;
if ( result ! = GP_OK ) {
// m_camera is not initialized, so we cannot get result as string
emit error ( i18n ( " Could not access driver. Check your gPhoto2 installation. " ) ) ;
return false ;
}
// set the camera's model
GPPortInfo info ;
GPPortInfoList * il ;
gp_port_info_list_new ( & il ) ;
gp_port_info_list_load ( il ) ;
gp_port_info_list_get_info ( il , gp_port_info_list_lookup_path ( il , m_path . toLocal8Bit ( ) . data ( ) ) , & info ) ;
gp_camera_set_abilities ( m_camera , m_abilities ) ;
gp_camera_set_port_info ( m_camera , info ) ;
gp_port_info_list_free ( il ) ;
// this might take some time (esp. for non-existent camera) - better be done asynchronously
result = gp_camera_init ( m_camera , glob_context ) ;
if ( result ! = GP_OK ) {
gp_camera_free ( m_camera ) ;
m_camera = NULL ;
emit error (
i18n ( " Unable to initialize camera. Check your port settings and camera connectivity and try again. " ) ,
QString : : fromLocal8Bit ( gp_result_as_string ( result ) ) ) ;
return false ;
}
return m_camera ;
}
2015-03-02 02:53:29 +00:00
}
Camera * KCamera : : camera ( )
{
2021-07-12 23:46:14 +03:00
initCamera ( ) ;
return m_camera ;
2015-03-02 02:53:29 +00:00
}
QString KCamera : : summary ( )
{
2021-07-12 23:46:14 +03:00
int result ;
CameraText summary ;
2015-03-02 02:53:29 +00:00
2021-07-12 23:46:14 +03:00
initCamera ( ) ;
2015-03-02 02:53:29 +00:00
2021-07-12 23:46:14 +03:00
result = gp_camera_get_summary ( m_camera , & summary , glob_context ) ;
if ( result ! = GP_OK ) {
return i18n ( " No camera summary information is available. \n " ) ;
}
return QString : : fromLocal8Bit ( summary . text ) ;
2015-03-02 02:53:29 +00:00
}
bool KCamera : : configure ( )
{
2021-07-12 23:46:14 +03:00
CameraWidget * window ;
int result ;
2015-03-02 02:53:29 +00:00
2021-07-12 23:46:14 +03:00
initCamera ( ) ;
2015-03-02 02:53:29 +00:00
2021-07-12 23:46:14 +03:00
result = gp_camera_get_config ( m_camera , & window , glob_context ) ;
if ( result ! = GP_OK ) {
emit error ( i18n ( " Camera configuration failed. " ) , QString : : fromLocal8Bit ( gp_result_as_string ( result ) ) ) ;
return false ;
}
2015-03-02 02:53:29 +00:00
2021-07-12 23:46:14 +03:00
KameraConfigDialog kcd ( m_camera , window ) ;
result = kcd . exec ( ) ? GP_PROMPT_OK : GP_PROMPT_CANCEL ;
2015-03-02 02:53:29 +00:00
2021-07-12 23:46:14 +03:00
if ( result = = GP_PROMPT_OK ) {
result = gp_camera_set_config ( m_camera , window , glob_context ) ;
if ( result ! = GP_OK ) {
emit error ( i18n ( " Camera configuration failed. " ) , QString : : fromLocal8Bit ( gp_result_as_string ( result ) ) ) ;
return false ;
}
}
2015-03-02 02:53:29 +00:00
2021-07-12 23:46:14 +03:00
return true ;
2015-03-02 02:53:29 +00:00
}
bool KCamera : : test ( )
{
2021-07-12 23:46:14 +03:00
// TODO: Make testing non-blocking (maybe via KIO?)
// Currently, a failed serial test times out at about 30 sec.
return camera ( ) ! = 0 ;
2015-03-02 02:53:29 +00:00
}
void KCamera : : load ( KConfig * config )
{
2021-07-12 23:46:14 +03:00
KConfigGroup group = config - > group ( m_name ) ;
if ( m_model . isNull ( ) ) {
m_model = group . readEntry ( " Model " ) ;
}
if ( m_path . isNull ( ) ) {
m_path = group . readEntry ( " Path " ) ;
}
invalidateCamera ( ) ;
2015-03-02 02:53:29 +00:00
}
void KCamera : : save ( KConfig * config )
{
2021-07-12 23:46:14 +03:00
KConfigGroup group = config - > group ( m_name ) ;
group . writeEntry ( " Model " , m_model ) ;
group . writeEntry ( " Path " , m_path ) ;
2015-03-02 02:53:29 +00:00
}
QString KCamera : : portName ( )
{
2021-07-12 23:46:14 +03:00
QString port = m_path . left ( m_path . indexOf ( " : " ) ) . toLower ( ) ;
if ( port = = " serial " ) {
return i18n ( " Serial " ) ;
}
if ( port = = " usb " ) {
return i18n ( " USB " ) ;
}
return i18n ( " Unknown port " ) ;
2015-03-02 02:53:29 +00:00
}
void KCamera : : setName ( const QString & name )
{
2021-07-12 23:46:14 +03:00
m_name = name ;
2015-03-02 02:53:29 +00:00
}
void KCamera : : setModel ( const QString & model )
{
2021-07-12 23:46:14 +03:00
m_model = model ;
invalidateCamera ( ) ;
initInformation ( ) ;
2015-03-02 02:53:29 +00:00
}
void KCamera : : setPath ( const QString & path )
{
2021-07-12 23:46:14 +03:00
m_path = path ;
invalidateCamera ( ) ;
2015-03-02 02:53:29 +00:00
}
void KCamera : : invalidateCamera ( )
{
2021-07-12 23:46:14 +03:00
if ( m_camera ) {
gp_camera_free ( m_camera ) ;
m_camera = NULL ;
}
2015-03-02 02:53:29 +00:00
}
bool KCamera : : isTestable ( ) const
{
2021-07-12 23:46:14 +03:00
return true ;
2015-03-02 02:53:29 +00:00
}
bool KCamera : : isConfigurable ( )
{
2021-07-12 23:46:14 +03:00
initInformation ( ) ;
return m_abilities . operations & GP_OPERATION_CONFIG ;
2015-03-02 02:53:29 +00:00
}
QStringList KCamera : : supportedPorts ( )
{
2021-07-12 23:46:14 +03:00
initInformation ( ) ;
QStringList ports ;
if ( m_abilities . port & GP_PORT_SERIAL ) {
ports . append ( " serial " ) ;
}
if ( m_abilities . port & GP_PORT_USB ) {
ports . append ( " usb " ) ;
}
return ports ;
2015-03-02 02:53:29 +00:00
}
CameraAbilities KCamera : : abilities ( )
{
2021-07-12 23:46:14 +03:00
return m_abilities ;
2015-03-02 02:53:29 +00:00
}
// ---------- KameraSelectCamera ------------
KameraDeviceSelectDialog : : KameraDeviceSelectDialog ( QWidget * parent , KCamera * device )
2021-07-12 23:46:14 +03:00
: KDialog ( parent )
2015-03-02 02:53:29 +00:00
{
2021-07-12 23:55:00 +03:00
setCaption ( i18n ( " Select Camera Device " ) ) ;
setButtons ( Ok | Cancel ) ;
setDefaultButton ( Ok ) ;
setModal ( true ) ;
showButtonSeparator ( true ) ;
2021-07-12 23:46:14 +03:00
m_device = device ;
connect ( m_device , SIGNAL ( error ( const QString & ) ) ,
SLOT ( slot_error ( const QString & ) ) ) ;
connect ( m_device , SIGNAL ( error ( const QString & , const QString & ) ) ,
SLOT ( slot_error ( const QString & , const QString & ) ) ) ;
QWidget * page = new QWidget ( this ) ;
setMainWidget ( page ) ;
// a layout with vertical boxes
QHBoxLayout * topLayout = new QHBoxLayout ( page ) ;
topLayout - > setSpacing ( KDialog : : spacingHint ( ) ) ;
topLayout - > setMargin ( 0 ) ;
// the models list
m_modelSel = new QListView ( page ) ;
m_model = new QStandardItemModel ( this ) ;
m_model - > setColumnCount ( 1 ) ;
m_model - > setHeaderData ( 0 , Qt : : Horizontal , i18nc ( " @title:column " , " Supported Cameras " ) ) ;
m_modelSel - > setModel ( m_model ) ;
topLayout - > addWidget ( m_modelSel ) ;
connect ( m_modelSel , SIGNAL ( activated ( const QModelIndex & ) ) ,
SLOT ( slot_setModel ( const QModelIndex & ) ) ) ;
// make sure listview only as wide as it needs to be
m_modelSel - > setSizePolicy ( QSizePolicy ( QSizePolicy : : Maximum , QSizePolicy : : Preferred ) ) ;
QVBoxLayout * rightLayout = new QVBoxLayout ( ) ;
rightLayout - > setSpacing ( KDialog : : spacingHint ( ) ) ;
rightLayout - > setMargin ( 0 ) ;
topLayout - > addLayout ( rightLayout ) ;
m_portSelectGroup = new QGroupBox ( i18n ( " Port " ) , page ) ;
QVBoxLayout * vertLayout = new QVBoxLayout ;
m_portSelectGroup - > setLayout ( vertLayout ) ;
rightLayout - > addWidget ( m_portSelectGroup ) ;
m_portSettingsGroup = new QGroupBox ( i18n ( " Port Settings " ) , page ) ;
QVBoxLayout * lay = new QVBoxLayout ;
m_portSettingsGroup - > setLayout ( lay ) ;
rightLayout - > addWidget ( m_portSettingsGroup ) ;
// Create port type selection radiobuttons.
m_serialRB = new QRadioButton ( i18n ( " Serial " ) ) ;
vertLayout - > addWidget ( m_serialRB ) ;
m_serialRB - > setWhatsThis ( i18n ( " If this option is checked, the camera has to be connected to one of the computer's serial ports (known as COM ports in Microsoft Windows.) " ) ) ;
m_USBRB = new QRadioButton ( i18n ( " USB " ) ) ;
vertLayout - > addWidget ( m_USBRB ) ;
m_USBRB - > setWhatsThis ( i18n ( " If this option is checked, the camera has to be connected to one of the computer's USB ports, or to a USB hub. " ) ) ;
// Create port settings widget stack
m_settingsStack = new QStackedWidget ;
QWidget * grid2 = new QWidget ( m_settingsStack ) ;
QGridLayout * gridLayout2 = new QGridLayout ( grid2 ) ;
2015-03-02 02:53:29 +00:00
gridLayout2 - > setSpacing ( KDialog : : spacingHint ( ) ) ;
2021-07-12 23:46:14 +03:00
grid2 - > setLayout ( gridLayout2 ) ;
2015-03-02 02:53:29 +00:00
QLabel * label2 = new QLabel ( i18n ( " Port " ) , grid2 ) ;
2021-07-12 23:46:14 +03:00
gridLayout2 - > addWidget ( label2 , 0 , 0 , Qt : : AlignLeft ) ;
2015-03-02 02:53:29 +00:00
lay - > addWidget ( grid2 ) ;
lay - > addWidget ( m_settingsStack ) ;
2021-07-12 23:46:14 +03:00
connect ( m_serialRB , SIGNAL ( toggled ( bool ) ) ,
this , SLOT ( changeCurrentIndex ( ) ) ) ;
connect ( m_USBRB , SIGNAL ( toggled ( bool ) ) ,
this , SLOT ( changeCurrentIndex ( ) ) ) ;
// none tab
m_settingsStack - > insertWidget ( INDEX_NONE , new QLabel ( i18n ( " No port type selected. " ) , m_settingsStack ) ) ;
// serial tab
QWidget * grid = new QWidget ( m_settingsStack ) ;
QGridLayout * gridLayout = new QGridLayout ( grid ) ;
gridLayout - > setSpacing ( KDialog : : spacingHint ( ) ) ;
grid - > setLayout ( gridLayout ) ;
QLabel * label = new QLabel ( i18n ( " Port: " ) , grid ) ;
m_serialPortCombo = new QComboBox ( grid ) ;
m_serialPortCombo - > setEditable ( true ) ;
m_serialPortCombo - > setWhatsThis ( i18n ( " Specify here the serial port to which you connect the camera. " ) ) ;
gridLayout - > addWidget ( label , 1 , 0 , Qt : : AlignLeft ) ;
gridLayout - > addWidget ( m_serialPortCombo , 1 , 1 , Qt : : AlignRight ) ;
m_settingsStack - > insertWidget ( INDEX_SERIAL , grid ) ;
m_settingsStack - > insertWidget ( INDEX_USB , new
QLabel ( i18n ( " No further configuration is required for USB cameras. " ) ,
m_settingsStack ) ) ;
// query gphoto2 for existing serial ports
GPPortInfoList * list ;
GPPortInfo info ;
int gphoto_ports = 0 ;
gp_port_info_list_new ( & list ) ;
if ( gp_port_info_list_load ( list ) > = 0 ) {
gphoto_ports = gp_port_info_list_count ( list ) ;
}
for ( int i = 0 ; i < gphoto_ports ; i + + ) {
if ( gp_port_info_list_get_info ( list , i , & info ) > = 0 ) {
2015-03-02 02:53:29 +00:00
# ifdef HAVE_GPHOTO2_5
2021-07-12 23:46:14 +03:00
char * xpath ;
gp_port_info_get_path ( info , & xpath ) ;
if ( strncmp ( xpath , " serial: " , 7 ) = = 0 ) {
m_serialPortCombo - > addItem ( QString : : fromLocal8Bit ( xpath ) . mid ( 7 ) ) ;
}
2015-03-02 02:53:29 +00:00
# else
2021-07-12 23:46:14 +03:00
if ( strncmp ( info . path , " serial: " , 7 ) = = 0 ) {
m_serialPortCombo - > addItem ( QString : : fromLocal8Bit ( info . path ) . mid ( 7 ) ) ;
}
2015-03-02 02:53:29 +00:00
# endif
2021-07-12 23:46:14 +03:00
}
}
gp_port_info_list_free ( list ) ;
2015-03-02 02:53:29 +00:00
2021-07-12 23:46:14 +03:00
// add a spacer
rightLayout - > addStretch ( ) ;
2015-03-02 02:53:29 +00:00
2021-07-12 23:46:14 +03:00
populateCameraListView ( ) ;
load ( ) ;
2015-03-02 02:53:29 +00:00
2021-07-12 23:46:14 +03:00
enableButtonOk ( false ) ;
m_portSelectGroup - > setEnabled ( false ) ;
m_portSettingsGroup - > setEnabled ( false ) ;
2015-03-02 02:53:29 +00:00
}
void KameraDeviceSelectDialog : : changeCurrentIndex ( )
{
2021-07-12 23:46:14 +03:00
QRadioButton * send = dynamic_cast < QRadioButton * > ( sender ( ) ) ;
if ( send ) {
if ( send = = m_serialRB ) {
m_settingsStack - > setCurrentIndex ( INDEX_SERIAL ) ;
} else if ( send = = m_USBRB ) {
m_settingsStack - > setCurrentIndex ( INDEX_USB ) ;
2015-03-02 02:53:29 +00:00
}
}
}
bool KameraDeviceSelectDialog : : populateCameraListView ( )
{
2021-07-12 23:46:14 +03:00
gp_abilities_list_new ( & m_device - > m_abilitylist ) ;
gp_abilities_list_load ( m_device - > m_abilitylist , glob_context ) ;
int numCams = gp_abilities_list_count ( m_device - > m_abilitylist ) ;
CameraAbilities a ;
if ( numCams < 0 ) {
// XXX libgphoto2 failed to get te camera list
return false ;
} else {
for ( int x = 0 ; x < numCams ; + + x ) {
if ( gp_abilities_list_get_abilities ( m_device - > m_abilitylist , x , & a ) = = GP_OK ) {
QStandardItem * cameraItem = new QStandardItem ;
cameraItem - > setEditable ( false ) ;
cameraItem - > setText ( a . model ) ;
m_model - > appendRow ( cameraItem ) ;
}
}
return true ;
}
2015-03-02 02:53:29 +00:00
}
void KameraDeviceSelectDialog : : save ( )
{
2021-07-12 23:46:14 +03:00
m_device - > setModel ( m_modelSel - > currentIndex ( ) . data ( Qt : : DisplayRole ) . toString ( ) ) ;
2015-03-02 02:53:29 +00:00
2021-07-12 23:46:14 +03:00
if ( m_serialRB - > isChecked ( ) ) {
m_device - > setPath ( " serial: " + m_serialPortCombo - > currentText ( ) ) ;
} else if ( m_USBRB - > isChecked ( ) ) {
m_device - > setPath ( " usb: " ) ;
}
2015-03-02 02:53:29 +00:00
}
void KameraDeviceSelectDialog : : load ( )
{
2021-07-12 23:46:14 +03:00
QString path = m_device - > path ( ) ;
QString port = path . left ( path . indexOf ( ' : ' ) ) . toLower ( ) ;
2015-03-02 02:53:29 +00:00
2021-07-12 23:46:14 +03:00
if ( port = = " serial " ) {
setPortType ( INDEX_SERIAL ) ;
}
if ( port = = " usb " ) {
setPortType ( INDEX_USB ) ;
}
2015-03-02 02:53:29 +00:00
2021-07-12 23:46:14 +03:00
QList < QStandardItem * > items = m_model - > findItems ( m_device - > model ( ) ) ;
foreach ( QStandardItem * item , items ) {
const QModelIndex index = m_model - > indexFromItem ( item ) ;
m_modelSel - > selectionModel ( ) - > select ( index , QItemSelectionModel : : Select ) ;
}
2015-03-02 02:53:29 +00:00
}
void KameraDeviceSelectDialog : : slot_setModel ( const QModelIndex & modelIndex )
{
enableButtonOk ( true ) ;
m_portSelectGroup - > setEnabled ( true ) ;
m_portSettingsGroup - > setEnabled ( true ) ;
QString model = modelIndex . data ( Qt : : DisplayRole ) . toString ( ) ;
2021-07-12 23:46:14 +03:00
CameraAbilities abilities ;
int index = gp_abilities_list_lookup_model ( m_device - > m_abilitylist , model . toLocal8Bit ( ) . data ( ) ) ;
if ( index < 0 ) {
slot_error ( i18n ( " Description of abilities for camera %1 is not available. "
" Configuration options may be incorrect. " , model ) ) ;
}
int result = gp_abilities_list_get_abilities ( m_device - > m_abilitylist , index , & abilities ) ;
if ( result = = GP_OK ) {
// enable radiobuttons for supported port types
m_serialRB - > setEnabled ( abilities . port & GP_PORT_SERIAL ) ;
m_USBRB - > setEnabled ( abilities . port & GP_PORT_USB ) ;
// if there's only one available port type, make sure it's selected
if ( abilities . port = = GP_PORT_SERIAL ) {
setPortType ( INDEX_SERIAL ) ;
}
if ( abilities . port = = GP_PORT_USB ) {
setPortType ( INDEX_USB ) ;
}
} else {
slot_error ( i18n ( " Description of abilities for camera %1 is not available. "
" Configuration options may be incorrect. " , model ) ) ;
}
2015-03-02 02:53:29 +00:00
}
void KameraDeviceSelectDialog : : setPortType ( int type )
{
2021-07-12 23:46:14 +03:00
// Enable the correct button
if ( type = = INDEX_USB ) {
m_USBRB - > setChecked ( true ) ;
} else if ( type = = INDEX_SERIAL ) {
m_serialRB - > setChecked ( true ) ;
}
2015-03-02 02:53:29 +00:00
// Bring the right tab to the front
m_settingsStack - > setCurrentIndex ( type ) ;
}
void KameraDeviceSelectDialog : : slot_error ( const QString & message )
{
2021-07-12 23:46:14 +03:00
KMessageBox : : error ( this , message ) ;
2015-03-02 02:53:29 +00:00
}
void KameraDeviceSelectDialog : : slot_error ( const QString & message , const QString & details )
{
2021-07-12 23:46:14 +03:00
KMessageBox : : detailedError ( this , message , details ) ;
2015-03-02 02:53:29 +00:00
}