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
21 #include "ManageProfilesDialog.h"
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>
34 #include <KKeySequenceWidget>
38 #include "EditProfileDialog.h"
39 #include "SessionManager.h"
40 #include "ui_ManageProfilesDialog.h"
42 using namespace Konsole
;
44 ManageProfilesDialog::ManageProfilesDialog(QWidget
* 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)) );
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);
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
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
105 int margin
= style()->pixelMetric( QStyle::PM_HeaderGripMargin
) * columnCount
;
106 _ui
->sessionTable
->setMinimumWidth( totalWidth
+ margin
);
107 _ui
->sessionTable
->horizontalHeader()->setStretchLastSection(true);
110 ManageProfilesDialog::~ManageProfilesDialog()
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
>(),
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
)
135 void ManageProfilesDialog::removeItems(const Profile::Ptr info
)
137 int row
= rowForProfile(info
);
140 _sessionModel
->removeRow(row
);
142 void ManageProfilesDialog::updateItems(const Profile::Ptr info
)
144 int row
= rowForProfile(info
);
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
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
);
164 const bool isFavorite
= SessionManager::instance()->findFavorites().contains(info
);
166 items
[FavoriteStatusColumn
]->setData(KIcon("favorites"),Qt::DecorationRole
);
168 items
[FavoriteStatusColumn
]->setData(KIcon(),Qt::DecorationRole
);
169 items
[FavoriteStatusColumn
]->setData(QVariant::fromValue(info
),ProfileKeyRole
);
172 QString shortcut
= SessionManager::instance()->shortcut(info
).
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())
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())
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
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() )
238 else if ( !isDefault
&& font
.bold() )
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
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();
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
));
316 QList
<Profile::Ptr
> ManageProfilesDialog::selectedProfiles() const
318 QList
<Profile::Ptr
> list
;
319 QItemSelectionModel
* selection
= _ui
->sessionTable
->selectionModel();
323 foreach(const QModelIndex
& index
, selection
->selectedIndexes())
325 if (index
.column() == ProfileNameColumn
)
326 list
<< index
.data(ProfileKeyRole
).value
<Profile::Ptr
>();
331 Profile::Ptr
ManageProfilesDialog::currentProfile() const
333 QItemSelectionModel
* selection
= _ui
->sessionTable
->selectionModel();
335 if ( !selection
|| selection
->selectedRows().count() != 1 )
336 return Profile::Ptr();
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
>() ==
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
,
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;
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
,
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());
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
))
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();
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
);
454 QStyledItemDelegate::paint(painter
,option
,index
);
457 #include "ManageProfilesDialog.moc"