• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

Konsole

EditProfileDialog.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
00003 
00004     This program is free software; you can redistribute it and/or modify
00005     it under the terms of the GNU General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or
00007     (at your option) any later version.
00008 
00009     This program is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU General Public License for more details.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program; if not, write to the Free Software
00016     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017     02110-1301  USA.
00018 */
00019 
00020 // Own
00021 #include "EditProfileDialog.h"
00022 
00023 // Qt
00024 #include <QtGui/QKeyEvent>
00025 #include <QtGui/QBrush>
00026 #include <QtGui/QPainter>
00027 #include <QtGui/QStandardItem>
00028 #include <QtCore/QTextCodec>
00029 #include <QtGui/QLinearGradient>
00030 #include <QtGui/QRadialGradient>
00031 
00032 #include <QtCore/QTimer>
00033 #include <QtCore/QTimeLine>
00034 
00035 // KDE
00036 #include <kcodecaction.h>
00037 #include <KDebug>
00038 #include <KFontDialog>
00039 #include <KIcon>
00040 #include <KIconDialog>
00041 #include <KFileDialog>
00042 #include <KUrlCompletion>
00043 #include <KWindowSystem>
00044 #include <KTextEdit>
00045 
00046 // Konsole
00047 #include "ColorScheme.h"
00048 #include "ColorSchemeEditor.h"
00049 #include "ui_EditProfileDialog.h"
00050 #include "KeyBindingEditor.h"
00051 #include "KeyboardTranslator.h"
00052 #include "SessionManager.h"
00053 #include "ShellCommand.h"
00054 #include "TabTitleFormatAction.h"
00055 
00056 using namespace Konsole;
00057 
00058 EditProfileDialog::EditProfileDialog(QWidget* parent)
00059     : KDialog(parent)
00060     , _colorSchemeAnimationTimeLine(0)
00061     , _delayedPreviewTimer(new QTimer(this))
00062 {
00063     setCaption(i18n("Edit Profile"));
00064     setButtons( KDialog::Ok | KDialog::Cancel | KDialog::Apply );
00065 
00066     connect( this , SIGNAL(applyClicked()) , this , SLOT(save()) );
00067     connect( _delayedPreviewTimer , SIGNAL(timeout()) , this , SLOT(delayedPreviewActivate()) );
00068     _ui = new Ui::EditProfileDialog();
00069     _ui->setupUi(mainWidget());
00070 
00071     // - Renable in a later KDE 4.x release when this feature works again
00072     _ui->enableResizeWindowButton->setVisible(false);
00073     
00074 #ifdef __GNUC__
00075 #warning "Re-enable when flow control is working again - bug in KDE 4.1"
00076 #endif
00077     _ui->enableFlowControlButton->setEnabled(false);
00078 
00079     // there are various setupXYZPage() methods to load the items
00080     // for each page and update their states to match the profile
00081     // being edited.
00082     //
00083     // these are only called when needed ( ie. when the user clicks
00084     // the tab to move to that page ).
00085     //
00086     // the _pageNeedsUpdate vector keeps track of the pages that have
00087     // not been updated since the last profile change and will need
00088     // to be refreshed when the user switches to them
00089     _pageNeedsUpdate.resize( _ui->tabWidget->count() );
00090     connect( _ui->tabWidget , SIGNAL(currentChanged(int)) , this , 
00091             SLOT(preparePage(int)) );
00092 
00093     _tempProfile = new Profile;
00094     _tempProfile->setHidden(true);
00095 }
00096 EditProfileDialog::~EditProfileDialog()
00097 {
00098     delete _ui;
00099 }
00100 void EditProfileDialog::save()
00101 {
00102     if ( _tempProfile->isEmpty() )
00103         return;
00104 
00105     SessionManager::instance()->changeProfile(_profile,_tempProfile->setProperties());
00106 
00107     // ensure that these settings are not undone by a call
00108     // to unpreview()
00109     QHashIterator<Profile::Property,QVariant> iter(_tempProfile->setProperties());
00110     while ( iter.hasNext() )
00111     {
00112         iter.next();
00113         _previewedProperties.remove(iter.key());
00114     }
00115 }
00116 void EditProfileDialog::reject()
00117 {
00118     unpreviewAll();
00119     KDialog::reject();
00120 }
00121 void EditProfileDialog::accept()
00122 {
00123     save();
00124     unpreviewAll();
00125     KDialog::accept(); 
00126 }
00127 QString EditProfileDialog::groupProfileNames(const ProfileGroup::Ptr group, int maxLength)
00128 {
00129     QString caption;
00130     int count = group->profiles().count();
00131     for (int i=0;i < count;i++)
00132     {
00133         caption += group->profiles()[i]->name();
00134         if (i < (count-1)) 
00135         {
00136             caption += ',';
00137             // limit caption length to prevent very long window titles
00138             if (maxLength > 0 && caption.length() > maxLength)
00139             {
00140                 caption += "...";
00141                 break;
00142             }
00143         }
00144     }
00145     return caption;
00146 }
00147 void EditProfileDialog::updateCaption(const Profile::Ptr profile)
00148 {
00149     const int MAX_GROUP_CAPTION_LENGTH = 25;
00150     ProfileGroup::Ptr group = profile->asGroup(); 
00151     if (group && group->profiles().count() > 1)
00152     {
00153         QString caption = groupProfileNames(group,MAX_GROUP_CAPTION_LENGTH); 
00154         setCaption( i18n("Edit Profile \"%1\"",caption) );
00155         // STRINGFREEZE - Change caption for groups after KDE 4.1 is released
00156         // setCaption( i18n("Editing %1 profiles",group->profiles().count()) )
00157     }
00158     else
00159         setCaption( i18n("Edit Profile \"%1\"",profile->name()) );
00160 }
00161 void EditProfileDialog::setProfile(Profile::Ptr profile)
00162 {
00163     _profile = profile;
00164 
00165     Q_ASSERT( profile );
00166 
00167     // update caption
00168     updateCaption(profile);
00169 
00170     // mark each page of the dialog as out of date
00171     // and force an update of the currently visible page
00172     //
00173     // the other pages will be updated as necessary
00174     _pageNeedsUpdate.fill(true);
00175     preparePage( _ui->tabWidget->currentIndex() );
00176 
00177     if ( _tempProfile )
00178     {
00179         _tempProfile = new Profile;
00180     }
00181 }
00182 const Profile::Ptr EditProfileDialog::lookupProfile() const
00183 {
00184     return _profile; 
00185 }
00186 void EditProfileDialog::preparePage(int page)
00187 {
00188     const Profile::Ptr info = lookupProfile();
00189 
00190     Q_ASSERT( _pageNeedsUpdate.count() > page );
00191     Q_ASSERT( info );
00192 
00193     QWidget* pageWidget = _ui->tabWidget->widget(page);
00194     
00195     if ( _pageNeedsUpdate[page] )
00196     {
00197        if ( pageWidget == _ui->generalTab )
00198             setupGeneralPage(info);
00199        else if ( pageWidget == _ui->tabsTab )
00200             setupTabsPage(info);
00201        else if ( pageWidget == _ui->appearanceTab )
00202             setupAppearancePage(info);
00203        else if ( pageWidget == _ui->scrollingTab )
00204             setupScrollingPage(info);
00205        else if ( pageWidget == _ui->keyboardTab )
00206             setupKeyboardPage(info);
00207        else if ( pageWidget == _ui->advancedTab )
00208             setupAdvancedPage(info);
00209        else
00210            Q_ASSERT(false);
00211 
00212         _pageNeedsUpdate[page] = false;
00213     }
00214 
00215     // start page entry animation for color schemes
00216     if ( pageWidget == _ui->appearanceTab )
00217             _colorSchemeAnimationTimeLine->start();
00218 }
00219 void EditProfileDialog::selectProfileName()
00220 {
00221     _ui->profileNameEdit->selectAll();
00222     _ui->profileNameEdit->setFocus();
00223 }
00224 void EditProfileDialog::setupGeneralPage(const Profile::Ptr info)
00225 {
00226     // basic profile options
00227     {
00228         ProfileGroup::Ptr group = info->asGroup(); 
00229         if (!group || group->profiles().count() < 2)
00230             _ui->profileNameEdit->setText( info->name() );
00231         else 
00232         {
00233             _ui->profileNameEdit->setText( groupProfileNames(group,-1) );
00234             _ui->profileNameLabel->setEnabled(false);
00235             _ui->profileNameEdit->setEnabled(false);
00236         }
00237     }
00238 
00239     ShellCommand command( info->command() , info->arguments() );
00240     _ui->commandEdit->setText( command.fullCommand() );
00241 
00242     KUrlCompletion* exeCompletion = new KUrlCompletion(KUrlCompletion::ExeCompletion);
00243     exeCompletion->setParent(this);
00244     exeCompletion->setDir(QString());
00245     _ui->commandEdit->setCompletionObject( exeCompletion );
00246     _ui->initialDirEdit->setText( info->defaultWorkingDirectory() );
00247 
00248     KUrlCompletion* dirCompletion = new KUrlCompletion(KUrlCompletion::DirCompletion);
00249     dirCompletion->setParent(this);
00250     _ui->initialDirEdit->setCompletionObject( dirCompletion );
00251     _ui->initialDirEdit->setClearButtonShown(true);
00252     _ui->dirSelectButton->setIcon( KIcon("folder-open") );
00253     _ui->iconSelectButton->setIcon( KIcon(info->icon()) );
00254     _ui->startInSameDirButton->setChecked(info->property<bool>(Profile::StartInCurrentSessionDir));
00255 
00256     // window options
00257     _ui->showMenuBarButton->setChecked( info->property<bool>(Profile::ShowMenuBar) );
00258 
00259     // signals and slots
00260     connect( _ui->dirSelectButton , SIGNAL(clicked()) , this , SLOT(selectInitialDir()) );
00261     connect( _ui->iconSelectButton , SIGNAL(clicked()) , this , SLOT(selectIcon()) );
00262     connect( _ui->startInSameDirButton , SIGNAL(toggled(bool)) , this , 
00263             SLOT(startInSameDir(bool)));
00264     connect( _ui->profileNameEdit , SIGNAL(textChanged(const QString&)) , this ,
00265             SLOT(profileNameChanged(const QString&)) );
00266     connect( _ui->initialDirEdit , SIGNAL(textChanged(const QString&)) , this , 
00267             SLOT(initialDirChanged(const QString&)) );
00268     connect(_ui->commandEdit , SIGNAL(textChanged(const QString&)) , this ,
00269             SLOT(commandChanged(const QString&)) ); 
00270     
00271     connect(_ui->showMenuBarButton , SIGNAL(toggled(bool)) , this , 
00272             SLOT(showMenuBar(bool)) );
00273 
00274     connect(_ui->environmentEditButton , SIGNAL(clicked()) , this , 
00275             SLOT(showEnvironmentEditor()) );
00276 }
00277 void EditProfileDialog::showEnvironmentEditor()
00278 {
00279     const Profile::Ptr info = lookupProfile();
00280 
00281     KDialog* dialog = new KDialog(this);
00282     KTextEdit* edit = new KTextEdit(dialog);
00283 
00284     QStringList currentEnvironment = info->property<QStringList>(Profile::Environment);
00285 
00286     edit->setPlainText( currentEnvironment.join("\n") );
00287     dialog->setPlainCaption(i18n("Edit Environment"));
00288     dialog->setMainWidget(edit);
00289 
00290     if ( dialog->exec() == QDialog::Accepted )
00291     {
00292         QStringList newEnvironment = edit->toPlainText().split('\n');
00293         _tempProfile->setProperty(Profile::Environment,newEnvironment);
00294     }
00295 
00296     dialog->deleteLater();
00297 }
00298 void EditProfileDialog::setupTabsPage(const Profile::Ptr info)
00299 {
00300     // tab title format
00301     _ui->tabTitleEdit->setClearButtonShown(true);
00302     _ui->remoteTabTitleEdit->setClearButtonShown(true);
00303     _ui->tabTitleEdit->setText( info->property<QString>(Profile::LocalTabTitleFormat) );
00304     _ui->remoteTabTitleEdit->setText( 
00305             info->property<QString>(Profile::RemoteTabTitleFormat));
00306 
00307     // tab options
00308     int tabMode = info->property<int>(Profile::TabBarMode);
00309     int tabPosition = info->property<int>(Profile::TabBarPosition);
00310 
00311     // note: Items should be in the same order as the 
00312     // Profile::TabBarModeEnum enum
00313     _ui->tabBarVisibilityCombo->addItems( QStringList() << i18n("Always Hide Tab Bar")
00314                                                         << i18n("Show Tab Bar When Needed") 
00315                                                         << i18n("Always Show Tab Bar") );
00316     _ui->tabBarVisibilityCombo->setCurrentIndex(tabMode);
00317 
00318     // note: Items should be in the same order as the
00319     // Profile::TabBarPositionEnum enum
00320     _ui->tabBarPositionCombo->addItems( QStringList() << i18n("Below Terminal Displays")
00321                                                       << i18n("Above Terminal Displays") );
00322 
00323     _ui->tabBarPositionCombo->setCurrentIndex(tabPosition);
00324     _ui->newTabButton->setChecked(info->property<bool>(Profile::ShowNewAndCloseTabButtons));
00325 
00326     // signals and slots
00327     connect( _ui->tabBarVisibilityCombo , SIGNAL(activated(int)) , this , 
00328              SLOT(tabBarVisibilityChanged(int)) );
00329     connect( _ui->tabBarPositionCombo , SIGNAL(activated(int)) , this ,
00330              SLOT(tabBarPositionChanged(int)) );
00331     connect( _ui->newTabButton , SIGNAL(toggled(bool)) , this ,
00332              SLOT(showNewTabButton(bool)) );
00333 
00334     connect(_ui->tabTitleEdit , SIGNAL(textChanged(const QString&)) , this ,
00335             SLOT(tabTitleFormatChanged(const QString&)) );
00336     connect(_ui->remoteTabTitleEdit , SIGNAL(textChanged(const QString&)) , this ,
00337             SLOT(remoteTabTitleFormatChanged(const QString&)));
00338 
00339     // menus for local and remote tab title dynamic elements
00340     TabTitleFormatAction* localTabTitleAction = new TabTitleFormatAction(this);
00341     localTabTitleAction->setContext(Session::LocalTabTitle);
00342     _ui->tabTitleEditButton->setMenu(localTabTitleAction->menu());
00343     connect( localTabTitleAction , SIGNAL(dynamicElementSelected(const QString&)) , 
00344             this , SLOT(insertTabTitleText(const QString&)) );
00345 
00346     TabTitleFormatAction* remoteTabTitleAction = new TabTitleFormatAction(this);
00347     remoteTabTitleAction->setContext(Session::RemoteTabTitle);
00348     _ui->remoteTabTitleEditButton->setMenu(remoteTabTitleAction->menu());
00349     connect( remoteTabTitleAction , SIGNAL(dynamicElementSelected(const QString&)) ,
00350            this , SLOT(insertRemoteTabTitleText(const QString&)) ); 
00351 }
00352 void EditProfileDialog::showNewTabButton(bool show)
00353 { _tempProfile->setProperty(Profile::ShowNewAndCloseTabButtons,show); }
00354 void EditProfileDialog::tabBarVisibilityChanged(int newValue)
00355 {
00356     _tempProfile->setProperty( Profile::TabBarMode , newValue );
00357 }
00358 void EditProfileDialog::tabBarPositionChanged(int newValue)
00359 {
00360     _tempProfile->setProperty( Profile::TabBarPosition , newValue );
00361 }
00362 void EditProfileDialog::insertTabTitleText(const QString& text)
00363 {
00364     _ui->tabTitleEdit->insert(text);
00365 }
00366 void EditProfileDialog::insertRemoteTabTitleText(const QString& text)
00367 {
00368     _ui->remoteTabTitleEdit->insert(text);
00369 }
00370 void EditProfileDialog::showMenuBar(bool show)
00371 {
00372     _tempProfile->setProperty(Profile::ShowMenuBar,show);
00373 }
00374 void EditProfileDialog::tabTitleFormatChanged(const QString& format)
00375 {
00376     _tempProfile->setProperty(Profile::LocalTabTitleFormat,format);
00377 }
00378 void EditProfileDialog::remoteTabTitleFormatChanged(const QString& format)
00379 {
00380     _tempProfile->setProperty(Profile::RemoteTabTitleFormat,format);
00381 }
00382 
00383 void EditProfileDialog::selectIcon()
00384 {
00385     const QString& icon = KIconDialog::getIcon(KIconLoader::Desktop, KIconLoader::Application,
00386                                                false, 0, false, this);
00387     if (!icon.isEmpty())
00388     {
00389         _ui->iconSelectButton->setIcon( KIcon(icon) );
00390         _tempProfile->setProperty(Profile::Icon,icon);
00391     }
00392 }
00393 void EditProfileDialog::profileNameChanged(const QString& text)
00394 {
00395     _tempProfile->setProperty(Profile::Name,text);
00396     updateCaption(_tempProfile);
00397 }
00398 void EditProfileDialog::startInSameDir(bool sameDir)
00399 {
00400     _tempProfile->setProperty(Profile::StartInCurrentSessionDir,sameDir);
00401 }
00402 void EditProfileDialog::initialDirChanged(const QString& dir)
00403 {
00404     _tempProfile->setProperty(Profile::Directory,dir);
00405 }
00406 void EditProfileDialog::commandChanged(const QString& command)
00407 {
00408     ShellCommand shellCommand(command);
00409 
00410     _tempProfile->setProperty(Profile::Command,shellCommand.command());
00411     _tempProfile->setProperty(Profile::Arguments,shellCommand.arguments());
00412 }
00413 void EditProfileDialog::selectInitialDir()
00414 {
00415     const KUrl url = KFileDialog::getExistingDirectoryUrl(_ui->initialDirEdit->text(),
00416                                                           this,
00417                                                           i18n("Select Initial Directory"));
00418 
00419     if ( !url.isEmpty() )
00420         _ui->initialDirEdit->setText(url.path());
00421 }
00422 void EditProfileDialog::setupAppearancePage(const Profile::Ptr info)
00423 {
00424     ColorSchemeViewDelegate* delegate = new ColorSchemeViewDelegate(this);
00425     _ui->colorSchemeList->setItemDelegate(delegate);
00426     
00427     _colorSchemeAnimationTimeLine = new QTimeLine( 500 , this );
00428     delegate->setEntryTimeLine(_colorSchemeAnimationTimeLine);
00429     
00430     connect( _colorSchemeAnimationTimeLine , SIGNAL(valueChanged(qreal)) , this ,
00431              SLOT(colorSchemeAnimationUpdate()) );
00432    
00433     _ui->transparencyWarningWidget->setVisible(false);
00434     _ui->transparencyWarningWidget->setText(i18n("This color scheme uses a transparent background"
00435                                                  " which does not appear to be supported on your"
00436                                                  " desktop"));
00437     _ui->editColorSchemeButton->setEnabled(false);
00438     _ui->removeColorSchemeButton->setEnabled(false);
00439 
00440     // setup color list
00441     updateColorSchemeList(true);
00442     
00443     _ui->colorSchemeList->setMouseTracking(true);
00444     _ui->colorSchemeList->installEventFilter(this);
00445     _ui->colorSchemeList->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn );
00446 
00447     connect( _ui->colorSchemeList->selectionModel() , 
00448             SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)) 
00449             , this , SLOT(colorSchemeSelected()) );
00450     connect( _ui->colorSchemeList , SIGNAL(entered(const QModelIndex&)) , this , 
00451             SLOT(previewColorScheme(const QModelIndex&)) );
00452     
00453     updateColorSchemeButtons();
00454 
00455     connect( _ui->editColorSchemeButton , SIGNAL(clicked()) , this , 
00456             SLOT(editColorScheme()) );
00457     connect( _ui->removeColorSchemeButton , SIGNAL(clicked()) , this ,
00458             SLOT(removeColorScheme()) );
00459     connect( _ui->newColorSchemeButton , SIGNAL(clicked()) , this , 
00460             SLOT(newColorScheme()) );
00461 
00462     // setup font preview
00463     bool antialias = info->property<bool>(Profile::AntiAliasFonts);
00464 
00465     QFont font = info->font();
00466     if (!antialias)
00467         font.setStyleStrategy(QFont::NoAntialias);
00468 
00469     _ui->fontPreviewLabel->installEventFilter(this);
00470     _ui->fontPreviewLabel->setFont(font);
00471     _ui->fontSizeSlider->setValue( font.pointSize() );
00472     _ui->fontSizeSlider->setMinimum( KGlobalSettings::smallestReadableFont().pointSize() );
00473 
00474     connect( _ui->fontSizeSlider , SIGNAL(valueChanged(int)) , this ,
00475              SLOT(setFontSize(int)) );
00476     connect( _ui->editFontButton , SIGNAL(clicked()) , this ,
00477              SLOT(showFontDialog()) );
00478 
00479     // setup font smoothing 
00480     _ui->antialiasTextButton->setChecked(antialias);
00481     connect( _ui->antialiasTextButton , SIGNAL(toggled(bool)) , this , 
00482              SLOT(setAntialiasText(bool)) );
00483 }
00484 void EditProfileDialog::setAntialiasText(bool enable)
00485 {
00486     _tempProfile->setProperty(Profile::AntiAliasFonts,enable);
00487 
00488     // update preview to reflect text smoothing state
00489     fontSelected(_ui->fontPreviewLabel->font());
00490 }
00491 void EditProfileDialog::colorSchemeAnimationUpdate()
00492 {
00493     QAbstractItemModel* model = _ui->colorSchemeList->model();
00494 
00495     for ( int i = model->rowCount() ; i >= 0 ; i-- )
00496         _ui->colorSchemeList->update( model->index(i,0) );
00497 }
00498 void EditProfileDialog::updateColorSchemeList(bool selectCurrentScheme)
00499 {
00500     if (!_ui->colorSchemeList->model())
00501         _ui->colorSchemeList->setModel(new QStandardItemModel(this));
00502 
00503     const QString& name = lookupProfile()->colorScheme();
00504     const ColorScheme* currentScheme = ColorSchemeManager::instance()->findColorScheme(name);
00505 
00506     QStandardItemModel* model = qobject_cast<QStandardItemModel*>(_ui->colorSchemeList->model());
00507 
00508     Q_ASSERT(model);
00509     
00510     model->clear();
00511 
00512     QList<const ColorScheme*> schemeList = ColorSchemeManager::instance()->allColorSchemes();
00513     QListIterator<const ColorScheme*> schemeIter(schemeList);
00514 
00515     QStandardItem* selectedItem = 0;
00516 
00517     while (schemeIter.hasNext())
00518     {
00519         const ColorScheme* colors = schemeIter.next();
00520         QStandardItem* item = new QStandardItem(colors->description());
00521         item->setData( QVariant::fromValue(colors) ,  Qt::UserRole + 1);
00522         item->setFlags( item->flags() );
00523        
00524         if ( currentScheme == colors ) 
00525             selectedItem = item;  
00526 
00527         model->appendRow(item);
00528     }
00529 
00530     model->sort(0);
00531 
00532     if ( selectCurrentScheme && selectedItem )
00533     {
00534         _ui->colorSchemeList->updateGeometry();
00535         _ui->colorSchemeList->selectionModel()->setCurrentIndex( selectedItem->index() , 
00536                                                                  QItemSelectionModel::Select );
00537 
00538         // update transparency warning label
00539         updateTransparencyWarning();
00540     }
00541 }
00542 void EditProfileDialog::updateKeyBindingsList(bool selectCurrentTranslator)
00543 {
00544     if (!_ui->keyBindingList->model())
00545         _ui->keyBindingList->setModel(new QStandardItemModel(this));
00546 
00547     KeyboardTranslatorManager* keyManager = KeyboardTranslatorManager::instance();
00548 
00549     const QString& name = lookupProfile()
00550                                     ->property<QString>(Profile::KeyBindings);
00551 
00552     const KeyboardTranslator* currentTranslator = keyManager->findTranslator(name);
00553     
00554     QStandardItemModel* model = qobject_cast<QStandardItemModel*>(_ui->keyBindingList->model());
00555 
00556     Q_ASSERT(model);
00557 
00558     model->clear();
00559 
00560     QStandardItem* selectedItem = 0;
00561 
00562     QList<QString> translatorNames = keyManager->allTranslators();
00563     QListIterator<QString> iter(translatorNames);
00564     while (iter.hasNext())
00565     {
00566         const QString& name = iter.next();
00567 
00568         const KeyboardTranslator* translator = keyManager->findTranslator(name);
00569 
00570         QStandardItem* item = new QStandardItem(translator->description());
00571         item->setData(QVariant::fromValue(translator),Qt::UserRole+1);
00572         item->setIcon( KIcon("preferences-desktop-keyboard") );
00573 
00574         if ( translator == currentTranslator )
00575             selectedItem = item;
00576 
00577         model->appendRow(item);
00578     }
00579 
00580     model->sort(0);
00581     
00582     if ( selectCurrentTranslator && selectedItem )
00583     {
00584         _ui->keyBindingList->selectionModel()->setCurrentIndex( selectedItem->index() , 
00585                                                                   QItemSelectionModel::Select );
00586     }
00587 }
00588 bool EditProfileDialog::eventFilter( QObject* watched , QEvent* event )
00589 {
00590     if ( watched == _ui->colorSchemeList && event->type() == QEvent::Leave )
00591     {
00592         if ( _tempProfile->isPropertySet(Profile::ColorScheme) )
00593             preview(Profile::ColorScheme,_tempProfile->colorScheme());
00594         else
00595             unpreview(Profile::ColorScheme);
00596     }
00597     if ( watched == _ui->fontPreviewLabel && event->type() == QEvent::FontChange )
00598     {
00599         const QFont& labelFont = _ui->fontPreviewLabel->font();
00600         _ui->fontPreviewLabel->setText(i18n("%1, size %2",labelFont.family(),labelFont.pointSize()));
00601     }
00602 
00603     return KDialog::eventFilter(watched,event);
00604 }
00605 void EditProfileDialog::unpreviewAll()
00606 {
00607     _delayedPreviewTimer->stop();
00608     _delayedPreviewProperties.clear();
00609 
00610     QHash<Profile::Property,QVariant> map;
00611     QHashIterator<int,QVariant> iter(_previewedProperties);
00612     while ( iter.hasNext() )
00613     {
00614         iter.next();
00615         map.insert((Profile::Property)iter.key(),iter.value());
00616     }
00617 
00618     // undo any preview changes
00619     if ( !map.isEmpty() )
00620         SessionManager::instance()->changeProfile(_profile,map,false);
00621 }
00622 void EditProfileDialog::unpreview(int property)
00623 {
00624     _delayedPreviewProperties.remove(property);
00625     
00626     if (!_previewedProperties.contains(property))
00627         return;
00628     
00629     QHash<Profile::Property,QVariant> map;
00630     map.insert((Profile::Property)property,_previewedProperties[property]);
00631     SessionManager::instance()->changeProfile(_profile,map,false); 
00632 
00633     _previewedProperties.remove(property);
00634 }
00635 void EditProfileDialog::delayedPreview(int property , const QVariant& value)
00636 {
00637     _delayedPreviewProperties.insert(property,value); 
00638 
00639     _delayedPreviewTimer->stop();
00640     _delayedPreviewTimer->start(300);
00641 }
00642 void EditProfileDialog::delayedPreviewActivate()
00643 {
00644     Q_ASSERT( qobject_cast<QTimer*>(sender()) );
00645 
00646     QMutableHashIterator<int,QVariant> iter(_delayedPreviewProperties);
00647     if ( iter.hasNext() ) 
00648     {
00649         iter.next();
00650         preview(iter.key(),iter.value());
00651     }
00652 }
00653 void EditProfileDialog::preview(int property , const QVariant& value)
00654 {
00655     QHash<Profile::Property,QVariant> map;
00656     map.insert((Profile::Property)property,value);
00657 
00658     _delayedPreviewProperties.remove(property);
00659 
00660     const Profile::Ptr original = lookupProfile();
00661 
00662     // skip previews for profile groups if the profiles in the group
00663     // have conflicting original values for the property
00664     //
00665     // TODO - Save the original values for each profile and use to unpreview properties
00666     ProfileGroup::Ptr group = original->asGroup();
00667     if (group && group->profiles().count() > 1 &&
00668         original->property<QVariant>((Profile::Property)property).isNull())
00669         return;
00670 
00671     if (!_previewedProperties.contains(property))   
00672     {
00673         _previewedProperties.insert(property , original->property<QVariant>((Profile::Property)property) );
00674     }
00675 
00676     // temporary change to color scheme
00677     SessionManager::instance()->changeProfile( _profile , map , false);
00678 }
00679 void EditProfileDialog::previewColorScheme(const QModelIndex& index)
00680 {
00681     const QString& name = index.data(Qt::UserRole+1).value<const ColorScheme*>()->name();
00682 
00683     delayedPreview( Profile::ColorScheme , name );
00684 }
00685 void EditProfileDialog::removeColorScheme()
00686 {
00687     QModelIndexList selected = _ui->colorSchemeList->selectionModel()->selectedIndexes();
00688 
00689     if ( !selected.isEmpty() )
00690     {
00691         const QString& name = selected.first().data(Qt::UserRole+1).value<const ColorScheme*>()->name();
00692         
00693         if (ColorSchemeManager::instance()->deleteColorScheme(name))    
00694             _ui->colorSchemeList->model()->removeRow(selected.first().row());
00695     }
00696 }
00697 void EditProfileDialog::showColorSchemeEditor(bool isNewScheme)
00698 {    
00699     QModelIndexList selected = _ui->colorSchemeList->selectionModel()->selectedIndexes();
00700 
00701     QAbstractItemModel* model = _ui->colorSchemeList->model();
00702     const ColorScheme* colors = 0;
00703     if ( !selected.isEmpty() )
00704         colors = model->data(selected.first(),Qt::UserRole+1).value<const ColorScheme*>();
00705     else
00706         colors = ColorSchemeManager::instance()->defaultColorScheme();
00707 
00708     Q_ASSERT(colors);
00709 
00710     KDialog* dialog = new KDialog(this);
00711 
00712     if ( isNewScheme )
00713         dialog->setCaption(i18n("New Color Scheme"));
00714     else
00715         dialog->setCaption(i18n("Edit Color Scheme"));
00716 
00717     ColorSchemeEditor* editor = new ColorSchemeEditor;
00718     dialog->setMainWidget(editor);
00719     editor->setup(colors);
00720 
00721     if ( isNewScheme )
00722         editor->setDescription(i18n("New Color Scheme"));
00723         
00724     if ( dialog->exec() == QDialog::Accepted )
00725     {
00726         ColorScheme* newScheme = new ColorScheme(*editor->colorScheme());
00727 
00728         // if this is a new color scheme, pick a name based on the description
00729         if ( isNewScheme )
00730             newScheme->setName(newScheme->description());
00731 
00732         ColorSchemeManager::instance()->addColorScheme( newScheme );
00733         
00734         updateColorSchemeList(true);
00735 
00736         preview(Profile::ColorScheme,newScheme->name());
00737     }
00738 }
00739 void EditProfileDialog::newColorScheme()
00740 {
00741     showColorSchemeEditor(true);    
00742 }
00743 void EditProfileDialog::editColorScheme()
00744 {
00745     showColorSchemeEditor(false);
00746 }
00747 void EditProfileDialog::colorSchemeSelected()
00748 {
00749     QModelIndexList selected = _ui->colorSchemeList->selectionModel()->selectedIndexes();
00750 
00751     if ( !selected.isEmpty() )
00752     {
00753         QAbstractItemModel* model = _ui->colorSchemeList->model();
00754         const ColorScheme* colors = model->data(selected.first(),Qt::UserRole+1).value<const ColorScheme*>();
00755 
00756         kDebug() << "Setting temp profile color to" << colors->name();
00757         
00758         previewColorScheme(selected.first());
00759         _tempProfile->setProperty(Profile::ColorScheme,colors->name());
00760 
00761         updateTransparencyWarning();
00762     }
00763 
00764     updateColorSchemeButtons();
00765 }
00766 void EditProfileDialog::updateColorSchemeButtons()
00767 {
00768     enableIfNonEmptySelection(_ui->editColorSchemeButton,_ui->colorSchemeList->selectionModel());
00769     enableIfNonEmptySelection(_ui->removeColorSchemeButton,_ui->colorSchemeList->selectionModel());
00770 }
00771 void EditProfileDialog::updateKeyBindingsButtons()
00772 {    
00773     enableIfNonEmptySelection(_ui->editKeyBindingsButton,_ui->keyBindingList->selectionModel());
00774     enableIfNonEmptySelection(_ui->removeKeyBindingsButton,_ui->keyBindingList->selectionModel());
00775 }
00776 void EditProfileDialog::enableIfNonEmptySelection(QWidget* widget,QItemSelectionModel* selectionModel)
00777 {
00778     widget->setEnabled(selectionModel->hasSelection());
00779 }
00780 void EditProfileDialog::updateTransparencyWarning() 
00781 {
00782     // zero or one indexes can be selected
00783     foreach( const QModelIndex& index , _ui->colorSchemeList->selectionModel()->selectedIndexes() ) 
00784     {
00785         bool hasTransparency = index.data(Qt::UserRole+1).value<const ColorScheme*>()->opacity() < 1.0;
00786         _ui->transparencyWarningWidget->setHidden(KWindowSystem::compositingActive() || !hasTransparency);
00787     }
00788 }
00789 void EditProfileDialog::setupKeyboardPage(const Profile::Ptr /* info */)
00790 {
00791     // setup translator list
00792     updateKeyBindingsList(true); 
00793 
00794     connect( _ui->keyBindingList->selectionModel() , 
00795                 SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)),
00796                 SLOT(keyBindingSelected()) );
00797     connect( _ui->newKeyBindingsButton , SIGNAL(clicked()) , this ,
00798             SLOT(newKeyBinding()) );
00799 
00800     updateKeyBindingsButtons();
00801 
00802     connect( _ui->editKeyBindingsButton , SIGNAL(clicked()) , this , 
00803           SLOT(editKeyBinding()) );  
00804     connect( _ui->removeKeyBindingsButton , SIGNAL(clicked()) , this ,
00805             SLOT(removeKeyBinding()) );
00806 }
00807 void EditProfileDialog::keyBindingSelected()
00808 {
00809     QModelIndexList selected = _ui->keyBindingList->selectionModel()->selectedIndexes();
00810 
00811     if ( !selected.isEmpty() )
00812     {
00813         QAbstractItemModel* model = _ui->keyBindingList->model();
00814         const KeyboardTranslator* translator = model->data(selected.first(),Qt::UserRole+1)
00815                                                 .value<const KeyboardTranslator*>();
00816         _tempProfile->setProperty(Profile::KeyBindings,translator->name());
00817     }
00818 
00819     updateKeyBindingsButtons();
00820 }
00821 void EditProfileDialog::removeKeyBinding()
00822 {
00823     QModelIndexList selected = _ui->keyBindingList->selectionModel()->selectedIndexes();
00824 
00825     if ( !selected.isEmpty() )
00826     {
00827         const QString& name = selected.first().data(Qt::UserRole+1).value<const KeyboardTranslator*>()->name();
00828         if (KeyboardTranslatorManager::instance()->deleteTranslator(name))
00829             _ui->keyBindingList->model()->removeRow(selected.first().row());   
00830     }
00831 }
00832 void EditProfileDialog::showKeyBindingEditor(bool isNewTranslator)
00833 {
00834     QModelIndexList selected = _ui->keyBindingList->selectionModel()->selectedIndexes();
00835     QAbstractItemModel* model = _ui->keyBindingList->model();
00836 
00837     const KeyboardTranslator* translator = 0;
00838     if ( !selected.isEmpty() )
00839         translator = model->data(selected.first(),Qt::UserRole+1).value<const KeyboardTranslator*>();
00840     else
00841         translator = KeyboardTranslatorManager::instance()->defaultTranslator();
00842 
00843     Q_ASSERT(translator);
00844 
00845     KDialog* dialog = new KDialog(this);
00846 
00847     if ( isNewTranslator )
00848         dialog->setCaption(i18n("New Key Binding List"));
00849     else
00850         dialog->setCaption(i18n("Edit Key Binding List"));
00851 
00852     KeyBindingEditor* editor = new KeyBindingEditor;
00853     dialog->setMainWidget(editor);
00854     
00855     if ( translator )
00856         editor->setup(translator);
00857 
00858     if ( isNewTranslator )
00859         editor->setDescription(i18n("New Key Binding List"));
00860 
00861     if ( dialog->exec() == QDialog::Accepted )
00862     {
00863         KeyboardTranslator* newTranslator = new KeyboardTranslator(*editor->translator());
00864 
00865         if ( isNewTranslator )
00866             newTranslator->setName(newTranslator->description());
00867 
00868         KeyboardTranslatorManager::instance()->addTranslator( newTranslator );
00869 
00870         updateKeyBindingsList();
00871         
00872         const QString& currentTranslator = lookupProfile()
00873                                         ->property<QString>(Profile::KeyBindings);
00874 
00875         if ( newTranslator->name() == currentTranslator )
00876         {
00877             _tempProfile->setProperty(Profile::KeyBindings,newTranslator->name());
00878         }
00879     }
00880 }
00881 void EditProfileDialog::newKeyBinding()
00882 {
00883     showKeyBindingEditor(true);
00884 }
00885 void EditProfileDialog::editKeyBinding()
00886 {
00887     showKeyBindingEditor(false);
00888 }
00889 void EditProfileDialog::setupCombo( ComboOption* options , const Profile::Ptr profile )
00890 {
00891     while ( options->button != 0 )
00892     {
00893         options->button->setChecked(profile->property<bool>((Profile::Property)options->property));
00894         connect( options->button , SIGNAL(toggled(bool)) , this , options->slot );
00895 
00896         ++options;
00897     }
00898 }
00899 void EditProfileDialog::setupRadio( RadioOption* possible , int actual )
00900 {
00901     while (possible->button != 0)
00902     {
00903         if ( possible->property == actual )
00904             possible->button->setChecked(true);
00905         else
00906             possible->button->setChecked(false);
00907    
00908         connect( possible->button , SIGNAL(clicked()) , this , possible->slot );
00909 
00910         ++possible;
00911     }
00912 }
00913 
00914 void EditProfileDialog::setupScrollingPage(const Profile::Ptr profile)
00915 {
00916     // setup scrollbar radio
00917     int scrollBarPosition = profile->property<int>(Profile::ScrollBarPosition);
00918    
00919     RadioOption positions[] = { {_ui->scrollBarHiddenButton,Profile::ScrollBarHidden,SLOT(hideScrollBar())},
00920                                 {_ui->scrollBarLeftButton,Profile::ScrollBarLeft,SLOT(showScrollBarLeft())},
00921                                 {_ui->scrollBarRightButton,Profile::ScrollBarRight,SLOT(showScrollBarRight())},
00922                                 {0,0,0} 
00923                               }; 
00924 
00925     setupRadio( positions , scrollBarPosition );
00926    
00927     // setup scrollback type radio
00928     int scrollBackType = profile->property<int>(Profile::HistoryMode);
00929     
00930     RadioOption types[] = { {_ui->disableScrollbackButton,Profile::DisableHistory,SLOT(noScrollBack())},
00931                             {_ui->fixedScrollbackButton,Profile::FixedSizeHistory,SLOT(fixedScrollBack())},
00932                             {_ui->unlimitedScrollbackButton,Profile::UnlimitedHistory,SLOT(unlimitedScrollBack())},
00933                             {0,0,0} };
00934     setupRadio( types , scrollBackType ); 
00935     
00936     // setup scrollback line count spinner
00937     _ui->scrollBackLinesSpinner->setValue( profile->property<int>(Profile::HistorySize) );
00938 
00939     // signals and slots
00940     connect( _ui->scrollBackLinesSpinner , SIGNAL(valueChanged(int)) , this , 
00941             SLOT(scrollBackLinesChanged(int)) );
00942 }
00943 
00944 void EditProfileDialog::scrollBackLinesChanged(int lineCount)
00945 {
00946     _tempProfile->setProperty(Profile::HistorySize , lineCount);
00947 }
00948 void EditProfileDialog::noScrollBack()
00949 {
00950     _tempProfile->setProperty(Profile::HistoryMode , Profile::DisableHistory);
00951 }
00952 void EditProfileDialog::fixedScrollBack()
00953 {
00954     _tempProfile->setProperty(Profile::HistoryMode , Profile::FixedSizeHistory);
00955 }
00956 void EditProfileDialog::unlimitedScrollBack()
00957 {
00958     _tempProfile->setProperty(Profile::HistoryMode , Profile::UnlimitedHistory );
00959 }
00960 void EditProfileDialog::hideScrollBar()
00961 {
00962     _tempProfile->setProperty(Profile::ScrollBarPosition , Profile::ScrollBarHidden );
00963 }
00964 void EditProfileDialog::showScrollBarLeft()
00965 {
00966     _tempProfile->setProperty(Profile::ScrollBarPosition , Profile::ScrollBarLeft );
00967 }
00968 void EditProfileDialog::showScrollBarRight()
00969 {
00970     _tempProfile->setProperty(Profile::ScrollBarPosition , Profile::ScrollBarRight );
00971 }
00972 void EditProfileDialog::setupAdvancedPage(const Profile::Ptr profile)
00973 {
00974     ComboOption  options[] = { { _ui->enableBlinkingTextButton , Profile::BlinkingTextEnabled , 
00975                                  SLOT(toggleBlinkingText(bool)) },
00976                                { _ui->enableFlowControlButton , Profile::FlowControlEnabled ,
00977                                  SLOT(toggleFlowControl(bool)) },
00978                                { _ui->enableResizeWindowButton , Profile::AllowProgramsToResizeWindow ,
00979                                  SLOT(toggleResizeWindow(bool)) },
00980                                { _ui->enableBlinkingCursorButton , Profile::BlinkingCursorEnabled ,
00981                                  SLOT(toggleBlinkingCursor(bool)) },
00982                                { _ui->enableBidiRenderingButton , Profile::BidiRenderingEnabled ,
00983                                  SLOT(togglebidiRendering(bool)) },
00984                                { 0 , 0 , 0 }
00985                              };
00986     setupCombo( options , profile );
00987 
00988     // interaction options
00989     _ui->wordCharacterEdit->setText( profile->property<QString>(Profile::WordCharacters) );
00990 
00991     connect( _ui->wordCharacterEdit , SIGNAL(textChanged(const QString&)) , this , 
00992             SLOT(wordCharactersChanged(const QString&)) );
00993 
00994     // cursor options
00995     if ( profile->property<bool>(Profile::UseCustomCursorColor) )
00996         _ui->customCursorColorButton->setChecked(true);
00997     else
00998         _ui->autoCursorColorButton->setChecked(true);
00999 
01000     _ui->customColorSelectButton->setColor( profile->property<QColor>(Profile::CustomCursorColor) );
01001 
01002     connect( _ui->customCursorColorButton , SIGNAL(clicked()) , this , SLOT(customCursorColor()) );
01003     connect( _ui->autoCursorColorButton , SIGNAL(clicked()) , this , SLOT(autoCursorColor()) );
01004     connect( _ui->customColorSelectButton , SIGNAL(changed(const QColor&)) , 
01005             SLOT(customCursorColorChanged(const QColor&)) );
01006 
01007     int shape = profile->property<int>(Profile::CursorShape);
01008     _ui->cursorShapeCombo->setCurrentIndex(shape);
01009 
01010     connect( _ui->cursorShapeCombo , SIGNAL(activated(int)) , this , SLOT(setCursorShape(int)) ); 
01011 
01012     // encoding options
01013     QAction* codecAction = new KCodecAction(this);
01014     _ui->selectEncodingButton->setMenu( codecAction->menu() );
01015     connect( codecAction , SIGNAL(triggered(QTextCodec*)) , this , SLOT(setDefaultCodec(QTextCodec*)) );
01016 
01017     _ui->characterEncodingLabel->setText( profile->property<QString>(Profile::DefaultEncoding) );
01018 
01019 }
01020 void EditProfileDialog::setDefaultCodec(QTextCodec* codec)
01021 {
01022     QString name = QString(codec->name());
01023 
01024     _tempProfile->setProperty(Profile::DefaultEncoding,name);
01025     _ui->characterEncodingLabel->setText(codec->name());
01026 }
01027 void EditProfileDialog::customCursorColorChanged(const QColor& color)
01028 {
01029     _tempProfile->setProperty(Profile::CustomCursorColor,color);
01030 
01031     // ensure that custom cursor colors are enabled
01032     _ui->customCursorColorButton->click();
01033 }
01034 void EditProfileDialog::wordCharactersChanged(const QString& text)
01035 {
01036     _tempProfile->setProperty(Profile::WordCharacters,text);
01037 }
01038 void EditProfileDialog::autoCursorColor()
01039 {
01040     _tempProfile->setProperty(Profile::UseCustomCursorColor,false);
01041 }
01042 void EditProfileDialog::customCursorColor()
01043 {
01044     _tempProfile->setProperty(Profile::UseCustomCursorColor,true);
01045 }
01046 void EditProfileDialog::setCursorShape(int index)
01047 {
01048     _tempProfile->setProperty(Profile::CursorShape,index);
01049 }
01050 void EditProfileDialog::togglebidiRendering(bool enable)
01051 {
01052     _tempProfile->setProperty(Profile::BidiRenderingEnabled,enable);
01053 }
01054 void EditProfileDialog::toggleBlinkingCursor(bool enable)
01055 {
01056     _tempProfile->setProperty(Profile::BlinkingCursorEnabled,enable);
01057 }
01058 void EditProfileDialog::toggleBlinkingText(bool enable)
01059 {
01060     _tempProfile->setProperty(Profile::BlinkingTextEnabled,enable);
01061 }
01062 void EditProfileDialog::toggleFlowControl(bool enable)
01063 {
01064     _tempProfile->setProperty(Profile::FlowControlEnabled,enable);
01065 }
01066 void EditProfileDialog::toggleResizeWindow(bool enable)
01067 {
01068     _tempProfile->setProperty(Profile::AllowProgramsToResizeWindow,enable);
01069 }
01070 void EditProfileDialog::fontSelected(const QFont& font)
01071 {
01072     QFont previewFont = font;
01073 
01074    QSlider* slider = _ui->fontSizeSlider;
01075    _ui->fontSizeSlider->setRange( qMin(slider->minimum(),font.pointSize()) ,
01076                                   qMax(slider->maximum(),font.pointSize()) );
01077    _ui->fontSizeSlider->setValue(font.pointSize());
01078 
01079     
01080    QFont::StyleStrategy strategy;
01081    if (_tempProfile->property<bool>(Profile::AntiAliasFonts))
01082            strategy = QFont::PreferAntialias;
01083    else
01084            strategy = QFont::NoAntialias;
01085 
01086    previewFont.setStyleStrategy(strategy);
01087 
01088    _ui->fontPreviewLabel->setFont(previewFont);
01089    
01090    _tempProfile->setProperty(Profile::Font,font);
01091 
01092    preview(Profile::Font,font);
01093 }
01094 void EditProfileDialog::showFontDialog()
01095 {
01096     QFont currentFont = _ui->fontPreviewLabel->font();
01097    
01098     KFontDialog* dialog = new KFontDialog(this, KFontChooser::FixedFontsOnly);
01099     dialog->setFont(currentFont, true);
01100 
01101     connect( dialog , SIGNAL(fontSelected(const QFont&)) , this , SLOT(fontSelected(const QFont&)) );
01102 
01103     if (dialog->exec() == QDialog::Rejected)
01104         fontSelected(currentFont);
01105 }
01106 void EditProfileDialog::setFontSize(int pointSize)
01107 {
01108     QFont newFont = _ui->fontPreviewLabel->font();
01109     newFont.setPointSize(pointSize);
01110     _ui->fontPreviewLabel->setFont(newFont);
01111 
01112     _tempProfile->setProperty(Profile::Font,newFont);
01113 
01114     preview(Profile::Font,newFont);
01115 }
01116 ColorSchemeViewDelegate::ColorSchemeViewDelegate(QObject* parent)
01117  : QAbstractItemDelegate(parent)
01118 {
01119 
01120 }
01121 
01122 void ColorSchemeViewDelegate::setEntryTimeLine(QTimeLine* timeLine)
01123 {
01124     _entryTimeLine = timeLine;
01125 }
01126 
01127 void ColorSchemeViewDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
01128                        const QModelIndex& index) const
01129 {
01130     // entry animation
01131     //
01132     // note that the translation occurs for each item drawn, but the 
01133     // painter is not reset between painting items.  this means that when
01134     // the items are painted in order ( as occurs when the list is first
01135     // shown ), there is a visually pleasing staggering of items as they
01136     // enter.
01137     if ( _entryTimeLine != 0 )
01138     {
01139         qreal value = 1.0-_entryTimeLine->currentValue();
01140         painter->translate(  value * 
01141                              option.rect.width() , 0 );
01142 
01143         painter->setOpacity( _entryTimeLine->currentValue() );
01144     }
01145 
01146     const ColorScheme* scheme = index.data(Qt::UserRole + 1).value<const ColorScheme*>();
01147 
01148     Q_ASSERT(scheme);
01149 
01150     bool transparencyAvailable = KWindowSystem::compositingActive();
01151 
01152     painter->setRenderHint( QPainter::Antialiasing );
01153 
01154     // draw background
01155     painter->setPen( QPen(scheme->foregroundColor() , 1) );
01156 
01157     // radial gradient for background
01158     // from a lightened version of the scheme's background color in the center to
01159     // a darker version at the outer edge
01160     QColor color = scheme->backgroundColor();
01161     QRectF backgroundRect = QRectF(option.rect).adjusted(1.5,1.5,-1.5,-1.5);
01162   
01163     QRadialGradient backgroundGradient(backgroundRect.center() , backgroundRect.width() / 2);
01164     backgroundGradient.setColorAt( 0 , color.lighter(105) );
01165     backgroundGradient.setColorAt( 1 , color.darker(115) );
01166    
01167     const int backgroundRectXRoundness = 4;
01168     const int backgroundRectYRoundness = 30;
01169 
01170     QPainterPath backgroundRectPath(backgroundRect.topLeft());
01171     backgroundRectPath.addRoundRect( backgroundRect , backgroundRectXRoundness , backgroundRectYRoundness );
01172 
01173     if ( transparencyAvailable )
01174     {
01175         painter->save();
01176         color.setAlphaF(scheme->opacity());
01177         painter->setCompositionMode( QPainter::CompositionMode_Source );
01178         painter->setBrush(backgroundGradient);
01179 
01180         painter->drawPath(backgroundRectPath);
01181         painter->restore();
01182     }
01183     else
01184     {
01185         painter->setBrush(backgroundGradient);
01186         painter->drawPath(backgroundRectPath);
01187     }
01188 
01189     // draw stripe at the side using scheme's foreground color
01190     painter->setPen( QPen(Qt::NoPen) );
01191     QPainterPath path( option.rect.topLeft() );
01192     path.lineTo( option.rect.width() / 10.0 , option.rect.top() );
01193     path.lineTo( option.rect.bottomLeft() );
01194     path.lineTo( option.rect.topLeft() );
01195     painter->setBrush( scheme->foregroundColor() );
01196     painter->drawPath(path.intersected(backgroundRectPath));
01197 
01198     // draw highlight 
01199     // with a linear gradient going from translucent white to transparent
01200     QLinearGradient gradient( option.rect.topLeft() , option.rect.bottomLeft() );
01201     gradient.setColorAt( 0 , QColor(255,255,255,90) );
01202     gradient.setColorAt( 1 , Qt::transparent );
01203     painter->setBrush(gradient);
01204     painter->drawRoundRect( backgroundRect , 4 , 30 );
01205 
01206     //const bool isChecked = index.data(Qt::CheckStateRole) == Qt::Checked;
01207     const bool isSelected = option.state & QStyle::State_Selected;
01208 
01209     // draw border on selected items
01210     if ( isSelected ) //|| isChecked )
01211     {
01212         static const int selectedBorderWidth = 6;
01213 
01214 
01215         painter->setBrush( QBrush(Qt::NoBrush) );
01216         QPen pen;
01217         
01218         QColor highlightColor = option.palette.highlight().color();
01219 
01220         if ( isSelected )
01221             highlightColor.setAlphaF(1.0);
01222         else
01223             highlightColor.setAlphaF(0.7);
01224 
01225         pen.setBrush(highlightColor);
01226         pen.setWidth(selectedBorderWidth);
01227         pen.setJoinStyle(Qt::MiterJoin);
01228         
01229         painter->setPen(pen);
01230 
01231 
01232         painter->drawRect( option.rect.adjusted(selectedBorderWidth/2,
01233                                                 selectedBorderWidth/2,
01234                                                 -selectedBorderWidth/2,
01235                                                 -selectedBorderWidth/2) );
01236     }
01237 
01238     // draw color scheme name using scheme's foreground color
01239     QPen pen(scheme->foregroundColor());
01240     painter->setPen(pen);
01241 
01242     painter->drawText( option.rect , Qt::AlignCenter , 
01243                         index.data(Qt::DisplayRole).value<QString>() );
01244 
01245 }
01246 
01247 QSize ColorSchemeViewDelegate::sizeHint( const QStyleOptionViewItem& option,
01248                        const QModelIndex& /*index*/) const
01249 {
01250     const int width = 200;
01251     qreal colorWidth = (qreal)width / TABLE_COLORS;
01252     int margin = 5;
01253     qreal heightForWidth = ( colorWidth * 2 ) + option.fontMetrics.height() + margin;
01254 
01255     // temporary
01256     return QSize(width,(int)heightForWidth);
01257 }
01258 
01259 #include "EditProfileDialog.moc"

Konsole

Skip menu "Konsole"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • Konsole
  • Libraries
  •   libkonq
Generated for API Reference by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal