/*
Copyright ( C ) 2001 The Kompany
2002 - 2003 Ilya Konstantinov < kde - devel @ future . shiny . co . il >
2002 - 2003 Marcus Meissner < marcus @ jet . franken . de >
2003 Nadeem Hasan < nhasan @ nadmm . com >
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 <tqlabel.h>
# include <tqlayout.h>
# include <kgenericfactory.h>
# include <ksimpleconfig.h>
# include <kaction.h>
# include <kiconloader.h>
# include <kmessagebox.h>
# include <kiconview.h>
# include <kdialog.h>
# include <klocale.h>
# include <ktoolbar.h>
# include <kpopupmenu.h>
# include <kprotocolinfo.h>
# include <kdebug.h>
# include "kameraconfigdialog.h"
# include "kameradevice.h"
# include "kamera.h"
# include "kamera.moc"
typedef KGenericFactory < KKameraConfig , TQWidget > KKameraConfigFactory ;
K_EXPORT_COMPONENT_FACTORY ( kcm_kamera , KKameraConfigFactory ( " kcmkamera " ) )
// --------------- Camera control center module widget ---
KKameraConfig * KKameraConfig : : m_instance = NULL ;
KKameraConfig : : KKameraConfig ( TQWidget * tqparent , const char * name , const TQStringList & )
: KCModule ( KKameraConfigFactory : : instance ( ) , tqparent , name )
{
m_devicePopup = new KPopupMenu ( this ) ;
m_actions = new KActionCollection ( this ) ;
m_config = new KSimpleConfig ( KProtocolInfo : : config ( " camera " ) ) ;
m_context = gp_context_new ( ) ;
if ( m_context ) {
// Register the callback functions
gp_context_set_cancel_func ( m_context , cbGPCancel , this ) ;
gp_context_set_idle_func ( m_context , cbGPIdle , this ) ;
displayGPSuccessDialogue ( ) ;
// load existing configuration
load ( ) ;
} else {
displayGPFailureDialogue ( ) ;
}
// store instance for frontend_prompt
m_instance = this ;
}
KKameraConfig : : ~ KKameraConfig ( )
{
delete m_config ;
}
void KKameraConfig : : defaults ( )
{
load ( true ) ;
}
void KKameraConfig : : displayGPFailureDialogue ( void )
{
new TQLabel ( i18n ( " Unable to initialize the gPhoto2 libraries. " ) , this ) ;
}
void KKameraConfig : : displayGPSuccessDialogue ( void )
{
// set the kcontrol module buttons
setButtons ( Help | Apply | Cancel | Ok ) ;
// create a tqlayout with two vertical boxes
TQVBoxLayout * topLayout = new TQVBoxLayout ( this , 0 , 0 ) ;
topLayout - > setAutoAdd ( true ) ;
m_toolbar = new KToolBar ( this , " ToolBar " ) ;
m_toolbar - > setMovingEnabled ( false ) ;
// create list of devices
m_deviceSel = new KIconView ( this ) ;
connect ( m_deviceSel , TQT_SIGNAL ( rightButtonClicked ( TQIconViewItem * , const TQPoint & ) ) ,
TQT_SLOT ( slot_deviceMenu ( TQIconViewItem * , const TQPoint & ) ) ) ;
connect ( m_deviceSel , TQT_SIGNAL ( doubleClicked ( TQIconViewItem * ) ) ,
TQT_SLOT ( slot_configureCamera ( ) ) ) ;
connect ( m_deviceSel , TQT_SIGNAL ( selectionChanged ( TQIconViewItem * ) ) ,
TQT_SLOT ( slot_deviceSelected ( TQIconViewItem * ) ) ) ;
m_deviceSel - > tqsetSizePolicy ( TQSizePolicy ( TQSizePolicy : : Expanding , TQSizePolicy : : Expanding ) ) ;
// create actions
KAction * act ;
act = new KAction ( i18n ( " Add " ) , " camera " , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( slot_addCamera ( ) ) , m_actions , " camera_add " ) ;
act - > setWhatsThis ( i18n ( " Click this button to add a new camera. " ) ) ;
act - > plug ( m_toolbar ) ;
m_toolbar - > insertLineSeparator ( ) ;
act = new KAction ( i18n ( " Test " ) , " camera_test " , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( slot_testCamera ( ) ) , m_actions , " camera_test " ) ;
act - > setWhatsThis ( i18n ( " Click this button to remove the selected camera from the list. " ) ) ;
act - > plug ( m_toolbar ) ;
act = new KAction ( i18n ( " Remove " ) , " edittrash " , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( slot_removeCamera ( ) ) , m_actions , " camera_remove " ) ;
act - > setWhatsThis ( i18n ( " Click this button to remove the selected camera from the list. " ) ) ;
act - > plug ( m_toolbar ) ;
act = new KAction ( i18n ( " Configure... " ) , " configure " , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( slot_configureCamera ( ) ) , m_actions , " camera_configure " ) ;
act - > setWhatsThis ( i18n ( " Click this button to change the configuration of the selected camera.<br><br>The availability of this feature and the contents of the Configuration dialog depend on the camera model. " ) ) ;
act - > plug ( m_toolbar ) ;
act = new KAction ( i18n ( " Information " ) , " hwinfo " , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( slot_cameraSummary ( ) ) , m_actions , " camera_summary " ) ;
act - > setWhatsThis ( i18n ( " Click this button to view a summary of the current status of the selected camera.<br><br>The availability of this feature and the contents of the Configuration dialog depend on the camera model. " ) ) ;
act - > plug ( m_toolbar ) ;
m_toolbar - > insertLineSeparator ( ) ;
act = new KAction ( i18n ( " Cancel " ) , " stop " , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( slot_cancelOperation ( ) ) , m_actions , " camera_cancel " ) ;
act - > setWhatsThis ( i18n ( " Click this button to cancel the current camera operation. " ) ) ;
act - > setEnabled ( false ) ;
act - > plug ( m_toolbar ) ;
}
void KKameraConfig : : populateDeviceListView ( void )
{
m_deviceSel - > clear ( ) ;
CameraDevicesMap : : Iterator it ;
for ( it = m_devices . begin ( ) ; it ! = m_devices . end ( ) ; it + + ) {
if ( it . data ( ) ) {
new TQIconViewItem ( m_deviceSel , it . key ( ) , DesktopIcon ( " camera " ) ) ;
}
}
slot_deviceSelected ( m_deviceSel - > currentItem ( ) ) ;
}
void KKameraConfig : : save ( void )
{
CameraDevicesMap : : Iterator it ;
for ( it = m_devices . begin ( ) ; it ! = m_devices . end ( ) ; it + + )
{
it . data ( ) - > save ( m_config ) ;
}
m_config - > sync ( ) ;
}
void KKameraConfig : : load ( void )
{
load ( false ) ;
}
void KKameraConfig : : load ( bool useDefaults )
{
m_config - > setReadDefaults ( useDefaults ) ;
TQStringList groupList = m_config - > groupList ( ) ;
TQStringList : : Iterator it ;
int i , count ;
CameraList * list ;
CameraAbilitiesList * al ;
GPPortInfoList * il ;
const char * model , * value ;
KCamera * kcamera ;
for ( it = groupList . begin ( ) ; it ! = groupList . end ( ) ; it + + ) {
if ( * it ! = " <default> " ) {
m_config - > setGroup ( * it ) ;
if ( m_config - > readEntry ( " Path " ) . tqcontains ( " usb: " ) )
continue ;
kcamera = new KCamera ( * it , m_config - > readEntry ( " Path " ) ) ;
connect ( kcamera , TQT_SIGNAL ( error ( const TQString & ) ) , TQT_SLOT ( slot_error ( const TQString & ) ) ) ;
connect ( kcamera , TQT_SIGNAL ( error ( const TQString & , const TQString & ) ) , TQT_SLOT ( slot_error ( const TQString & , const TQString & ) ) ) ;
kcamera - > load ( m_config ) ;
m_devices [ * it ] = kcamera ;
}
}
m_cancelPending = false ;
gp_list_new ( & list ) ;
gp_abilities_list_new ( & al ) ;
gp_abilities_list_load ( al , m_context ) ;
gp_port_info_list_new ( & il ) ;
gp_port_info_list_load ( il ) ;
gp_abilities_list_detect ( al , il , list , m_context ) ;
gp_abilities_list_free ( al ) ;
gp_port_info_list_free ( il ) ;
count = gp_list_count ( list ) ;
TQMap < TQString , TQString > ports , names ;
for ( i = 0 ; i < count ; i + + ) {
gp_list_get_name ( list , i , & model ) ;
gp_list_get_value ( list , i , & value ) ;
ports [ value ] = model ;
if ( ! strcmp ( value , " usb: " ) )
names [ model ] = value ;
}
if ( ports . tqcontains ( " usb: " ) & & names [ ports [ " usb: " ] ] ! = " usb: " )
ports . remove ( " usb: " ) ;
TQMap < TQString , TQString > : : iterator portit ;
for ( portit = ports . begin ( ) ; portit ! = ports . end ( ) ; portit + + ) {
/* kdDebug() << "Adding USB camera: " << portit.data() << " at " << portit.key() << endl; */
kcamera = new KCamera ( portit . data ( ) , portit . key ( ) ) ;
connect ( kcamera , TQT_SIGNAL ( error ( const TQString & ) ) , TQT_SLOT ( slot_error ( const TQString & ) ) ) ;
connect ( kcamera , TQT_SIGNAL ( error ( const TQString & , const TQString & ) ) , TQT_SLOT ( slot_error ( const TQString & , const TQString & ) ) ) ;
m_devices [ portit . data ( ) ] = kcamera ;
}
populateDeviceListView ( ) ;
gp_list_free ( list ) ;
emit changed ( useDefaults ) ;
}
void KKameraConfig : : beforeCameraOperation ( void )
{
m_cancelPending = false ;
m_actions - > action ( " camera_test " ) - > setEnabled ( false ) ;
m_actions - > action ( " camera_remove " ) - > setEnabled ( false ) ;
m_actions - > action ( " camera_configure " ) - > setEnabled ( false ) ;
m_actions - > action ( " camera_summary " ) - > setEnabled ( false ) ;
m_actions - > action ( " camera_cancel " ) - > setEnabled ( true ) ;
}
void KKameraConfig : : afterCameraOperation ( void )
{
m_actions - > action ( " camera_cancel " ) - > setEnabled ( false ) ;
// if we're regaining control after a Cancel...
if ( m_cancelPending ) {
tqApp - > restoreOverrideCursor ( ) ;
m_cancelPending = false ;
}
// if any item was selected before the operation was run
// it makes sense for the relevant toolbar buttons to be enabled
slot_deviceSelected ( m_deviceSel - > currentItem ( ) ) ;
}
TQString KKameraConfig : : suggestName ( const TQString & name )
{
TQString new_name = name ;
new_name . tqreplace ( " / " , " " ) ; // we cannot have a slash in a URI's host
if ( ! m_devices . tqcontains ( new_name ) ) return new_name ;
// try new names with a number appended until we find a free one
int i = 1 ;
while ( i + + < 0xffff ) {
new_name = name + " ( " + TQString : : number ( i ) + " ) " ;
if ( ! m_devices . tqcontains ( new_name ) ) return new_name ;
}
return TQString ( ) ;
}
void KKameraConfig : : slot_addCamera ( )
{
KCamera * m_device = new KCamera ( TQString ( ) , TQString ( ) ) ;
connect ( m_device , TQT_SIGNAL ( error ( const TQString & ) ) , TQT_SLOT ( slot_error ( const TQString & ) ) ) ;
connect ( m_device , TQT_SIGNAL ( error ( const TQString & , const TQString & ) ) , TQT_SLOT ( slot_error ( const TQString & , const TQString & ) ) ) ;
KameraDeviceSelectDialog dialog ( this , m_device ) ;
if ( dialog . exec ( ) = = TQDialog : : Accepted ) {
dialog . save ( ) ;
m_device - > setName ( suggestName ( m_device - > model ( ) ) ) ;
m_devices . insert ( m_device - > name ( ) , m_device ) ;
populateDeviceListView ( ) ;
emit changed ( true ) ;
} else {
delete m_device ;
}
}
void KKameraConfig : : slot_removeCamera ( )
{
TQString name = m_deviceSel - > currentItem ( ) - > text ( ) ;
if ( m_devices . tqcontains ( name ) ) {
KCamera * m_device = m_devices [ name ] ;
m_devices . remove ( name ) ;
delete m_device ;
m_config - > deleteGroup ( name , true ) ;
populateDeviceListView ( ) ;
emit changed ( true ) ;
}
}
void KKameraConfig : : slot_testCamera ( )
{
beforeCameraOperation ( ) ;
TQString name = m_deviceSel - > currentItem ( ) - > text ( ) ;
if ( m_devices . tqcontains ( name ) ) {
KCamera * m_device = m_devices [ name ] ;
if ( m_device - > test ( ) )
KMessageBox : : information ( this , i18n ( " Camera test was successful. " ) ) ;
}
afterCameraOperation ( ) ;
}
void KKameraConfig : : slot_configureCamera ( )
{
TQString name = m_deviceSel - > currentItem ( ) - > text ( ) ;
if ( m_devices . tqcontains ( name ) ) {
KCamera * m_device = m_devices [ name ] ;
m_device - > configure ( ) ;
}
}
void KKameraConfig : : slot_cameraSummary ( )
{
TQString summary ;
TQString name = m_deviceSel - > currentItem ( ) - > text ( ) ;
if ( m_devices . tqcontains ( name ) ) {
KCamera * m_device = m_devices [ name ] ;
summary = m_device - > summary ( ) ;
if ( ! summary . isNull ( ) ) {
KMessageBox : : information ( this , summary ) ;
}
}
}
void KKameraConfig : : slot_cancelOperation ( )
{
m_cancelPending = true ;
// Prevent the user from keeping clicking Cancel
m_actions - > action ( " camera_cancel " ) - > setEnabled ( false ) ;
// and indicate that the click on Cancel did have some effect
tqApp - > setOverrideCursor ( TQt : : WaitCursor ) ;
}
void KKameraConfig : : slot_deviceMenu ( TQIconViewItem * item , const TQPoint & point )
{
if ( item ) {
m_devicePopup - > clear ( ) ;
m_actions - > action ( " camera_test " ) - > plug ( m_devicePopup ) ;
m_actions - > action ( " camera_remove " ) - > plug ( m_devicePopup ) ;
m_actions - > action ( " camera_configure " ) - > plug ( m_devicePopup ) ;
m_actions - > action ( " camera_summary " ) - > plug ( m_devicePopup ) ;
m_devicePopup - > popup ( point ) ;
}
}
void KKameraConfig : : slot_deviceSelected ( TQIconViewItem * item )
{
m_actions - > action ( " camera_test " ) - > setEnabled ( item ) ;
m_actions - > action ( " camera_remove " ) - > setEnabled ( item ) ;
m_actions - > action ( " camera_configure " ) - > setEnabled ( item ) ;
m_actions - > action ( " camera_summary " ) - > setEnabled ( item ) ;
}
void KKameraConfig : : cbGPIdle ( GPContext * /*context*/ , void * /*data*/ )
{
/*KKameraConfig *self( reinterpret_cast<KKameraConfig*>(data) );*/
tqApp - > processEvents ( ) ;
}
GPContextFeedback KKameraConfig : : cbGPCancel ( GPContext * /*context*/ , void * data )
{
KKameraConfig * self ( reinterpret_cast < KKameraConfig * > ( data ) ) ;
// Since in practice no camera driver supports idle callbacks yet,
// we'll use the cancel callback as opportunity to process events
tqApp - > processEvents ( ) ;
// If a cancel request is pending, ask gphoto to cancel
if ( self - > m_cancelPending )
return GP_CONTEXT_FEEDBACK_CANCEL ;
else
return GP_CONTEXT_FEEDBACK_OK ;
}
TQString KKameraConfig : : quickHelp ( ) const
{
return i18n ( " <h1>Digital Camera</h1> \n "
" This module allows you to configure support for your digital camera. \n "
" You would need to select the camera's model and the port it is connected \n "
" to on your computer (e.g. USB, Serial, Firewire). If your camera doesn't \n "
" appear in the list of <i>Supported Cameras</i>, go to the \n "
" <a href= \" http://www.gphoto.org \" >GPhoto web site</a> for a possible update.<br><br> \n "
" To view and download images from the digital camera, go to address \n "
" <a href= \" camera:/ \" >camera:/</a> in Konqueror and other KDE applications. " ) ;
}
void KKameraConfig : : slot_error ( const TQString & message )
{
KMessageBox : : error ( this , message ) ;
}
void KKameraConfig : : slot_error ( const TQString & message , const TQString & details )
{
KMessageBox : : detailedError ( this , message , details ) ;
}