Commit f7c469f3 authored by hjk's avatar hjk
Browse files

Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline

parents 897cd466 16a5aec1
......@@ -776,6 +776,40 @@
\image qtcreator-vcs-gitbranch.png
\endtable
\section2 Common options
The \gui{Version Control/Common} settings page features common settings for
version control systems, such as commit message line wrapping and checking options.
\gui{Submit message checking script} is a script or program that can be used to
perform checks on the submit message before submitting. It is passed the
submit message as first parameter. On error, it should output a message on standard error and
return an exit code different from 0.
\gui{User/alias configuration file} takes a file in a mailmap format that lists
user names and aliases:
\code
Jon Doe <Jon.Doe@company.com>
Hans Mustermann <Hans.Mustermann@company.com> hm <info@company.com>
\endcode
The second line specifies that the alias \e{hm} and the corresponding email address should
be used for \e{Hans Mustermann}. If the file is present, the submit editor will feature
a context menu option \gui{Insert name...} that will pop up a dialog letting the user
choose a name to be inserted.
\gui{User field configuration file} is a simple text file consisting of lines specifying submit message fields that take user names, for example:
\code
Reviewed-by:
Signed-off-by:
\endcode
The fields will appear below the submit message. They provide completion on the
aliases/public user names specified in the \e{User/alias configuration file} and an additional
button that opens the aforementioned user name dialog.
*/
......
......@@ -190,7 +190,10 @@ int ExpressionUnderCursor::previousBlockState(const QTextBlock &block)
return 0;
}
QString ExpressionUnderCursor::operator()(const QTextCursor &cursor)
void ExpressionUnderCursor::init(const QTextCursor &cursor,
QList<SimpleToken> *tokens,
QString *text,
int *startPosition)
{
enum { MAX_BLOCK_COUNT = 5 };
......@@ -203,8 +206,6 @@ QString ExpressionUnderCursor::operator()(const QTextCursor &cursor)
initialBlock = initialBlock.previous();
}
QString text;
QTextBlock it = initialBlock;
for (; it.isValid(); it = it.next()) {
QString textBlock = it.text();
......@@ -212,18 +213,29 @@ QString ExpressionUnderCursor::operator()(const QTextCursor &cursor)
if (it == block)
textBlock = textBlock.left(cursor.position() - cursor.block().position());
text += textBlock;
text->append(textBlock);
if (it == block)
break;
text += QLatin1Char('\n');
text->append(QLatin1Char('\n'));
}
SimpleLexer tokenize;
tokenize.setSkipComments(true);
QList<SimpleToken> tokens = tokenize(text, previousBlockState(initialBlock));
tokens.prepend(SimpleToken()); // sentinel
tokens->append(tokenize(*text, previousBlockState(initialBlock)));
tokens->prepend(SimpleToken()); // sentinel
if (startPosition)
*startPosition = initialBlock.position();
}
QString ExpressionUnderCursor::operator()(const QTextCursor &cursor)
{
QList<SimpleToken> tokens;
QString text;
init(cursor, &tokens, &text);
_jumpedComma = false;
......@@ -236,3 +248,28 @@ QString ExpressionUnderCursor::operator()(const QTextCursor &cursor)
- tokens.at(i).position());
}
int ExpressionUnderCursor::startOfFunctionCall(const QTextCursor &cursor)
{
QList<SimpleToken> tokens;
QString text;
int startPosition;
init(cursor, &tokens, &text, &startPosition);
int index = tokens.size();
forever {
const SimpleToken &tk = tokens.at(index - 1);
if (tk.is(T_EOF_SYMBOL))
break;
else if (tk.is(T_LPAREN))
return startPosition + tk.position();
else if (tk.is(T_RPAREN))
index = startOfMatchingBrace(tokens, index);
else
--index;
}
return -1;
}
......@@ -50,8 +50,14 @@ public:
~ExpressionUnderCursor();
QString operator()(const QTextCursor &cursor);
int startOfFunctionCall(const QTextCursor &cursor);
private:
void init(const QTextCursor &cursor,
QList<SimpleToken> *tokens,
QString *text,
int *startPosition = 0);
int startOfMatchingBrace(const QList<SimpleToken> &tk, int index);
int startOfExpression(const QList<SimpleToken> &tk, int index);
int previousBlockState(const QTextBlock &block);
......
......@@ -72,5 +72,6 @@
<file>images/unknownfile.png</file>
<file>images/unlocked.png</file>
<file>images/extension.png</file>
<file>images/darkclosebutton.png</file>
</qresource>
</RCC>
......@@ -744,6 +744,15 @@ IEditor *EditorManager::pickUnusedEditor() const
}
void EditorManager::closeEditor(const QModelIndex &index)
{
IEditor *editor = index.data(Qt::UserRole).value<Core::IEditor*>();
if (editor)
closeEditor(editor);
else
m_d->m_editorModel->removeEditor(index);
}
void EditorManager::activateEditor(const QModelIndex &index, Internal::EditorView *view)
{
IEditor *editor = index.data(Qt::UserRole).value<IEditor*>();
......
......@@ -127,6 +127,7 @@ public:
Internal::EditorModel *openedEditorsModel() const;
void activateEditor(const QModelIndex &index, Internal::EditorView *view = 0);
void closeEditor(const QModelIndex &index);
QList<IEditor*> editorsForFiles(QList<IFile*> files) const;
......@@ -151,8 +152,6 @@ public:
Internal::OpenEditorsWindow *windowPopup() const;
void showWindowPopup() const;
// Internal::EditorSplitter *editorSplitter() const;
void showEditorInfoBar(const QString &kind,
const QString &infoText,
const QString &buttonText = QString(),
......
......@@ -76,7 +76,7 @@ QByteArray EditorModel::Entry::kind() const
int EditorModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return 1;
return 2;
}
int EditorModel::rowCount(const QModelIndex &parent) const
......@@ -180,6 +180,19 @@ void EditorModel::removeEditor(IEditor *editor)
disconnect(editor, SIGNAL(changed()), this, SLOT(itemChanged()));
}
void EditorModel::removeEditor(const QModelIndex &index)
{
int idx = index.row();
if (idx < 0)
return;
IEditor *editor= m_editors.at(idx).editor;
beginRemoveRows(QModelIndex(), idx, idx);
m_editors.removeAt(idx);
endRemoveRows();
if (editor)
disconnect(editor, SIGNAL(changed()), this, SLOT(itemChanged()));
}
void EditorModel::removeAllRestoredEditors()
{
for (int i = m_editors.count()-1; i >= 0; --i) {
......@@ -227,7 +240,7 @@ void EditorModel::emitDataChanged(IEditor *editor)
QModelIndex EditorModel::index(int row, int column, const QModelIndex &parent) const
{
Q_UNUSED(parent);
if (column != 0 || row < 0 || row >= m_editors.count())
if (column < 0 || column > 1 || row < 0 || row >= m_editors.count())
return QModelIndex();
return createIndex(row, column);
}
......
......@@ -86,6 +86,8 @@ public:
QList<Entry> entries() const { return m_editors; }
void removeEditor(IEditor *editor);
void removeEditor(const QModelIndex &index);
void removeAllRestoredEditors();
void emitDataChanged(IEditor *editor);
......
......@@ -53,26 +53,62 @@ Q_DECLARE_METATYPE(Core::IEditor*)
using namespace Core;
using namespace Core::Internal;
OpenEditorsDelegate::OpenEditorsDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{
}
void OpenEditorsDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
if (option.state & QStyle::State_MouseOver) {
painter->fillRect(option.rect, option.palette.alternateBase());
}
QStyledItemDelegate::paint(painter, option, index);
if (index.column() == 1 && option.state & QStyle::State_MouseOver) {
QIcon icon((option.state & QStyle::State_Selected) ? ":/core/images/closebutton.png"
: ":/core/images/darkclosebutton.png");
QRect iconRect(option.rect.right() - option.rect.height(),
option.rect.top(),
option.rect.height(),
option.rect.height());
icon.paint(painter, iconRect, Qt::AlignRight | Qt::AlignVCenter);
}
}
OpenEditorsWidget::OpenEditorsWidget()
{
m_ui.setupUi(this);
setWindowTitle(tr("Open Documents"));
setWindowIcon(QIcon(Constants::ICON_DIR));
setFocusProxy(m_ui.editorList);
m_ui.editorList->setFocusPolicy(Qt::NoFocus);
m_ui.editorList->viewport()->setAttribute(Qt::WA_Hover);
m_ui.editorList->setItemDelegate(new OpenEditorsDelegate(this));
m_ui.editorList->header()->hide();
m_ui.editorList->setIndentation(0);
m_ui.editorList->setSelectionMode(QAbstractItemView::ExtendedSelection);
m_ui.editorList->setTextElideMode(Qt::ElideMiddle);
m_ui.editorList->installEventFilter(this);
m_ui.editorList->setFrameStyle(QFrame::NoFrame);
m_ui.editorList->setAttribute(Qt::WA_MacShowFocusRect, false);
EditorManager *em = EditorManager::instance();
m_ui.editorList->setModel(em->openedEditorsModel());
m_ui.editorList->setSelectionMode(QAbstractItemView::NoSelection);
m_ui.editorList->setSelectionBehavior(QAbstractItemView::SelectRows);
m_ui.editorList->header()->setStretchLastSection(false);
m_ui.editorList->header()->setResizeMode(0, QHeaderView::Stretch);
m_ui.editorList->header()->setResizeMode(1, QHeaderView::Fixed);
m_ui.editorList->header()->resizeSection(1, 16);
connect(em, SIGNAL(currentEditorChanged(Core::IEditor*)),
this, SLOT(updateCurrentItem(Core::IEditor*)));
connect(m_ui.editorList, SIGNAL(clicked(QModelIndex)),
this, SLOT(selectEditor(QModelIndex)));
//updateEditorList();
}
OpenEditorsWidget::~OpenEditorsWidget()
......@@ -86,96 +122,28 @@ void OpenEditorsWidget::updateCurrentItem(Core::IEditor *editor)
return;
}
EditorManager *em = EditorManager::instance();
m_ui.editorList->clearSelection(); //we are in extended selectionmode
m_ui.editorList->setCurrentIndex(em->openedEditorsModel()->indexOf(editor));
m_ui.editorList->selectionModel()->select(m_ui.editorList->currentIndex(),
QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
m_ui.editorList->scrollTo(m_ui.editorList->currentIndex());
}
void OpenEditorsWidget::selectEditor(const QModelIndex &index)
{
EditorManager::instance()->activateEditor(index);
}
void OpenEditorsWidget::selectEditor()
{
selectEditor(m_ui.editorList->currentIndex());
}
void OpenEditorsWidget::closeEditors()
{
/* ### TODO
QList<IFile *> selectedFiles;
QList<IEditor *> selectedEditors;
foreach (QTreeWidgetItem *item, m_ui.editorList->selectedItems()) {
selectedEditors.append(item->data(0, Qt::UserRole).value<IEditor *>());
selectedFiles.append(item->data(0, Qt::UserRole).value<IEditor *>()->file());
}
ICore *core = ICore::instance();
bool cancelled = false;
core->fileManager()->saveModifiedFiles(selectedFiles, &cancelled);
if (cancelled)
return;
core->editorManager()->closeEditors(selectedEditors);
updateEditorList();
*/
}
void OpenEditorsWidget::closeAllEditors()
{
m_ui.editorList->selectAll();
closeEditors();
}
bool OpenEditorsWidget::eventFilter(QObject *obj, QEvent *event)
{
if (obj == m_ui.editorList) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
switch (keyEvent->key()) {
case Qt::Key_Return:
selectEditor(m_ui.editorList->currentIndex());
return true;
case Qt::Key_Delete: //fall through
case Qt::Key_Backspace:
if (keyEvent->modifiers() == Qt::NoModifier) {
closeEditors();
return true;
}
break;
default:
break;
}
}
if (event->type() == QEvent::ContextMenu) {
QContextMenuEvent *contextMenuEvent = static_cast<QContextMenuEvent *>(event);
QMenu menu;
menu.addAction(tr("&Select"), this, SLOT(selectEditor()));
//todo menu.addAction(tr("&Close"), this, SLOT(closeEditors()));
//todo menu.addAction(tr("Close &All"), this, SLOT(closeAllEditors()));
if (m_ui.editorList->selectionModel()->selectedIndexes().isEmpty())
menu.setEnabled(false);
menu.exec(contextMenuEvent->globalPos());
return true;
}
} else if (obj == m_widget) {
if (event->type() == QEvent::FocusIn) {
QFocusEvent *e = static_cast<QFocusEvent *>(event);
if (e->reason() != Qt::MouseFocusReason) {
// we should not set the focus in a event filter for a focus event,
// so do it when the focus event is processed
QTimer::singleShot(0, this, SLOT(putFocusToEditorList()));
}
}
if (index.column() == 1) { // the funky close button
EditorManager::instance()->closeEditor(index);
// work around a bug in itemviews where the delegate wouldn't get the QStyle::State_MouseOver
QPoint cursorPos = QCursor::pos();
QWidget *vp = m_ui.editorList->viewport();
QMouseEvent e(QEvent::MouseMove, vp->mapFromGlobal(cursorPos), cursorPos, Qt::NoButton, 0, 0);
QCoreApplication::sendEvent(vp, &e);
} else {
m_ui.editorList->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
EditorManager::instance()->activateEditor(index);
}
return false;
}
void OpenEditorsWidget::putFocusToEditorList()
{
m_ui.editorList->setFocus();
}
NavigationView OpenEditorsViewFactory::createWidget()
{
......
......@@ -40,6 +40,7 @@
#include <QtGui/QKeySequence>
#include <QtGui/QAbstractButton>
#include <QtGui/QTreeWidgetItem>
#include <QtGui/QStyledItemDelegate>
namespace Core {
namespace Internal {
......@@ -52,15 +53,9 @@ public:
OpenEditorsWidget();
~OpenEditorsWidget();
bool eventFilter(QObject *obj, QEvent *event);
private slots:
void selectEditor(const QModelIndex &);
void selectEditor();
void closeEditors();
void closeAllEditors();
void updateCurrentItem(Core::IEditor*);
void putFocusToEditorList();
private:
Ui::OpenEditorsView m_ui;
......@@ -80,4 +75,16 @@ public:
} // namespace Internal
} // namespace Core
class OpenEditorsDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
OpenEditorsDelegate(QObject *parent = 0);
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const;
};
#endif // OPENEDITORSVIEW_H
......@@ -77,7 +77,9 @@ class FunctionArgumentWidget : public QLabel
public:
FunctionArgumentWidget();
void showFunctionHint(QList<Function *> functionSymbols, const LookupContext &context);
void showFunctionHint(QList<Function *> functionSymbols,
const LookupContext &context,
int startPosition);
protected:
bool eventFilter(QObject *obj, QEvent *e);
......@@ -96,6 +98,7 @@ private:
int m_startpos;
int m_currentarg;
int m_current;
TextEditor::ITextEditor *m_editor;
......@@ -103,7 +106,6 @@ private:
QFrame *m_popupFrame;
QList<Function *> m_items;
LookupContext m_context;
int m_current;
};
class ConvertToCompletionItem: protected NameVisitor
......@@ -193,6 +195,7 @@ protected:
using namespace CppTools::Internal;
FunctionArgumentWidget::FunctionArgumentWidget():
m_startpos(-1),
m_current(0)
{
QObject *editorObject = Core::EditorManager::instance()->currentEditor();
......@@ -243,18 +246,24 @@ FunctionArgumentWidget::FunctionArgumentWidget():
setTextFormat(Qt::RichText);
setMargin(1);
qApp->installEventFilter(this);
}
void FunctionArgumentWidget::showFunctionHint(QList<Function *> functionSymbols,
const LookupContext &context)
const LookupContext &context,
int startPosition)
{
Q_ASSERT(!functionSymbols.isEmpty());
if (m_startpos == startPosition)
return;
m_popupFrame->hide();
m_items = functionSymbols;
m_context = context;
m_startpos = m_editor->position();
m_startpos = startPosition;
m_current = 0;
// update the text
......@@ -263,12 +272,10 @@ void FunctionArgumentWidget::showFunctionHint(QList<Function *> functionSymbols,
m_pager->setVisible(functionSymbols.size() > 1);
QPoint pos = m_editor->cursorRect().topLeft();
QPoint pos = m_editor->cursorRect(m_startpos).topLeft();
pos.setY(pos.y() - m_popupFrame->sizeHint().height() - 1);
m_popupFrame->move(pos);
m_popupFrame->show();
qApp->installEventFilter(this);
}
void FunctionArgumentWidget::nextPage()
......@@ -337,7 +344,6 @@ bool FunctionArgumentWidget::eventFilter(QObject *obj, QEvent *e)
if (obj != m_editor->widget())
break;
}
qDebug() << e;
close();
break;
case QEvent::MouseButtonPress:
......@@ -346,7 +352,6 @@ bool FunctionArgumentWidget::eventFilter(QObject *obj, QEvent *e)
case QEvent::Wheel: {
QWidget *widget = qobject_cast<QWidget *>(obj);
if (! (widget == this || m_popupFrame->isAncestorOf(widget))) {
qDebug() << e << widget;
close();
}
}
......@@ -434,10 +439,13 @@ static int startOfOperator(TextEditor::ITextEditable *editor,
if (ch2 != QLatin1Char('.') && ch == QLatin1Char('.')) {
k = T_DOT;
--start;
} else if (ch == QLatin1Char(',')) {
k = T_COMMA;
--start;
} else if (wantFunctionCall && ch == QLatin1Char('(')) {
k = T_LPAREN;
--start;
} else if (ch2 == QLatin1Char(':') && ch == QLatin1Char(':')) {
} else if (ch3 != QLatin1Char(':') && ch2 == QLatin1Char(':') && ch == QLatin1Char(':')) {
k = T_COLON_COLON;
start -= 2;
} else if (ch2 == QLatin1Char('-') && ch == QLatin1Char('>')) {
......@@ -468,7 +476,6 @@ static int startOfOperator(TextEditor::ITextEditable *editor,
k = T_EOF_SYMBOL;
start = pos;
}
else if (tk.is(T_COMMENT) || tk.isLiteral()) {
k = T_EOF_SYMBOL;
start = pos;
......@@ -520,10 +527,6 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
edit->convertPosition(editor->position(), &line, &column);
// qDebug() << "line:" << line << "column:" << column;
ExpressionUnderCursor expressionUnderCursor;
QString expression;
if (m_completionOperator == T_DOXY_COMMENT) {
for (int i = 1; i < T_DOXY_LAST_TAG; ++i) {
TextEditor::CompletionItem item(this);
......@@ -535,11 +538,23 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
return m_startPosition;
}
ExpressionUnderCursor expressionUnderCursor;
QTextCursor tc(edit->document());
if (m_completionOperator) {
QTextCursor tc(edit->document());
if (m_completionOperator == T_COMMA) {
tc.setPosition(endOfExpression);
const int start = expressionUnderCursor.startOfFunctionCall(tc);
if (start != -1) {
endOfExpression = start;
m_startPosition = start + 1;
m_completionOperator = T_LPAREN;
}
}
QString expression;
tc.setPosition(endOfExpression);
if (m_completionOperator) {
expression = expressionUnderCursor(tc);
if (m_completionOperator == T_LPAREN) {
......@@ -553,12 +568,12 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
// We don't want a function completion when the cursor isn't at the opening brace
expression.clear();
m_completionOperator = T_EOF_SYMBOL;
m_startPosition = editor->position();
}