/* This file is part of KDevelop Copyright 2008 Andreas Pakulat Copyright 2010 David Nolden This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "sessionchooserdialog.h" #include "sessioncontroller.h" #include "core.h" #include #include #include #include #include #include using namespace KDevelop; SessionChooserDialog::SessionChooserDialog(QListView* view, QAbstractItemModel* model, KLineEdit* filter) : m_view(view), m_model(model), m_filter(filter), m_deleteCandidateRow(-1) { m_updateStateTimer.setInterval(5000); m_updateStateTimer.setSingleShot(false); m_updateStateTimer.start(); connect(&m_updateStateTimer, SIGNAL(timeout()), SLOT(updateState())); connect(view, SIGNAL(doubleClicked(QModelIndex)), SLOT(doubleClicked(QModelIndex))); connect(view, SIGNAL(entered(QModelIndex)), SLOT(itemEntered(QModelIndex))); m_deleteButton = new KPushButton(view->viewport()); m_deleteButton->setIcon(KIcon("edit-delete")); m_deleteButton->setToolTip(i18nc("@info", "Delete session")); m_deleteButton->hide(); connect(m_deleteButton, SIGNAL(clicked(bool)), SLOT(deleteButtonPressed())); m_deleteButtonTimer.setInterval(500); m_deleteButtonTimer.setSingleShot(true); connect(&m_deleteButtonTimer, SIGNAL(timeout()), SLOT(showDeleteButton())); view->setMouseTracking(true); view->installEventFilter(this); filter->installEventFilter(this); connect(filter, SIGNAL(textChanged(QString)), SLOT(filterTextChanged())); setCaption(i18n("Pick a Session")); setButtons(KDialog::Ok | KDialog::Close); button(Ok)->setText(i18n("Run")); button(Ok)->setIcon(KIcon("media-playback-start")); } void SessionChooserDialog::filterTextChanged() { m_view->selectionModel()->setCurrentIndex(m_model->index(0, 0), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); bool enabled = m_view->model()->rowCount(QModelIndex())>0; button(KDialog::Ok)->setEnabled(enabled); m_deleteButton->setVisible(false); } void SessionChooserDialog::doubleClicked(const QModelIndex& index) { if(m_model->flags(index) & Qt::ItemIsEnabled) accept(); } void SessionChooserDialog::updateState() { // Sometimes locking may take some time, so we stop the timer, to prevent an 'avalanche' of events m_updateStateTimer.stop(); for(int row = 0; row < m_model->rowCount(); ++row) { QString session = m_model->index(row, 0).data().toString(); if(session.isEmpty()) //create new session continue; QString state, tooltip; SessionRunInfo info = SessionController::sessionRunInfo(session); if(info.isRunning) { tooltip = i18n("Active session.\npid %1, app %2, host %3", info.holderPid, info.holderApp, info.holderHostname); state = i18n("Running"); } m_model->setData(m_model->index(row, 1), !info.isRunning ? KIcon("") : KIcon("media-playback-start"), Qt::DecorationRole); m_model->setData(m_model->index(row, 1), tooltip, Qt::ToolTipRole); m_model->setData(m_model->index(row, 2), state, Qt::DisplayRole); } m_updateStateTimer.start(); } void SessionChooserDialog::itemEntered(const QModelIndex& index) { // The last row says "Create new session", we don't want to delete that if(index.row() == m_model->rowCount()-1) { m_deleteButton->hide(); m_deleteButtonTimer.stop(); return; } // align the delete-button to stay on the right border of the item // we need the right most column's index QModelIndex in = m_model->index( index.row(), 1 ); const QRect rect = m_view->visualRect(in); m_deleteButton->resize(rect.height(), rect.height()); QPoint p(rect.right() - m_deleteButton->size().width(), rect.top()+rect.height()/2-m_deleteButton->height()/2); m_deleteButton->move(p); m_deleteCandidateRow = index.row(); m_deleteButtonTimer.start(); } void SessionChooserDialog::showDeleteButton() { m_deleteButton->show(); } bool SessionChooserDialog::eventFilter(QObject* object, QEvent* event) { if(object == m_view && event->type() == QEvent::Leave ) { m_deleteButtonTimer.stop(); m_deleteButton->hide(); } if(object == m_filter && event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast(event); if(keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down) { QModelIndex currentIndex = m_view->selectionModel()->currentIndex(); int selectRow = -1; if(keyEvent->key() == Qt::Key_Up) { if(!currentIndex.isValid()) { selectRow = m_model->rowCount()-1; } else if(currentIndex.row()-1 >= 0) { selectRow = currentIndex.row()-1; } } else if(keyEvent->key() == Qt::Key_Down) { if(!currentIndex.isValid()) { selectRow = 0; } else if(currentIndex.row()+1 < m_model->rowCount()) { selectRow = currentIndex.row()+1; } } if (selectRow != -1) { m_view->selectionModel()->setCurrentIndex(m_model->index(selectRow, 0), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); } return true; } } return false; } void SessionChooserDialog::deleteButtonPressed() { if(m_deleteCandidateRow == -1) return; QModelIndex index = m_model->index(m_deleteCandidateRow, 0); const QString uuid = m_model->data(index, Qt::DisplayRole).toString(); TryLockSessionResult result = SessionController::tryLockSession( uuid ); if( !result.lock ) { const QString errCaption = i18nc("@title", "Cannot Delete Session"); QString errText = i18nc("@info", "

Cannot delete a locked session."); if( result.runInfo.holderPid != -1 ) { errText += i18nc("@info", "

The session is locked by %1 on %2 (PID %3).", result.runInfo.holderApp, result.runInfo.holderHostname, result.runInfo.holderPid); } KMessageBox::error( this, errText, errCaption ); return; } const QString text = i18nc("@info", "The session and all contained settings will be deleted. The projects will stay unaffected. Do you really want to continue?"); const QString caption = i18nc("@title", "Delete Session"); const KGuiItem deleteItem = KStandardGuiItem::del(); const KGuiItem cancelItem = KStandardGuiItem::cancel(); if(KMessageBox::warningYesNo(this, text, caption, deleteItem, cancelItem) == KMessageBox::Yes) { QModelIndex index = m_model->index(m_deleteCandidateRow, 0); const QString uuid = m_model->data(index, Qt::DisplayRole).toString(); SessionController::deleteSessionFromDisk(result.lock); m_model->removeRows( m_deleteCandidateRow, 1 ); m_deleteCandidateRow = -1; } } #include "moc_sessionchooserdialog.cpp"