diff options
Diffstat (limited to 'kcontrol/iccconfig/iccconfig.cpp')
-rw-r--r-- | kcontrol/iccconfig/iccconfig.cpp | 319 |
1 files changed, 282 insertions, 37 deletions
diff --git a/kcontrol/iccconfig/iccconfig.cpp b/kcontrol/iccconfig/iccconfig.cpp index 4174f3ce8..05ea09cac 100644 --- a/kcontrol/iccconfig/iccconfig.cpp +++ b/kcontrol/iccconfig/iccconfig.cpp @@ -1,8 +1,7 @@ /** - * smartcard.cpp + * iccconfig.cpp * - * Copyright (c) 2001 George Staikos <[email protected]> - * Copyright (c) 2001 Fernando Llobregat <[email protected]> + * Copyright (c) 2009-2010 Timothy Pearson <[email protected]> * * 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->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->iccFile, 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); } |