@ -1,8 +1,7 @@
/**
* smartcard . cpp
* iccconfig . cpp
*
* Copyright ( c ) 2001 George Staikos < staikos @ kde . org >
* Copyright ( c ) 2001 Fernando Llobregat < fernando . llobregat @ free . fr >
* Copyright ( c ) 2009 - 2010 Timothy Pearson < kb9vqf @ pearsoncomputing . net >
*
* 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
@ -19,8 +18,6 @@
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*/
# include "iccconfig.h"
# include <qcheckbox.h>
# include <qlabel.h>
# include <qlayout.h>
@ -32,6 +29,7 @@
# include <kaboutdata.h>
# include <kapplication.h>
# include <kconfig.h>
# include <kcombobox.h>
# include <kdebug.h>
# include <kdialog.h>
# include <kglobal.h>
@ -39,6 +37,7 @@
# include <klocale.h>
# include <kmessagebox.h>
# include <kpopupmenu.h>
# include <kinputdialog.h>
# include <kurlrequester.h>
# include <kgenericfactory.h>
@ -48,6 +47,8 @@
# include <stdio.h>
# include <qstring.h>
# include "iccconfig.h"
using namespace std ;
/**** DLL Interface ****/
@ -55,6 +56,7 @@ typedef KGenericFactory<KICCConfig, QWidget> KICCCFactory;
K_EXPORT_COMPONENT_FACTORY ( kcm_iccconfig , KICCCFactory ( " kcmiccconfig " ) )
KSimpleConfig * config ;
KSimpleConfig * systemconfig ;
/**** KICCConfig ****/
@ -63,7 +65,8 @@ KICCConfig::KICCConfig(QWidget *parent, const char *name, const QStringList &)
{
QVBoxLayout * layout = new QVBoxLayout ( this , KDialog : : marginHint ( ) , KDialog : : spacingHint ( ) ) ;
config = new KSimpleConfig ( QString : : fromLatin1 ( KDE_CONFDIR " /kicc/kiccconfigrc " ) ) ;
config = new KSimpleConfig ( QString : : fromLatin1 ( " kiccconfigrc " ) ) ;
systemconfig = new KSimpleConfig ( QString : : fromLatin1 ( KDE_CONFDIR " /kicc/kiccconfigrc " ) ) ;
KAboutData * about =
new KAboutData ( I18N_NOOP ( " kcmiccconfig " ) , I18N_NOOP ( " KDE ICC Profile Control Module " ) ,
@ -76,25 +79,149 @@ KICCConfig::KICCConfig(QWidget *parent, const char *name, const QStringList &)
base = new ICCConfigBase ( this ) ;
layout - > add ( base ) ;
setRootOnlyMsg ( i18n ( " <b>The ICC color profile is a system wide setting, and requires administrator access</b><br>To alter the system's ICC profile, click on the \" Administrator Mode \" button below. " ) ) ;
setRootOnlyMsg ( i18n ( " <b>The global ICC color profile is a system wide setting, and requires administrator access</b><br>To alter the system's global ICC profile, click on the \" Administrator Mode \" button below. " ) ) ;
setUseRootOnlyMsg ( true ) ;
connect ( base - > systemEnableSupport , SIGNAL ( clicked ( ) ) , SLOT ( changed ( ) ) ) ;
connect ( base - > systemEnableSupport , SIGNAL ( toggled ( bool ) ) , base - > systemIccFile , SLOT ( setEnabled ( bool ) ) ) ;
connect ( base - > enableSupport , SIGNAL ( clicked ( ) ) , SLOT ( changed ( ) ) ) ;
connect ( base - > enableSupport , SIGNAL ( toggled ( bool ) ) , base - > iccFile , SLOT ( setEnabled ( bool ) ) ) ;
connect ( base - > iccFile , SIGNAL ( textChanged ( const QString & ) ) , SLOT ( changed ( ) ) ) ;
connect ( base - > enableSupport , SIGNAL ( toggled ( bool ) ) , base - > randrScreenList , SLOT ( setEnabled ( bool ) ) ) ;
connect ( base - > enableSupport , SIGNAL ( toggled ( bool ) ) , base - > iccProfileList , SLOT ( setEnabled ( bool ) ) ) ;
connect ( base - > enableSupport , SIGNAL ( toggled ( bool ) ) , base - > addProfileButton , SLOT ( setEnabled ( bool ) ) ) ;
connect ( base - > enableSupport , SIGNAL ( toggled ( bool ) ) , base - > renameProfileButton , SLOT ( setEnabled ( bool ) ) ) ;
connect ( base - > enableSupport , SIGNAL ( toggled ( bool ) ) , base - > deleteProfileButton , SLOT ( setEnabled ( bool ) ) ) ;
connect ( base - > iccProfileList , SIGNAL ( activated ( int ) ) , this , SLOT ( selectProfile ( int ) ) ) ;
connect ( base - > randrScreenList , SIGNAL ( activated ( int ) ) , this , SLOT ( selectScreen ( int ) ) ) ;
connect ( base - > iccFile , SIGNAL ( textChanged ( const QString & ) ) , SLOT ( updateArray ( ) ) ) ;
connect ( base - > systemIccFile , SIGNAL ( textChanged ( const QString & ) ) , SLOT ( changed ( ) ) ) ;
connect ( base - > addProfileButton , SIGNAL ( clicked ( ) ) , this , SLOT ( addProfile ( ) ) ) ;
connect ( base - > renameProfileButton , SIGNAL ( clicked ( ) ) , this , SLOT ( renameProfile ( ) ) ) ;
connect ( base - > deleteProfileButton , SIGNAL ( clicked ( ) ) , this , SLOT ( deleteProfile ( ) ) ) ;
load ( ) ;
if ( getuid ( ) ! = 0 | | ! config - > checkConfigFilesWritable ( true ) ) {
if ( ! config - > checkConfigFilesWritable ( true ) ) {
base - > enableSupport - > setEnabled ( false ) ;
base - > randrScreenList - > setEnabled ( false ) ;
base - > iccProfileList - > setEnabled ( false ) ;
base - > iccFile - > setEnabled ( false ) ;
base - > addProfileButton - > setEnabled ( false ) ;
base - > renameProfileButton - > setEnabled ( false ) ;
base - > deleteProfileButton - > setEnabled ( false ) ;
}
if ( getuid ( ) ! = 0 | | ! systemconfig - > checkConfigFilesWritable ( true ) ) {
base - > systemEnableSupport - > setEnabled ( false ) ;
base - > systemIccFile - > setEnabled ( false ) ;
}
}
KICCConfig : : ~ KICCConfig ( )
{
delete [ ] iccFileArray ;
delete config ;
delete systemconfig ;
}
void KICCConfig : : deleteProfile ( ) {
int i ;
QString * iccFileArrayNew ;
// Delete the profile
config - > deleteGroup ( base - > iccProfileList - > currentText ( ) ) ;
base - > iccProfileList - > removeItem ( base - > iccProfileList - > currentItem ( ) ) ;
base - > iccProfileList - > setCurrentItem ( base - > iccProfileList - > count ( ) - 1 ) ;
// Contract the profile memory
numberOfProfiles - - ;
iccFileArrayNew = new QString [ numberOfProfiles * numberOfScreens ] ;
for ( i = 0 ; i < ( numberOfProfiles * numberOfScreens ) ; i + + ) {
iccFileArrayNew [ i ] = iccFileArray [ i ] ;
}
delete [ ] iccFileArray ;
iccFileArray = iccFileArrayNew ;
}
void KICCConfig : : renameProfile ( ) {
int i ;
QString * iccFileArrayNew ;
// Pop up a text entry box asking for the name of the new profile
bool _ok = false ;
bool _end = false ;
QString _new ;
QString _text = i18n ( " Please enter the new profile name below: " ) ;
QString _error ;
while ( ! _end ) {
_new = KInputDialog : : getText ( i18n ( " ICC Profile Configuration " ) , _error + _text , QString : : null , & _ok , this ) ;
if ( ! _ok ) {
_end = true ;
} else {
_error = QString ( ) ;
if ( ! _new . isEmpty ( ) ) {
if ( findProfileIndex ( _new ) ! = - 1 )
_error = i18n ( " Error: A profile with that name already exists " ) + QString ( " \n " ) ;
else
_end = true ;
}
}
}
// Rename the profile
config - > deleteGroup ( base - > iccProfileList - > currentText ( ) ) ;
base - > iccProfileList - > changeItem ( _new , base - > iccProfileList - > currentItem ( ) ) ;
updateDisplayedInformation ( ) ;
emit changed ( ) ;
}
void KICCConfig : : addProfile ( ) {
int i ;
QString * iccFileArrayNew ;
// Pop up a text entry box asking for the name of the new profile
bool _ok = false ;
bool _end = false ;
QString _new ;
QString _text = i18n ( " Please enter the new profile name below: " ) ;
QString _error ;
while ( ! _end ) {
_new = KInputDialog : : getText ( i18n ( " ICC Profile Configuration " ) , _error + _text , QString : : null , & _ok , this ) ;
if ( ! _ok ) {
_end = true ;
} else {
_error = QString ( ) ;
if ( ! _new . isEmpty ( ) ) {
if ( findProfileIndex ( _new ) ! = - 1 )
_error = i18n ( " Error: A profile with that name already exists " ) + QString ( " \n " ) ;
else
_end = true ;
}
}
}
// Expand the profile memory
numberOfProfiles + + ;
iccFileArrayNew = new QString [ numberOfProfiles * numberOfScreens ] ;
for ( i = 0 ; i < ( ( numberOfProfiles - 1 ) * numberOfScreens ) ; i + + ) {
iccFileArrayNew [ i ] = iccFileArray [ i ] ;
}
delete [ ] iccFileArray ;
iccFileArray = iccFileArrayNew ;
for ( ; i < ( numberOfProfiles * numberOfScreens ) ; i + + ) {
iccFileArray [ i ] = " " ;
}
// Insert the new profile name
base - > iccProfileList - > insertItem ( _new , - 1 ) ;
base - > iccProfileList - > setCurrentItem ( base - > iccProfileList - > count ( ) - 1 ) ;
updateDisplayedInformation ( ) ;
emit changed ( ) ;
}
void KICCConfig : : load ( )
@ -102,52 +229,170 @@ void KICCConfig::load()
load ( false ) ;
}
void KICCConfig : : selectProfile ( int slotNumber ) {
updateDisplayedInformation ( ) ;
emit changed ( ) ;
}
void KICCConfig : : selectScreen ( int slotNumber ) {
updateDisplayedInformation ( ) ;
}
void KICCConfig : : updateArray ( void ) {
iccFileArray [ ( ( base - > iccProfileList - > currentItem ( ) ) * ( base - > randrScreenList - > count ( ) ) ) + ( base - > randrScreenList - > currentItem ( ) ) ] = base - > iccFile - > url ( ) ;
config - > setGroup ( base - > iccProfileList - > currentText ( ) ) ;
if ( config - > readEntry ( base - > randrScreenList - > currentText ( ) ) ! = iccFileArray [ ( ( base - > iccProfileList - > currentItem ( ) ) * ( base - > randrScreenList - > count ( ) ) ) + ( base - > randrScreenList - > currentItem ( ) ) ] ) {
emit changed ( ) ;
}
}
void KICCConfig : : updateDisplayedInformation ( ) {
base - > iccFile - > setURL ( iccFileArray [ ( ( base - > iccProfileList - > currentItem ( ) ) * ( base - > randrScreenList - > count ( ) ) ) + ( base - > randrScreenList - > currentItem ( ) ) ] ) ;
}
QString KICCConfig : : extractFileName ( QString displayName , QString profileName ) {
//
}
int KICCConfig : : findProfileIndex ( QString profileName ) {
int i ;
for ( i = 0 ; i < numberOfProfiles ; i + + ) {
if ( base - > iccProfileList - > text ( i ) = = profileName ) {
return i ;
}
}
return - 1 ;
}
int KICCConfig : : findScreenIndex ( QString screenName ) {
int i ;
for ( i = 0 ; i < ( base - > randrScreenList - > count ( ) ) ; i + + ) {
if ( base - > randrScreenList - > text ( i ) = = screenName ) {
return i ;
}
}
return - 1 ;
}
void KICCConfig : : load ( bool useDefaults )
{
//Update the toggle buttons with the current configuration
int i ;
int j ;
// FIXME Should use font size (basically resultant string length) to set button widths...
base - > addProfileButton - > setFixedWidth ( 110 ) ;
base - > renameProfileButton - > setFixedWidth ( 90 ) ;
base - > deleteProfileButton - > setFixedWidth ( 90 ) ;
XRROutputInfo * output_info ;
KRandrSimpleAPI * randrsimple = new KRandrSimpleAPI : : KRandrSimpleAPI ( ) ;
config - > setReadDefaults ( useDefaults ) ;
config - > setGroup ( NULL ) ;
base - > enableSupport - > setChecked ( config - > readBoolEntry ( " EnableICC " , false ) ) ;
base - > randrScreenList - > setEnabled ( config - > readBoolEntry ( " EnableICC " , false ) ) ;
base - > iccProfileList - > setEnabled ( config - > readBoolEntry ( " EnableICC " , false ) ) ;
base - > iccFile - > setEnabled ( config - > readBoolEntry ( " EnableICC " , false ) ) ;
base - > iccFile - > setURL ( config - > readEntry ( " ICCFile " ) ) ;
base - > addProfileButton - > setEnabled ( config - > readBoolEntry ( " EnableICC " , false ) ) ;
base - > renameProfileButton - > setEnabled ( config - > readBoolEntry ( " EnableICC " , false ) ) ;
base - > deleteProfileButton - > setEnabled ( config - > readBoolEntry ( " EnableICC " , false ) ) ;
numberOfScreens = 0 ;
if ( randrsimple - > isValid ( ) = = true ) {
randr_display = XOpenDisplay ( NULL ) ;
randr_screen_info = randrsimple - > read_screen_info ( randr_display ) ;
for ( i = 0 ; i < randr_screen_info - > n_output ; i + + ) {
output_info = randr_screen_info - > outputs [ i ] - > info ;
base - > randrScreenList - > insertItem ( output_info - > name , - 1 ) ;
numberOfScreens + + ;
}
}
else {
base - > randrScreenList - > insertItem ( " Default " , - 1 ) ;
numberOfScreens + + ;
}
// Find all profile names
numberOfProfiles = 0 ;
cfgProfiles = config - > groupList ( ) ;
for ( QStringList : : Iterator i ( cfgProfiles . begin ( ) ) ; i ! = cfgProfiles . end ( ) ; + + i ) {
base - > iccProfileList - > insertItem ( ( * i ) , - 1 ) ;
numberOfProfiles + + ;
}
if ( numberOfProfiles = = 0 ) {
base - > iccProfileList - > insertItem ( " <default> " , - 1 ) ;
numberOfProfiles + + ;
}
// Load all profiles into memory
iccFileArray = new QString [ numberOfProfiles * numberOfScreens ] ;
for ( i = 0 ; i < ( base - > iccProfileList - > count ( ) ) ; i + + ) {
config - > setGroup ( base - > iccProfileList - > text ( i ) ) ;
for ( j = 0 ; j < ( base - > randrScreenList - > count ( ) ) ; j + + ) {
iccFileArray [ ( i * ( base - > randrScreenList - > count ( ) ) ) + j ] = config - > readEntry ( base - > randrScreenList - > text ( j ) ) ;
}
}
if ( ( findProfileIndex ( base - > iccProfileList - > currentText ( ) ) > = 0 ) & & ( findScreenIndex ( base - > randrScreenList - > currentText ( ) ) > = 0 ) ) {
base - > iccFile - > setURL ( iccFileArray [ ( findProfileIndex ( base - > iccProfileList - > currentText ( ) ) * base - > randrScreenList - > count ( ) ) + findScreenIndex ( base - > randrScreenList - > currentText ( ) ) ] ) ;
}
else {
base - > iccFile - > setURL ( " " ) ;
}
systemconfig - > setGroup ( NULL ) ;
base - > systemEnableSupport - > setChecked ( systemconfig - > readBoolEntry ( " EnableICC " , false ) ) ;
base - > systemIccFile - > setEnabled ( systemconfig - > readBoolEntry ( " EnableICC " , false ) ) ;
base - > systemIccFile - > setURL ( systemconfig - > readEntry ( " ICCFile " ) ) ;
delete randrsimple ;
emit changed ( useDefaults ) ;
}
void KICCConfig : : save ( )
{
int i ;
int j ;
KRandrSimpleAPI * randrsimple = new KRandrSimpleAPI : : KRandrSimpleAPI ( ) ;
// Write system configuration
systemconfig - > setGroup ( NULL ) ;
systemconfig - > writeEntry ( " EnableICC " , base - > systemEnableSupport - > isChecked ( ) ) ;
systemconfig - > writeEntry ( " ICCFile " , base - > systemIccFile - > url ( ) ) ;
// Write user configuration
config - > setGroup ( NULL ) ;
config - > writeEntry ( " DefaultProfile " , m_defaultProfile ) ;
config - > writeEntry ( " EnableICC " , base - > enableSupport - > isChecked ( ) ) ;
config - > writeEntry ( " ICCFile " , base - > iccFile - > url ( ) ) ;
if ( base - > enableSupport - > isChecked ( ) ) {
// Apply ICC settings with XCalib
string icc_command = " /usr/bin/xcalib " ;
FILE * pipe_xcalib ;
char xcalib_result [ 2048 ] ;
int i ;
xcalib_result [ 0 ] = 0 ;
icc_command . append ( base - > iccFile - > url ( ) . ascii ( ) ) ;
if ( ( pipe_xcalib = popen ( icc_command . c_str ( ) , " r " ) ) = = NULL )
{
printf ( " Xcalib pipe error \n \r " ) ;
}
else {
fgets ( xcalib_result , 2048 , pipe_xcalib ) ;
pclose ( pipe_xcalib ) ;
for ( i = 1 ; i < 2048 ; i + + ) {
if ( xcalib_result [ i ] = = 0 ) {
xcalib_result [ i - 1 ] = 0 ;
i = 2048 ;
}
}
if ( strlen ( xcalib_result ) > 2 ) {
KMessageBox : : error ( this , QString ( " Unable to apply ICC configuration: \n \r %1 " ) . arg ( xcalib_result ) ) ;
}
// Save all profiles to disk
for ( i = 0 ; i < ( base - > iccProfileList - > count ( ) ) ; i + + ) {
config - > setGroup ( base - > iccProfileList - > text ( i ) ) ;
for ( j = 0 ; j < ( base - > randrScreenList - > count ( ) ) ; j + + ) {
config - > writeEntry ( base - > randrScreenList - > text ( j ) , iccFileArray [ ( i * ( base - > randrScreenList - > count ( ) ) ) + j ] ) ;
}
}
config - > sync ( ) ;
systemconfig - > sync ( ) ;
QString errorstr ;
if ( base - > enableSupport - > isChecked ( ) = = true ) {
errorstr = randrsimple - > applyIccConfiguration ( base - > iccProfileList - > currentText ( ) , KDE_CONFDIR ) ;
}
else if ( base - > systemEnableSupport - > isChecked ( ) = = true ) {
errorstr = randrsimple - > applySystemWideIccConfiguration ( KDE_CONFDIR ) ;
}
else {
errorstr = randrsimple - > clearIccConfiguration ( ) ;
}
if ( errorstr ! = " " ) {
KMessageBox : : error ( this , QString ( " Unable to apply ICC configuration: \n \r %1 " ) . arg ( errorstr ) ) ;
}
emit changed ( false ) ;
}