add more spacing
[personal-kdebase.git] / apps / konsole / src / ManageProfilesDialog.cpp
blobd341196845136e3e6e9d04e7545e84e8a7888065
1 /*
2 Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301 USA.
20 // Own
21 #include "ManageProfilesDialog.h"
23 // Qt
24 #include <QtGui/QCheckBox>
25 #include <QtGui/QHeaderView>
26 #include <QtGui/QItemDelegate>
27 #include <QtGui/QItemEditorCreator>
28 #include <QtCore/QMetaEnum>
29 #include <QtGui/QScrollBar>
30 #include <QtGui/QShowEvent>
31 #include <QtGui/QStandardItem>
33 // KDE
34 #include <KKeySequenceWidget>
35 #include <KDebug>
37 // Konsole
38 #include "EditProfileDialog.h"
39 #include "SessionManager.h"
40 #include "ui_ManageProfilesDialog.h"
42 using namespace Konsole;
44 ManageProfilesDialog::ManageProfilesDialog(QWidget* parent)
45 : KDialog(parent)
46 , _sessionModel(new QStandardItemModel(this))
48 setCaption(i18n("Manage Profiles"));
49 setButtons( KDialog::Close );
51 _ui = new Ui::ManageProfilesDialog();
52 _ui->setupUi(mainWidget());
54 // hide vertical header
55 _ui->sessionTable->verticalHeader()->hide();
56 _ui->sessionTable->setItemDelegateForColumn(FavoriteStatusColumn,new FavoriteItemDelegate(this));
57 _ui->sessionTable->setItemDelegateForColumn(ShortcutColumn,new ShortcutItemDelegate(this));
58 _ui->sessionTable->setEditTriggers(_ui->sessionTable->editTriggers() | QAbstractItemView::SelectedClicked);
60 // update table and listen for changes to the session types
61 connect( SessionManager::instance() , SIGNAL(profileAdded(Profile::Ptr)) , this,
62 SLOT(addItems(Profile::Ptr)) );
63 connect( SessionManager::instance() , SIGNAL(profileRemoved(Profile::Ptr)) , this,
64 SLOT(removeItems(Profile::Ptr)) );
65 connect( SessionManager::instance() , SIGNAL(profileChanged(Profile::Ptr)) , this,
66 SLOT(updateItems(Profile::Ptr)) );
67 connect( SessionManager::instance() ,
68 SIGNAL(favoriteStatusChanged(Profile::Ptr,bool)) , this ,
69 SLOT(updateFavoriteStatus(Profile::Ptr,bool)) );
70 populateTable();
72 // resize the session table to the full width of the table
73 _ui->sessionTable->horizontalHeader()->setHighlightSections(false);
74 _ui->sessionTable->resizeColumnsToContents();
76 // allow a larger width for the shortcut column to account for the
77 // increased with needed by the shortcut editor compared with just
78 // displaying the text of the shortcut
79 _ui->sessionTable->setColumnWidth(ShortcutColumn,
80 _ui->sessionTable->columnWidth(ShortcutColumn)+100);
82 // setup buttons
83 connect( _ui->newSessionButton , SIGNAL(clicked()) , this , SLOT(newType()) );
84 connect( _ui->editSessionButton , SIGNAL(clicked()) , this , SLOT(editSelected()) );
85 connect( _ui->deleteSessionButton , SIGNAL(clicked()) , this , SLOT(deleteSelected()) );
86 connect( _ui->setAsDefaultButton , SIGNAL(clicked()) , this , SLOT(setSelectedAsDefault()) );
89 void ManageProfilesDialog::showEvent(QShowEvent*)
91 Q_ASSERT( _ui->sessionTable->model() );
93 // try to ensure that all the text in all the columns is visible initially.
94 // FIXME: this is not a good solution, look for a more correct way to do this
96 int totalWidth = 0;
97 int columnCount = _ui->sessionTable->model()->columnCount();
99 for ( int i = 0 ; i < columnCount ; i++ )
100 totalWidth += _ui->sessionTable->columnWidth(i);
102 // the margin is added to account for the space taken by the resize grips
103 // between the columns, this ensures that a horizontal scroll bar is not added
104 // automatically
105 int margin = style()->pixelMetric( QStyle::PM_HeaderGripMargin ) * columnCount;
106 _ui->sessionTable->setMinimumWidth( totalWidth + margin );
107 _ui->sessionTable->horizontalHeader()->setStretchLastSection(true);
110 ManageProfilesDialog::~ManageProfilesDialog()
112 delete _ui;
114 void ManageProfilesDialog::itemDataChanged(QStandardItem* item)
116 if ( item->column() == ShortcutColumn )
118 QKeySequence sequence = QKeySequence::fromString(item->text());
119 SessionManager::instance()->setShortcut(item->data(ShortcutRole).value<Profile::Ptr>(),
120 sequence);
123 int ManageProfilesDialog::rowForProfile(const Profile::Ptr info) const
125 for (int i=0;i<_sessionModel->rowCount();i++)
127 if (_sessionModel->item(i,ProfileNameColumn)->data(ProfileKeyRole)
128 .value<Profile::Ptr>() == info)
130 return i;
133 return -1;
135 void ManageProfilesDialog::removeItems(const Profile::Ptr info)
137 int row = rowForProfile(info);
138 if (row < 0)
139 return;
140 _sessionModel->removeRow(row);
142 void ManageProfilesDialog::updateItems(const Profile::Ptr info)
144 int row = rowForProfile(info);
145 if (row < 0)
146 return;
148 QList<QStandardItem*> items;
149 items << _sessionModel->item(row,ProfileNameColumn);
150 items << _sessionModel->item(row,FavoriteStatusColumn);
151 items << _sessionModel->item(row,ShortcutColumn);
152 updateItemsForProfile(info,items);
154 void ManageProfilesDialog::updateItemsForProfile(const Profile::Ptr info, QList<QStandardItem*>& items) const
156 // Profile Name
157 items[ProfileNameColumn]->setText(info->name());
158 if ( !info->icon().isEmpty() )
159 items[ProfileNameColumn]->setIcon( KIcon(info->icon()) );
161 items[ProfileNameColumn]->setData(QVariant::fromValue(info),ProfileKeyRole);
163 // Favorite Status
164 const bool isFavorite = SessionManager::instance()->findFavorites().contains(info);
165 if ( isFavorite )
166 items[FavoriteStatusColumn]->setData(KIcon("favorites"),Qt::DecorationRole);
167 else
168 items[FavoriteStatusColumn]->setData(KIcon(),Qt::DecorationRole);
169 items[FavoriteStatusColumn]->setData(QVariant::fromValue(info),ProfileKeyRole);
171 // Shortcut
172 QString shortcut = SessionManager::instance()->shortcut(info).
173 toString();
174 items[ShortcutColumn]->setText(shortcut);
175 items[ShortcutColumn]->setData(QVariant::fromValue(info),ShortcutRole);
177 void ManageProfilesDialog::addItems(const Profile::Ptr profile)
179 if (profile->isHidden())
180 return;
182 QList<QStandardItem*> items;
183 for (int i=0;i<3;i++)
184 items << new QStandardItem;
185 updateItemsForProfile(profile,items);
186 _sessionModel->appendRow(items);
188 void ManageProfilesDialog::populateTable()
190 Q_ASSERT(!_ui->sessionTable->model());
192 _ui->sessionTable->setModel(_sessionModel);
193 // ensure profiles list is complete
194 // this may be expensive, but will only be done the first time
195 // that the dialog is shown.
196 SessionManager::instance()->loadAllProfiles();
198 // setup session table
199 _sessionModel->setHorizontalHeaderLabels( QStringList() << i18n("Name")
200 << i18n("Show in Menu")
201 << i18n("Shortcut") );
202 foreach(const Profile::Ptr info,SessionManager::instance()->loadedProfiles())
204 addItems(info);
206 updateDefaultItem();
208 connect( _sessionModel , SIGNAL(itemChanged(QStandardItem*)) , this ,
209 SLOT(itemDataChanged(QStandardItem*)) );
211 // listen for changes in the table selection and update the state of the form's buttons
212 // accordingly.
214 // it appears that the selection model is changed when the model itself is replaced,
215 // so the signals need to be reconnected each time the model is updated.
216 connect( _ui->sessionTable->selectionModel() ,
217 SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&)) , this ,
218 SLOT(tableSelectionChanged(const QItemSelection&)) );
220 tableSelectionChanged( _ui->sessionTable->selectionModel()->selection() );
222 void ManageProfilesDialog::updateDefaultItem()
224 Profile::Ptr defaultProfile = SessionManager::instance()->defaultProfile();
226 for ( int i = 0 ; i < _sessionModel->rowCount() ; i++ )
228 QStandardItem* item = _sessionModel->item(i);
229 QFont font = item->font();
231 bool isDefault = ( defaultProfile == item->data().value<Profile::Ptr>() );
233 if ( isDefault && !font.bold() )
235 font.setBold(true);
236 item->setFont(font);
238 else if ( !isDefault && font.bold() )
240 font.setBold(false);
241 item->setFont(font);
245 void ManageProfilesDialog::tableSelectionChanged(const QItemSelection&)
247 const int selectedRows = _ui->sessionTable->selectionModel()->selectedRows().count();
248 const SessionManager* manager = SessionManager::instance();
249 const bool isNotDefault = (selectedRows > 0) && currentProfile() != manager->defaultProfile();
251 _ui->newSessionButton->setEnabled(selectedRows < 2);
252 _ui->editSessionButton->setEnabled(selectedRows > 0);
253 // do not allow the default session type to be removed
254 _ui->deleteSessionButton->setEnabled(isNotDefault);
255 _ui->setAsDefaultButton->setEnabled(isNotDefault && (selectedRows < 2));
257 void ManageProfilesDialog::deleteSelected()
259 foreach(Profile::Ptr profile, selectedProfiles())
261 if (profile != SessionManager::instance()->defaultProfile())
262 SessionManager::instance()->deleteProfile(profile);
265 void ManageProfilesDialog::setSelectedAsDefault()
267 SessionManager::instance()->setDefaultProfile(currentProfile());
268 // do not allow the new default session type to be removed
269 _ui->deleteSessionButton->setEnabled(false);
270 _ui->setAsDefaultButton->setEnabled(false);
272 // update font of new default item
273 updateDefaultItem();
275 void ManageProfilesDialog::newType()
277 EditProfileDialog dialog(this);
279 // setup a temporary profile which is a clone of the selected profile
280 // or the default if no profile is selected
281 Profile::Ptr sourceProfile;
283 Profile::Ptr selectedProfile = currentProfile();
284 if ( !selectedProfile )
285 sourceProfile = SessionManager::instance()->defaultProfile();
286 else
287 sourceProfile = selectedProfile;
289 Q_ASSERT( sourceProfile );
291 Profile::Ptr newProfile = Profile::Ptr(new Profile(SessionManager::instance()->fallbackProfile()));
292 newProfile->clone(sourceProfile,true);
293 newProfile->setProperty(Profile::Name,i18n("New Profile"));
295 dialog.setProfile(newProfile);
296 dialog.selectProfileName();
298 if ( dialog.exec() == QDialog::Accepted )
300 SessionManager::instance()->addProfile(newProfile);
301 SessionManager::instance()->setFavorite(newProfile,true);
304 void ManageProfilesDialog::editSelected()
306 EditProfileDialog dialog(this);
307 // the dialog will delete the profile group when it is destroyed
308 ProfileGroup* group = new ProfileGroup;
309 foreach(Profile::Ptr profile,selectedProfiles())
310 group->addProfile(profile);
311 group->updateValues();
313 dialog.setProfile(Profile::Ptr(group));
314 dialog.exec();
316 QList<Profile::Ptr> ManageProfilesDialog::selectedProfiles() const
318 QList<Profile::Ptr> list;
319 QItemSelectionModel* selection = _ui->sessionTable->selectionModel();
320 if (!selection)
321 return list;
323 foreach(const QModelIndex& index, selection->selectedIndexes())
325 if (index.column() == ProfileNameColumn)
326 list << index.data(ProfileKeyRole).value<Profile::Ptr>();
329 return list;
331 Profile::Ptr ManageProfilesDialog::currentProfile() const
333 QItemSelectionModel* selection = _ui->sessionTable->selectionModel();
335 if ( !selection || selection->selectedRows().count() != 1 )
336 return Profile::Ptr();
338 return selection->
339 selectedIndexes().first().data(ProfileKeyRole).value<Profile::Ptr>();
341 void ManageProfilesDialog::updateFavoriteStatus(Profile::Ptr profile, bool favorite)
343 Q_ASSERT( _sessionModel );
345 int rowCount = _sessionModel->rowCount();
346 for (int i=0;i < rowCount;i++)
348 QModelIndex index = _sessionModel->index(i,FavoriteStatusColumn);
349 if (index.data(ProfileKeyRole).value<Profile::Ptr>() ==
350 profile )
352 const KIcon icon = favorite ? KIcon("favorites") : KIcon();
353 _sessionModel->setData(index,icon,Qt::DecorationRole);
357 void ManageProfilesDialog::setShortcutEditorVisible(bool visible)
359 _ui->sessionTable->setColumnHidden(ShortcutColumn,!visible);
361 void StyledBackgroundPainter::drawBackground(QPainter* painter, const QStyleOptionViewItem& option,
362 const QModelIndex&)
364 const QStyleOptionViewItemV3* v3option = qstyleoption_cast<const QStyleOptionViewItemV3*>(&option);
365 const QWidget* widget = v3option ? v3option->widget : 0;
367 QStyle* style = widget ? widget->style() : QApplication::style();
369 style->drawPrimitive(QStyle::PE_PanelItemViewItem,&option,painter,widget);
372 FavoriteItemDelegate::FavoriteItemDelegate(QObject* parent)
373 : QStyledItemDelegate(parent)
376 void FavoriteItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
378 // See implementation of QStyledItemDelegate::paint()
379 QStyleOptionViewItemV4 opt = option;
380 initStyleOption(&opt,index);
382 StyledBackgroundPainter::drawBackground(painter,opt,index);
384 int margin = (opt.rect.height()-opt.decorationSize.height())/2;
385 margin++;
387 opt.rect.setTop(opt.rect.top()+margin);
388 opt.rect.setBottom(opt.rect.bottom()-margin);
390 QIcon icon = index.data(Qt::DecorationRole).value<QIcon>();
391 icon.paint(painter,opt.rect,Qt::AlignCenter);
394 bool FavoriteItemDelegate::editorEvent(QEvent* event,QAbstractItemModel*,
395 const QStyleOptionViewItem&,const QModelIndex& index)
397 if ( event->type() == QEvent::MouseButtonPress || event->type() == QEvent::KeyPress
398 || event->type() == QEvent::MouseButtonDblClick )
400 Profile::Ptr profile = index.data(ManageProfilesDialog::ProfileKeyRole).value<Profile::Ptr>();
401 const bool isFavorite = !SessionManager::instance()->findFavorites().contains(profile);
403 SessionManager::instance()->setFavorite(profile,
404 isFavorite);
407 return true;
409 ShortcutItemDelegate::ShortcutItemDelegate(QObject* parent)
410 : QStyledItemDelegate(parent)
413 void ShortcutItemDelegate::editorModified(const QKeySequence& keys)
415 kDebug() << keys.toString();
417 KKeySequenceWidget* editor = qobject_cast<KKeySequenceWidget*>(sender());
418 Q_ASSERT(editor);
419 _modifiedEditors.insert(editor);
421 void ShortcutItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,
422 const QModelIndex& index) const
424 _itemsBeingEdited.remove(index);
426 if (!_modifiedEditors.contains(editor))
427 return;
429 QString shortcut = qobject_cast<KKeySequenceWidget*>(editor)->keySequence().toString();
430 model->setData(index,shortcut,Qt::DisplayRole);
432 _modifiedEditors.remove(editor);
435 QWidget* ShortcutItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem&, const QModelIndex& index) const
437 _itemsBeingEdited.insert(index);
439 KKeySequenceWidget* editor = new KKeySequenceWidget(parent);
440 editor->setFocusPolicy(Qt::StrongFocus);
441 editor->setModifierlessAllowed(false);
442 QString shortcutString = index.data(Qt::DisplayRole).toString();
443 editor->setKeySequence(QKeySequence::fromString(shortcutString));
444 connect(editor,SIGNAL(keySequenceChanged(QKeySequence)),this,SLOT(editorModified(QKeySequence)));
445 editor->captureKeySequence();
446 return editor;
448 void ShortcutItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
449 const QModelIndex& index) const
451 if (_itemsBeingEdited.contains(index))
452 StyledBackgroundPainter::drawBackground(painter,option,index);
453 else
454 QStyledItemDelegate::paint(painter,option,index);
457 #include "ManageProfilesDialog.moc"