/*************************************************************************** ** ** This file is part of Qt Creator ** ** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Qt Software Information (qt-info@nokia.com) ** ** ** Non-Open Source Usage ** ** Licensees may use this file in accordance with the Qt Beta Version ** License Agreement, Agreement version 2.2 provided with the Software or, ** alternatively, in accordance with the terms contained in a written ** agreement between you and Nokia. ** ** GNU General Public License Usage ** ** Alternatively, this file may be used under the terms of the GNU General ** Public License versions 2.0 or 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the packaging ** of this file. Please review the following information to ensure GNU ** General Public Licensing requirements will be met: ** ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and ** http://www.gnu.org/copyleft/gpl.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt GPL Exception version ** 1.2, included in the file GPL_EXCEPTION.txt in this package. ** ***************************************************************************/ #include #include #include #include "proeditor.h" #include "proitems.h" #include "proeditormodel.h" #include "procommandmanager.h" #include "proxml.h" using namespace Qt4ProjectManager::Internal; ProEditor::ProEditor(QWidget *parent, bool shortcuts) : QWidget(parent) { m_shortcuts = shortcuts; m_advanced = false; setupUi(this); m_setFocusToListView = true; m_blockSelectionSignal = false; m_cutAction = new QAction(tr("Cut"), this); m_copyAction = new QAction(tr("Copy"), this); m_pasteAction = new QAction(tr("Paste"), this); } ProEditor::~ProEditor() { } void ProEditor::initialize(ProEditorModel *model, ProItemInfoManager *infomanager) { m_model = model; m_infomanager = infomanager; initialize(); } ProScopeFilter *ProEditor::filterModel() const { return m_filter; } void ProEditor::selectScope(const QModelIndex &scope) { m_setFocusToListView = false; QModelIndex parent = m_filter->mapToSource(scope); m_editListView->setRootIndex(parent); m_editListView->setCurrentIndex(m_model->index(0,0,parent)); m_setFocusToListView = true; } void ProEditor::initialize() { m_model->setInfoManager(m_infomanager); m_filter = new ProScopeFilter(this); m_filter->setSourceModel(m_model); m_contextMenu = new QMenu(this); if (m_shortcuts) { m_cutAction->setShortcut(QKeySequence(tr("Ctrl+X"))); m_copyAction->setShortcut(QKeySequence(tr("Ctrl+C"))); m_pasteAction->setShortcut(QKeySequence(tr("Ctrl+V"))); m_editListView->installEventFilter(this); } m_contextMenu->addAction(m_cutAction); m_contextMenu->addAction(m_copyAction); m_contextMenu->addAction(m_pasteAction); QMenu *addMenu = new QMenu(m_addToolButton); m_addVariable = addMenu->addAction(tr("Add Variable"), this, SLOT(addVariable())); m_addScope = addMenu->addAction(tr("Add Scope"), this, SLOT(addScope())); m_addBlock = addMenu->addAction(tr("Add Block"), this, SLOT(addBlock())); m_addToolButton->setMenu(addMenu); m_addToolButton->setPopupMode(QToolButton::InstantPopup); m_editListView->setModel(m_model); m_editListView->setContextMenuPolicy(Qt::CustomContextMenu); connect(m_editListView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(showContextMenu(const QPoint &))); connect(m_editListView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(updateState())); connect(m_moveUpToolButton, SIGNAL(clicked()), this, SLOT(moveUp())); connect(m_moveDownToolButton, SIGNAL(clicked()), this, SLOT(moveDown())); connect(m_removeToolButton, SIGNAL(clicked()), this, SLOT(remove())); connect(m_cutAction, SIGNAL(triggered()), this, SLOT(cut())); connect(m_copyAction, SIGNAL(triggered()), this, SLOT(copy())); connect(m_pasteAction, SIGNAL(triggered()), this, SLOT(paste())); updatePasteAction(); } bool ProEditor::eventFilter(QObject *, QEvent *event) { if (event->type() == QEvent::ShortcutOverride) { QKeyEvent *k = static_cast(event); if (k->modifiers() == Qt::ControlModifier) { switch(k->key()) { case Qt::Key_X: cut(); return true; case Qt::Key_C: copy(); return true; case Qt::Key_V: paste(); return true; } } } else if (event->type() == QEvent::FocusIn) { updateActions(true); } else if (event->type() == QEvent::FocusOut) { updateActions(false); } return false; } void ProEditor::showContextMenu(const QPoint &pos) { updatePasteAction(); m_contextMenu->popup(m_editListView->viewport()->mapToGlobal(pos)); } void ProEditor::updatePasteAction() { bool pasteEnabled = false; const QMimeData *data = QApplication::clipboard()->mimeData(); if (data) { if (data->hasFormat(QLatin1String("application/x-problock"))) { pasteEnabled = true; } } m_pasteAction->setEnabled(pasteEnabled); } void ProEditor::updateActions(bool focus) { bool copyEnabled = false; if (focus) copyEnabled = m_editListView->currentIndex().isValid(); m_cutAction->setEnabled(copyEnabled); m_copyAction->setEnabled(copyEnabled); } void ProEditor::updateState() { bool addEnabled = false; bool removeEnabled = false; bool upEnabled = false; bool downEnabled = false; QModelIndex parent = m_editListView->rootIndex(); ProBlock *scope = m_model->proBlock(parent); if (scope) { addEnabled = true; QModelIndex index = m_editListView->currentIndex(); if (index.isValid()) { removeEnabled = true; int count = m_model->rowCount(parent); int row = index.row(); if (row > 0) upEnabled = true; if (row < (count - 1)) downEnabled = true; } } if (!m_blockSelectionSignal) { emit itemSelected(m_editListView->currentIndex()); if (m_setFocusToListView) m_editListView->setFocus(Qt::OtherFocusReason); } updateActions(m_editListView->hasFocus()); m_addToolButton->setEnabled(addEnabled); m_removeToolButton->setEnabled(removeEnabled); m_moveUpToolButton->setEnabled(upEnabled); m_moveDownToolButton->setEnabled(downEnabled); } void ProEditor::moveUp() { m_editListView->setFocus(Qt::OtherFocusReason); QModelIndex index = m_editListView->currentIndex(); QModelIndex parent = index.parent(); int row = index.row() - 1; m_blockSelectionSignal = true; m_model->moveItem(index, row); m_blockSelectionSignal = false; index = m_model->index(row, 0, parent); m_editListView->setCurrentIndex(index); } void ProEditor::moveDown() { m_editListView->setFocus(Qt::OtherFocusReason); QModelIndex index = m_editListView->currentIndex(); QModelIndex parent = index.parent(); int row = index.row() + 1; m_blockSelectionSignal = true; m_model->moveItem(index, row); m_blockSelectionSignal = false; index = m_model->index(row, 0, parent); m_editListView->setCurrentIndex(index); } void ProEditor::remove() { m_editListView->setFocus(Qt::OtherFocusReason); m_model->removeItem(m_editListView->currentIndex()); updateState(); } void ProEditor::cut() { QModelIndex index = m_editListView->currentIndex(); if (!index.isValid()) return; if (ProItem *item = m_model->proItem(index)) { m_editListView->setFocus(Qt::OtherFocusReason); m_model->removeItem(index); QMimeData *data = new QMimeData(); QString xml = ProXmlParser::itemToString(item); if (item->kind() == ProItem::ValueKind) data->setData(QLatin1String("application/x-provalue"), xml.toUtf8()); else data->setData(QLatin1String("application/x-problock"), xml.toUtf8()); QApplication::clipboard()->setMimeData(data); } } void ProEditor::copy() { QModelIndex index = m_editListView->currentIndex(); if (!index.isValid()) return; if (ProItem *item = m_model->proItem(index)) { m_editListView->setFocus(Qt::OtherFocusReason); QMimeData *data = new QMimeData(); QString xml = ProXmlParser::itemToString(item); if (item->kind() == ProItem::ValueKind) data->setData(QLatin1String("application/x-provalue"), xml.toUtf8()); else data->setData(QLatin1String("application/x-problock"), xml.toUtf8()); QApplication::clipboard()->setMimeData(data); } } void ProEditor::paste() { if (const QMimeData *data = QApplication::clipboard()->mimeData()) { m_editListView->setFocus(Qt::OtherFocusReason); QModelIndex parent = m_editListView->rootIndex(); ProBlock *block = m_model->proBlock(parent); if (!block) return; QString xml; if (data->hasFormat(QLatin1String("application/x-provalue"))) { xml = QString::fromUtf8(data->data(QLatin1String("application/x-provalue"))); } else if (data->hasFormat(QLatin1String("application/x-problock"))) { xml = QString::fromUtf8(data->data(QLatin1String("application/x-problock"))); } if (ProItem *item = ProXmlParser::stringToItem(xml)) { QModelIndex parent = m_editListView->rootIndex(); int row = m_model->rowCount(parent); m_model->insertItem(item, row, parent); m_editListView->setCurrentIndex(m_model->index(row,0,parent)); } } } void ProEditor::addVariable() { QModelIndex parent = m_editListView->rootIndex(); if (ProBlock *pblock = m_model->proBlock(parent)) { m_editListView->setFocus(Qt::OtherFocusReason); int row = m_model->rowCount(parent); QString defid("..."); ProVariable::VariableOperator op = ProVariable::SetOperator; QList vars = m_infomanager->variables(); if (!vars.isEmpty()) { defid = vars.first()->id(); op = vars.first()->defaultOperator(); } ProVariable *var = new ProVariable(defid, pblock); var->setVariableOperator(op); m_model->insertItem(var, row, parent); m_editListView->setCurrentIndex(m_model->index(row,0,parent)); } } void ProEditor::addScope() { QModelIndex parent = m_editListView->rootIndex(); if (ProBlock *pblock = m_model->proBlock(parent)) { m_editListView->setFocus(Qt::OtherFocusReason); int row = m_model->rowCount(parent); ProBlock *scope = new ProBlock(pblock); scope->setBlockKind(ProBlock::ScopeKind); ProBlock *scopecontents = new ProBlock(scope); scopecontents->setBlockKind(ProBlock::ScopeContentsKind); QString defid("..."); QList vars = m_infomanager->scopes(); if (!vars.isEmpty()) defid = vars.first()->id(); scope->setItems(QList() << new ProCondition(defid) << scopecontents); m_model->insertItem(scope, row, parent); m_editListView->setCurrentIndex(m_model->index(row,0,parent)); } } void ProEditor::addBlock() { QModelIndex parent = m_editListView->rootIndex(); if (ProBlock *pblock = m_model->proBlock(parent)) { m_editListView->setFocus(Qt::OtherFocusReason); int row = m_model->rowCount(parent); ProBlock *block = new ProBlock(pblock); block->setBlockKind(ProBlock::NormalKind); block->setItems(QList() << new ProFunction("...")); m_model->insertItem(block, row, parent); m_editListView->setCurrentIndex(m_model->index(row,0,parent)); } }