forked from qt-creator/qt-creator
		
	
		
			
				
	
	
		
			387 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			387 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/***************************************************************************
 | 
						|
**
 | 
						|
** 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 "proeditor.h"
 | 
						|
#include "proitems.h"
 | 
						|
#include "proeditormodel.h"
 | 
						|
#include "procommandmanager.h"
 | 
						|
#include "proxml.h"
 | 
						|
 | 
						|
#include <QtGui/QMenu>
 | 
						|
#include <QtGui/QKeyEvent>
 | 
						|
#include <QtGui/QClipboard>
 | 
						|
 | 
						|
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<QKeyEvent*>(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<ProVariableInfo *> 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<ProScopeInfo *> vars = m_infomanager->scopes();
 | 
						|
        if (!vars.isEmpty())
 | 
						|
            defid = vars.first()->id();
 | 
						|
 | 
						|
        scope->setItems(QList<ProItem *>() << 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<ProItem *>() << new ProFunction("..."));
 | 
						|
        m_model->insertItem(block, row, parent);
 | 
						|
        m_editListView->setCurrentIndex(m_model->index(row,0,parent));
 | 
						|
    }
 | 
						|
}
 |