Initial import

This commit is contained in:
con
2008-12-02 12:01:29 +01:00
commit 05c35356ab
1675 changed files with 229938 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
<?xml version="1.0"?>
<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
<mime-type type="application/octet-stream">
<comment>unknown</comment>
<comment xml:lang="bg">Неизвестен тип</comment>
<comment xml:lang="ca">desconegut</comment>
<comment xml:lang="cs">Neznámý</comment>
<comment xml:lang="cy">Anhysbys</comment>
<comment xml:lang="da">ukendt</comment>
<comment xml:lang="de">unbekannt</comment>
<comment xml:lang="el">αγνωστο</comment>
<comment xml:lang="eo">nekonata</comment>
<comment xml:lang="es">desconocido</comment>
<comment xml:lang="eu">ezezaguna</comment>
<comment xml:lang="fi">tuntematon</comment>
<comment xml:lang="fr">inconnu</comment>
<comment xml:lang="hu">ismeretlen</comment>
<comment xml:lang="it">Sconosciuto</comment>
<comment xml:lang="ja">不明</comment>
<comment xml:lang="ko">알 수 없음</comment>
<comment xml:lang="lt">nežinoma</comment>
<comment xml:lang="ms">Entah</comment>
<comment xml:lang="nb">ukjent</comment>
<comment xml:lang="nl">onbekend</comment>
<comment xml:lang="nn">ukjend</comment>
<comment xml:lang="pl">nieznany typ</comment>
<comment xml:lang="pt">desconhecido</comment>
<comment xml:lang="pt_BR">Desconhecido</comment>
<comment xml:lang="ru">неизвестный</comment>
<comment xml:lang="rw">itazwi</comment>
<comment xml:lang="sq">nuk njihet</comment>
<comment xml:lang="sr">непознато</comment>
<comment xml:lang="sv">okänd</comment>
<comment xml:lang="uk">невідомо</comment>
<comment xml:lang="vi">không rõ</comment>
<comment xml:lang="zh_CN">未知</comment>
<comment xml:lang="zh_TW">不明</comment>
</mime-type>
</mime-info>

View File

@@ -0,0 +1,11 @@
<plugin name="BinEditor" version="0.9.1" compatVersion="0.9.1">
<vendor>Nokia Corporation</vendor>
<copyright>(C) 2008 Nokia Corporation</copyright>
<license>Nokia Technology Preview License Agreement</license>
<description>Binary editor component.</description>
<url>http://www.trolltech.com/</url>
<dependencyList>
<dependency name="Core" version="0.9.1"/>
<dependency name="TextEditor" version="0.9.1"/>
</dependencyList>
</plugin>

View File

@@ -0,0 +1,871 @@
/***************************************************************************
**
** 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 "bineditor.h"
#include <texteditor/fontsettings.h>
#include <texteditor/texteditorconstants.h>
#include <QtGui/QScrollBar>
#include <QtGui/QFontMetrics>
#include <QtGui/QPainter>
#include <QtGui/QScrollBar>
#include <QtGui/QWheelEvent>
#include <QtGui/QApplication>
#include <QtGui/QClipboard>
#include <QtCore/QDebug>
using namespace BINEditor;
static QByteArray calculateHexPattern(const QByteArray &pattern)
{
QByteArray result;
if (pattern.size() % 2 == 0) {
bool ok = true;
int i = 0;
while (i < pattern.size()) {
ushort s = pattern.mid(i, 2).toUShort(&ok, 16);
if (!ok) {
return QByteArray();
}
result.append(s);
i += 2;
}
}
return result;
}
BinEditor::BinEditor(QWidget *parent)
: QAbstractScrollArea(parent)
{
m_ieditor = 0;
init();
m_unmodifiedState = 0;
m_hexCursor = true;
m_cursorPosition = 0;
m_anchorPosition = 0;
m_lowNibble = false;
m_cursorVisible = false;
setFocusPolicy(Qt::WheelFocus);
m_addressString = QString(9, QLatin1Char(':'));
}
BinEditor::~BinEditor()
{
}
void BinEditor::init()
{
QFontMetrics fm(fontMetrics());
m_margin = 4;
m_descent = fm.descent();
m_ascent = fm.ascent();
m_lineHeight = fm.lineSpacing();
m_charWidth = fm.width(QChar(QLatin1Char('M')));
m_columnWidth = 2 * m_charWidth + fm.width(QChar(QLatin1Char(' ')));
m_numLines = m_data.size() / 16 + 1;
m_numVisibleLines = viewport()->height() / m_lineHeight;
m_textWidth = 16 * m_charWidth + m_charWidth;
int m_numberWidth = fm.width(QChar(QLatin1Char('9')));
m_labelWidth = 8 * m_numberWidth + 2 * m_charWidth;
int expectedCharWidth = m_columnWidth / 3;
const char *hex = "0123456789abcdef";
m_isMonospacedFont = true;
while (*hex) {
if (fm.width(QLatin1Char(*hex)) != expectedCharWidth) {
m_isMonospacedFont = false;
break;
}
++hex;
}
horizontalScrollBar()->setRange(0, 2 * m_margin + 16 * m_columnWidth
+ m_labelWidth + m_textWidth - viewport()->width());
horizontalScrollBar()->setPageStep(viewport()->width());
verticalScrollBar()->setRange(0, m_numLines - m_numVisibleLines);
verticalScrollBar()->setPageStep(m_numVisibleLines);
}
void BinEditor::setFontSettings(const TextEditor::FontSettings &fs)
{
setFont(fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_TEXT)).font());
}
void BinEditor::setBlinkingCursorEnabled(bool enable)
{
if (enable && QApplication::cursorFlashTime() > 0)
m_cursorBlinkTimer.start(QApplication::cursorFlashTime() / 2, this);
else
m_cursorBlinkTimer.stop();
m_cursorVisible = enable;
updateLines();
}
void BinEditor::focusInEvent(QFocusEvent *)
{
setBlinkingCursorEnabled(true);
}
void BinEditor::focusOutEvent(QFocusEvent *)
{
setBlinkingCursorEnabled(false);
}
void BinEditor::timerEvent(QTimerEvent *e)
{
if (e->timerId() == m_autoScrollTimer.timerId()) {
QRect visible = viewport()->rect();
QPoint pos;
const QPoint globalPos = QCursor::pos();
pos = viewport()->mapFromGlobal(globalPos);
QMouseEvent ev(QEvent::MouseMove, pos, globalPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
mouseMoveEvent(&ev);
int deltaY = qMax(pos.y() - visible.top(), visible.bottom() - pos.y()) - visible.height();
int deltaX = qMax(pos.x() - visible.left(), visible.right() - pos.x()) - visible.width();
int delta = qMax(deltaX, deltaY);
if (delta >= 0) {
if (delta < 7)
delta = 7;
int timeout = 4900 / (delta * delta);
m_autoScrollTimer.start(timeout, this);
if (deltaY > 0)
verticalScrollBar()->triggerAction(pos.y() < visible.center().y() ?
QAbstractSlider::SliderSingleStepSub
: QAbstractSlider::SliderSingleStepAdd);
if (deltaX > 0)
horizontalScrollBar()->triggerAction(pos.x() < visible.center().x() ?
QAbstractSlider::SliderSingleStepSub
: QAbstractSlider::SliderSingleStepAdd);
}
} else if (e->timerId() == m_cursorBlinkTimer.timerId()) {
m_cursorVisible = !m_cursorVisible;
updateLines();
}
QAbstractScrollArea::timerEvent(e);
}
void BinEditor::setModified(bool modified)
{
int unmodifiedState = modified ? -1 : m_undoStack.size();
if (unmodifiedState == m_unmodifiedState)
return;
m_unmodifiedState = unmodifiedState;
emit modificationChanged(m_undoStack.size() != m_unmodifiedState);
}
bool BinEditor::isModified() const
{
return (m_undoStack.size() != m_unmodifiedState);
}
void BinEditor::setData(const QByteArray &data)
{
m_data = data;
m_unmodifiedState = 0;
m_undoStack.clear();
m_redoStack.clear();
init();
emit cursorPositionChanged(m_cursorPosition);
viewport()->update();
}
QByteArray BinEditor::data() const
{
return m_data;
}
void BinEditor::resizeEvent(QResizeEvent *)
{
init();
}
void BinEditor::scrollContentsBy(int dx, int dy)
{
viewport()->scroll(isRightToLeft() ? -dx : dx, dy * m_lineHeight);
}
void BinEditor::changeEvent(QEvent *e)
{
QAbstractScrollArea::changeEvent(e);
if(e->type() == QEvent::ActivationChange) {
if (!isActiveWindow())
m_autoScrollTimer.stop();
}
init();
viewport()->update();
}
void BinEditor::wheelEvent(QWheelEvent *e)
{
if (e->modifiers() & Qt::ControlModifier) {
const int delta = e->delta();
if (delta < 0)
zoomOut();
else if (delta > 0)
zoomIn();
return;
}
QAbstractScrollArea::wheelEvent(e);
}
QRect BinEditor::cursorRect() const
{
int topLine = verticalScrollBar()->value();
int line = m_cursorPosition / 16;
int y = (line - topLine) * m_lineHeight;
int xoffset = horizontalScrollBar()->value();
int column = m_cursorPosition % 16;
int x = m_hexCursor ?
(-xoffset + m_margin + m_labelWidth + column * m_columnWidth)
: (-xoffset + m_margin + m_labelWidth + 16 * m_columnWidth + m_charWidth + column * m_charWidth);
int w = m_hexCursor ? m_columnWidth : m_charWidth;
return QRect(x, y, w, m_lineHeight);
}
int BinEditor::posAt(const QPoint &pos) const
{
int xoffset = horizontalScrollBar()->value();
int x = xoffset + pos.x() - m_margin - m_labelWidth;
int column = qMin(15, qMax(0,x) / m_columnWidth);
int topLine = verticalScrollBar()->value();
int line = pos.y() / m_lineHeight;
if (x > 16 * m_columnWidth + m_charWidth/2) {
x -= 16 * m_columnWidth + m_charWidth;
for (column = 0; column < 15; ++column) {
int pos = (topLine + line) * 16 + column;
if (pos < 0 || pos >= m_data.size())
break;
QChar qc(QLatin1Char(m_data.at(pos)));
if (!qc.isPrint())
qc = 0xB7;
x -= fontMetrics().width(qc);
if (x <= 0)
break;
}
}
return (qMin(m_data.size(), qMin(m_numLines, topLine + line) * 16) + column);
}
bool BinEditor::inTextArea(const QPoint &pos) const
{
int xoffset = horizontalScrollBar()->value();
int x = xoffset + pos.x() - m_margin - m_labelWidth;
return (x > 16 * m_columnWidth + m_charWidth/2);
}
void BinEditor::updateLines(int fromPosition, int toPosition)
{
if (fromPosition < 0)
fromPosition = m_cursorPosition;
if (toPosition < 0)
toPosition = fromPosition;
int topLine = verticalScrollBar()->value();
int firstLine = qMin(fromPosition, toPosition) / 16;
int lastLine = qMax(fromPosition, toPosition) / 16;
int y = (firstLine - topLine) * m_lineHeight;
int h = (lastLine - firstLine + 1 ) * m_lineHeight;
viewport()->update(0, y, viewport()->width(), h);
}
int BinEditor::find(const QByteArray &pattern, int from, QTextDocument::FindFlags findFlags)
{
if (pattern.isEmpty())
return false;
bool backwards = (findFlags & QTextDocument::FindBackward);
int found = backwards ? m_data.lastIndexOf(pattern, from)
: m_data.indexOf(pattern, from);
int foundHex = -1;
QByteArray hexPattern = calculateHexPattern(pattern);
if (!hexPattern.isEmpty()) {
foundHex = backwards ? m_data.lastIndexOf(hexPattern, from)
: m_data.indexOf(hexPattern, from);
}
int pos = (found >= 0 && (foundHex < 0 || found < foundHex)) ? found : foundHex;
if (pos >= 0) {
setCursorPosition(pos);
setCursorPosition(pos + (found == pos ? pattern.size() : hexPattern.size()), KeepAnchor);
}
return pos;
}
int BinEditor::findPattern(const QByteArray &data, int from, int offset, int *match)
{
if (m_searchPattern.isEmpty())
return -1;
int normal = m_searchPattern.isEmpty()? -1 : data.indexOf(m_searchPattern, from - offset);
int hex = m_searchPatternHex.isEmpty()? -1 : data.indexOf(m_searchPatternHex, from - offset);
if (normal >= 0 && (hex < 0 || normal < hex)) {
if (match)
*match = m_searchPattern.length();
return normal + offset;
}
if (hex >= 0) {
if (match)
*match = m_searchPatternHex.length();
return hex + offset;
}
return -1;
}
void BinEditor::drawItems(QPainter *painter, int x, int y, const QString &itemString)
{
if (m_isMonospacedFont) {
painter->drawText(x, y, itemString);
} else {
for (int i = 0; i < 16; ++i)
painter->drawText(x + i*m_columnWidth, y, itemString.mid(i*3, 2));
}
}
QString BinEditor::addressString(uint address)
{
QChar *addressStringData = m_addressString.data();
const char *hex = "0123456789abcdef";
for (int h = 0; h < 4; ++h) {
int shift = 4*(7-h);
addressStringData[h] = hex[(address & (0xf<<shift))>>shift];
}
for (int h = 4; h < 8; ++h) {
int shift = 4*(7-h);
addressStringData[h+1] = hex[(address & (0xf<<shift))>>shift];
}
return m_addressString;
}
void BinEditor::paintEvent(QPaintEvent *e)
{
QPainter painter(viewport());
int topLine = verticalScrollBar()->value();
int xoffset = horizontalScrollBar()->value();
painter.drawLine(-xoffset + m_margin + m_labelWidth - m_charWidth/2, 0,
-xoffset + m_margin + m_labelWidth - m_charWidth/2, viewport()->height());
painter.drawLine(-xoffset + m_margin + m_labelWidth + 16 * m_columnWidth + m_charWidth/2, 0,
-xoffset + m_margin + m_labelWidth + 16 * m_columnWidth + m_charWidth/2, viewport()->height());
int viewport_height = viewport()->height();
QBrush alternate_base = palette().alternateBase();
for (int i = 0; i < 8; ++i) {
int bg_x = -xoffset + m_margin + (2 * i + 1) * m_columnWidth + m_labelWidth;
QRect r(bg_x - m_charWidth/2, 0, m_columnWidth, viewport_height);
painter.fillRect(e->rect() & r, palette().alternateBase());
}
int matchLength = 0;
QByteArray patternData;
int patternOffset = qMax(0, topLine*16 - m_searchPattern.size());
if (!m_searchPattern.isEmpty())
patternData = m_data.mid(patternOffset, m_numVisibleLines * 16);
int foundPatternAt = findPattern(patternData, patternOffset, patternOffset, &matchLength);
int selStart = qMin(m_cursorPosition, m_anchorPosition);
int selEnd = qMax(m_cursorPosition, m_anchorPosition);
QString itemString(QLatin1String("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"));
QChar *itemStringData = itemString.data();
const char *hex = "0123456789abcdef";
painter.setPen(palette().text().color());
for (int i = 0; i <= m_numVisibleLines; ++i) {
int line = topLine + i;
if (line >= m_numLines)
break;
int y = i * m_lineHeight + m_ascent;
if (y - m_ascent > e->rect().bottom())
break;
if (y + m_descent < e->rect().top())
continue;
painter.drawText(-xoffset, i * m_lineHeight + m_ascent, addressString(((uint) line) * 16));
QString printable;
int cursor = -1;
for (int c = 0; c < 16; ++c) {
int pos = line * 16 + c;
if (pos >= m_data.size())
break;
QChar qc(QLatin1Char(m_data.at(pos)));
if (qc.unicode() >= 127 || !qc.isPrint())
qc = 0xB7;
printable += qc;
}
QRect selectionRect;
QRect printableSelectionRect;
bool isFullySelected = (selStart < selEnd && selStart <= line*16 && (line+1)*16 <= selEnd);
for (int c = 0; c < 16; ++c) {
int pos = line * 16 + c;
if (pos >= m_data.size()) {
while(c < 16) {
itemStringData[c*3] = itemStringData[c*3+1] = ' ';
++c;
}
break;
}
if (foundPatternAt >= 0 && pos >= foundPatternAt + matchLength)
foundPatternAt = findPattern(patternData, foundPatternAt + matchLength, patternOffset, &matchLength);
uchar value = (uchar)m_data.at(pos);
itemStringData[c*3] = hex[value >> 4];
itemStringData[c*3+1] = hex[value & 0xf];
int item_x = -xoffset + m_margin + c * m_columnWidth + m_labelWidth;
if (foundPatternAt >= 0 && pos >= foundPatternAt && pos < foundPatternAt + matchLength) {
painter.fillRect(item_x, y-m_ascent, m_columnWidth, m_lineHeight, QColor(0xffef0b));
int printable_item_x = -xoffset + m_margin + m_labelWidth + 16 * m_columnWidth + m_charWidth
+ painter.fontMetrics().width( printable.left(c));
painter.fillRect(printable_item_x, y-m_ascent,
painter.fontMetrics().width(printable.at(c)),
m_lineHeight, QColor(0xffef0b));
}
if (selStart < selEnd && !isFullySelected && pos >= selStart && pos < selEnd) {
selectionRect |= QRect(item_x, y-m_ascent, m_columnWidth, m_lineHeight);
int printable_item_x = -xoffset + m_margin + m_labelWidth + 16 * m_columnWidth + m_charWidth
+ painter.fontMetrics().width( printable.left(c));
printableSelectionRect |= QRect(printable_item_x, y-m_ascent,
painter.fontMetrics().width(printable.at(c)),
m_lineHeight);
}
if (pos == m_cursorPosition)
cursor = c;
}
int x = -xoffset + m_margin + m_labelWidth;
if (isFullySelected) {
painter.save();
painter.fillRect(x, y-m_ascent, 16*m_columnWidth, m_lineHeight, palette().highlight());
painter.setPen(palette().highlightedText().color());
drawItems(&painter, x, y, itemString);
painter.restore();
} else {
drawItems(&painter, x, y, itemString);
if (!selectionRect.isEmpty()) {
painter.save();
painter.fillRect(selectionRect, palette().highlight());
painter.setPen(palette().highlightedText().color());
painter.setClipRect(selectionRect);
drawItems(&painter, x, y, itemString);
painter.restore();
}
}
if (cursor >= 0) {
int w = painter.fontMetrics().boundingRect(itemString.mid(cursor*3, 2)).width();
QRect cursorRect(x + cursor * m_columnWidth, y - m_ascent, w + 1, m_lineHeight);
painter.save();
painter.setPen(Qt::red);
painter.drawRect(cursorRect.adjusted(0, 0, 0, -1));
painter.restore();
if (m_hexCursor && m_cursorVisible) {
if (m_lowNibble)
cursorRect.adjust(painter.fontMetrics().width(itemString.left(1)), 0, 0, 0);
painter.fillRect(cursorRect, Qt::red);
painter.save();
painter.setClipRect(cursorRect);
painter.setPen(Qt::white);
drawItems(&painter, x, y, itemString);
painter.restore();
}
}
int text_x = -xoffset + m_margin + m_labelWidth + 16 * m_columnWidth + m_charWidth;
if (isFullySelected) {
painter.save();
painter.fillRect(text_x, y-m_ascent, painter.fontMetrics().width(printable), m_lineHeight,
palette().highlight());
painter.setPen(palette().highlightedText().color());
painter.drawText(text_x, y, printable);
painter.restore();
}else {
painter.drawText(text_x, y, printable);
if (!printableSelectionRect.isEmpty()) {
painter.save();
painter.fillRect(printableSelectionRect, palette().highlight());
painter.setPen(palette().highlightedText().color());
painter.setClipRect(printableSelectionRect);
painter.drawText(text_x, y, printable);
painter.restore();
}
}
if (cursor >= 0) {
QRect cursorRect(text_x + painter.fontMetrics().width(printable.left(cursor)),
y-m_ascent,
painter.fontMetrics().width(printable.at(cursor)),
m_lineHeight);
painter.save();
if (m_hexCursor || !m_cursorVisible) {
painter.setPen(Qt::red);
painter.drawRect(cursorRect.adjusted(0, 0, 0, -1));
} else {
painter.setClipRect(cursorRect);
painter.fillRect(cursorRect, Qt::red);
painter.setPen(Qt::white);
painter.drawText(text_x, y, printable);
}
painter.restore();
}
}
}
int BinEditor::cursorPosition() const
{
return m_cursorPosition;
}
void BinEditor::setCursorPosition(int pos, MoveMode moveMode)
{
pos = qMin(m_data.size()-1, qMax(0, pos));
if (pos == m_cursorPosition
&& (m_anchorPosition == m_cursorPosition || moveMode == KeepAnchor)
&& !m_lowNibble)
return;
int oldCursorPosition = m_cursorPosition;
bool hasSelection = m_anchorPosition != m_cursorPosition;
m_lowNibble = false;
if (!hasSelection)
updateLines();
m_cursorPosition = pos;
if (moveMode == MoveAnchor) {
if (hasSelection)
updateLines(m_anchorPosition, oldCursorPosition);
m_anchorPosition = m_cursorPosition;
}
hasSelection = m_anchorPosition != m_cursorPosition;
updateLines(hasSelection ? oldCursorPosition : m_cursorPosition, m_cursorPosition);
ensureCursorVisible();
if (hasSelection != (m_anchorPosition != m_anchorPosition))
emit copyAvailable(m_anchorPosition != m_cursorPosition);
emit cursorPositionChanged(m_cursorPosition);
}
void BinEditor::ensureCursorVisible()
{
QRect cr = cursorRect();
QRect vr = viewport()->rect();
if (!vr.contains(cr)) {
if (cr.top() < vr.top())
verticalScrollBar()->setValue(m_cursorPosition / 16);
else if (cr.bottom() > vr.bottom())
verticalScrollBar()->setValue(m_cursorPosition / 16 - m_numVisibleLines + 1);
}
}
void BinEditor::mousePressEvent(QMouseEvent *e)
{
if (e->button() != Qt::LeftButton)
return;
setCursorPosition(posAt(e->pos()));
setBlinkingCursorEnabled(true);
if (m_hexCursor == inTextArea(e->pos())) {
m_hexCursor = !m_hexCursor;
updateLines();
}
}
void BinEditor::mouseMoveEvent(QMouseEvent *e)
{
if (!(e->buttons() & Qt::LeftButton))
return;
setCursorPosition(posAt(e->pos()), KeepAnchor);
if (m_hexCursor == inTextArea(e->pos())) {
m_hexCursor = !m_hexCursor;
updateLines();
}
QRect visible = viewport()->rect();
if (visible.contains(e->pos()))
m_autoScrollTimer.stop();
else if (!m_autoScrollTimer.isActive())
m_autoScrollTimer.start(100, this);
}
void BinEditor::mouseReleaseEvent(QMouseEvent *)
{
if (m_autoScrollTimer.isActive()) {
m_autoScrollTimer.stop();
ensureCursorVisible();
}
}
void BinEditor::selectAll()
{
setCursorPosition(0);
setCursorPosition(m_data.size()-1, KeepAnchor);
}
void BinEditor::clear()
{
setData(QByteArray());
}
bool BinEditor::event(QEvent *e) {
if (e->type() == QEvent::KeyPress) {
switch (static_cast<QKeyEvent*>(e)->key()) {
case Qt::Key_Tab:
case Qt::Key_Backtab:
m_hexCursor = !m_hexCursor;
setBlinkingCursorEnabled(true);
ensureCursorVisible();
e->accept();
return true;
default:;
}
}
return QAbstractScrollArea::event(e);
}
void BinEditor::keyPressEvent(QKeyEvent *e)
{
if (e == QKeySequence::SelectAll) {
e->accept();
selectAll();
return;
} else if (e == QKeySequence::Copy) {
e->accept();
copy();
return;
} else if (e == QKeySequence::Undo) {
e->accept();
undo();
return;
} else if (e == QKeySequence::Redo) {
e->accept();
redo();
return;
}
MoveMode moveMode = e->modifiers() & Qt::ShiftModifier ? KeepAnchor : MoveAnchor;
switch (e->key()) {
case Qt::Key_Up:
setCursorPosition(m_cursorPosition - 16, moveMode);
break;
case Qt::Key_Down:
setCursorPosition(m_cursorPosition + 16, moveMode);
break;
case Qt::Key_Right:
setCursorPosition(m_cursorPosition + 1, moveMode);
break;
case Qt::Key_Left:
setCursorPosition(m_cursorPosition - 1, moveMode);
break;
case Qt::Key_PageUp:
case Qt::Key_PageDown: {
int line = qMax(0, m_cursorPosition / 16 - verticalScrollBar()->value());
verticalScrollBar()->triggerAction(e->key() == Qt::Key_PageUp ?
QScrollBar::SliderPageStepSub : QScrollBar::SliderPageStepAdd);
setCursorPosition((verticalScrollBar()->value() + line) * 16 + m_cursorPosition % 16, moveMode);
} break;
case Qt::Key_Home:
setCursorPosition((e->modifiers() & Qt::ControlModifier) ?
0 : (m_cursorPosition/16 * 16), moveMode);
break;
case Qt::Key_End:
setCursorPosition((e->modifiers() & Qt::ControlModifier) ?
(m_data.size()-1) : (m_cursorPosition/16 * 16 + 15), moveMode);
break;
default: {
QString text = e->text();
for (int i = 0; i < text.length(); ++i) {
QChar c = text.at(i);
if (m_hexCursor) {
c = c.toLower();
int nibble = -1;
if (c.unicode() >= 'a' && c.unicode() <= 'f')
nibble = c.unicode() - 'a' + 10;
else if (c.unicode() >= '0' && c.unicode() <= '9')
nibble = c.unicode() - '0';
if (nibble < 0)
continue;
if (m_lowNibble) {
changeData(m_cursorPosition, nibble + (m_data[m_cursorPosition] & 0xf0));
m_lowNibble = false;
setCursorPosition(m_cursorPosition + 1);
} else {
changeData(m_cursorPosition, (nibble << 4) + (m_data[m_cursorPosition] & 0x0f), true);
m_lowNibble = true;
updateLines();
}
} else {
if (c.unicode() >= 128 || !c.isPrint())
continue;
changeData(m_cursorPosition, c.unicode(), m_cursorPosition + 1);
setCursorPosition(m_cursorPosition + 1);
}
setBlinkingCursorEnabled(true);
}
}
}
e->accept();
}
void BinEditor::zoomIn(int range)
{
QFont f = font();
const int newSize = f.pointSize() + range;
if (newSize <= 0)
return;
f.setPointSize(newSize);
setFont(f);
}
void BinEditor::zoomOut(int range)
{
zoomIn(-range);
}
void BinEditor::copy()
{
int selStart = qMin(m_cursorPosition, m_anchorPosition);
int selEnd = qMax(m_cursorPosition, m_anchorPosition);
if (selStart < selEnd)
QApplication::clipboard()->setText(QString::fromLatin1(m_data.mid(selStart, selEnd - selStart)));
}
void BinEditor::highlightSearchResults(const QByteArray &pattern, QTextDocument::FindFlags /*findFlags*/)
{
if (m_searchPattern == pattern)
return;
m_searchPattern = pattern;
m_searchPatternHex = calculateHexPattern(pattern);
viewport()->update();
}
void BinEditor::changeData(int position, uchar character, bool highNibble)
{
m_redoStack.clear();
if (m_unmodifiedState > m_undoStack.size())
m_unmodifiedState = -1;
BinEditorEditCommand cmd;
cmd.position = position;
cmd.character = (uchar) m_data[position];
cmd.highNibble = highNibble;
if (!highNibble && !m_undoStack.isEmpty() && m_undoStack.top().position == position && m_undoStack.top().highNibble) {
// compress
cmd.character = m_undoStack.top().character;
m_undoStack.pop();
}
m_data[position] = (char) character;
bool emitModificationChanged = (m_undoStack.size() == m_unmodifiedState);
m_undoStack.push(cmd);
if (emitModificationChanged) {
emit modificationChanged(m_undoStack.size() != m_unmodifiedState);
}
if (m_undoStack.size() == 1)
emit undoAvailable(true);
}
void BinEditor::undo()
{
if (m_undoStack.isEmpty())
return;
bool emitModificationChanged = (m_undoStack.size() == m_unmodifiedState);
BinEditorEditCommand cmd = m_undoStack.pop();
emitModificationChanged |= (m_undoStack.size() == m_unmodifiedState);
uchar c = m_data[cmd.position];
m_data[cmd.position] = (char)cmd.character;
cmd.character = c;
m_redoStack.push(cmd);
setCursorPosition(cmd.position);
if (emitModificationChanged)
emit modificationChanged(m_undoStack.size() != m_unmodifiedState);
if (!m_undoStack.size())
emit undoAvailable(false);
if (m_redoStack.size() == 1)
emit redoAvailable(true);
}
void BinEditor::redo()
{
if (m_redoStack.isEmpty())
return;
BinEditorEditCommand cmd = m_redoStack.pop();
uchar c = m_data[cmd.position];
m_data[cmd.position] = (char)cmd.character;
cmd.character = c;
bool emitModificationChanged = (m_undoStack.size() == m_unmodifiedState);
m_undoStack.push(cmd);
setCursorPosition(cmd.position + 1);
if (emitModificationChanged)
emit modificationChanged(m_undoStack.size() != m_unmodifiedState);
if (m_undoStack.size() == 1)
emit undoAvailable(true);
if (!m_redoStack.size())
emit redoAvailable(false);
}

View File

@@ -0,0 +1,181 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef BINEDITOR_H
#define BINEDITOR_H
#include <QtGui/qabstractscrollarea.h>
#include <QtCore/qbasictimer.h>
#include <QtCore/qstack.h>
#include <QtGui/qtextdocument.h>
#include <QtGui/qtextformat.h>
namespace Core {
class IEditor;
}
namespace TextEditor {
class FontSettings;
}
namespace BINEditor {
class BinEditor : public QAbstractScrollArea
{
Q_OBJECT
Q_PROPERTY(bool modified READ isModified WRITE setModified DESIGNABLE false)
public:
BinEditor(QWidget *parent = 0);
~BinEditor();
void setData(const QByteArray &data);
QByteArray data() const;
void zoomIn(int range = 1);
void zoomOut(int range = 1);
enum MoveMode {
MoveAnchor,
KeepAnchor
};
int cursorPosition() const;
void setCursorPosition(int pos, MoveMode moveMode = MoveAnchor);
void setModified(bool);
bool isModified() const;
int find(const QByteArray &pattern, int from = 0, QTextDocument::FindFlags findFlags = 0);
void selectAll();
void clear();
void undo();
void redo();
Core::IEditor *editorInterface() const { return m_ieditor; }
void setEditorInterface(Core::IEditor *ieditor) { m_ieditor = ieditor; }
bool hasSelection() const { return m_cursorPosition != m_anchorPosition; }
int selectionStart() const { return qMin(m_anchorPosition, m_cursorPosition); }
int selectionEnd() const { return qMax(m_anchorPosition, m_cursorPosition); }
bool event(QEvent*);
bool isUndoAvailable() const { return m_undoStack.size(); }
bool isRedoAvailable() const { return m_redoStack.size(); }
QString addressString(uint address);
public Q_SLOTS:
void setFontSettings(const TextEditor::FontSettings &fs);
void highlightSearchResults(const QByteArray &pattern, QTextDocument::FindFlags findFlags = 0);
void copy();
Q_SIGNALS:
void modificationChanged(bool modified);
void undoAvailable(bool);
void redoAvailable(bool);
void copyAvailable(bool);
void cursorPositionChanged(int position);
protected:
void scrollContentsBy(int dx, int dy);
void paintEvent(QPaintEvent *e);
void resizeEvent(QResizeEvent *);
void changeEvent(QEvent *);
void wheelEvent(QWheelEvent *e);
void mousePressEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
void keyPressEvent(QKeyEvent *e);
void focusInEvent(QFocusEvent *);
void focusOutEvent(QFocusEvent *);
void timerEvent(QTimerEvent *);
private:
QByteArray m_data;
int m_unmodifiedState;
int m_margin;
int m_descent;
int m_ascent;
int m_lineHeight;
int m_charWidth;
int m_labelWidth;
int m_textWidth;
int m_columnWidth;
int m_numLines;
int m_numVisibleLines;
bool m_cursorVisible;
int m_cursorPosition;
int m_anchorPosition;
bool m_hexCursor;
bool m_lowNibble;
bool m_isMonospacedFont;
QByteArray m_searchPattern;
QByteArray m_searchPatternHex;
QBasicTimer m_cursorBlinkTimer;
void init();
int posAt(const QPoint &pos) const;
bool inTextArea(const QPoint &pos) const;
QRect cursorRect() const;
void updateLines(int fromPosition = -1, int toPosition = -1);
void ensureCursorVisible();
void setBlinkingCursorEnabled(bool enable);
void changeData(int position, uchar character, bool highNibble = false);
int findPattern(const QByteArray &data, int from, int offset, int *match);
void drawItems(QPainter *painter, int x, int y, const QString &itemString);
struct BinEditorEditCommand {
int position;
uchar character;
bool highNibble;
};
QStack<BinEditorEditCommand> m_undoStack, m_redoStack;
QBasicTimer m_autoScrollTimer;
Core::IEditor *m_ieditor;
QString m_addressString;
};
} // namespace BINEditor
#endif // BINEDITOR_H

View File

@@ -0,0 +1,13 @@
TEMPLATE = lib
TARGET = BinEditor
include(bineditor_dependencies.pri)
HEADERS += bineditorplugin.h \
bineditor.h \
bineditorconstants.h
SOURCES += bineditorplugin.cpp \
bineditor.cpp
RESOURCES += bineditor.qrc

View File

@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/bineditor" >
<file>BinEditor.mimetypes.xml</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,4 @@
include(../../qworkbenchplugin.pri)
include(../../libs/utils/utils.pri)
include(../../plugins/texteditor/texteditor.pri)
include(../../plugins/coreplugin/coreplugin.pri)

View File

@@ -0,0 +1,43 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef BINEDITORCONSTANTS_H
#define BINEDITORCONSTANTS_H
namespace BINEditor {
namespace Constants {
const char * const C_BINEDITOR = "Binary Editor";
const char * const C_BINEDITOR_MIMETYPE = "application/octet-stream";
}
}
#endif // BINEDITORCONSTANTS_H

View File

@@ -0,0 +1,503 @@
/***************************************************************************
**
** 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 "bineditorplugin.h"
#include "bineditor.h"
#include "bineditorconstants.h"
#include <QtCore/QFileInfo>
#include <QtGui/QMenu>
#include <QtGui/QAction>
#include <QtGui/QMainWindow>
#include <QtGui/QHBoxLayout>
#include <QtCore/QFile>
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/mimedatabase.h>
#include <coreplugin/uniqueidmanager.h>
#include <coreplugin/actionmanager/actionmanagerinterface.h>
#include <coreplugin/editormanager/editormanager.h>
#include <texteditor/texteditorsettings.h>
#include <texteditor/fontsettings.h>
#include <find/ifindsupport.h>
#include <utils/linecolumnlabel.h>
#include <utils/reloadpromptutils.h>
using namespace BINEditor;
using namespace BINEditor::Internal;
class BinEditorFind : public Find::IFindSupport
{
Q_OBJECT
public:
BinEditorFind(BinEditor *editor) { m_editor = editor; m_incrementalStartPos = -1; }
~BinEditorFind() {}
bool supportsReplace() const { return false; }
void resetIncrementalSearch() { m_incrementalStartPos = -1; }
void clearResults() { m_editor->highlightSearchResults(QByteArray()); }
QString currentFindString() const { return QString(); }
QString completedFindString() const { return QString(); }
int find(const QByteArray &pattern, int pos, QTextDocument::FindFlags findFlags) {
if (pattern.isEmpty()) {
m_editor->setCursorPosition(pos);
return pos;
}
int found = m_editor->find(pattern, pos, findFlags);
if (found < 0)
found = m_editor->find(pattern,
(findFlags & QTextDocument::FindBackward)?m_editor->data().size()-1:0,
findFlags);
return found;
}
bool findIncremental(const QString &txt, QTextDocument::FindFlags findFlags) {
QByteArray pattern = txt.toLatin1();
if (m_incrementalStartPos < 0)
m_incrementalStartPos = m_editor->selectionStart();
int pos = m_incrementalStartPos;
findFlags &= ~QTextDocument::FindBackward;
int found = find(pattern, pos, findFlags);
if (found >= 0)
m_editor->highlightSearchResults(pattern, findFlags);
else
m_editor->highlightSearchResults(QByteArray(), 0);
return found >= 0;
}
bool findStep(const QString &txt, QTextDocument::FindFlags findFlags) {
QByteArray pattern = txt.toLatin1();
bool wasReset = (m_incrementalStartPos < 0);
int pos = m_editor->cursorPosition();
if (findFlags & QTextDocument::FindBackward)
pos = m_editor->selectionStart()-1;
int found = find(pattern, pos, findFlags);
if (found)
m_incrementalStartPos = found;
if (wasReset && found >= 0)
m_editor->highlightSearchResults(pattern, findFlags);
return found >= 0;
}
bool replaceStep(const QString &, const QString &,
QTextDocument::FindFlags) { return false;}
int replaceAll(const QString &, const QString &,
QTextDocument::FindFlags) { return 0; }
private:
BinEditor *m_editor;
int m_incrementalStartPos;
};
class BinEditorFile : public Core::IFile
{
Q_OBJECT
public:
BinEditorFile(BinEditor *parent) :
Core::IFile(parent),
m_mimeType(QLatin1String(BINEditor::Constants::C_BINEDITOR_MIMETYPE))
{
m_editor = parent;
}
~BinEditorFile() {}
virtual QString mimeType() const { return m_mimeType; }
bool save(const QString &fileName = QString()) {
QFile file(fileName);
if (file.open(QIODevice::WriteOnly)) {
file.write(m_editor->data());
file.close();
m_editor->setModified(false);
m_editor->editorInterface()->setDisplayName(QFileInfo(fileName).fileName());
m_fileName = fileName;
emit changed();
return true;
}
return false;
}
bool open(const QString &fileName) {
QFile file(fileName);
if (file.open(QIODevice::ReadOnly)) {
m_fileName = fileName;
m_editor->setData(file.readAll());
m_editor->editorInterface()->setDisplayName(QFileInfo(fileName).fileName());
file.close();
return true;
}
return false;
}
void setFilename(const QString &filename) {
m_fileName = filename;
}
QString fileName() const {
return m_fileName;
}
QString defaultPath() const { return QString(); }
QString suggestedFileName() const { return QString(); }
QString fileFilter() const { return QString(); }
QString fileExtension() const { return QString(); }
bool isModified() const {
return m_editor->isModified();
}
bool isReadOnly() const {
const QFileInfo fi(m_fileName);
return !fi.isWritable();
}
bool isSaveAsAllowed() const { return true; }
void modified(ReloadBehavior *behavior) {
const QString fileName = m_fileName;
switch (*behavior) {
case Core::IFile::ReloadNone:
return;
case Core::IFile::ReloadAll:
open(fileName);
return;
case Core::IFile::ReloadPermissions:
emit changed();
return;
case Core::IFile::AskForReload:
break;
}
switch (Core::Utils::reloadPrompt(fileName, BinEditorPlugin::core()->mainWindow())) {
case Core::Utils::ReloadCurrent:
open(fileName);
break;
case Core::Utils::ReloadAll:
open(fileName);
*behavior = Core::IFile::ReloadAll;
break;
case Core::Utils::ReloadSkipCurrent:
break;
case Core::Utils::ReloadNone:
*behavior = Core::IFile::ReloadNone;
break;
}
}
private:
const QString m_mimeType;
BinEditor *m_editor;
QString m_fileName;
};
class BinEditorInterface : public Core::IEditor
{
Q_OBJECT
public:
BinEditorInterface(BinEditor *parent ) : Core::IEditor(parent) {
m_editor = parent;
m_file = new BinEditorFile(parent);
m_context << BinEditorPlugin::core()->uniqueIDManager()->
uniqueIdentifier(Core::Constants::K_DEFAULT_BINARY_EDITOR);
m_context << BinEditorPlugin::core()->uniqueIDManager()->uniqueIdentifier(Constants::C_BINEDITOR);
m_cursorPositionLabel = new Core::Utils::LineColumnLabel;
QHBoxLayout *l = new QHBoxLayout;
QWidget *w = new QWidget;
l->setMargin(0);
l->setContentsMargins(0, 0, 5, 0);
l->addStretch(1);
l->addWidget(m_cursorPositionLabel);
w->setLayout(l);
m_toolBar = new QToolBar;
m_toolBar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
m_toolBar->addWidget(w);
connect(m_editor, SIGNAL(cursorPositionChanged(int)), this, SLOT(updateCursorPosition(int)));
}
~BinEditorInterface() {}
QWidget *widget() { return m_editor; }
QList<int> context() const { return m_context; }
bool createNew(const QString & /* contents */ = QString()) {
m_editor->setData(QByteArray());
m_file->setFilename(QString());
return true;
}
bool open(const QString &fileName = QString()) {
return m_file->open(fileName);
}
Core::IFile *file() { return m_file; }
const char *kind() const { return Core::Constants::K_DEFAULT_BINARY_EDITOR; }
QString displayName() const { return m_displayName; }
void setDisplayName(const QString &title) { m_displayName = title; emit changed(); }
bool duplicateSupported() const { return false; }
IEditor *duplicate(QWidget */*parent*/) { return 0; }
QByteArray saveState() const { return QByteArray();} // TODO
bool restoreState(const QByteArray &/*state*/) {return false;} // TODO
QToolBar *toolBar() { return m_toolBar; }
signals:
void changed();
public slots:
void updateCursorPosition(int position) {
m_cursorPositionLabel->setText(m_editor->addressString((uint)position),
m_editor->addressString((uint)m_editor->data().size()));
}
private:
BinEditor *m_editor;
QString m_displayName;
BinEditorFile *m_file;
QList<int> m_context;
QToolBar *m_toolBar;
Core::Utils::LineColumnLabel *m_cursorPositionLabel;
};
///////////////////////////////// BinEditorFactory //////////////////////////////////
BinEditorFactory::BinEditorFactory(BinEditorPlugin *owner) :
m_kind(QLatin1String(Core::Constants::K_DEFAULT_BINARY_EDITOR)),
m_mimeTypes(QLatin1String(BINEditor::Constants::C_BINEDITOR_MIMETYPE)),
m_owner(owner)
{
}
QString BinEditorFactory::kind() const
{
return m_kind;
}
Core::IFile *BinEditorFactory::open(const QString &fileName)
{
Core::IEditor *iface = m_owner->m_core->editorManager()->openEditor(fileName, kind());
return iface ? iface->file() : 0;
}
Core::IEditor *BinEditorFactory::createEditor(QWidget *parent)
{
BinEditor *editor = new BinEditor(parent);
m_owner->initializeEditor(editor);
return editor->editorInterface();
}
QStringList BinEditorFactory::mimeTypes() const
{
return m_mimeTypes;
}
///////////////////////////////// BinEditorPlugin //////////////////////////////////
BinEditorPlugin *BinEditorPlugin::m_instance = 0;
BinEditorPlugin::BinEditorPlugin() :
m_core(0)
{
m_undoAction = m_redoAction = m_copyAction = m_selectAllAction = 0;
m_instance = this;
}
BinEditorPlugin::~BinEditorPlugin()
{
m_instance = 0;
}
BinEditorPlugin *BinEditorPlugin::instance()
{
return m_instance;
}
Core::ICore *BinEditorPlugin::core()
{
return m_instance->m_core;
}
QAction *BinEditorPlugin::registerNewAction(const QString &id, const QString &title)
{
QAction *result = new QAction(title, this);
m_core->actionManager()->registerAction(result, id, m_context);
return result;
}
QAction *BinEditorPlugin::registerNewAction(const QString &id,
QObject *receiver,
const char *slot,
const QString &title)
{
QAction *rc = registerNewAction(id, title);
if (!rc)
return 0;
connect(rc, SIGNAL(triggered()), receiver, slot);
return rc;
}
void BinEditorPlugin::initializeEditor(BinEditor *editor)
{
BinEditorInterface *editorInterface = new BinEditorInterface(editor);
QObject::connect(editor, SIGNAL(modificationChanged(bool)), editorInterface, SIGNAL(changed()));
editor->setEditorInterface(editorInterface);
m_context << BinEditorPlugin::core()->uniqueIDManager()->uniqueIdentifier(Constants::C_BINEDITOR);
if (!m_undoAction) {
m_undoAction = registerNewAction(QLatin1String(Core::Constants::UNDO),
this, SLOT(undoAction()),
tr("&Undo"));
m_redoAction = registerNewAction(QLatin1String(Core::Constants::REDO),
this, SLOT(redoAction()),
tr("&Redo"));
m_copyAction = registerNewAction(QLatin1String(Core::Constants::COPY),
this, SLOT(copyAction()));
m_selectAllAction = registerNewAction(QLatin1String(Core::Constants::SELECTALL),
this, SLOT(selectAllAction()));
}
// Font settings
TextEditor::TextEditorSettings *settings = TextEditor::TextEditorSettings::instance();
editor->setFontSettings(settings->fontSettings());
connect(settings, SIGNAL(fontSettingsChanged(TextEditor::FontSettings)),
editor, SLOT(setFontSettings(TextEditor::FontSettings)));
QObject::connect(editor, SIGNAL(undoAvailable(bool)), this, SLOT(updateActions()));
QObject::connect(editor, SIGNAL(redoAvailable(bool)), this, SLOT(updateActions()));
QObject::connect(editor, SIGNAL(copyAvailable(bool)), this, SLOT(updateActions()));
Aggregation::Aggregate *aggregate = new Aggregation::Aggregate;
BinEditorFind *binEditorFind = new BinEditorFind(editor);
aggregate->add(binEditorFind);
aggregate->add(editor);
}
bool BinEditorPlugin::initialize(const QStringList & /*arguments*/, QString *errorMessage)
{
m_core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>();
if (!m_core->mimeDatabase()->addMimeTypes(QLatin1String(":/bineditor/BinEditor.mimetypes.xml"), errorMessage))
return false;
connect(m_core, SIGNAL(contextAboutToChange(Core::IContext *)),
this, SLOT(updateCurrentEditor(Core::IContext *)));
addAutoReleasedObject(new BinEditorFactory(this));
return true;
}
void BinEditorPlugin::extensionsInitialized()
{
}
void BinEditorPlugin::updateCurrentEditor(Core::IContext *object)
{
do {
if (!object) {
if (!m_currentEditor)
return;
m_currentEditor = 0;
break;
}
BinEditor *editor = qobject_cast<BinEditor *>(object->widget());
if (!editor) {
if (!m_currentEditor)
return;
m_currentEditor = 0;
break;
}
if (editor == m_currentEditor)
return;
m_currentEditor = editor;
} while (false);
updateActions();
}
void BinEditorPlugin::updateActions()
{
bool hasEditor = (m_currentEditor != 0);
if (m_selectAllAction)
m_selectAllAction->setEnabled(hasEditor);
if (m_undoAction)
m_undoAction->setEnabled(m_currentEditor && m_currentEditor->isUndoAvailable());
if (m_redoAction)
m_redoAction->setEnabled(m_currentEditor && m_currentEditor->isRedoAvailable());
if (m_copyAction)
m_copyAction->setEnabled(m_currentEditor && m_currentEditor->hasSelection());
}
void BinEditorPlugin::undoAction()
{
if (m_currentEditor)
m_currentEditor->undo();
}
void BinEditorPlugin::redoAction()
{
if (m_currentEditor)
m_currentEditor->redo();
}
void BinEditorPlugin::copyAction()
{
if (m_currentEditor)
m_currentEditor->copy();
}
void BinEditorPlugin::selectAllAction()
{
if (m_currentEditor)
m_currentEditor->selectAll();
}
Q_EXPORT_PLUGIN(BinEditorPlugin)
#include "bineditorplugin.moc"

View File

@@ -0,0 +1,124 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef BINEDITORPLUGIN_H
#define BINEDITORPLUGIN_H
#include <QtCore/qplugin.h>
#include <QtCore/QPointer>
#include <QtCore/QStringList>
#include <QtGui/QAction>
#include <extensionsystem/iplugin.h>
#include <coreplugin/editormanager/ieditorfactory.h>
namespace Core {
class ICore;
class IWizard;
}
namespace BINEditor {
class BinEditor;
namespace Internal {
class BinEditorFactory;
class BinEditorPlugin : public ExtensionSystem::IPlugin
{
Q_OBJECT
public:
BinEditorPlugin();
~BinEditorPlugin();
static BinEditorPlugin *instance();
static Core::ICore *core();
bool initialize(const QStringList &arguments, QString *error_message = 0);
void extensionsInitialized();
// Connect editor to settings changed signals.
void initializeEditor(BinEditor *editor);
private slots:
void undoAction();
void redoAction();
void copyAction();
void selectAllAction();
void updateActions();
void updateCurrentEditor(Core::IContext *object);
private:
QList<int> m_context;
QAction *registerNewAction(const QString &id, const QString &title = QString());
QAction *registerNewAction(const QString &id, QObject *receiver, const char *slot,
const QString &title = QString());
QAction *m_undoAction;
QAction *m_redoAction;
QAction *m_copyAction;
QAction *m_selectAllAction;
friend class BinEditorFactory;
Core::IEditor *createEditor(QWidget *parent);
static BinEditorPlugin *m_instance;
Core::ICore *m_core;
typedef QList<Core::IWizard *> WizardList;
WizardList m_wizards;
BinEditorFactory *m_factory;
QPointer<BinEditor> m_currentEditor;
};
class BinEditorFactory : public Core::IEditorFactory
{
Q_OBJECT
public:
explicit BinEditorFactory(BinEditorPlugin *owner);
virtual QStringList mimeTypes() const;
Core::IEditor *createEditor(QWidget *parent);
QString kind() const;
Core::IFile *open(const QString &fileName);
private:
const QString m_kind;
const QStringList m_mimeTypes;
BinEditorPlugin *m_owner;
};
} // namespace Internal
} // namespace BINEditor
#endif // BINEDITORPLUGIN_H

View File

@@ -0,0 +1,12 @@
<plugin name="Bookmarks" version="0.9.1" compatVersion="0.9.1">
<vendor>Nokia Corporation</vendor>
<copyright>(C) 2008 Nokia Corporation</copyright>
<license>Nokia Technology Preview License Agreement</license>
<description>Bookmarks in text editors.</description>
<url>http://www.trolltech.com/</url>
<dependencyList>
<dependency name="TextEditor" version="0.9.1"/>
<dependency name="ProjectExplorer" version="0.9.1"/>
<dependency name="Core" version="0.9.1"/>
</dependencyList>
</plugin>

View File

@@ -0,0 +1,96 @@
/***************************************************************************
**
** 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 "bookmark.h"
#include "bookmarkmanager.h"
#include <QtCore/QDebug>
#include <QtGui/QTextBlock>
using namespace Bookmarks::Internal;
const QIcon Bookmark::m_bookmarkIcon = QIcon(":/bookmarks/images/bookmark.png");
Bookmark::Bookmark(const QString& fileName, int lineNumber, BookmarkManager *manager)
: BaseTextMark(fileName, lineNumber), m_manager(manager)
{
m_fileName = fileName;
m_fileInfo.setFile(fileName);
m_onlyFile = m_fileInfo.fileName();
m_path = m_fileInfo.path();
m_lineNumber= lineNumber;
}
QIcon Bookmark::icon() const
{
return m_bookmarkIcon;
}
void Bookmark::removedFromEditor()
{
m_manager->removeBookmark(this);
}
void Bookmark::updateLineNumber(int lineNumber)
{
if (lineNumber != m_lineNumber) {
m_lineNumber = lineNumber;
m_manager->updateBookmark(this);
}
}
void Bookmark::updateBlock(const QTextBlock &block)
{
if (m_lineText != block.text()) {
m_lineText = block.text();
m_manager->updateBookmark(this);
}
}
QString Bookmark::lineText() const
{
return m_lineText;
}
QString Bookmark::filePath() const
{
return m_fileName;
}
QString Bookmark::fileName() const
{
return m_onlyFile;
}
QString Bookmark::path() const
{
return m_path;
}

View File

@@ -0,0 +1,85 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef BOOKMARK_H
#define BOOKMARK_H
#include <texteditor/itexteditor.h>
#include <texteditor/basetextmark.h>
QT_BEGIN_NAMESPACE
class QTreeWidgetItem;
QT_END_NAMESPACE
#include <QtCore/QFileInfo>
namespace Bookmarks {
namespace Internal {
class BookmarkManager;
class Bookmark : public TextEditor::BaseTextMark
{
Q_OBJECT
public:
Bookmark(const QString& fileName, int lineNumber, BookmarkManager *manager);
QIcon icon() const;
void updateLineNumber(int lineNumber);
void updateBlock(const QTextBlock &block);
void removedFromEditor();
QString filePath() const;
QString fileName() const;
QString path() const;
QString lineText() const;
inline int lineNumber() const { return m_lineNumber; }
private:
static const QIcon m_bookmarkIcon;
BookmarkManager *m_manager;
int m_lineNumber;
QString m_name;
QString m_fileName;
QString m_onlyFile;
QString m_path;
QString m_lineText;
QFileInfo m_fileInfo;
};
} // namespace Internal
} // namespace Bookmarks
#endif // BOOKMARK_H

View File

@@ -0,0 +1,742 @@
/***************************************************************************
**
** 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 "bookmarkmanager.h"
#include "bookmark.h"
#include "bookmarksplugin.h"
#include "bookmarks_global.h"
#include <projectexplorer/ProjectExplorerInterfaces>
#include <coreplugin/icore.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/uniqueidmanager.h>
#include <texteditor/basetexteditor.h>
#include <QtGui/QAction>
#include <QtCore/QFileInfo>
#include <QtCore/QDebug>
#include <QtGui/QPainter>
#include <QtGui/QContextMenuEvent>
Q_DECLARE_METATYPE(Bookmarks::Internal::Bookmark*)
using namespace Bookmarks;
using namespace Bookmarks::Internal;
using namespace ProjectExplorer;
BookmarkDelegate::BookmarkDelegate(QObject *parent)
: QStyledItemDelegate(parent), m_normalPixmap(0), m_selectedPixmap(0)
{
}
BookmarkDelegate::~BookmarkDelegate()
{
delete m_normalPixmap;
delete m_selectedPixmap;
}
QSize BookmarkDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItemV4 opt = option;
initStyleOption(&opt, index);
QFontMetrics fm(option.font);
QSize s;
s.setWidth(option.rect.width());
s.setHeight(fm.height() * 2 + 10);
return s;
}
void BookmarkDelegate::generateGradientPixmap(int width, int height, QColor color, bool selected) const
{
QColor c = color;
c.setAlpha(0);
QPixmap *pixmap = new QPixmap(width+1, height);
pixmap->fill(c);
QPainter painter(pixmap);
painter.setPen(Qt::NoPen);
QLinearGradient lg;
lg.setCoordinateMode(QGradient::ObjectBoundingMode);
lg.setFinalStop(1,0);
lg.setColorAt(0, c);
lg.setColorAt(0.4, color);
painter.setBrush(lg);
painter.drawRect(0, 0, width+1, height);
if (selected)
m_selectedPixmap = pixmap;
else
m_normalPixmap = pixmap;
}
void BookmarkDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItemV4 opt = option;
initStyleOption(&opt, index);
painter->save();
QFontMetrics fm(opt.font);
static int lwidth = fm.width("8888") + 18;
QColor backgroundColor;
QColor textColor;
bool selected = opt.state & QStyle::State_Selected;
if (selected) {
painter->setBrush(opt.palette.highlight().color());
backgroundColor = opt.palette.highlight().color();
if (!m_selectedPixmap)
generateGradientPixmap(lwidth, fm.height()+1, backgroundColor, selected);
} else {
painter->setBrush(opt.palette.background().color());
backgroundColor = opt.palette.background().color();
if (!m_normalPixmap)
generateGradientPixmap(lwidth, fm.height(), backgroundColor, selected);
}
painter->setPen(Qt::NoPen);
painter->drawRect(opt.rect);
// Set Text Color
if (opt.state & QStyle::State_Selected)
textColor = opt.palette.highlightedText().color();
else
textColor = opt.palette.text().color();
painter->setPen(textColor);
// TopLeft
QString topLeft = index.data(BookmarkManager::Filename ).toString();
painter->drawText(6, 2 + opt.rect.top() + fm.ascent(), topLeft);
QString topRight = index.data(BookmarkManager::LineNumber).toString();
// Check wheter we need to be fancy and paint some background
int fwidth = fm.width(topLeft);
if (fwidth + lwidth > opt.rect.width()) {
int left = opt.rect.right() - lwidth;
painter->drawPixmap(left, opt.rect.top(), selected? *m_selectedPixmap : *m_normalPixmap);
}
// topRight
painter->drawText(opt.rect.right() - fm.width(topRight) - 6 , 2 + opt.rect.top() + fm.ascent(), topRight);
// Directory
QColor mix;
mix.setRgbF(0.7 * textColor.redF() + 0.3 * backgroundColor.redF(),
0.7 * textColor.greenF() + 0.3 * backgroundColor.greenF(),
0.7 * textColor.blueF() + 0.3 * backgroundColor.blueF());
painter->setPen(mix);
//
// QString directory = index.data(BookmarkManager::Directory).toString();
// int availableSpace = opt.rect.width() - 12;
// if (fm.width(directory) > availableSpace) {
// // We need a shorter directory
// availableSpace -= fm.width("...");
//
// int pos = directory.size();
// int idx;
// forever {
// idx = directory.lastIndexOf("/", pos-1);
// if(idx == -1) {
// // Can't happen, this means the string did fit after all?
// break;
// }
// int width = fm.width(directory.mid(idx, pos-idx));
// if (width > availableSpace) {
// directory = "..." + directory.mid(pos);
// break;
// } else {
// pos = idx;
// availableSpace -= width;
// }
// }
// }
//
// painter->drawText(3, opt.rect.top() + fm.ascent() + fm.height() + 6, directory);
QString lineText = index.data(BookmarkManager::LineText).toString().trimmed();
painter->drawText(6, opt.rect.top() + fm.ascent() + fm.height() + 6, lineText);
// Separator lines
painter->setPen(QColor::fromRgb(150,150,150));
painter->drawLine(0, opt.rect.bottom(), opt.rect.right(), opt.rect.bottom());
painter->restore();
}
BookmarkView::BookmarkView(QWidget *parent)
: QListView(parent)
{
setWindowTitle(tr("Bookmarks"));
setWindowIcon(QIcon(":/bookmarks/images/bookmark.png"));
connect(this, SIGNAL(clicked(const QModelIndex &)),
this, SLOT(gotoBookmark(const QModelIndex &)));
m_bookmarkContext = new BookmarkContext(this);
Core::ICore *core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>();
core->addContextObject(m_bookmarkContext);
setItemDelegate(new BookmarkDelegate(this));
setFrameStyle(QFrame::NoFrame);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setFocusPolicy(Qt::NoFocus);
}
BookmarkView::~BookmarkView()
{
Core::ICore *core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>();
core->removeContextObject(m_bookmarkContext);
}
void BookmarkView::contextMenuEvent(QContextMenuEvent *event)
{
QMenu menu;
QAction *remove = menu.addAction("&Remove Bookmark");
QAction *removeAll = menu.addAction("Remove all Bookmarks");
m_contextMenuIndex = indexAt(event->pos());
if (!m_contextMenuIndex.isValid())
remove->setEnabled(false);
if (model()->rowCount() == 0)
removeAll->setEnabled(false);
connect(remove, SIGNAL(triggered()),
this, SLOT(removeFromContextMenu()));
connect(removeAll, SIGNAL(triggered()),
this, SLOT(removeAll()));
menu.exec(mapToGlobal(event->pos()));
}
void BookmarkView::removeFromContextMenu()
{
removeBookmark(m_contextMenuIndex);
}
void BookmarkView::removeBookmark(const QModelIndex& index)
{
BookmarkManager *manager = static_cast<BookmarkManager *>(model());
Bookmark *bm = manager->bookmarkForIndex(index);
manager->removeBookmark(bm);
}
// The perforcemance of this function could be greatly improved.
//
void BookmarkView::removeAll()
{
BookmarkManager *manager = static_cast<BookmarkManager *>(model());
while (manager->rowCount()) {
QModelIndex index = manager->index(0, 0);
removeBookmark(index);
}
}
void BookmarkView::setModel(QAbstractItemModel *model)
{
BookmarkManager *manager = qobject_cast<BookmarkManager *>(model);
Q_ASSERT(manager);
QListView::setModel(model);
setSelectionModel(manager->selectionModel());
setSelectionMode(QAbstractItemView::SingleSelection);
setSelectionBehavior(QAbstractItemView::SelectRows);
}
void BookmarkView::gotoBookmark(const QModelIndex &index)
{
static_cast<BookmarkManager *>(model())->gotoBookmark(index);
}
////
// BookmarkContext
////
BookmarkContext::BookmarkContext(BookmarkView *widget)
: m_bookmarkView(widget)
{
Core::ICore *core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>();
m_context << core->uniqueIDManager()->uniqueIdentifier(Constants::BOOKMARKS_CONTEXT);
}
QList<int> BookmarkContext::context() const
{
return m_context;
}
QWidget *BookmarkContext::widget()
{
return m_bookmarkView;
}
////
// BookmarkManager
////
BookmarkManager::BookmarkManager() :
m_core(BookmarksPlugin::core()),
m_bookmarkIcon(QIcon(QLatin1String(":/bookmarks/images/bookmark.png")))
{
m_selectionModel = new QItemSelectionModel(this, this);
connect(m_core, SIGNAL(contextChanged(Core::IContext*)),
this, SLOT(updateActionStatus()));
ExtensionSystem::PluginManager *pm = m_core->pluginManager();
ProjectExplorerPlugin *projectExplorer = pm->getObject<ProjectExplorerPlugin>();
connect(projectExplorer->session(), SIGNAL(sessionLoaded()),
this, SLOT(loadBookmarks()));
updateActionStatus();
}
BookmarkManager::~BookmarkManager()
{
DirectoryFileBookmarksMap::iterator it, end;
end = m_bookmarksMap.end();
for (it = m_bookmarksMap.begin(); it != end; ++it) {
FileNameBookmarksMap *bookmarks = it.value();
qDeleteAll(bookmarks->values());
delete bookmarks;
}
}
QItemSelectionModel *BookmarkManager::selectionModel() const
{
return m_selectionModel;
}
QModelIndex BookmarkManager::index(int row, int column, const QModelIndex &parent) const
{
if (parent.isValid())
return QModelIndex();
else
return createIndex(row, column, 0);
}
QModelIndex BookmarkManager::parent(const QModelIndex &) const
{
return QModelIndex();
}
int BookmarkManager::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
else
return m_bookmarksList.count();
}
int BookmarkManager::columnCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return 3;
}
QVariant BookmarkManager::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.column() !=0 || index.row() < 0 || index.row() >= m_bookmarksList.count())
return QVariant();
if (role == BookmarkManager::Filename)
return m_bookmarksList.at(index.row())->fileName();
else if (role == BookmarkManager::LineNumber)
return m_bookmarksList.at(index.row())->lineNumber();
else if (role == BookmarkManager::Directory)
return m_bookmarksList.at(index.row())->path();
else if (role == BookmarkManager::LineText)
return m_bookmarksList.at(index.row())->lineText();
else if (role == Qt::ToolTipRole)
return m_bookmarksList.at(index.row())->filePath();
return QVariant();
}
void BookmarkManager::toggleBookmark()
{
TextEditor::ITextEditor *editor = currentTextEditor();
if (!editor)
return;
const QFileInfo fi(editor->file()->fileName());
const int editorLine = editor->currentLine();
// Remove any existing bookmark on this line
if (Bookmark *mark = findBookmark(fi.path(), fi.fileName(), editorLine)) {
// TODO check if the bookmark is really on the same markable Interface
removeBookmark(mark);
return;
}
// Add a new bookmark if no bookmark existed on this line
Bookmark *bookmark = new Bookmark(fi.filePath(), editorLine, this);
addBookmark(bookmark);
}
void BookmarkManager::updateBookmark(Bookmark *bookmark)
{
int idx = m_bookmarksList.indexOf(bookmark);
emit dataChanged(index(idx, 0, QModelIndex()), index(idx, 2, QModelIndex()));
saveBookmarks();
}
void BookmarkManager::removeBookmark(Bookmark *bookmark)
{
const QFileInfo fi(bookmark->filePath() );
FileNameBookmarksMap *files = m_bookmarksMap.value(fi.path());
FileNameBookmarksMap::iterator i = files->begin();
while (i != files->end()) {
if (i.value() == bookmark) {
files->erase(i);
delete bookmark;
break;
}
++i;
}
if (files->count() <= 0) {
m_bookmarksMap.remove(fi.path());
delete files;
}
int idx = m_bookmarksList.indexOf(bookmark);
beginRemoveRows(QModelIndex(), idx, idx);
m_bookmarksList.removeAt(idx);
endRemoveRows();
if (selectionModel()->currentIndex().isValid())
selectionModel()->setCurrentIndex(selectionModel()->currentIndex(), QItemSelectionModel::Select | QItemSelectionModel::Clear);
updateActionStatus();
saveBookmarks();
}
Bookmark *BookmarkManager::bookmarkForIndex(QModelIndex index)
{
if (!index.isValid() || index.row() >= m_bookmarksList.size())
return 0;
return m_bookmarksList.at(index.row());
}
void BookmarkManager::gotoBookmark(const QModelIndex &idx)
{
gotoBookmark(m_bookmarksList.at(idx.row()));
}
void BookmarkManager::gotoBookmark(Bookmark* bookmark)
{
TextEditor::BaseTextEditor::openEditorAt(bookmark->filePath(),
bookmark->lineNumber());
}
void BookmarkManager::nextInDocument()
{
documentPrevNext(true);
}
void BookmarkManager::prevInDocument()
{
documentPrevNext(false);
}
void BookmarkManager::documentPrevNext(bool next)
{
TextEditor::ITextEditor *editor = currentTextEditor();
int editorLine = editor->currentLine();
QFileInfo fi(editor->file()->fileName());
if (!m_bookmarksMap.contains(fi.path()))
return;
int firstLine = -1;
int lastLine = -1;
int prevLine = -1;
int nextLine = -1;
const QList<Bookmark*> marks = m_bookmarksMap.value(fi.path())->values(fi.fileName());
for (int i = 0; i < marks.count(); ++i) {
int markLine = marks.at(i)->lineNumber();
if (firstLine == -1 || firstLine > markLine)
firstLine = markLine;
if (lastLine < markLine)
lastLine = markLine;
if (markLine < editorLine && prevLine < markLine)
prevLine = markLine;
if (markLine > editorLine &&
(nextLine == -1 || nextLine > markLine))
nextLine = markLine;
}
m_core->editorManager()->addCurrentPositionToNavigationHistory(true);
if (next) {
if (nextLine == -1)
editor->gotoLine(firstLine);
else
editor->gotoLine(nextLine);
} else {
if (prevLine == -1)
editor->gotoLine(lastLine);
else
editor->gotoLine(prevLine);
}
m_core->editorManager()->addCurrentPositionToNavigationHistory();
}
void BookmarkManager::next()
{
QModelIndex current = selectionModel()->currentIndex();
if (!current.isValid())
return;
int row = current.row() + 1;
if (row == m_bookmarksList.size())
row = 0;
QModelIndex newIndex = current.sibling(row, current.column());
selectionModel()->setCurrentIndex(newIndex, QItemSelectionModel::Select | QItemSelectionModel::Clear);
gotoBookmark(newIndex);
}
void BookmarkManager::prev()
{
QModelIndex current = selectionModel()->currentIndex();
if (!current.isValid())
return;
int row = current.row();
if (row == 0)
row = m_bookmarksList.size();
--row;
QModelIndex newIndex = current.sibling(row, current.column());
selectionModel()->setCurrentIndex(newIndex, QItemSelectionModel::Select | QItemSelectionModel::Clear);
gotoBookmark(newIndex);
}
TextEditor::ITextEditor *BookmarkManager::currentTextEditor() const
{
Core::IEditor *currEditor = m_core->editorManager()->currentEditor();
if (!currEditor)
return 0;
return qobject_cast<TextEditor::ITextEditor *>(currEditor);
}
/* Returns the current session. */
SessionManager* BookmarkManager::sessionManager() const
{
ExtensionSystem::PluginManager *pm = m_core->pluginManager();
ProjectExplorerPlugin *pe = pm->getObject<ProjectExplorerPlugin>();
return pe->session();
}
BookmarkManager::State BookmarkManager::state() const
{
if (m_bookmarksMap.empty())
return NoBookMarks;
TextEditor::ITextEditor *editor = currentTextEditor();
if (!editor)
return HasBookMarks;
const QFileInfo fi(editor->file()->fileName());
const DirectoryFileBookmarksMap::const_iterator dit = m_bookmarksMap.constFind(fi.path());
if (dit == m_bookmarksMap.constEnd())
return HasBookMarks;
return HasBookmarksInDocument;
}
void BookmarkManager::updateActionStatus()
{
emit updateActions(state());
}
void BookmarkManager::moveUp()
{
QModelIndex current = selectionModel()->currentIndex();
int row = current.row();
if (row == 0)
row = m_bookmarksList.size();
--row;
// swap current.row() and row
Bookmark *b = m_bookmarksList.at(row);
m_bookmarksList[row] = m_bookmarksList.at(current.row());
m_bookmarksList[current.row()] = b;
QModelIndex topLeft = current.sibling(row, 0);
QModelIndex bottomRight = current.sibling(current.row(), 2);
emit dataChanged(topLeft, bottomRight);
selectionModel()->setCurrentIndex(current.sibling(row, 0), QItemSelectionModel::Select | QItemSelectionModel::Clear);
}
void BookmarkManager::moveDown()
{
QModelIndex current = selectionModel()->currentIndex();
int row = current.row();
++row;
if (row == m_bookmarksList.size())
row = 0;
// swap current.row() and row
Bookmark *b = m_bookmarksList.at(row);
m_bookmarksList[row] = m_bookmarksList.at(current.row());
m_bookmarksList[current.row()] = b;
QModelIndex topLeft = current.sibling(current.row(), 0);
QModelIndex bottomRight = current.sibling(row, 2);
emit dataChanged(topLeft, bottomRight);
selectionModel()->setCurrentIndex(current.sibling(row, 0), QItemSelectionModel::Select | QItemSelectionModel::Clear);
}
/* Returns the bookmark at the given file and line number, or 0 if no such bookmark exists. */
Bookmark* BookmarkManager::findBookmark(const QString &path, const QString &fileName, int lineNumber)
{
if (m_bookmarksMap.contains(path)) {
foreach (Bookmark *bookmark, m_bookmarksMap.value(path)->values(fileName)) {
if (bookmark->lineNumber() == lineNumber)
return bookmark;
}
}
return 0;
}
/* Adds a bookmark to the internal data structures. The 'userset' parameter
* determines whether action status should be updated and whether the bookmarks
* should be saved to the session settings.
*/
void BookmarkManager::addBookmark(Bookmark *bookmark, bool userset)
{
beginInsertRows(QModelIndex(), m_bookmarksList.size(), m_bookmarksList.size());
const QFileInfo fi(bookmark->filePath());
const QString &path = fi.path();
if (!m_bookmarksMap.contains(path))
m_bookmarksMap.insert(path, new FileNameBookmarksMap());
m_bookmarksMap.value(path)->insert(fi.fileName(), bookmark);
m_bookmarksList.append(bookmark);
endInsertRows();
if (userset) {
updateActionStatus();
saveBookmarks();
}
selectionModel()->setCurrentIndex(index(m_bookmarksList.size()-1 , 0, QModelIndex()), QItemSelectionModel::Select | QItemSelectionModel::Clear);
}
/* Adds a new bookmark based on information parsed from the string. */
void BookmarkManager::addBookmark(const QString &s)
{
int index2 = s.lastIndexOf(':');
int index1 = s.indexOf(':');
if (index2 != -1 || index1 != -1) {
const QString &filePath = s.mid(index1+1, index2-index1-1);
const int lineNumber = s.mid(index2 + 1).toInt();
const QFileInfo fi(filePath);
if (!filePath.isEmpty() && !findBookmark(fi.path(), fi.fileName(), lineNumber)) {
Bookmark *b = new Bookmark(filePath, lineNumber, this);
addBookmark(b, false);
}
} else {
qDebug() << "BookmarkManager::addBookmark() Invalid bookmark string:" << s;
}
}
/* Puts the bookmark in a string for storing it in the settings. */
QString BookmarkManager::bookmarkToString(const Bookmark *b)
{
const QLatin1Char colon(':');
// Empty string was the name of the bookmark, which now is always ""
return QLatin1String("") + colon + b->filePath() + colon + QString::number(b->lineNumber());
}
/* Saves the bookmarks to the session settings. */
void BookmarkManager::saveBookmarks()
{
SessionManager *s = sessionManager();
if (!s)
return;
QStringList list;
foreach (const FileNameBookmarksMap *bookmarksMap, m_bookmarksMap)
foreach (const Bookmark *bookmark, *bookmarksMap)
list << bookmarkToString(bookmark);
s->setValue("Bookmarks", list);
}
/* Loads the bookmarks from the session settings. */
void BookmarkManager::loadBookmarks()
{
SessionManager *s = sessionManager();
if (!s)
return;
const QStringList &list = s->value("Bookmarks").toStringList();
foreach (const QString &bookmarkString, list)
addBookmark(bookmarkString);
updateActionStatus();
}
// BookmarkViewFactory
BookmarkViewFactory::BookmarkViewFactory(BookmarkManager *bm)
: m_manager(bm)
{
}
QString BookmarkViewFactory::displayName()
{
return "Bookmarks";
}
QKeySequence BookmarkViewFactory::activationSequence()
{
return QKeySequence(Qt::ALT + Qt::Key_M);
}
Core::NavigationView BookmarkViewFactory::createWidget()
{
BookmarkView *bookmarkView = new BookmarkView();
bookmarkView->setModel(m_manager);
Core::NavigationView view;
view.widget = bookmarkView;
return view;
}

View File

@@ -0,0 +1,193 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef BOOKMARKMANAGER_H
#define BOOKMARKMANAGER_H
#include <QtCore/QAbstractItemModel>
#include <QtGui/QListView>
#include <QtCore/QList>
#include <QtGui/QPixmap>
#include <QtGui/QStyledItemDelegate>
#include <coreplugin/icontext.h>
#include <coreplugin/inavigationwidgetfactory.h>
namespace ProjectExplorer {
class SessionManager;
}
namespace Core {
class ICore;
class IEditor;
}
namespace TextEditor {
class ITextEditor;
}
namespace Bookmarks {
namespace Internal {
class Bookmark;
class BookmarksPlugin;
class BookmarkContext;
class BookmarkManager : public QAbstractItemModel
{
Q_OBJECT
public:
BookmarkManager();
~BookmarkManager();
void updateBookmark(Bookmark *bookmark);
void removeBookmark(Bookmark *bookmark); // Does not remove the mark
Bookmark *bookmarkForIndex(QModelIndex index);
enum State { NoBookMarks, HasBookMarks, HasBookmarksInDocument };
State state() const;
// Model stuff
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &child) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
void gotoBookmark(const QModelIndex &);
// this QItemSelectionModel is shared by all views
QItemSelectionModel *selectionModel() const;
enum Roles {Filename = Qt::UserRole, LineNumber = Qt::UserRole + 1, Directory = Qt::UserRole + 2, LineText = Qt::UserRole + 3};
public slots:
void toggleBookmark();
void nextInDocument();
void prevInDocument();
void next();
void prev();
void moveUp();
void moveDown();
signals:
void updateActions(int state);
void currentIndexChanged(const QModelIndex &);
private slots:
void updateActionStatus();
void gotoBookmark(Bookmark *bookmark);
void loadBookmarks();
private:
TextEditor::ITextEditor *currentTextEditor() const;
ProjectExplorer::SessionManager* sessionManager() const;
void documentPrevNext(bool next);
Bookmark* findBookmark(const QString &path, const QString &fileName, int lineNumber);
void addBookmark(Bookmark *bookmark, bool userset = true);
void addBookmark(const QString &s);
static QString bookmarkToString(const Bookmark *b);
void saveBookmarks();
typedef QMultiMap<QString, Bookmark*> FileNameBookmarksMap;
typedef QMap<QString, FileNameBookmarksMap*> DirectoryFileBookmarksMap;
DirectoryFileBookmarksMap m_bookmarksMap;
Core::ICore *m_core;
QIcon m_bookmarkIcon;
QList<Bookmark *> m_bookmarksList;
QItemSelectionModel *m_selectionModel;
};
class BookmarkView : public QListView {
Q_OBJECT
public:
BookmarkView(QWidget *parent = 0);
~BookmarkView();
void setModel(QAbstractItemModel * model);
public slots:
void gotoBookmark(const QModelIndex &index);
protected slots:
void removeFromContextMenu();
void removeAll();
protected:
void contextMenuEvent(QContextMenuEvent *event);
void removeBookmark(const QModelIndex& index);
private:
BookmarkContext *m_bookmarkContext;
QModelIndex m_contextMenuIndex;
};
class BookmarkContext : public Core::IContext
{
public:
BookmarkContext(BookmarkView *widget);
virtual QList<int> context() const;
virtual QWidget *widget();
private:
BookmarkView *m_bookmarkView;
QList<int> m_context;
};
class BookmarkViewFactory : public Core::INavigationWidgetFactory
{
public:
BookmarkViewFactory(BookmarkManager *bm);
virtual QString displayName();
virtual QKeySequence activationSequence();
virtual Core::NavigationView createWidget();
private:
BookmarkManager *m_manager;
};
class BookmarkDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
BookmarkDelegate(QObject * parent = 0);
~BookmarkDelegate();
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
private:
void generateGradientPixmap(int width, int height, QColor color, bool selected) const;
mutable QPixmap *m_normalPixmap;
mutable QPixmap *m_selectedPixmap;
};
} // namespace Internal
} // namespace Bookmarks
#endif // BOOKMARKMANAGER_H

View File

@@ -0,0 +1,18 @@
TEMPLATE = lib
TARGET = Bookmarks
include(../../qworkbenchplugin.pri)
include(../../plugins/projectexplorer/projectexplorer.pri)
include(../../plugins/coreplugin/coreplugin.pri)
include(../../plugins/texteditor/texteditor.pri)
HEADERS += bookmarksplugin.h \
bookmark.h \
bookmarkmanager.h \
bookmarks_global.h
SOURCES += bookmarksplugin.cpp \
bookmark.cpp \
bookmarkmanager.cpp
RESOURCES += bookmarks.qrc

View File

@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/bookmarks" >
<file>images/bookmark.png</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,56 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef BOOKMARKS_GLOBAL_H
#define BOOKMARKS_GLOBAL_H
namespace Bookmarks {
namespace Constants {
const char * const BOOKMARKS_TOGGLE_ACTION = "Bookmarks.Toggle";
const char * const BOOKMARKS_MOVEUP_ACTION = "Bookmarks.MoveUp";
const char * const BOOKMARKS_MOVEDOWN_ACTION = "Bookmarks.MoveDown";
const char * const BOOKMARKS_PREV_ACTION = "Bookmarks.Previous";
const char * const BOOKMARKS_NEXT_ACTION = "Bookmarks.Next";
const char * const BOOKMARKS_PREVDIR_ACTION = "Bookmarks.Previous.Directory";
const char * const BOOKMARKS_NEXTDIR_ACTION = "Bookmarks.Next.Directory";
const char * const BOOKMARKS_PREVDOC_ACTION = "Bookmarks.Previous.Document";
const char * const BOOKMARKS_NEXTDOC_ACTION = "Bookmarks.Next.Document";
const char * const BOOKMARKS_MENU = "Bookmarks.Menu";
const char * const BOOKMARKS_CONTEXT = "Bookmarks";
} //namespace Constants
} //namespace Bookmarks
#endif //BOOKMARKS_GLOBAL_H

View File

@@ -0,0 +1,185 @@
/***************************************************************************
**
** 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 "bookmarksplugin.h"
#include "bookmarkmanager.h"
#include "bookmarks_global.h"
#include <QtCore/qplugin.h>
#include <QtGui/QMenu>
#include <QDebug>
#include <texteditor/texteditorconstants.h>
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/uniqueidmanager.h>
#include <coreplugin/actionmanager/actionmanagerinterface.h>
using namespace Bookmarks::Constants;
using namespace Bookmarks::Internal;
BookmarksPlugin *BookmarksPlugin::m_instance = 0;
BookmarksPlugin::BookmarksPlugin():
m_bookmarkManager(0),
m_core(0)
{
m_instance = this;
}
void BookmarksPlugin::extensionsInitialized()
{
}
bool BookmarksPlugin::initialize(const QStringList & /*arguments*/, QString *)
{
m_core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>();
Core::ActionManagerInterface *am = m_core->actionManager();
QList<int> context = QList<int>() << m_core->uniqueIDManager()->
uniqueIdentifier(Constants::BOOKMARKS_CONTEXT);
QList<int> textcontext, globalcontext;
textcontext << m_core->uniqueIDManager()->
uniqueIdentifier(TextEditor::Constants::C_TEXTEDITOR);
globalcontext << Core::Constants::C_GLOBAL_ID;
Core::IActionContainer *mtools =
am->actionContainer(Core::Constants::M_TOOLS);
Core::IActionContainer *mbm =
am->createMenu(QLatin1String(BOOKMARKS_MENU));
mbm->menu()->setTitle(tr("&Bookmarks"));
mtools->addMenu(mbm);
//Toggle
m_toggleAction = new QAction(tr("Toggle Bookmark"), this);
Core::ICommand *cmd =
am->registerAction(m_toggleAction, BOOKMARKS_TOGGLE_ACTION, textcontext);
#ifndef Q_OS_MAC
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+M")));
#else
cmd->setDefaultKeySequence(QKeySequence(tr("Meta+M")));
#endif
mbm->addAction(cmd);
QAction *sep = new QAction(this);
sep->setSeparator(true);
cmd = am->registerAction(sep, QLatin1String("Bookmarks.Sep.Toggle"), textcontext);
mbm->addAction(cmd);
// Move Up
m_moveUpAction = new QAction(tr("Move Up"), this);
cmd = am->registerAction(m_moveUpAction, BOOKMARKS_MOVEUP_ACTION, context);
mbm->addAction(cmd);
// Move Down
m_moveDownAction = new QAction(tr("Move Down"), this);
cmd = am->registerAction(m_moveDownAction, BOOKMARKS_MOVEDOWN_ACTION, context);
mbm->addAction(cmd);
sep = new QAction(this);
sep->setSeparator(true);
cmd = am->registerAction(sep, QLatin1String("Bookmarks.Sep.Navigation"), context);
mbm->addAction(cmd);
//Previous
m_prevAction = new QAction(tr("Previous Bookmark"), this);
cmd = am->registerAction(m_prevAction, BOOKMARKS_PREV_ACTION, globalcontext);
#ifndef Q_OS_MAC
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+,")));
#else
cmd->setDefaultKeySequence(QKeySequence(tr("Meta+,")));
#endif
mbm->addAction(cmd);
//Next
m_nextAction = new QAction(tr("Next Bookmark"), this);
cmd = am->registerAction(m_nextAction, BOOKMARKS_NEXT_ACTION, globalcontext);
#ifndef Q_OS_MAC
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+.")));
#else
cmd->setDefaultKeySequence(QKeySequence(tr("Meta+.")));
#endif
mbm->addAction(cmd);
sep = new QAction(this);
sep->setSeparator(true);
cmd = am->registerAction(sep, QLatin1String("Bookmarks.Sep.DirNavigation"), globalcontext);
mbm->addAction(cmd);
//Previous Doc
m_docPrevAction = new QAction(tr("Previous Bookmark In Document"), this);
cmd = am->registerAction(m_docPrevAction, BOOKMARKS_PREVDOC_ACTION, globalcontext);
mbm->addAction(cmd);
//Next Doc
m_docNextAction = new QAction(tr("Next Bookmark In Document"), this);
cmd = am->registerAction(m_docNextAction, BOOKMARKS_NEXTDOC_ACTION, globalcontext);
mbm->addAction(cmd);
m_bookmarkManager = new BookmarkManager;
connect(m_toggleAction, SIGNAL(triggered()), m_bookmarkManager, SLOT(toggleBookmark()));
connect(m_prevAction, SIGNAL(triggered()), m_bookmarkManager, SLOT(prev()));
connect(m_nextAction, SIGNAL(triggered()), m_bookmarkManager, SLOT(next()));
connect(m_docPrevAction, SIGNAL(triggered()), m_bookmarkManager, SLOT(prevInDocument()));
connect(m_docNextAction, SIGNAL(triggered()), m_bookmarkManager, SLOT(nextInDocument()));
connect(m_moveUpAction, SIGNAL(triggered()), m_bookmarkManager, SLOT(moveUp()));
connect(m_moveDownAction, SIGNAL(triggered()), m_bookmarkManager, SLOT(moveDown()));
connect(m_bookmarkManager, SIGNAL(updateActions(int)), this, SLOT(updateActions(int)));
updateActions(m_bookmarkManager->state());
addAutoReleasedObject(new BookmarkViewFactory(m_bookmarkManager));
return true;
}
BookmarksPlugin::~BookmarksPlugin()
{
delete m_bookmarkManager;
}
void BookmarksPlugin::updateActions(int state)
{
const bool hasbm = state >= BookmarkManager::HasBookMarks;
const bool hasdocbm = state == BookmarkManager::HasBookmarksInDocument;
m_toggleAction->setEnabled(true);
m_prevAction->setEnabled(hasbm);
m_nextAction->setEnabled(hasbm);
m_docPrevAction->setEnabled(hasdocbm);
m_docNextAction->setEnabled(hasdocbm);
m_moveUpAction->setEnabled(hasbm);
m_moveDownAction->setEnabled(hasbm);
}
Q_EXPORT_PLUGIN(BookmarksPlugin)

View File

@@ -0,0 +1,86 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef BOOKMARKS_H
#define BOOKMARKS_H
#include <QtCore/QObject>
#include <QtCore/QMultiMap>
#include <extensionsystem/iplugin.h>
QT_FORWARD_DECLARE_CLASS(QAction)
namespace Core {
class ICore;
}
namespace Bookmarks {
namespace Internal {
class BookmarkManager;
class BookmarksPlugin : public ExtensionSystem::IPlugin
{
Q_OBJECT
public:
BookmarksPlugin();
~BookmarksPlugin();
static BookmarksPlugin *instance() { return m_instance; }
static Core::ICore *core() { return m_instance->m_core; }
bool initialize(const QStringList &arguments, QString *error_message);
void extensionsInitialized();
public slots:
void updateActions(int stateMask);
private:
static BookmarksPlugin *m_instance;
BookmarkManager *m_bookmarkManager;
Core::ICore *m_core;
QAction *m_toggleAction;
QAction *m_prevAction;
QAction *m_nextAction;
QAction *m_docPrevAction;
QAction *m_docNextAction;
QAction *m_moveUpAction;
QAction *m_moveDownAction;
};
} // namespace Internal
} // namespace Bookmarks
#endif // BOOKMARKS_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 913 B

View File

@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
<mime-type type="text/x-cmake">
<sub-class-of type="text/plain"/>
<comment>CMake Project file</comment>
<glob pattern="CMakeLists.txt"/>
</mime-type>
</mime-info>

View File

@@ -0,0 +1,14 @@
<plugin name="CMakeProjectManager" version="0.9.1" compatVersion="0.9.1">
<vendor>Nokia Corporation</vendor>
<copyright>(C) 2008 Nokia Corporation</copyright>
<license>### TODO</license>
<description>CMake support</description>
<url>http://www.trolltech.com/</url>
<dependencyList>
<dependency name="TextEditor" version="0.9.1"/>
<dependency name="ProjectExplorer" version="0.9.1"/>
<dependency name="CppTools" version="0.9.1"/>
<dependency name="CppEditor" version="0.9.1"/>
<dependency name="Help" version="0.9.1"/>
</dependencyList>
</plugin>

View File

@@ -0,0 +1,441 @@
/***************************************************************************
**
** 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 "cmakeproject.h"
#include "cmakeprojectconstants.h"
#include "cmakeprojectnodes.h"
#include <extensionsystem/pluginmanager.h>
#include <cpptools/cppmodelmanagerinterface.h>
#include <QtCore/QDebug>
using namespace CMakeProjectManager;
using namespace CMakeProjectManager::Internal;
CMakeProject::CMakeProject(CMakeManager *manager, const QString &fileName)
: m_manager(manager), m_fileName(fileName), m_rootNode(new CMakeProjectNode(m_fileName))
{
//TODO
m_file = new CMakeFile(this, fileName);
QDir dir = QFileInfo(m_fileName).absoluteDir();
QString cbpFile = findCbpFile(dir);
if (cbpFile.isEmpty())
cbpFile = createCbpFile(dir);
QList<ProjectExplorer::FileNode *> fileList;
QStringList includeFiles;
if (parseCbpFile(cbpFile, fileList, includeFiles)) {
buildTree(m_rootNode, fileList);
foreach(ProjectExplorer::FileNode *fn, fileList)
m_files.append(fn->path());
m_files.sort();
includeFiles.sort();
includeFiles.removeDuplicates();
CppTools::CppModelManagerInterface *modelmanager = ExtensionSystem::PluginManager::instance()->getObject<CppTools::CppModelManagerInterface>();
if (modelmanager) {
CppTools::CppModelManagerInterface::ProjectInfo *pinfo = modelmanager->projectInfo(this);
pinfo->includePaths = includeFiles;
pinfo->sourceFiles = m_files; // TODO we only want C++ files, not all other stuff that might be in the project
// TODO defines
}
} else {
// TODO report error
}
}
CMakeProject::~CMakeProject()
{
delete m_rootNode;
}
QString CMakeProject::findCbpFile(const QDir &directory)
{
// Find the cbp file
// TODO the cbp file is named like the project() command in the CMakeList.txt file
// so this method below could find the wrong cbp file, if the user changes the project()
// name
foreach(const QString &cbpFile , directory.entryList())
{
if (cbpFile.endsWith(".cbp")) {
return directory.path() + "/" + cbpFile;
}
}
return QString::null;
}
QString CMakeProject::createCbpFile(const QDir &)
{
// TODO create a cbp file.
// Issue: Where to create it? We want to do that in the build directory
// but at this stage we don't know the build directory yet
// So create it in a temp directory?
// Issue: We want to reuse whatever CMakeCache.txt that is alread there, which
// would indicate, creating it in the build directory
// Or we could use a temp directory and use -C builddirectory
return QString::null;
}
bool CMakeProject::parseCbpFile(const QString &fileName, QList<ProjectExplorer::FileNode *> &fileList, QStringList &includeFiles)
{
QFile fi(fileName);
if (fi.exists() && fi.open(QFile::ReadOnly)) {
QXmlStreamReader stream(&fi);
while(!stream.atEnd()) {
stream.readNext();
if (stream.name() == "CodeBlocks_project_file") {
parseCodeBlocks_project_file(stream, fileList, includeFiles);
} else if (stream.isStartElement()) {
parseUnknownElement(stream);
}
}
fi.close();
return true;
}
return false;
}
void CMakeProject::parseCodeBlocks_project_file(QXmlStreamReader &stream, QList<ProjectExplorer::FileNode *> &fileList, QStringList &includeFiles)
{
while(!stream.atEnd()) {
stream.readNext();
if (stream.isEndElement()) {
return;
} else if (stream.name() == "Project") {
parseProject(stream, fileList, includeFiles);
} else if (stream.isStartElement()) {
parseUnknownElement(stream);
}
}
}
void CMakeProject::parseProject(QXmlStreamReader &stream, QList<ProjectExplorer::FileNode *> &fileList, QStringList &includeFiles)
{
while(!stream.atEnd()) {
stream.readNext();
if (stream.isEndElement()) {
return;
} else if (stream.name() == "Unit") {
parseUnit(stream, fileList);
} else if (stream.name() == "Build") {
parseBuild(stream, includeFiles);
} else if (stream.isStartElement()) {
parseUnknownElement(stream);
}
}
}
void CMakeProject::parseBuild(QXmlStreamReader &stream, QStringList &includeFiles)
{
while(!stream.atEnd()) {
stream.readNext();
if (stream.isEndElement()) {
return;
} else if (stream.name() == "Target") {
parseTarget(stream, includeFiles);
} else if (stream.isStartElement()) {
parseUnknownElement(stream);
}
}
}
void CMakeProject::parseTarget(QXmlStreamReader &stream, QStringList &includeFiles)
{
while(!stream.atEnd()) {
stream.readNext();
if (stream.isEndElement()) {
return;
} else if (stream.name() == "Compiler") {
parseCompiler(stream, includeFiles);
} else if (stream.isStartElement()) {
parseUnknownElement(stream);
}
}
}
void CMakeProject::parseCompiler(QXmlStreamReader &stream, QStringList &includeFiles)
{
while(!stream.atEnd()) {
stream.readNext();
if (stream.isEndElement()) {
return;
} else if (stream.name() == "Add") {
parseAdd(stream, includeFiles);
} else if (stream.isStartElement()) {
parseUnknownElement(stream);
}
}
}
void CMakeProject::parseAdd(QXmlStreamReader &stream, QStringList &includeFiles)
{
includeFiles.append(stream.attributes().value("directory").toString());
while(!stream.atEnd()) {
stream.readNext();
if (stream.isEndElement()) {
return;
} else if (stream.isStartElement()) {
parseUnknownElement(stream);
}
}
}
void CMakeProject::parseUnit(QXmlStreamReader &stream, QList<ProjectExplorer::FileNode *> &fileList)
{
//qDebug()<<stream.attributes().value("filename");
QString fileName = stream.attributes().value("filename").toString();
if (!fileName.endsWith(".rule"))
fileList.append( new ProjectExplorer::FileNode(fileName, ProjectExplorer::SourceType, false));
while(!stream.atEnd()) {
stream.readNext();
if (stream.isEndElement()) {
return;
} else if (stream.isStartElement()) {
parseUnknownElement(stream);
}
}
}
void CMakeProject::parseUnknownElement(QXmlStreamReader &stream)
{
Q_ASSERT(stream.isStartElement());
while (!stream.atEnd()) {
stream.readNext();
if (stream.isEndElement())
break;
if (stream.isStartElement())
parseUnknownElement(stream);
}
}
void CMakeProject::buildTree(CMakeProjectNode *rootNode, QList<ProjectExplorer::FileNode *> list)
{
//m_rootNode->addFileNodes(fileList, m_rootNode);
qSort(list.begin(), list.end(), ProjectExplorer::ProjectNode::sortNodesByPath);
foreach( ProjectExplorer::FileNode *fn, list) {
// Get relative path to rootNode
QString parentDir = QFileInfo(fn->path()).absolutePath();
ProjectExplorer::FolderNode *folder = findOrCreateFolder(rootNode, parentDir);
rootNode->addFileNodes(QList<ProjectExplorer::FileNode *>()<< fn, folder);
}
//m_rootNode->addFileNodes(list, rootNode);
}
ProjectExplorer::FolderNode *CMakeProject::findOrCreateFolder(CMakeProjectNode *rootNode, QString directory)
{
QString relativePath = QDir(QFileInfo(rootNode->path()).path()).relativeFilePath(directory);
QStringList parts = relativePath.split("/");
ProjectExplorer::FolderNode *parent = rootNode;
foreach(const QString &part, parts) {
// Find folder in subFolders
bool found = false;
foreach(ProjectExplorer::FolderNode *folder, parent->subFolderNodes()) {
if (QFileInfo(folder->path()).fileName() == part) {
// yeah found something :)
parent = folder;
found = true;
break;
}
}
if (!found) {
// No FolderNode yet, so create it
ProjectExplorer::FolderNode *tmp = new ProjectExplorer::FolderNode(part);
rootNode->addFolderNodes(QList<ProjectExplorer::FolderNode *>() << tmp, parent);
parent = tmp;
}
}
return parent;
}
QString CMakeProject::name() const
{
// TODO
return "";
}
Core::IFile *CMakeProject::file() const
{
return m_file;
}
ProjectExplorer::IProjectManager *CMakeProject::projectManager() const
{
return m_manager;
}
QList<Core::IFile *> CMakeProject::dependencies()
{
return QList<Core::IFile *>();
}
QList<ProjectExplorer::Project *> CMakeProject::dependsOn()
{
return QList<Project *>();
}
bool CMakeProject::isApplication() const
{
return true;
}
ProjectExplorer::Environment CMakeProject::environment(const QString &buildConfiguration) const
{
Q_UNUSED(buildConfiguration)
//TODO
return ProjectExplorer::Environment::systemEnvironment();
}
QString CMakeProject::buildDirectory(const QString &buildConfiguration) const
{
Q_UNUSED(buildConfiguration)
//TODO
return "";
}
ProjectExplorer::BuildStepConfigWidget *CMakeProject::createConfigWidget()
{
return new CMakeBuildSettingsWidget;
}
QList<ProjectExplorer::BuildStepConfigWidget*> CMakeProject::subConfigWidgets()
{
return QList<ProjectExplorer::BuildStepConfigWidget*>();
}
// This method is called for new build configurations
// You should probably set some default values in this method
void CMakeProject::newBuildConfiguration(const QString &buildConfiguration)
{
Q_UNUSED(buildConfiguration);
//TODO
}
ProjectExplorer::ProjectNode *CMakeProject::rootProjectNode() const
{
return m_rootNode;
}
QStringList CMakeProject::files(FilesMode fileMode) const
{
Q_UNUSED(fileMode);
// TODO
return m_files;
}
void CMakeProject::saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &writer)
{
// TODO
Q_UNUSED(writer)
}
void CMakeProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader &reader)
{
// TODO
Q_UNUSED(reader)
}
CMakeFile::CMakeFile(CMakeProject *parent, QString fileName)
: Core::IFile(parent), m_project(parent), m_fileName(fileName)
{
}
bool CMakeFile::save(const QString &fileName)
{
// TODO
// Once we have an texteditor open for this file, we probably do
// need to implement this, don't we.
Q_UNUSED(fileName);
return false;
}
QString CMakeFile::fileName() const
{
return m_fileName;
}
QString CMakeFile::defaultPath() const
{
return QString();
}
QString CMakeFile::suggestedFileName() const
{
return QString();
}
QString CMakeFile::mimeType() const
{
return Constants::CMAKEMIMETYPE;
}
bool CMakeFile::isModified() const
{
return false;
}
bool CMakeFile::isReadOnly() const
{
return true;
}
bool CMakeFile::isSaveAsAllowed() const
{
return false;
}
void CMakeFile::modified(ReloadBehavior *behavior)
{
Q_UNUSED(behavior);
}
CMakeBuildSettingsWidget::CMakeBuildSettingsWidget()
{
}
QString CMakeBuildSettingsWidget::displayName() const
{
return "CMake";
}
void CMakeBuildSettingsWidget::init(const QString &buildConfiguration)
{
Q_UNUSED(buildConfiguration);
// TODO
}

View File

@@ -0,0 +1,158 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef CMAKEPROJECT_H
#define CMAKEPROJECT_H
#include <projectexplorer/project.h>
#include <projectexplorer/projectnodes.h>
#include <projectexplorer/buildstep.h>
#include <coreplugin/ifile.h>
#include <QtCore/QXmlStreamReader>
#include "cmakeprojectmanager.h"
#include "cmakeprojectnodes.h"
namespace CMakeProjectManager {
namespace Internal{
class CMakeFile;
class CMakeProject : public ProjectExplorer::Project
{
Q_OBJECT
public:
CMakeProject(CMakeManager *manager, const QString &filename);
~CMakeProject();
virtual QString name() const;
virtual Core::IFile *file() const;
virtual ProjectExplorer::IProjectManager *projectManager() const;
virtual QList<Core::IFile *> dependencies(); //NBS TODO remove
virtual QList<ProjectExplorer::Project *> dependsOn(); //NBS TODO implement dependsOn
virtual bool isApplication() const;
virtual ProjectExplorer::Environment environment(const QString &buildConfiguration) const;
virtual QString buildDirectory(const QString &buildConfiguration) const;
virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
virtual QList<ProjectExplorer::BuildStepConfigWidget*> subConfigWidgets();
// This method is called for new build configurations
// You should probably set some default values in this method
virtual void newBuildConfiguration(const QString &buildConfiguration);
// // Returns the list of different views (such as "File View" or "Project View") the project supports.
// virtual QStringList supportedModels() const = 0;
//
// // Returns the tree representing the requested view.
// virtual QModelIndex model(const QString &modelId) const = 0;
virtual ProjectExplorer::ProjectNode *rootProjectNode() const;
// // Conversion functions
// virtual QModelIndex indexForNode(const Node *node, const QString &modelId) const = 0;
// virtual Node *nodeForIndex(const QModelIndex &index) const = 0;
// virtual Node *nodeForFile(const QString &filePath) const = 0;
virtual QStringList files(FilesMode fileMode) const;
private:
QString findCbpFile(const QDir &);
QString createCbpFile(const QDir &);
bool parseCbpFile(const QString &fileName, QList<ProjectExplorer::FileNode *> &fileList, QStringList &includeFiles);
void parseCodeBlocks_project_file(QXmlStreamReader &stream, QList<ProjectExplorer::FileNode *> &fileList, QStringList &includeFiles);
void parseProject(QXmlStreamReader &stream, QList<ProjectExplorer::FileNode *> &fileList, QStringList &includeFiles);
void parseBuild(QXmlStreamReader &stream, QStringList &includeFiles);
void parseTarget(QXmlStreamReader &stream, QStringList &includeFiles);
void parseCompiler(QXmlStreamReader &stream, QStringList &includeFiles);
void parseAdd(QXmlStreamReader &stream, QStringList &includeFiles);
void parseUnit(QXmlStreamReader &stream, QList<ProjectExplorer::FileNode *> &fileList);
void parseUnknownElement(QXmlStreamReader &stream);
void buildTree(CMakeProjectNode *rootNode, QList<ProjectExplorer::FileNode *> list);
ProjectExplorer::FolderNode *findOrCreateFolder(CMakeProjectNode *rootNode, QString directory);
CMakeManager *m_manager;
QString m_fileName;
CMakeFile *m_file;
// TODO probably need a CMake specific node structure
CMakeProjectNode* m_rootNode;
QStringList m_files;
protected:
virtual void saveSettingsImpl(ProjectExplorer::PersistentSettingsWriter &writer);
virtual void restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader &reader);
};
class CMakeFile : public Core::IFile
{
Q_OBJECT
public:
CMakeFile(CMakeProject *parent, QString fileName);
bool save(const QString &fileName = QString());
QString fileName() const;
QString defaultPath() const;
QString suggestedFileName() const;
QString mimeType() const;
bool isModified() const;
bool isReadOnly() const;
bool isSaveAsAllowed() const;
void modified(ReloadBehavior *behavior);
private:
CMakeProject *m_project;
QString m_fileName;
};
class CMakeBuildSettingsWidget : public ProjectExplorer::BuildStepConfigWidget
{
public:
CMakeBuildSettingsWidget();
virtual QString displayName() const;
// This is called to set up the config widget before showing it
// buildConfiguration is QString::null for the non buildConfiguration specific page
virtual void init(const QString &buildConfiguration);
};
}
}
#endif // CMAKEPROJECT_H

View File

@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/cmakeproject" >
<file>CMakeProject.mimetypes.xml</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,45 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef CMAKEPROJECTCONSTANTS_H
#define CMAKEPROJECTCONSTANTS_H
namespace CMakeProjectManager {
namespace Constants {
const char * const PROJECTCONTEXT = "CMakeProject.ProjectContext";
const char * const CMAKEMIMETYPE = "text/x-cmake"; // TOOD check that this is correct
}
}
#endif // CMAKEPROJECTCONSTANTS_H

View File

@@ -0,0 +1,72 @@
/***************************************************************************
**
** 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 "cmakeprojectmanager.h"
#include "cmakeprojectconstants.h"
#include "cmakeproject.h"
#include "cmakeprojectconstants.h"
#include <coreplugin/icore.h>
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/uniqueidmanager.h>
#include <projectexplorer/projectexplorerconstants.h>
using namespace CMakeProjectManager::Internal;
CMakeManager::CMakeManager()
{
Core::ICore *core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>();
m_projectContext = core->uniqueIDManager()->uniqueIdentifier(CMakeProjectManager::Constants::PROJECTCONTEXT);
m_projectLanguage = core->uniqueIDManager()->uniqueIdentifier(ProjectExplorer::Constants::LANG_CXX);
}
int CMakeManager::projectContext() const
{
return m_projectContext;
}
int CMakeManager::projectLanguage() const
{
return m_projectLanguage;
}
ProjectExplorer::Project *CMakeManager::openProject(const QString &fileName)
{
// TODO check wheter this project is already opened
return new CMakeProject(this, fileName);
}
QString CMakeManager::mimeType() const
{
return Constants::CMAKEMIMETYPE;
}

View File

@@ -0,0 +1,60 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef CMAKEPROJECTMANAGER_H
#define CMAKEPROJECTMANAGER_H
#include <projectexplorer/iprojectmanager.h>
namespace CMakeProjectManager {
namespace Internal {
class CMakeManager : public ProjectExplorer::IProjectManager
{
Q_OBJECT
public:
CMakeManager();
virtual int projectContext() const;
virtual int projectLanguage() const;
//virtual bool canOpenProject(const QString &fileName);
virtual ProjectExplorer::Project *openProject(const QString &fileName);
virtual QString mimeType() const;
//virtual QString fileFilter() const;
private:
int m_projectContext;
int m_projectLanguage;
};
}
}
#endif // CMAKEPROJECTMANAGER_H

View File

@@ -0,0 +1,14 @@
TEMPLATE = lib
TARGET = CMakeProjectManager
include(../../qworkbenchplugin.pri)
include(cmakeprojectmanager_dependencies.pri)
HEADERS = cmakeproject.h \
cmakeprojectplugin.h \
cmakeprojectmanager.h \
cmakeprojectconstants.h \
cmakeprojectnodes.h
SOURCES = cmakeproject.cpp \
cmakeprojectplugin.cpp \
cmakeprojectmanager.cpp \
cmakeprojectnodes.cpp
RESOURCES += cmakeproject.qrc

View File

@@ -0,0 +1,4 @@
include(../../plugins/projectexplorer/projectexplorer.pri)
include(../../plugins/cpptools/cpptools.pri)
include(../../plugins/cppeditor/cppeditor.pri)
include(../../plugins/texteditor/texteditor.pri)

View File

@@ -0,0 +1,89 @@
/***************************************************************************
**
** 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 "cmakeprojectnodes.h"
using namespace CMakeProjectManager;
using namespace CMakeProjectManager::Internal;
CMakeProjectNode::CMakeProjectNode(const QString &fileName)
: ProjectExplorer::ProjectNode(fileName)
{
}
bool CMakeProjectNode::hasTargets() const
{
// TODO
return true;
}
QList<ProjectExplorer::ProjectNode::ProjectAction> CMakeProjectNode::supportedActions() const
{
return QList<ProjectAction>();
}
bool CMakeProjectNode::addSubProjects(const QStringList &proFilePaths)
{
Q_UNUSED(proFilePaths);
return false;
}
bool CMakeProjectNode::removeSubProjects(const QStringList &proFilePaths)
{
Q_UNUSED(proFilePaths);
return false;
}
bool CMakeProjectNode::addFiles(const ProjectExplorer::FileType fileType, const QStringList &filePaths, QStringList *notAdded)
{
Q_UNUSED(fileType);
Q_UNUSED(filePaths);
Q_UNUSED(notAdded);
return false;
}
// TODO: Maybe remove fileType, can be detected by project
bool CMakeProjectNode::removeFiles(const ProjectExplorer::FileType fileType, const QStringList &filePaths, QStringList *notRemoved)
{
Q_UNUSED(fileType);
Q_UNUSED(filePaths);
Q_UNUSED(notRemoved);
return false;
}
bool CMakeProjectNode::renameFile(const ProjectExplorer::FileType fileType, const QString &filePath, const QString &newFilePath)
{
Q_UNUSED(fileType);
Q_UNUSED(filePath);
Q_UNUSED(newFilePath);
return false;
}

View File

@@ -0,0 +1,66 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef CMAKEPROJECTNODE_H
#define CMAKEPROJECTNODE_H
#include <projectexplorer/projectnodes.h>
namespace CMakeProjectManager {
namespace Internal {
class CMakeProjectNode : public ProjectExplorer::ProjectNode
{
public:
CMakeProjectNode(const QString &fileName);
virtual bool hasTargets() const;
virtual QList<ProjectExplorer::ProjectNode::ProjectAction> supportedActions() const;
virtual bool addSubProjects(const QStringList &proFilePaths);
virtual bool removeSubProjects(const QStringList &proFilePaths);
virtual bool addFiles(const ProjectExplorer::FileType fileType,
const QStringList &filePaths,
QStringList *notAdded = 0);
virtual bool removeFiles(const ProjectExplorer::FileType fileType,
const QStringList &filePaths,
QStringList *notRemoved = 0);
virtual bool renameFile(const ProjectExplorer::FileType fileType,
const QString &filePath,
const QString &newFilePath);
// TODO is protected in base class, and that's correct
using ProjectNode::addFileNodes;
using ProjectNode::addFolderNodes;
};
}
}
#endif // CMAKEPROJECTNODE_H

View File

@@ -0,0 +1,65 @@
/***************************************************************************
**
** 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 "cmakeprojectplugin.h"
#include <coreplugin/icore.h>
#include <coreplugin/mimedatabase.h>
#include <QtCore/qplugin.h>
#include <QtCore/QDebug>
#include "cmakeprojectmanager.h"
using namespace CMakeProjectManager::Internal;
CMakeProjectPlugin::CMakeProjectPlugin()
{
}
CMakeProjectPlugin::~CMakeProjectPlugin()
{
}
bool CMakeProjectPlugin::initialize(const QStringList & /*arguments*/, QString *error_message)
{
Core::ICore *core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>();
QString errorMessage;
core->mimeDatabase()->addMimeTypes(QLatin1String(":cmakeproject/CMakeProject.mimetypes.xml"), &errorMessage);
addAutoReleasedObject(new CMakeManager());
return true;
}
void CMakeProjectPlugin::extensionsInitialized()
{
}
Q_EXPORT_PLUGIN(CMakeProjectPlugin)

View File

@@ -0,0 +1,63 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef CMAKEPROJECTPLUGIN_H
#define CMAKEPROJECTPLUGIN_H
#include <extensionsystem/iplugin.h>
#include <QtCore/QObject>
namespace CMakeProjectManager {
namespace Internal {
class CMakeProjectPlugin
: public ExtensionSystem::IPlugin
{
Q_OBJECT
public:
CMakeProjectPlugin();
~CMakeProjectPlugin();
bool initialize(const QStringList &arguments, QString *error_message);
void extensionsInitialized();
private:
};
} // namespace Internal
} // namespace CMakeProject
#endif // CMAKEPROJECTPLUGIN_H

View File

@@ -0,0 +1,7 @@
<plugin name="Core" version="0.9.1" compatVersion="0.9.1">
<vendor>Nokia Corporation</vendor>
<copyright>(C) 2008 Nokia Corporation</copyright>
<license>Nokia Technology Preview License Agreement</license>
<description>The core plugin for the Qt IDE.</description>
<url>http://www.trolltech.com/</url>
</plugin>

View File

@@ -0,0 +1,696 @@
/***************************************************************************
**
** 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 "actioncontainer.h"
#include "command.h"
#include "coreimpl.h"
#include "coreconstants.h"
#include "uniqueidmanager.h"
#include <QtCore/QDebug>
#include <QtGui/QAction>
#include <QtGui/QToolBar>
#include <QtGui/QMenuBar>
Q_DECLARE_METATYPE(Core::Internal::MenuActionContainer*)
using namespace Core;
using namespace Core::Internal;
/*!
\class IActionContainer
\mainclass
\ingroup qwb
\inheaderfile iactioncontainer.h
\brief The class...
The Action Container interface...
*/
/*!
\enum IActionContainer::ContainerType
*/
/*!
\enum IActionContainer::EmptyAction
*/
/*!
\fn virtual IActionContainer::setEmptyAction(EmptyAction ea)
*/
/*!
\fn virtual int IActionContainer::id() const
*/
/*!
\fn virtual ContainerType IActionContainer::type() const
*/
/*!
\fn virtual QMenu *IActionContainer::menu() const
*/
/*!
\fn virtual QToolBar *IActionContainer::toolBar() const
*/
/*!
\fn virtual QMenuBar *IActionContainer::menuBar() const
*/
/*!
\fn virtual QAction *IActionContainer::insertLocation(const QString &group) const
*/
/*!
\fn virtual void IActionContainer::appendGroup(const QString &group, bool global)
*/
/*!
\fn virtual void IActionContainer::addAction(Core::ICommand *action, const QString &group)
*/
/*!
\fn virtual void IActionContainer::addMenu(Core::IActionContainer *menu, const QString &group)
*/
/*!
\fn virtual bool IActionContainer::update()
*/
/*!
\fn virtual IActionContainer::~IActionContainer()
*/
// ---------- ActionContainer ------------
/*!
\class ActionContainer
\ingroup qwb
\inheaderfile actioncontainer.h
*/
/*!
\enum ActionContainer::ContainerState
*/
/*!
\fn ActionContainer::ActionContainer(ContainerType type, int id)
*/
ActionContainer::ActionContainer(ContainerType type, int id)
: m_data(CS_None), m_type(type), m_id(id)
{
}
/*!
\fn virtual ActionContainer::~ActionContainer()
*/
/*!
...
*/
void ActionContainer::setEmptyAction(EmptyAction ea)
{
m_data = ((m_data & ~EA_Mask) | ea);
}
/*!
...
*/
bool ActionContainer::hasEmptyAction(EmptyAction ea) const
{
return (m_data & EA_Mask) == ea;
}
/*!
...
*/
void ActionContainer::setState(ContainerState state)
{
m_data |= state;
}
/*!
...
*/
bool ActionContainer::hasState(ContainerState state) const
{
return (m_data & state);
}
/*!
...
*/
void ActionContainer::appendGroup(const QString &group, bool global)
{
UniqueIDManager *idmanager = CoreImpl::instance()->uniqueIDManager();
int gid = idmanager->uniqueIdentifier(group);
m_groups << gid;
if (global)
ActionManager::instance()->registerGlobalGroup(gid, m_id);
}
/*!
...
*/
QAction *ActionContainer::insertLocation(const QString &group) const
{
UniqueIDManager *idmanager = CoreImpl::instance()->uniqueIDManager();
int grpid = idmanager->uniqueIdentifier(group);
int prevKey = 0;
int pos = ((grpid << 16) | 0xFFFF);
return beforeAction(pos, &prevKey);
}
/*!
\fn virtual void ActionContainer::insertAction(QAction *before, QAction *action) = 0
*/
/*!
\fn virtual void ActionContainer::insertMenu(QAction *before, QMenu *menu) = 0
*/
/*!
\fn QList<ICommand *> ActionContainer::commands() const
*/
/*!
\fn QList<IActionContainer *> ActionContainer::subContainers() const
*/
/*!
...
*/
void ActionContainer::addAction(ICommand *action, const QString &group)
{
if (!canAddAction(action))
return;
ActionManager *am = ActionManager::instance();
Action *a = static_cast<Action *>(action);
if (a->stateFlags() & Command::CS_PreLocation) {
QList<CommandLocation> locs = a->locations();
for (int i=0; i<locs.size(); ++i) {
if (IActionContainer *aci = am->actionContainer(locs.at(i).m_container)) {
ActionContainer *ac = static_cast<ActionContainer *>(aci);
ac->addAction(action, locs.at(i).m_position, false);
}
}
a->setStateFlags(a->stateFlags() | Command::CS_Initialized);
} else {
UniqueIDManager *idmanager = CoreImpl::instance()->uniqueIDManager();
int grpid = idmanager->uniqueIdentifier(Constants::G_DEFAULT_TWO);
if (!group.isEmpty())
grpid = idmanager->uniqueIdentifier(group);
if (!m_groups.contains(grpid) && !am->defaultGroups().contains(grpid))
qWarning() << "*** addAction(): Unknown group: " << group;
int pos = ((grpid << 16) | 0xFFFF);
addAction(action, pos, true);
}
}
/*!
...
*/
void ActionContainer::addMenu(IActionContainer *menu, const QString &group)
{
if (!canAddMenu(menu))
return;
ActionManager *am = ActionManager::instance();
MenuActionContainer *mc = static_cast<MenuActionContainer *>(menu);
if (mc->hasState(ActionContainer::CS_PreLocation)) {
CommandLocation loc = mc->location();
if (IActionContainer *aci = am->actionContainer(loc.m_container)) {
ActionContainer *ac = static_cast<ActionContainer *>(aci);
ac->addMenu(menu, loc.m_position, false);
}
mc->setState(ActionContainer::CS_Initialized);
} else {
UniqueIDManager *idmanager = CoreImpl::instance()->uniqueIDManager();
int grpid = idmanager->uniqueIdentifier(Constants::G_DEFAULT_TWO);
if (!group.isEmpty())
grpid = idmanager->uniqueIdentifier(group);
if (!m_groups.contains(grpid) && !am->defaultGroups().contains(grpid))
qWarning() << "*** addMenu(): Unknown group: " << group;
int pos = ((grpid << 16) | 0xFFFF);
addMenu(menu, pos, true);
}
}
/*!
...
*/
int ActionContainer::id() const
{
return m_id;
}
/*!
...
*/
IActionContainer::ContainerType ActionContainer::type() const
{
return m_type;
}
/*!
...
*/
QMenu *ActionContainer::menu() const
{
return 0;
}
/*!
...
*/
QToolBar *ActionContainer::toolBar() const
{
return 0;
}
/*!
...
*/
QMenuBar *ActionContainer::menuBar() const
{
return 0;
}
/*!
...
*/
bool ActionContainer::canAddAction(ICommand *action) const
{
if (action->type() != ICommand::CT_OverridableAction)
return false;
Command *cmd = static_cast<Command *>(action);
if (cmd->stateFlags() & Command::CS_Initialized)
return false;
return true;
}
/*!
...
*/
bool ActionContainer::canAddMenu(IActionContainer *menu) const
{
if (menu->type() != IActionContainer::CT_Menu)
return false;
ActionContainer *container = static_cast<ActionContainer *>(menu);
if (container->hasState(ActionContainer::CS_Initialized))
return false;
return true;
}
/*!
...
*/
void ActionContainer::addAction(ICommand *action, int pos, bool setpos)
{
Action *a = static_cast<Action *>(action);
int prevKey = 0;
QAction *ba = beforeAction(pos, &prevKey);
if (setpos) {
pos = calcPosition(pos, prevKey);
CommandLocation loc;
loc.m_container = m_id;
loc.m_position = pos;
QList<CommandLocation> locs = a->locations();
locs.append(loc);
a->setLocations(locs);
}
m_commands.append(action);
m_posmap.insert(pos, action->id());
insertAction(ba, a->action());
}
/*!
...
*/
void ActionContainer::addMenu(IActionContainer *menu, int pos, bool setpos)
{
MenuActionContainer *mc = static_cast<MenuActionContainer *>(menu);
int prevKey = 0;
QAction *ba = beforeAction(pos, &prevKey);
if (setpos) {
pos = calcPosition(pos, prevKey);
CommandLocation loc;
loc.m_container = m_id;
loc.m_position = pos;
mc->setLocation(loc);
}
m_subContainers.append(menu);
m_posmap.insert(pos, menu->id());
insertMenu(ba, mc->menu());
}
/*!
...
\internal
*/
QAction *ActionContainer::beforeAction(int pos, int *prevKey) const
{
ActionManager *am = ActionManager::instance();
int baId = -1;
(*prevKey) = -1;
QMap<int, int>::const_iterator i = m_posmap.constBegin();
while (i != m_posmap.constEnd()) {
if (i.key() > pos) {
baId = i.value();
break;
}
(*prevKey) = i.key();
++i;
}
if (baId == -1)
return 0;
if (ICommand *cmd = am->command(baId))
return cmd->action();
if (IActionContainer *container = am->actionContainer(baId))
if (QMenu *menu = container->menu())
return menu->menuAction();
return 0;
}
/*!
...
\internal
*/
int ActionContainer::calcPosition(int pos, int prevKey) const
{
int grp = (pos & 0xFFFF0000);
if (prevKey == -1)
return grp;
int prevgrp = (prevKey & 0xFFFF0000);
if (grp != prevgrp)
return grp;
return grp + (prevKey & 0xFFFF) + 10;
}
// ---------- MenuActionContainer ------------
/*!
\class MenuActionContainer
\ingroup qwb
\inheaderfile actioncontainer.h
*/
/*!
...
*/
MenuActionContainer::MenuActionContainer(int id)
: ActionContainer(CT_Menu, id), m_menu(0)
{
setEmptyAction(EA_Disable);
}
/*!
...
*/
void MenuActionContainer::setMenu(QMenu *menu)
{
m_menu = menu;
QVariant v;
qVariantSetValue<MenuActionContainer*>(v, this);
m_menu->menuAction()->setData(v);
}
/*!
...
*/
QMenu *MenuActionContainer::menu() const
{
return m_menu;
}
/*!
...
*/
void MenuActionContainer::insertAction(QAction *before, QAction *action)
{
m_menu->insertAction(before, action);
}
/*!
...
*/
void MenuActionContainer::insertMenu(QAction *before, QMenu *menu)
{
m_menu->insertMenu(before, menu);
}
/*!
...
*/
void MenuActionContainer::setLocation(const CommandLocation &location)
{
m_location = location;
}
/*!
...
*/
CommandLocation MenuActionContainer::location() const
{
return m_location;
}
/*!
...
*/
bool MenuActionContainer::update()
{
if (hasEmptyAction(EA_None))
return true;
bool hasitems = false;
foreach (IActionContainer *container, subContainers()) {
if (container == this) {
qWarning() << Q_FUNC_INFO << "container" << (this->menu() ? this->menu()->title() : "") << "contains itself as subcontainer";
continue;
}
if (container->update()) {
hasitems = true;
break;
}
}
if (!hasitems) {
foreach (ICommand *command, commands()) {
if (command->isActive()) {
hasitems = true;
break;
}
}
}
if (hasEmptyAction(EA_Hide))
m_menu->setVisible(hasitems);
else if (hasEmptyAction(EA_Disable))
m_menu->setEnabled(hasitems);
return hasitems;
}
// ---------- ToolBarActionContainer ------------
/*!
\class ToolBarActionContainer
\ingroup qwb
\inheaderfile actioncontainer.h
*/
/*!
...
*/
ToolBarActionContainer::ToolBarActionContainer(int id)
: ActionContainer(CT_ToolBar, id), m_toolBar(0)
{
setEmptyAction(EA_None);
}
/*!
...
*/
void ToolBarActionContainer::setToolBar(QToolBar *toolBar)
{
m_toolBar = toolBar;
}
/*!
...
*/
QToolBar *ToolBarActionContainer::toolBar() const
{
return m_toolBar;
}
/*!
...
*/
void ToolBarActionContainer::insertAction(QAction *before, QAction *action)
{
m_toolBar->insertAction(before, action);
}
/*!
...
*/
void ToolBarActionContainer::insertMenu(QAction *, QMenu *)
{
// not implemented
}
/*!
...
*/
bool ToolBarActionContainer::update()
{
if (hasEmptyAction(EA_None))
return true;
bool hasitems = false;
foreach (ICommand *command, commands()) {
if (command->isActive()) {
hasitems = true;
break;
}
}
if (hasEmptyAction(EA_Hide))
m_toolBar->setVisible(hasitems);
else if (hasEmptyAction(EA_Disable))
m_toolBar->setEnabled(hasitems);
return hasitems;
}
// ---------- MenuBarActionContainer ------------
/*!
\class MenuBarActionContainer
\ingroup qwb
\inheaderfile actioncontainer.h
*/
/*!
...
*/
MenuBarActionContainer::MenuBarActionContainer(int id)
: ActionContainer(CT_ToolBar, id), m_menuBar(0)
{
setEmptyAction(EA_None);
}
/*!
...
*/
void MenuBarActionContainer::setMenuBar(QMenuBar *menuBar)
{
m_menuBar = menuBar;
}
/*!
...
*/
QMenuBar *MenuBarActionContainer::menuBar() const
{
return m_menuBar;
}
/*!
...
*/
void MenuBarActionContainer::insertAction(QAction *before, QAction *action)
{
m_menuBar->insertAction(before, action);
}
/*!
...
*/
void MenuBarActionContainer::insertMenu(QAction *before, QMenu *menu)
{
m_menuBar->insertMenu(before, menu);
}
/*!
...
*/
bool MenuBarActionContainer::update()
{
if (hasEmptyAction(EA_None))
return true;
bool hasitems = false;
QList<QAction *> actions = m_menuBar->actions();
for (int i=0; i<actions.size(); ++i) {
if (actions.at(i)->isVisible()) {
hasitems = true;
break;
}
}
if (hasEmptyAction(EA_Hide))
m_menuBar->setVisible(hasitems);
else if (hasEmptyAction(EA_Disable))
m_menuBar->setEnabled(hasitems);
return hasitems;
}

View File

@@ -0,0 +1,157 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef ACTIONCONTAINER_H
#define ACTIONCONTAINER_H
#include "actionmanager.h"
#include <coreplugin/actionmanager/iactioncontainer.h>
#include <coreplugin/actionmanager/icommand.h>
namespace Core {
namespace Internal {
class ActionContainer : public Core::IActionContainer
{
public:
enum ContainerState {
CS_None = 0x000000,
CS_Initialized = 0x010000,
CS_PreLocation = 0x020000,
CS_UserDefined = 0x040000
};
ActionContainer(ContainerType type, int id);
virtual ~ActionContainer() {}
void setEmptyAction(EmptyAction ea);
bool hasEmptyAction(EmptyAction ea) const;
void setState(ContainerState state);
bool hasState(ContainerState state) const;
QAction *insertLocation(const QString &group) const;
void appendGroup(const QString &group, bool global = false);
void addAction(ICommand *action, const QString &group = QString());
void addMenu(IActionContainer *menu, const QString &group = QString());
int id() const;
ContainerType type() const;
QMenu *menu() const;
QToolBar *toolBar() const;
QMenuBar *menuBar() const;
virtual void insertAction(QAction *before, QAction *action) = 0;
virtual void insertMenu(QAction *before, QMenu *menu) = 0;
QList<ICommand *> commands() const { return m_commands; }
QList<IActionContainer *> subContainers() const { return m_subContainers; }
protected:
bool canAddAction(ICommand *action) const;
bool canAddMenu(IActionContainer *menu) const;
void addAction(ICommand *action, int pos, bool setpos);
void addMenu(IActionContainer *menu, int pos, bool setpos);
private:
QAction *beforeAction(int pos, int *prevKey) const;
int calcPosition(int pos, int prevKey) const;
QList<int> m_groups;
int m_data;
ContainerType m_type;
int m_id;
QMap<int, int> m_posmap;
QList<IActionContainer *> m_subContainers;
QList<ICommand *> m_commands;
};
class MenuActionContainer : public ActionContainer
{
public:
MenuActionContainer(int id);
void setMenu(QMenu *menu);
QMenu *menu() const;
void setLocation(const CommandLocation &location);
CommandLocation location() const;
void insertAction(QAction *before, QAction *action);
void insertMenu(QAction *before, QMenu *menu);
bool update();
private:
QMenu *m_menu;
CommandLocation m_location;
};
class ToolBarActionContainer : public ActionContainer
{
public:
ToolBarActionContainer(int id);
void setToolBar(QToolBar *toolBar);
QToolBar *toolBar() const;
void insertAction(QAction *before, QAction *action);
void insertMenu(QAction *before, QMenu *menu);
bool update();
private:
QToolBar *m_toolBar;
};
class MenuBarActionContainer : public ActionContainer
{
public:
MenuBarActionContainer(int id);
void setMenuBar(QMenuBar *menuBar);
QMenuBar *menuBar() const;
void insertAction(QAction *before, QAction *action);
void insertMenu(QAction *before, QMenu *menu);
bool update();
private:
QMenuBar *m_menuBar;
};
} // namespace Internal
} // namespace Core
#endif //ACTIONCONTAINER_H

View File

@@ -0,0 +1,560 @@
/***************************************************************************
**
** 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 "actionmanager.h"
#include "mainwindow.h"
#include "actioncontainer.h"
#include "command.h"
#include "uniqueidmanager.h"
#include <coreplugin/coreconstants.h>
#include <QtCore/QDebug>
#include <QtCore/QSettings>
#include <QtGui/QMenu>
#include <QtGui/QAction>
#include <QtGui/QShortcut>
#include <QtGui/QToolBar>
#include <QtGui/QMenuBar>
namespace {
enum { warnAboutFindFailures = 0 };
}
/*!
\class Core::ActionManagerInterface
\mainclass
\ingroup qwb
\inheaderfile actionmanagerinterface.h
\brief All actions should be registered in the ActionManager, since this enables the user to
e.g. change their shortcuts at a central place.
The ActionManagerInterface is the central bookkeeper of actions and their shortcuts and layout.
You get the only implementation of this class from the core interface (ICore::actionManager()).
The main reasons for the need of this class is to provide a central place where the user
can specify all his keyboard shortcuts, and to provide a solution for actions that should
behave differently in different contexts (like the copy/replace/undo/redo actions).
All actions that are registered with the same string id (but different context lists)
are considered to be overloads of the same command. The action that is visible to the user
is the one returned by ICommand::action(). (If you provide yourself a user visible
representation of your action be sure to always use ICommand::action() for this.)
If this action is invoked by the user, the signal is forwarded to the registered action that
is valid for the current context.
You use this class also to add items to registered
action containers like the applications menu bar. For this you register your action via the
registerAction methods, get the action container for a specific id (like specified in
Core::Constants) with a call of
actionContainer(const QString&) and add your command to this container.
Guidelines:
\list
\o Always register your actions and shortcuts!
\o When registering an action with cmd=registerAction(action, id, contexts) be sure to connect
your own action connect(action, SIGNAL...) but make cmd->action() visible to the user, i.e.
widget->addAction(cmd->action()).
\o Use this class to add actions to the applications menus
\endlist
\sa Core::ICore, Core::ICommand
\sa Core::IActionContainer
*/
/*!
\fn virtual IActionContainer *ActionManagerInterface::createMenu(const QString &id) = 0
...
*/
/*!
\fn virtual IActionContainer *ActionManagerInterface::createMenuBar(const QString &id) = 0
...
*/
/*!
\fn virtual ICommand *ActionManagerInterface::registerAction(QAction *action, const QString &id, const QList<int> &context) = 0
...
*/
/*!
\fn virtual ICommand *ActionManagerInterface::registerShortcut(QShortcut *shortcut, const QString &id, const QList<int> &context) = 0
...
*/
/*!
\fn virtual ICommand *ActionManagerInterface::registerAction(QAction *action, const QString &id) = 0
...
*/
/*!
\fn virtual void ActionManagerInterface::addAction(ICommand *action, const QString &globalGroup) = 0
...
*/
/*!
\fn virtual void ActionManagerInterface::addMenu(IActionContainer *menu, const QString &globalGroup) = 0
...
*/
/*!
\fn virtual ICommand *ActionManagerInterface::command(const QString &id) const = 0
...
*/
/*!
\fn virtual IActionContainer *ActionManagerInterface::actionContainer(const QString &id) const = 0
...
*/
/*!
\fn virtual ActionManagerInterface::~ActionManagerInterface()
...
*/
using namespace Core;
using namespace Core::Internal;
ActionManager* ActionManager::m_instance = 0;
/*!
\class ActionManager
\ingroup qwb
\inheaderfile actionmanager.h
\sa ActionContainer
*/
/*!
...
*/
ActionManager::ActionManager(MainWindow *mainWnd, UniqueIDManager *uidmgr) :
ActionManagerInterface(mainWnd),
m_mainWnd(mainWnd)
{
m_defaultGroups << uidmgr->uniqueIdentifier(Constants::G_DEFAULT_ONE);
m_defaultGroups << uidmgr->uniqueIdentifier(Constants::G_DEFAULT_TWO);
m_defaultGroups << uidmgr->uniqueIdentifier(Constants::G_DEFAULT_THREE);
m_instance = this;
}
/*!
...
*/
ActionManager::~ActionManager()
{
qDeleteAll(m_idCmdMap.values());
qDeleteAll(m_idContainerMap.values());
}
/*!
...
*/
ActionManager* ActionManager::instance()
{
return m_instance;
}
/*!
...
*/
QList<int> ActionManager::defaultGroups() const
{
return m_defaultGroups;
}
/*!
...
*/
QList<Command *> ActionManager::commands() const
{
return m_idCmdMap.values();
}
/*!
...
*/
QList<ActionContainer *> ActionManager::containers() const
{
return m_idContainerMap.values();
}
/*!
...
*/
void ActionManager::registerGlobalGroup(int groupId, int containerId)
{
if (m_globalgroups.contains(groupId)) {
qWarning() << "registerGlobalGroup: Global group "
<< m_mainWnd->uniqueIDManager()->stringForUniqueIdentifier(groupId)
<< " already registered";
} else {
m_globalgroups.insert(groupId, containerId);
}
}
/*!
...
*/
bool ActionManager::hasContext(int context) const
{
return m_context.contains(context);
}
/*!
...
*/
void ActionManager::setContext(const QList<int> &context)
{
// here are possibilities for speed optimization if necessary:
// let commands (de-)register themselves for contexts
// and only update commands that are either in old or new contexts
m_context = context;
const IdCmdMap::const_iterator cmdcend = m_idCmdMap.constEnd();
for (IdCmdMap::const_iterator it = m_idCmdMap.constBegin(); it != cmdcend; ++it)
it.value()->setCurrentContext(m_context);
const IdContainerMap::const_iterator acend = m_idContainerMap.constEnd();
for ( IdContainerMap::const_iterator it = m_idContainerMap.constBegin(); it != acend; ++it)
it.value()->update();
}
/*!
\internal
*/
bool ActionManager::hasContext(QList<int> context) const
{
for (int i=0; i<m_context.count(); ++i) {
if (context.contains(m_context.at(i)))
return true;
}
return false;
}
/*!
...
*/
IActionContainer *ActionManager::createMenu(const QString &id)
{
const int uid = m_mainWnd->uniqueIDManager()->uniqueIdentifier(id);
const IdContainerMap::const_iterator it = m_idContainerMap.constFind(uid);
if (it != m_idContainerMap.constEnd())
return it.value();
QMenu *m = new QMenu(m_mainWnd);
m->setObjectName(id);
MenuActionContainer *mc = new MenuActionContainer(uid);
mc->setMenu(m);
m_idContainerMap.insert(uid, mc);
return mc;
}
/*!
...
*/
IActionContainer *ActionManager::createMenuBar(const QString &id)
{
const int uid = m_mainWnd->uniqueIDManager()->uniqueIdentifier(id);
const IdContainerMap::const_iterator it = m_idContainerMap.constFind(uid);
if (it != m_idContainerMap.constEnd())
return it.value();
QMenuBar *mb = new QMenuBar; // No parent (System menu bar on Mac OS X)
mb->setObjectName(id);
MenuBarActionContainer *mbc = new MenuBarActionContainer(uid);
mbc->setMenuBar(mb);
m_idContainerMap.insert(uid, mbc);
return mbc;
}
/*!
...
*/
ICommand *ActionManager::registerAction(QAction *action, const QString &id, const QList<int> &context)
{
OverrideableAction *a = 0;
ICommand *c = registerOverridableAction(action, id, false);
a = static_cast<OverrideableAction *>(c);
if (a)
a->addOverrideAction(action, context);
return a;
}
/*!
...
*/
ICommand *ActionManager::registerAction(QAction *action, const QString &id)
{
return registerOverridableAction(action, id, true);
}
/*!
\internal
*/
ICommand *ActionManager::registerOverridableAction(QAction *action, const QString &id, bool checkUnique)
{
OverrideableAction *a = 0;
const int uid = m_mainWnd->uniqueIDManager()->uniqueIdentifier(id);
if (Command *c = m_idCmdMap.value(uid, 0)) {
if (c->type() != ICommand::CT_OverridableAction) {
qWarning() << "registerAction: id" << id << "is registered with a different command type.";
return c;
}
a = static_cast<OverrideableAction *>(c);
}
if (!a) {
a = new OverrideableAction(uid);
m_idCmdMap.insert(uid, a);
}
if (!a->action()) {
QAction *baseAction = new QAction(m_mainWnd);
baseAction->setObjectName(id);
baseAction->setCheckable(action->isCheckable());
baseAction->setIcon(action->icon());
baseAction->setIconText(action->iconText());
baseAction->setText(action->text());
baseAction->setToolTip(action->toolTip());
baseAction->setStatusTip(action->statusTip());
baseAction->setWhatsThis(action->whatsThis());
baseAction->setChecked(action->isChecked());
baseAction->setSeparator(action->isSeparator());
baseAction->setShortcutContext(Qt::ApplicationShortcut);
baseAction->setEnabled(false);
baseAction->setObjectName(id);
baseAction->setParent(m_mainWnd);
#ifdef Q_OS_MAC
baseAction->setIconVisibleInMenu(false);
#endif
a->setAction(baseAction);
m_mainWnd->addAction(baseAction);
a->setKeySequence(a->keySequence());
a->setDefaultKeySequence(QKeySequence());
} else if (checkUnique) {
qWarning() << "registerOverridableAction: id" << id << "is already registered.";
}
return a;
}
/*!
...
*/
ICommand *ActionManager::registerShortcut(QShortcut *shortcut, const QString &id, const QList<int> &context)
{
Shortcut *sc = 0;
int uid = m_mainWnd->uniqueIDManager()->uniqueIdentifier(id);
if (Command *c = m_idCmdMap.value(uid, 0)) {
if (c->type() != ICommand::CT_Shortcut) {
qWarning() << "registerShortcut: id" << id << "is registered with a different command type.";
return c;
}
sc = static_cast<Shortcut *>(c);
} else {
sc = new Shortcut(uid);
m_idCmdMap.insert(uid, sc);
}
if (sc->shortcut()) {
qWarning() << "registerShortcut: action already registered (id" << id << ".";
return sc;
}
if (!hasContext(context))
shortcut->setEnabled(false);
shortcut->setObjectName(id);
shortcut->setParent(m_mainWnd);
sc->setShortcut(shortcut);
if (context.isEmpty())
sc->setContext(QList<int>() << 0);
else
sc->setContext(context);
sc->setKeySequence(shortcut->key());
sc->setDefaultKeySequence(QKeySequence());
return sc;
}
/*!
\fn void ActionManager::addAction(Core::ICommand *action, const QString &globalGroup)
*/
void ActionManager::addAction(ICommand *action, const QString &globalGroup)
{
const int gid = m_mainWnd->uniqueIDManager()->uniqueIdentifier(globalGroup);
if (!m_globalgroups.contains(gid)) {
qWarning() << "addAction: Unknown global group " << globalGroup;
return;
}
const int cid = m_globalgroups.value(gid);
if (IActionContainer *aci = actionContainer(cid)) {
aci->addAction(action, globalGroup);
} else {
qWarning() << "addAction: Cannot find container." << cid << '/' << gid;
}
}
/*!
\fn void ActionManager::addMenu(Core::IActionContainer *menu, const QString &globalGroup)
*/
void ActionManager::addMenu(IActionContainer *menu, const QString &globalGroup)
{
const int gid = m_mainWnd->uniqueIDManager()->uniqueIdentifier(globalGroup);
if (!m_globalgroups.contains(gid)) {
qWarning() << "addAction: Unknown global group " << globalGroup;
return;
}
const int cid = m_globalgroups.value(gid);
if (IActionContainer *aci = actionContainer(cid)) {
aci->addMenu(menu, globalGroup);
} else {
qWarning() << "addAction: Cannot find container." << cid << '/' << gid;
}
}
/*!
...
*/
ICommand *ActionManager::command(const QString &id) const
{
const int uid = m_mainWnd->uniqueIDManager()->uniqueIdentifier(id);
const IdCmdMap::const_iterator it = m_idCmdMap.constFind(uid);
if (it == m_idCmdMap.constEnd()) {
if (warnAboutFindFailures)
qWarning() << "ActionManager::command(): failed to find :" << id << '/' << uid;
return 0;
}
return it.value();
}
/*!
...
*/
IActionContainer *ActionManager::actionContainer(const QString &id) const
{
const int uid = m_mainWnd->uniqueIDManager()->uniqueIdentifier(id);
const IdContainerMap::const_iterator it = m_idContainerMap.constFind(uid);
if ( it == m_idContainerMap.constEnd()) {
if (warnAboutFindFailures)
qWarning() << "ActionManager::actionContainer(): failed to find :" << id << '/' << uid;
return 0;
}
return it.value();
}
/*!
...
*/
ICommand *ActionManager::command(int uid) const
{
const IdCmdMap::const_iterator it = m_idCmdMap.constFind(uid);
if (it == m_idCmdMap.constEnd()) {
if (warnAboutFindFailures)
qWarning() << "ActionManager::command(): failed to find :" << m_mainWnd->uniqueIDManager()->stringForUniqueIdentifier(uid) << '/' << uid;
return 0;
}
return it.value();
}
/*!
...
*/
IActionContainer *ActionManager::actionContainer(int uid) const
{
const IdContainerMap::const_iterator it = m_idContainerMap.constFind(uid);
if (it == m_idContainerMap.constEnd()) {
if (warnAboutFindFailures)
qWarning() << "ActionManager::actionContainer(): failed to find :" << m_mainWnd->uniqueIDManager()->stringForUniqueIdentifier(uid) << uid;
return 0;
}
return it.value();
}
static const char *settingsGroup = "KeyBindings";
static const char *idKey = "ID";
static const char *sequenceKey = "Keysequence";
/*!
\internal
*/
void ActionManager::initialize()
{
QSettings *settings = m_mainWnd->settings();
const int shortcuts = settings->beginReadArray(QLatin1String(settingsGroup));
for (int i=0; i<shortcuts; ++i) {
settings->setArrayIndex(i);
const QString sid = settings->value(QLatin1String(idKey)).toString();
const QKeySequence key(settings->value(QLatin1String(sequenceKey)).toString());
const int id = m_mainWnd->uniqueIDManager()->uniqueIdentifier(sid);
ICommand *cmd = command(id);
if (cmd)
cmd->setKeySequence(key);
}
settings->endArray();
}
/*!
...
*/
void ActionManager::saveSettings(QSettings *settings)
{
settings->beginWriteArray(QLatin1String(settingsGroup));
int count = 0;
const IdCmdMap::const_iterator cmdcend = m_idCmdMap.constEnd();
for (IdCmdMap::const_iterator j = m_idCmdMap.constBegin(); j != cmdcend; ++j) {
const int id = j.key();
Command *cmd = j.value();
QKeySequence key = cmd->keySequence();
if (key != cmd->defaultKeySequence()) {
const QString sid = m_mainWnd->uniqueIDManager()->stringForUniqueIdentifier(id);
settings->setArrayIndex(count);
settings->setValue(QLatin1String(idKey), sid);
settings->setValue(QLatin1String(sequenceKey), key.toString());
count++;
}
}
settings->endArray();
}

View File

@@ -0,0 +1,129 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef ACTIONMANAGER_H
#define ACTIONMANAGER_H
#include <coreplugin/actionmanager/actionmanagerinterface.h>
#include <QtCore/QMap>
#include <QtCore/QHash>
#include <QtCore/QMultiHash>
QT_BEGIN_NAMESPACE
class QSettings;
QT_END_NAMESPACE
struct CommandLocation {
int m_container;
int m_position;
};
namespace Core {
class UniqueIDManager;
namespace Internal {
class ActionContainer;
class MainWindow;
class Command;
class ActionManager : public Core::ActionManagerInterface
{
Q_OBJECT
public:
ActionManager(MainWindow *mainWnd, UniqueIDManager *uidmgr);
~ActionManager();
void setContext(const QList<int> &context);
static ActionManager* instance();
void saveSettings(QSettings *settings);
QList<int> defaultGroups() const;
QList<Command *> commands() const;
QList<ActionContainer *> containers() const;
bool hasContext(int context) const;
ICommand *command(int uid) const;
IActionContainer *actionContainer(int uid) const;
void registerGlobalGroup(int groupId, int containerId);
void initialize();
//ActionManager Interface
IActionContainer *createMenu(const QString &id);
IActionContainer *createMenuBar(const QString &id);
ICommand *registerAction(QAction *action, const QString &id,
const QList<int> &context);
ICommand *registerAction(QAction *action, const QString &id);
ICommand *registerShortcut(QShortcut *shortcut, const QString &id,
const QList<int> &context);
void addAction(Core::ICommand *action, const QString &globalGroup);
void addMenu(Core::IActionContainer *menu, const QString &globalGroup);
Core::ICommand *command(const QString &id) const;
Core::IActionContainer *actionContainer(const QString &id) const;
private:
bool hasContext(QList<int> context) const;
ICommand *registerOverridableAction(QAction *action, const QString &id,
bool checkUnique);
static ActionManager* m_instance;
QList<int> m_defaultGroups;
typedef QHash<int, Command *> IdCmdMap;
IdCmdMap m_idCmdMap;
typedef QHash<int, ActionContainer *> IdContainerMap;
IdContainerMap m_idContainerMap;
typedef QMap<int, int> GlobalGroupMap;
GlobalGroupMap m_globalgroups;
QList<int> m_context;
MainWindow *m_mainWnd;
};
} // namespace Internal
} // namespace Core
#endif //ACTIONMANAGER_H

View File

@@ -0,0 +1,76 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef ACTIONMANAGERINTERFACE_H
#define ACTIONMANAGERINTERFACE_H
#include "coreplugin/core_global.h"
#include <coreplugin/actionmanager/iactioncontainer.h>
#include <coreplugin/actionmanager/icommand.h>
#include <QtCore/QObject>
#include <QtCore/QList>
QT_BEGIN_NAMESPACE
class QAction;
class QShortcut;
class QString;
QT_END_NAMESPACE
namespace Core {
class CORE_EXPORT ActionManagerInterface : public QObject
{
Q_OBJECT
public:
ActionManagerInterface(QObject *parent = 0) : QObject(parent) {}
virtual ~ActionManagerInterface() {}
virtual IActionContainer *createMenu(const QString &id) = 0;
virtual IActionContainer *createMenuBar(const QString &id) = 0;
virtual ICommand *registerAction(QAction *action, const QString &id, const QList<int> &context) = 0;
virtual ICommand *registerShortcut(QShortcut *shortcut, const QString &id, const QList<int> &context) = 0;
virtual ICommand *registerAction(QAction *action, const QString &id) = 0;
virtual void addAction(ICommand *action, const QString &globalGroup) = 0;
virtual void addMenu(IActionContainer *menu, const QString &globalGroup) = 0;
virtual ICommand *command(const QString &id) const = 0;
virtual IActionContainer *actionContainer(const QString &id) const = 0;
};
} // namespace Core
#endif // ACTIONMANAGERINTERFACE_H

View File

@@ -0,0 +1,579 @@
/***************************************************************************
**
** 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 <QtCore/QDebug>
#include <QtGui/QAction>
#include <QtGui/QShortcut>
#include "command.h"
/*!
\class Core::ICommand
\mainclass
\ingroup qwb
\inheaderfile icommand.h
\brief The class...
The Command interface...
*/
/*!
\enum ICommand::CommandType
*/
/*!
\enum ICommand::CommandAttribute
*/
/*!
\fn void ICommand::setCategory(const QString &name)
Sets the category to \a name.
*/
/*!
\fn virtual void ICommand::setDefaultKeySequence(const QKeySequence &key)
*/
/*!
\fn virtual int ICommand::id() const
*/
/*!
\fn virtual CommandType ICommand::type() const
*/
/*!
\fn virtual QAction *ICommand::action() const
*/
/*!
\fn virtual QShortcut *ICommand::shortcut() const
*/
/*!
\fn virtual void ICommand::setAttribute(CommandAttribute attr)
*/
/*!
\fn virtual void ICommand::removeAttribute(CommandAttribute attr)
*/
/*!
\fn virtual bool ICommand::hasAttribute(CommandAttribute attr) const
*/
/*!
\fn virtual bool ICommand::isActive() const
*/
/*!
\fn virtual ICommand::~ICommand()
*/
using namespace Core::Internal;
/*!
\class Command
\ingroup qwb
\inheaderfile command.h
*/
/*!
\enum Command::CommandState
*/
/*!
\fn Command::Command(CommandType type, int id)
*/
Command::Command(CommandType type, int id)
: m_type(type), m_id(id)
{
}
/*!
\fn virtual Command::~Command()
*/
/*!
...
*/
void Command::setStateFlags(int state)
{
m_type |= (state & CS_Mask);
}
/*!
...
*/
int Command::stateFlags() const
{
return (m_type & CS_Mask);
}
/*!
\fn virtual QString Command::name() const
*/
/*!
...
*/
void Command::setCategory(const QString &name)
{
m_category = name;
}
/*!
...
*/
QString Command::category() const
{
if (m_category.isEmpty())
return QObject::tr("Other");
return m_category;
}
/*!
...
*/
void Command::setDefaultKeySequence(const QKeySequence &key)
{
m_defaultKey = key;
}
/*!
...
*/
QKeySequence Command::defaultKeySequence() const
{
return m_defaultKey;
}
void Command::setDefaultText(const QString &text)
{
m_defaultText = text;
}
QString Command::defaultText() const
{
return m_defaultText;
}
/*!
...
*/
int Command::id() const
{
return m_id;
}
/*!
...
*/
Command::CommandType Command::type() const
{
return (CommandType)(m_type & CT_Mask);
}
/*!
...
*/
QAction *Command::action() const
{
return 0;
}
/*!
...
*/
QShortcut *Command::shortcut() const
{
return 0;
}
/*!
...
*/
void Command::setAttribute(CommandAttribute attr)
{
m_type |= attr;
}
/*!
...
*/
void Command::removeAttribute(CommandAttribute attr)
{
m_type &= ~attr;
}
/*!
...
*/
bool Command::hasAttribute(CommandAttribute attr) const
{
return (m_type & attr);
}
QString Command::stringWithAppendedShortcut(const QString &str) const
{
return QString("%1 <span style=\"color: gray; font-size: small\">%2</span>").arg(str).arg(
keySequence().toString(QKeySequence::NativeText));
}
/*!
\fn virtual bool Command::setCurrentContext(const QList<int> &context) = 0
*/
// ---------- Shortcut ------------
/*!
\class Shortcut
\ingroup qwb
\inheaderfile command.h
*/
/*!
...
*/
Shortcut::Shortcut(int id)
: Command(CT_Shortcut, id), m_shortcut(0)
{
}
/*!
...
*/
QString Shortcut::name() const
{
if (!m_shortcut)
return QString();
return m_shortcut->whatsThis();
}
/*!
...
*/
void Shortcut::setShortcut(QShortcut *shortcut)
{
m_shortcut = shortcut;
}
/*!
...
*/
QShortcut *Shortcut::shortcut() const
{
return m_shortcut;
}
/*!
...
*/
void Shortcut::setContext(const QList<int> &context)
{
m_context = context;
}
/*!
...
*/
QList<int> Shortcut::context() const
{
return m_context;
}
/*!
...
*/
void Shortcut::setDefaultKeySequence(const QKeySequence &key)
{
setKeySequence(key);
Command::setDefaultKeySequence(key);
}
void Shortcut::setKeySequence(const QKeySequence &key)
{
m_shortcut->setKey(key);
emit keySequenceChanged();
}
QKeySequence Shortcut::keySequence() const
{
return m_shortcut->key();
}
void Shortcut::setDefaultText(const QString &text)
{
m_defaultText = text;
}
QString Shortcut::defaultText() const
{
return m_defaultText;
}
/*!
...
*/
bool Shortcut::setCurrentContext(const QList<int> &context)
{
foreach (int ctxt, m_context) {
if (context.contains(ctxt)) {
m_shortcut->setEnabled(true);
return true;
}
}
m_shortcut->setEnabled(false);
return false;
}
/*!
...
*/
bool Shortcut::isActive() const
{
return m_shortcut->isEnabled();
}
// ---------- Action ------------
/*!
\class Action
\ingroup qwb
\inheaderfile command.h
*/
/*!
...
*/
Action::Action(CommandType type, int id)
: Command(type, id), m_action(0)
{
}
/*!
...
*/
QString Action::name() const
{
if (!m_action)
return QString();
return m_action->text();
}
/*!
...
*/
void Action::setAction(QAction *action)
{
m_action = action;
if (m_action) {
m_action->setParent(this);
m_toolTip = m_action->toolTip();
}
}
/*!
...
*/
QAction *Action::action() const
{
return m_action;
}
/*!
...
*/
void Action::setLocations(const QList<CommandLocation> &locations)
{
m_locations = locations;
}
/*!
...
*/
QList<CommandLocation> Action::locations() const
{
return m_locations;
}
/*!
...
*/
void Action::setDefaultKeySequence(const QKeySequence &key)
{
setKeySequence(key);
Command::setDefaultKeySequence(key);
}
void Action::setKeySequence(const QKeySequence &key)
{
m_action->setShortcut(key);
updateToolTipWithKeySequence();
emit keySequenceChanged();
}
void Action::updateToolTipWithKeySequence()
{
if (m_action->shortcut().isEmpty())
m_action->setToolTip(m_toolTip);
else
m_action->setToolTip(stringWithAppendedShortcut(m_toolTip));
}
QKeySequence Action::keySequence() const
{
return m_action->shortcut();
}
// ---------- OverrideableAction ------------
/*!
\class OverrideableAction
\ingroup qwb
\inheaderfile command.h
*/
/*!
...
*/
OverrideableAction::OverrideableAction(int id)
: Action(CT_OverridableAction, id), m_currentAction(0), m_active(false),
m_contextInitialized(false)
{
}
/*!
...
*/
void OverrideableAction::setAction(QAction *action)
{
Action::setAction(action);
}
/*!
...
*/
bool OverrideableAction::setCurrentContext(const QList<int> &context)
{
m_context = context;
QAction *oldAction = m_currentAction;
m_currentAction = 0;
for (int i = 0; i < m_context.size(); ++i) {
if (QAction *a = m_contextActionMap.value(m_context.at(i), 0)) {
m_currentAction = a;
break;
}
}
if (m_currentAction == oldAction && m_contextInitialized)
return true;
m_contextInitialized = true;
if (oldAction) {
disconnect(oldAction, SIGNAL(changed()), this, SLOT(actionChanged()));
disconnect(m_action, SIGNAL(triggered(bool)), oldAction, SIGNAL(triggered(bool)));
disconnect(m_action, SIGNAL(toggled(bool)), oldAction, SLOT(setChecked(bool)));
}
if (m_currentAction) {
connect(m_currentAction, SIGNAL(changed()), this, SLOT(actionChanged()));
// we want to avoid the toggling semantic on slot trigger(), so we just connect the signals
connect(m_action, SIGNAL(triggered(bool)), m_currentAction, SIGNAL(triggered(bool)));
// we need to update the checked state, so we connect to setChecked slot, which also fires a toggled signal
connect(m_action, SIGNAL(toggled(bool)), m_currentAction, SLOT(setChecked(bool)));
actionChanged();
m_active = true;
return true;
}
if (hasAttribute(CA_Hide))
m_action->setVisible(false);
m_action->setEnabled(false);
m_active = false;
return false;
}
/*!
...
*/
void OverrideableAction::addOverrideAction(QAction *action, const QList<int> &context)
{
if (context.isEmpty()) {
m_contextActionMap.insert(0, action);
} else {
for (int i=0; i<context.size(); ++i) {
int k = context.at(i);
if (m_contextActionMap.contains(k))
qWarning() << QString("addOverrideAction: action already registered for context when registering '%1'").arg(action->text());
m_contextActionMap.insert(k, action);
}
}
}
/*!
...
*/
void OverrideableAction::actionChanged()
{
if (hasAttribute(CA_UpdateIcon)) {
m_action->setIcon(m_currentAction->icon());
m_action->setIconText(m_currentAction->iconText());
}
if (hasAttribute(CA_UpdateText)) {
m_action->setText(m_currentAction->text());
m_toolTip = m_currentAction->toolTip();
updateToolTipWithKeySequence();
m_action->setStatusTip(m_currentAction->statusTip());
m_action->setWhatsThis(m_currentAction->whatsThis());
}
bool block = m_action->blockSignals(true);
m_action->setChecked(m_currentAction->isChecked());
m_action->blockSignals(block);
m_action->setEnabled(m_currentAction->isEnabled());
m_action->setVisible(m_currentAction->isVisible());
}
/*!
...
*/
bool OverrideableAction::isActive() const
{
return m_active;
}

View File

@@ -0,0 +1,178 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef COMMAND_H
#define COMMAND_H
#include "icommand.h"
#include "actionmanager.h"
#include <QtCore/QList>
#include <QtCore/QMultiMap>
#include <QtCore/QPointer>
#include <QtGui/QKeySequence>
namespace Core {
namespace Internal {
class Command : public Core::ICommand
{
Q_OBJECT
public:
enum CommandState {
CS_PreLocation = 0x020000,
CS_LocationChanged = 0x040000,
CS_Initialized = 0x080000,
CS_Mask = 0xFF0000
};
Command(CommandType type, int id);
virtual ~Command() {}
void setStateFlags(int state);
int stateFlags() const;
virtual QString name() const = 0;
void setCategory(const QString &name);
QString category() const;
void setDefaultKeySequence(const QKeySequence &key);
QKeySequence defaultKeySequence() const;
void setDefaultText(const QString &text);
QString defaultText() const;
int id() const;
CommandType type() const;
QAction *action() const;
QShortcut *shortcut() const;
void setAttribute(CommandAttribute attr);
void removeAttribute(CommandAttribute attr);
bool hasAttribute(CommandAttribute attr) const;
virtual bool setCurrentContext(const QList<int> &context) = 0;
QString stringWithAppendedShortcut(const QString &str) const;
protected:
QString m_category;
int m_type;
int m_id;
QKeySequence m_defaultKey;
QString m_defaultText;
};
class Shortcut : public Command
{
Q_OBJECT
public:
Shortcut(int id);
QString name() const;
void setDefaultKeySequence(const QKeySequence &key);
void setKeySequence(const QKeySequence &key);
QKeySequence keySequence() const;
virtual void setDefaultText(const QString &key);
virtual QString defaultText() const;
void setShortcut(QShortcut *shortcut);
QShortcut *shortcut() const;
void setContext(const QList<int> &context);
QList<int> context() const;
bool setCurrentContext(const QList<int> &context);
bool isActive() const;
private:
QList<int> m_context;
QShortcut *m_shortcut;
QString m_defaultText;
};
class Action : public Command
{
Q_OBJECT
public:
Action(CommandType type, int id);
QString name() const;
void setDefaultKeySequence(const QKeySequence &key);
void setKeySequence(const QKeySequence &key);
QKeySequence keySequence() const;
virtual void setAction(QAction *action);
QAction *action() const;
void setLocations(const QList<CommandLocation> &locations);
QList<CommandLocation> locations() const;
protected:
void updateToolTipWithKeySequence();
QAction *m_action;
QList<CommandLocation> m_locations;
QString m_toolTip;
};
class OverrideableAction : public Action
{
Q_OBJECT
public:
OverrideableAction(int id);
void setAction(QAction *action);
bool setCurrentContext(const QList<int> &context);
void addOverrideAction(QAction *action, const QList<int> &context);
bool isActive() const;
private slots:
void actionChanged();
private:
QPointer<QAction> m_currentAction;
QList<int> m_context;
QMap<int, QPointer<QAction> > m_contextActionMap;
bool m_active;
bool m_contextInitialized;
};
} // namespace Internal
} // namespace Core
#endif //COMMAND_H

View File

@@ -0,0 +1,126 @@
/***************************************************************************
**
** 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 "coreimpl.h"
#include "commandsfile.h"
#include "shortcutsettings.h"
#include "command.h"
#include <coreplugin/uniqueidmanager.h>
#include <QtCore/QFile>
#include <QtXml/QDomDocument>
using namespace Core;
using namespace Core::Internal;
/*!
\class CommandsFile
\brief The CommandsFile class provides a collection of import and export commands.
\ingroup qwb
\inheaderfile commandsfile.h
*/
/*!
...
*/
CommandsFile::CommandsFile(const QString &filename)
: m_filename(filename)
{
}
/*!
...
*/
QMap<QString, QKeySequence> CommandsFile::importCommands() const
{
QMap<QString, QKeySequence> result;
QFile file(m_filename);
if (!file.open(QIODevice::ReadOnly))
return result;
QDomDocument doc("KeyboardMappingScheme");
if (!doc.setContent(&file))
return result;
QDomElement root = doc.documentElement();
if (root.nodeName() != QLatin1String("mapping"))
return result;
QDomElement ks = root.firstChildElement();
for (; !ks.isNull(); ks = ks.nextSiblingElement()) {
if (ks.nodeName() == QLatin1String("shortcut")) {
QString id = ks.attribute(QLatin1String("id"));
QKeySequence shortcutkey;
QDomElement keyelem = ks.firstChildElement("key");
if (!keyelem.isNull())
shortcutkey = QKeySequence(keyelem.attribute("value"));
result.insert(id, shortcutkey);
}
}
file.close();
return result;
}
/*!
...
*/
bool CommandsFile::exportCommands(const QList<ShortcutItem *> &items)
{
UniqueIDManager *idmanager = CoreImpl::instance()->uniqueIDManager();
QFile file(m_filename);
if (!file.open(QIODevice::WriteOnly))
return false;
QDomDocument doc("KeyboardMappingScheme");
QDomElement root = doc.createElement("mapping");
doc.appendChild(root);
for (int i=0; i<items.count(); ++i) {
ShortcutItem *item = items.at(i);
QDomElement ctag = doc.createElement("shortcut");
ctag.setAttribute(QLatin1String("id"), idmanager->stringForUniqueIdentifier(item->m_cmd->id()));
root.appendChild(ctag);
QDomElement ktag = doc.createElement("key");
ktag.setAttribute(QLatin1String("value"), item->m_key.toString());
ctag.appendChild(ktag);
}
file.write(doc.toByteArray());
file.close();
return true;
}

View File

@@ -0,0 +1,63 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef COMMANDSFILE_H
#define COMMANDSFILE_H
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QMap>
#include <QtCore/QList>
#include <QtGui/QKeySequence>
namespace Core {
namespace Internal {
struct ShortcutItem;
class CommandsFile : public QObject {
Q_OBJECT
public:
CommandsFile(const QString &filename);
QMap<QString, QKeySequence> importCommands() const;
bool exportCommands(const QList<ShortcutItem *> &items);
private:
QString m_filename;
};
} // namespace Internal
} // namespace Core
#endif //COMMANDSFILE_H

View File

@@ -0,0 +1,81 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef IACTIONCONTAINER_H
#define IACTIONCONTAINER_H
#include <QtCore/QObject>
#include <QtGui/QMenu>
#include <QtGui/QToolBar>
#include <QtGui/QMenuBar>
#include <QtGui/QAction>
namespace Core {
class ICommand;
class IActionContainer : public QObject
{
public:
enum ContainerType {
CT_Mask = 0xFF,
CT_Menu = 0x01,
CT_ToolBar = 0x02
};
enum EmptyAction {
EA_Mask = 0xFF00,
EA_None = 0x0100,
EA_Hide = 0x0200,
EA_Disable = 0x0300
};
virtual void setEmptyAction(EmptyAction ea) = 0;
virtual int id() const = 0;
virtual ContainerType type() const = 0;
virtual QMenu *menu() const = 0;
virtual QToolBar *toolBar() const = 0;
virtual QMenuBar *menuBar() const = 0;
virtual QAction *insertLocation(const QString &group) const = 0;
virtual void appendGroup(const QString &group, bool global = false) = 0;
virtual void addAction(Core::ICommand *action, const QString &group = QString()) = 0;
virtual void addMenu(Core::IActionContainer *menu, const QString &group = QString()) = 0;
virtual bool update() = 0;
virtual ~IActionContainer() {}
};
} // namespace Core
#endif // IACTIONCONTAINER_H

View File

@@ -0,0 +1,93 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef ICOMMAND_H
#define ICOMMAND_H
#include <coreplugin/core_global.h>
#include <QtGui/QAction>
#include <QtGui/QShortcut>
#include <QtGui/QKeySequence>
namespace Core {
class CORE_EXPORT ICommand : public QObject
{
Q_OBJECT
public:
enum CommandType {
CT_Shortcut = 0x0001,
CT_OverridableAction = 0x0002,
CT_Mask = 0x00FF
};
enum CommandAttribute {
CA_Hide = 0x0100,
CA_UpdateText = 0x0200,
CA_UpdateIcon = 0x0400,
CA_NonConfigureable = 0x8000,
CA_Mask = 0xFF00
};
virtual void setDefaultKeySequence(const QKeySequence &key) = 0;
virtual void setKeySequence(const QKeySequence &key) = 0;
virtual QKeySequence defaultKeySequence() const = 0;
virtual QKeySequence keySequence() const = 0;
virtual void setDefaultText(const QString &text) = 0;
virtual QString defaultText() const = 0;
virtual void setCategory(const QString &name) = 0;
virtual int id() const = 0;
virtual CommandType type() const = 0;
virtual QAction *action() const = 0;
virtual QShortcut *shortcut() const = 0;
virtual void setAttribute(CommandAttribute attr) = 0;
virtual void removeAttribute(CommandAttribute attr) = 0;
virtual bool hasAttribute(CommandAttribute attr) const = 0;
virtual bool isActive() const = 0;
virtual ~ICommand() {}
virtual QString stringWithAppendedShortcut(const QString &str) const = 0;
signals:
void keySequenceChanged();
};
} // namespace Core
#endif // ICOMMAND_H

View File

@@ -0,0 +1,671 @@
/***************************************************************************
**
** 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 "basefilewizard.h"
#include "mimedatabase.h"
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/ifilewizardextension.h>
#include <utils/filewizarddialog.h>
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QVector>
#include <QtCore/QDebug>
#include <QtCore/QSharedData>
#include <QtCore/QEventLoop>
#include <QtCore/QSharedPointer>
#include <QtGui/QMessageBox>
#include <QtGui/QWizard>
#include <QtGui/QMainWindow>
enum { debugWizard = 0 };
namespace Core {
class GeneratedFilePrivate : public QSharedData {
public:
GeneratedFilePrivate() {}
explicit GeneratedFilePrivate(const QString &p);
QString path;
QString contents;
QString editorKind;
};
GeneratedFilePrivate::GeneratedFilePrivate(const QString &p) :
path(p)
{
}
GeneratedFile::GeneratedFile() :
m_d(new GeneratedFilePrivate)
{
}
GeneratedFile::GeneratedFile(const QString &p) :
m_d(new GeneratedFilePrivate(p))
{
}
GeneratedFile::GeneratedFile(const GeneratedFile &rhs) :
m_d(rhs.m_d)
{
}
GeneratedFile &GeneratedFile::operator=(const GeneratedFile &rhs)
{
if (this != &rhs)
m_d.operator=(rhs.m_d);
return *this;
}
GeneratedFile::~GeneratedFile()
{
}
QString GeneratedFile::path() const
{
return m_d->path;
}
void GeneratedFile::setPath(const QString &p)
{
m_d->path = p;
}
QString GeneratedFile::contents() const
{
return m_d->contents;
}
void GeneratedFile::setContents(const QString &c)
{
m_d->contents = c;
}
QString GeneratedFile::editorKind() const
{
return m_d->editorKind;
}
void GeneratedFile::setEditorKind(const QString &k)
{
m_d->editorKind = k;
}
bool GeneratedFile::write(QString *errorMessage) const
{
// Ensure the directory
const QFileInfo info(m_d->path);
const QDir dir = info.absoluteDir();
if (!dir.exists()) {
if (!dir.mkpath(dir.absolutePath())) {
*errorMessage = BaseFileWizard::tr("Unable to create the directory %1.").arg(dir.absolutePath());
return false;
}
}
// Write out
QFile file(m_d->path);
if (!file.open(QIODevice::WriteOnly|QIODevice::Text)) {
*errorMessage = BaseFileWizard::tr("Unable to open %1 for writing: %2").arg(m_d->path, file.errorString());
return false;
}
if (file.write(m_d->contents.toUtf8()) == -1) {
*errorMessage = BaseFileWizard::tr("Error while writing to %1: %2").arg(m_d->path, file.errorString());
return false;
}
file.close();
return true;
}
// ------------ BaseFileWizardParameterData
class BaseFileWizardParameterData : public QSharedData {
public:
explicit BaseFileWizardParameterData(IWizard::Kind kind = IWizard::FileWizard);
IWizard::Kind kind;
QIcon icon;
QString description;
QString name;
QString category;
QString trCategory;
};
BaseFileWizardParameterData::BaseFileWizardParameterData(IWizard::Kind k) :
kind(k)
{
}
BaseFileWizardParameters::BaseFileWizardParameters(IWizard::Kind kind) :
m_d(new BaseFileWizardParameterData(kind))
{
}
BaseFileWizardParameters::BaseFileWizardParameters(const BaseFileWizardParameters &rhs) :
m_d(rhs.m_d)
{
}
BaseFileWizardParameters &BaseFileWizardParameters::operator=(const BaseFileWizardParameters &rhs)
{
if (this != &rhs)
m_d.operator=(rhs.m_d);
return *this;
}
BaseFileWizardParameters::~BaseFileWizardParameters()
{
}
IWizard::Kind BaseFileWizardParameters::kind() const
{
return m_d->kind;
}
void BaseFileWizardParameters::setKind(IWizard::Kind k)
{
m_d->kind = k;
}
QIcon BaseFileWizardParameters::icon() const
{
return m_d->icon;
}
void BaseFileWizardParameters::setIcon(const QIcon &icon)
{
m_d->icon = icon;
}
QString BaseFileWizardParameters::description() const
{
return m_d->description;
}
void BaseFileWizardParameters::setDescription(const QString &v)
{
m_d->description = v;
}
QString BaseFileWizardParameters::name() const
{
return m_d->name;
}
void BaseFileWizardParameters::setName(const QString &v)
{
m_d->name = v;
}
QString BaseFileWizardParameters::category() const
{
return m_d->category;
}
void BaseFileWizardParameters::setCategory(const QString &v)
{
m_d->category = v;
}
QString BaseFileWizardParameters::trCategory() const
{
return m_d->trCategory;
}
void BaseFileWizardParameters::setTrCategory(const QString &v)
{
m_d->trCategory = v;
}
/* WizardEventLoop: Special event loop that runs a QWizard and terminates if the page changes.
* Synopsis:
* \code
Wizard wizard(parent);
WizardEventLoop::WizardResult wr;
do {
wr = WizardEventLoop::execWizardPage(wizard);
} while (wr == WizardEventLoop::PageChanged);
* \endcode */
class WizardEventLoop : public QEventLoop
{
Q_OBJECT
Q_DISABLE_COPY(WizardEventLoop)
WizardEventLoop(QObject *parent);
public:
enum WizardResult { Accepted, Rejected , PageChanged };
static WizardResult execWizardPage(QWizard &w);
private slots:
void pageChanged(int);
void accepted();
void rejected();
private:
WizardResult execWizardPageI();
WizardResult m_result;
};
WizardEventLoop::WizardEventLoop(QObject *parent) :
QEventLoop(parent),
m_result(Rejected)
{
}
WizardEventLoop::WizardResult WizardEventLoop::execWizardPage(QWizard &wizard)
{
/* Install ourselves on the wizard. Main trick is here to connect
* to the page changed signal and quit() on it. */
WizardEventLoop *eventLoop = wizard.findChild<WizardEventLoop *>();
if (!eventLoop) {
eventLoop = new WizardEventLoop(&wizard);
connect(&wizard, SIGNAL(currentIdChanged(int)), eventLoop, SLOT(pageChanged(int)));
connect(&wizard, SIGNAL(accepted()), eventLoop, SLOT(accepted()));
connect(&wizard, SIGNAL(rejected()), eventLoop, SLOT(rejected()));
wizard.setAttribute(Qt::WA_ShowModal, true);
wizard.show();
}
const WizardResult result = eventLoop->execWizardPageI();
// Quitting?
if (result != PageChanged)
delete eventLoop;
if (debugWizard)
qDebug() << "WizardEventLoop::runWizard" << wizard.pageIds() << " returns " << result;
return result;
}
WizardEventLoop::WizardResult WizardEventLoop::execWizardPageI()
{
m_result = Rejected;
exec(QEventLoop::DialogExec);
return m_result;
}
void WizardEventLoop::pageChanged(int /*page*/)
{
m_result = PageChanged;
quit(); // !
}
void WizardEventLoop::accepted()
{
m_result = Accepted;
quit();
}
void WizardEventLoop::rejected()
{
m_result = Rejected;
quit();
}
// ---------------- BaseFileWizardPrivate
struct BaseFileWizardPrivate {
explicit BaseFileWizardPrivate(const Core::BaseFileWizardParameters &parameters,
Core::ICore *core);
const Core::BaseFileWizardParameters m_parameters;
QWizard *m_wizardDialog;
Core::ICore *m_core;
};
Core::BaseFileWizardPrivate::BaseFileWizardPrivate(const BaseFileWizardParameters &parameters,
Core::ICore *core) :
m_parameters(parameters),
m_wizardDialog(0),
m_core(core)
{
}
// ---------------- Wizard
BaseFileWizard::BaseFileWizard(const BaseFileWizardParameters &parameters,
Core::ICore *core,
QObject *parent) :
IWizard(parent),
m_d(new BaseFileWizardPrivate(parameters, core))
{
}
BaseFileWizard::~BaseFileWizard()
{
delete m_d;
}
IWizard::Kind BaseFileWizard::kind() const
{
return m_d->m_parameters.kind();
}
QIcon BaseFileWizard::icon() const
{
return m_d->m_parameters.icon();
}
QString BaseFileWizard::description() const
{
return m_d->m_parameters.description();
}
QString BaseFileWizard::name() const
{
return m_d->m_parameters.name();
}
QString BaseFileWizard::category() const
{
return m_d->m_parameters.category();
}
QString BaseFileWizard::trCategory() const
{
return m_d->m_parameters.trCategory();
}
QStringList BaseFileWizard::runWizard(const QString &path, QWidget *parent)
{
typedef QList<IFileWizardExtension*> ExtensionList;
QString errorMessage;
// Compile extension pages, purge out unused ones
ExtensionList extensions = ExtensionSystem::PluginManager::instance()->getObjects<IFileWizardExtension>();
WizardPageList allExtensionPages;
for (ExtensionList::iterator it = extensions.begin(); it != extensions.end(); ) {
const WizardPageList extensionPages = (*it)->extensionPages(this);
if (extensionPages.empty()) {
it = extensions.erase(it);
} else {
allExtensionPages += extensionPages;
++it;
}
}
if (debugWizard)
qDebug() << Q_FUNC_INFO << path << parent << "exs" << extensions.size() << allExtensionPages.size();
QWizardPage *firstExtensionPage = 0;
if (!allExtensionPages.empty())
firstExtensionPage = allExtensionPages.front();
// Create dialog and run it. Ensure that the dialog is deleted when
// leaving the func, but not before the IFileWizardExtension::process
// has been called
const QSharedPointer<QWizard> wizard(createWizardDialog(parent, path, allExtensionPages));
GeneratedFiles files;
// Run the wizard: Call generate files on switching to the first extension
// page is OR after 'Accepted' if there are no extension pages
while (true) {
const WizardEventLoop::WizardResult wr = WizardEventLoop::execWizardPage(*wizard);
if (wr == WizardEventLoop::Rejected) {
files.clear();
break;
}
const bool accepted = wr == WizardEventLoop::Accepted;
const bool firstExtensionPageHit = wr == WizardEventLoop::PageChanged
&& wizard->page(wizard->currentId()) == firstExtensionPage;
const bool needGenerateFiles = firstExtensionPageHit || (accepted && allExtensionPages.empty());
if (needGenerateFiles) {
QString errorMessage;
files = generateFiles(wizard.data(), &errorMessage);
if (files.empty()) {
QMessageBox::critical(0, tr("File Generation Failure"), errorMessage);
break;
}
}
if (firstExtensionPageHit)
foreach(IFileWizardExtension *ex, extensions)
ex->firstExtensionPageShown(files);
if (accepted)
break;
}
if (files.empty())
return QStringList();
// Compile result list and prompt for overwrite
QStringList result;
foreach (const GeneratedFile &generatedFile, files)
result.push_back(generatedFile.path());
switch (promptOverwrite(path, result, &errorMessage)) {
case OverwriteCanceled:
return QStringList();
case OverwriteError:
QMessageBox::critical(0, tr("Existing files"), errorMessage);
return QStringList();
case OverwriteOk:
break;
}
// Write
foreach (const GeneratedFile &generatedFile, files) {
if (!generatedFile.write(&errorMessage)) {
QMessageBox::critical(parent, tr("File Generation Failure"), errorMessage);
return QStringList();
}
}
// Run the extensions
foreach(IFileWizardExtension *ex, extensions)
if (!ex->process(files, &errorMessage)) {
QMessageBox::critical(parent, tr("File Generation Failure"), errorMessage);
return QStringList();
}
// Post generation handler
if (!postGenerateFiles(files, &errorMessage)) {
QMessageBox::critical(0, tr("File Generation Failure"), errorMessage);
return QStringList();
}
return result;
}
QPixmap BaseFileWizard::watermark()
{
return QPixmap(QLatin1String(":/qworkbench/images/qtwatermark.png"));
}
void BaseFileWizard::setupWizard(QWizard *w)
{
w->setPixmap(QWizard::WatermarkPixmap, watermark());
}
bool BaseFileWizard::postGenerateFiles(const GeneratedFiles &l, QString *errorMessage)
{
// File mode: open the editors in file mode and ensure editor pane
const Core::GeneratedFiles::const_iterator cend = l.constEnd();
for (Core::GeneratedFiles::const_iterator it = l.constBegin(); it != cend; ++it) {
if (!m_d->m_core->editorManager()->openEditor(it->path(), it->editorKind())) {
*errorMessage = tr("Failed to open an editor for %1").arg(it->path());
return false;
}
}
m_d->m_core->editorManager()->ensureEditorManagerVisible();
return true;
}
BaseFileWizard::OverwriteResult BaseFileWizard::promptOverwrite(const QString &location,
const QStringList &files,
QString *errorMessage) const
{
if (debugWizard)
qDebug() << Q_FUNC_INFO << location << files;
bool existingFilesFound = false;
bool oddStuffFound = false;
static const QString readOnlyMsg = tr(" [read only]");
static const QString directoryMsg = tr(" [directory]");
static const QString symLinkMsg = tr(" [symbolic link]");
// Format a file list message as ( "<file1> [readonly], <file2> [directory]").
QString fileNamesMsgPart;
foreach (const QString &fileName, files) {
const QFileInfo fi(fileName);
if (fi.exists()) {
existingFilesFound = true;
if (!fileNamesMsgPart.isEmpty())
fileNamesMsgPart += QLatin1String(", ");
fileNamesMsgPart += fi.fileName();
do {
if (fi.isDir()) {
oddStuffFound = true;
fileNamesMsgPart += directoryMsg;
break;
}
if (fi.isSymLink()) {
oddStuffFound = true;
fileNamesMsgPart += symLinkMsg;
break;
}
if (!fi.isWritable()) {
oddStuffFound = true;
fileNamesMsgPart += readOnlyMsg;
}
} while (false);
}
}
if (!existingFilesFound)
return OverwriteOk;
if (oddStuffFound) {
*errorMessage = tr("The project directory %1 contains files which cannot be overwritten:\n%2.").arg(location).arg(fileNamesMsgPart);
return OverwriteError;
}
const QString messageFormat = tr("The following files already exist in the directory %1:\n"
"%2.\nWould you like to overwrite them?");
const QString message = messageFormat.arg(location).arg(fileNamesMsgPart);
const bool yes = (QMessageBox::question(core()->mainWindow(),
tr("Existing files"), message,
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No)
== QMessageBox::Yes);
return yes ? OverwriteOk : OverwriteCanceled;
}
Core::ICore *BaseFileWizard::core() const
{
return m_d->m_core;
}
QList<IWizard*> BaseFileWizard::allWizards()
{
return ExtensionSystem::PluginManager::instance()->getObjects<IWizard>();
}
// Utility to find all registered wizards of a certain kind
class WizardKindPredicate {
public:
WizardKindPredicate(IWizard::Kind kind) : m_kind(kind) {}
bool operator()(const IWizard &w) const { return w.kind() == m_kind; }
private:
const IWizard::Kind m_kind;
};
QList<IWizard*> BaseFileWizard::findWizardsOfKind(Kind kind)
{
return findWizards(WizardKindPredicate(kind));
}
QString BaseFileWizard::buildFileName(const QString &path,
const QString &baseName,
const QString &extension)
{
QString rc = path;
if (!rc.isEmpty() && !rc.endsWith(QDir::separator()))
rc += QDir::separator();
rc += baseName;
// Add extension unless user specified something else
const QChar dot = QLatin1Char('.');
if (!extension.isEmpty() && !baseName.contains(dot)) {
if (!extension.startsWith(dot))
rc += dot;
rc += extension;
}
if (debugWizard)
qDebug() << Q_FUNC_INFO << rc;
return rc;
}
QString BaseFileWizard::preferredSuffix(const QString &mimeType) const
{
const QString rc = m_d->m_core->mimeDatabase()->preferredSuffixByType(mimeType);
if (rc.isEmpty())
qWarning("%s: WARNING: Unable to find a preferred suffix for %s.",
Q_FUNC_INFO, mimeType.toUtf8().constData());
return rc;
}
// ------------- StandardFileWizard(
StandardFileWizard::StandardFileWizard(const BaseFileWizardParameters &parameters,
Core::ICore *core,
QObject *parent) :
BaseFileWizard(parameters, core, parent)
{
}
QWizard *StandardFileWizard::createWizardDialog(QWidget *parent,
const QString &defaultPath,
const WizardPageList &extensionPages) const
{
Core::Utils::FileWizardDialog *standardWizardDialog = new Core::Utils::FileWizardDialog(parent);
standardWizardDialog->setWindowTitle(tr("New %1").arg(name()));
setupWizard(standardWizardDialog);
standardWizardDialog->setPath(defaultPath);
foreach (QWizardPage *p, extensionPages)
standardWizardDialog->addPage(p);
return standardWizardDialog;
}
GeneratedFiles StandardFileWizard::generateFiles(const QWizard *w,
QString *errorMessage) const
{
const Core::Utils::FileWizardDialog *standardWizardDialog = qobject_cast<const Core::Utils::FileWizardDialog *>(w);
return generateFilesFromPath(standardWizardDialog->path(),
standardWizardDialog->name(),
errorMessage);
}
} // namespace Core
#include "basefilewizard.moc"

View File

@@ -0,0 +1,244 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef BASEFILEWIZARD_H
#define BASEFILEWIZARD_H
#include "core_global.h"
#include <coreplugin/dialogs/iwizard.h>
#include <QtGui/QIcon>
#include <QtCore/QSharedDataPointer>
#include <QtCore/QMap>
#include <QtCore/QList>
QT_BEGIN_NAMESPACE
class QWizard;
class QWizardPage;
QT_END_NAMESPACE
namespace Core {
class ICore;
class IEditor;
class IFileWizardExtension;
class BaseFileWizardParameterData;
struct BaseFileWizardPrivate;
class GeneratedFilePrivate;
/*!
* Represents a file generated by a wizard. The Wizard class will check for
* each file whether it already exists and will report any errors that may
* occur during creation of the files.
*/
class CORE_EXPORT GeneratedFile {
public:
GeneratedFile();
explicit GeneratedFile(const QString &path);
GeneratedFile(const GeneratedFile &);
GeneratedFile &operator=(const GeneratedFile&);
~GeneratedFile();
// Full path of the file should be created, or the suggested file name
QString path() const;
void setPath(const QString &p);
// Contents of the file
QString contents() const;
void setContents(const QString &c);
// Kind of editor to open the file with
QString editorKind() const;
void setEditorKind(const QString &k);
bool write(QString *errorMessage) const;
private:
QSharedDataPointer<GeneratedFilePrivate> m_d;
};
typedef QList<GeneratedFile> GeneratedFiles;
/* Parameter class for passing parameters to instances of class Wizard
* containing name, icon and such. */
class CORE_EXPORT BaseFileWizardParameters {
public:
explicit BaseFileWizardParameters(IWizard::Kind kind = IWizard::FileWizard);
BaseFileWizardParameters(const BaseFileWizardParameters &);
BaseFileWizardParameters &operator=(const BaseFileWizardParameters&);
~BaseFileWizardParameters();
IWizard::Kind kind() const;
void setKind(IWizard::Kind k);
QIcon icon() const;
void setIcon(const QIcon&);
QString description() const;
void setDescription(const QString &);
QString name() const;
void setName(const QString &);
QString category() const;
void setCategory(const QString &);
QString trCategory() const;
void setTrCategory(const QString &);
private:
QSharedDataPointer<BaseFileWizardParameterData> m_d;
};
/* A generic wizard for creating files.
*
* The abstract methods:
*
* createWizardDialog() : Called to create the QWizard dialog to be shown
* generateFiles() : Generate file content
*
* must be implemented. The behaviour can be further customized by overwriting
* the virtual method:
* postGenerateFiles() : Called after generating the files.
*/
class CORE_EXPORT BaseFileWizard : public IWizard
{
Q_DISABLE_COPY(BaseFileWizard)
Q_OBJECT
public:
virtual ~BaseFileWizard();
// IWizard
virtual Kind kind() const;
virtual QIcon icon() const;
virtual QString description() const;
virtual QString name() const;
virtual QString category() const;
virtual QString trCategory() const;
virtual QStringList runWizard(const QString &path, QWidget *parent);
// Utility to find all registered wizards
static QList<IWizard*> allWizards();
// Utility to find all registered wizards of a certain kind
static QList<IWizard*> findWizardsOfKind(Kind kind);
// Build a file name, adding the extension unless baseName already has one
static QString buildFileName(const QString &path, const QString &baseName, const QString &extension);
// Return standard pixmap to be used as watermark
static QPixmap watermark();
// Set the standard watermark on a QWizard
static void setupWizard(QWizard *);
protected:
typedef QList<QWizardPage *> WizardPageList;
explicit BaseFileWizard(const BaseFileWizardParameters &parameters, Core::ICore *core, QObject *parent = 0);
// Overwrite to create the wizard dialog on the parent, adding
// the extension pages.
virtual QWizard *createWizardDialog(QWidget *parent,
const QString &defaultPath,
const WizardPageList &extensionPages) const = 0;
// Overwrite to query the parameters from the dialog and generate the files.
virtual GeneratedFiles generateFiles(const QWizard *w,
QString *errorMessage) const = 0;
/* Overwrite to perform steps to be done after files are actually created.
* The default implementation opens editors with the newly generated files. */
virtual bool postGenerateFiles(const GeneratedFiles &l, QString *errorMessage);
// Utility that returns the preferred suffix for a mime type
QString preferredSuffix(const QString &mimeType) const;
// Utility that performs an overwrite check on a set of files. It checks if
// the file exists, can be overwritten at all and prompts the user.
enum OverwriteResult { OverwriteOk, OverwriteError, OverwriteCanceled };
OverwriteResult promptOverwrite(const QString &location,
const QStringList &files,
QString *errorMessage) const;
Core::ICore *core() const;
private:
BaseFileWizardPrivate *m_d;
};
// StandardFileWizard convenience class for creating one file. It uses
// Core::Utils::FileWizardDialog and introduces a new virtual to generate the
// files from path and name.
class CORE_EXPORT StandardFileWizard : public BaseFileWizard {
Q_DISABLE_COPY(StandardFileWizard)
Q_OBJECT
protected:
explicit StandardFileWizard(const BaseFileWizardParameters &parameters, Core::ICore *core, QObject *parent = 0);
// Implemented to create a Core::Utils::FileWizardDialog
virtual QWizard *createWizardDialog(QWidget *parent,
const QString &defaultPath,
const WizardPageList &extensionPages) const;
// Implemented to retrieve path and name and call generateFilesFromPath()
virtual GeneratedFiles generateFiles(const QWizard *w,
QString *errorMessage) const;
// Newly introduced virtual that creates a file from a path
virtual GeneratedFiles generateFilesFromPath(const QString &path,
const QString &name,
QString *errorMessage) const = 0;
};
/* A utility to find all wizards supporting a view mode and matching a predicate */
template <class Predicate>
QList<IWizard*> findWizards(Predicate predicate)
{
// Filter all wizards
const QList<IWizard*> allWizards = BaseFileWizard::allWizards();
QList<IWizard*> rc;
const QList<IWizard*>::const_iterator cend = allWizards.constEnd();
for (QList<IWizard*>::const_iterator it = allWizards.constBegin(); it != cend; ++it)
if (predicate(*(*it)))
rc.push_back(*it);
return rc;
}
} // namespace Core
#endif // BASEFILEWIZARD_H

View File

@@ -0,0 +1,122 @@
/***************************************************************************
**
** 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 "basemode.h"
#include <QtGui/QWidget>
#include <extensionsystem/pluginmanager.h>
using namespace Core;
/*!
\class BaseMode
\mainclass
\ingroup qwb
\inheaderfile basemode.h
\brief A base implementation of the mode interface IMode.
The BaseMode class can be used directly for most IMode implementations. It has setter functions
for the mode properties and a convenience constructor.
The ownership of the widget is given to the BaseMode, so when the BaseMode is destroyed it
deletes its widget.
A typical use case is to do the following in the init method of a plugin:
\code
bool MyPlugin::init(QString *error_message)
{
[...]
addObject(new Core::BaseMode("mymode",
"MyPlugin.UniqueModeName",
icon,
50, // priority
new MyWidget));
[...]
}
\endcode
*/
/*!
\fn BaseMode::BaseMode(QObject *parent)
Creates a mode with empty name, no icon, lowest priority and no widget. You should use the
setter functions to give the mode a meaning.
\a parent
*/
BaseMode::BaseMode(QObject *parent):
IMode(parent),
m_priority(0),
m_widget(0)
{
}
/*!
\fn BaseMode::BaseMode(const QString &name,
const char * uniqueModeName,
const QIcon &icon,
int priority,
QWidget *widget,
QObject *parent)
Creates a mode with the given properties.
\a name
\a uniqueModeName
\a icon
\a priority
\a widget
\a parent
*/
BaseMode::BaseMode(const QString &name,
const char * uniqueModeName,
const QIcon &icon,
int priority,
QWidget *widget,
QObject *parent):
IMode(parent),
m_name(name),
m_icon(icon),
m_priority(priority),
m_widget(widget),
m_uniqueModeName(uniqueModeName)
{
}
/*!
\fn BaseMode::~BaseMode()
*/
BaseMode::~BaseMode()
{
delete m_widget;
}

View File

@@ -0,0 +1,86 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef BASEMODE_H
#define BASEMODE_H
#include "core_global.h"
#include "imode.h"
#include <QtCore/QObject>
#include <QtGui/QWidget>
namespace Core {
class CORE_EXPORT BaseMode
: public IMode
{
Q_OBJECT
public:
BaseMode(QObject *parent = 0);
BaseMode(const QString &name,
const char * uniqueModeName,
const QIcon &icon,
int priority,
QWidget *widget,
QObject *parent = 0);
~BaseMode();
// IMode
QString name() const { return m_name; }
QIcon icon() const { return m_icon; }
int priority() const { return m_priority; }
QWidget *widget() { return m_widget; }
const char *uniqueModeName() const { return m_uniqueModeName; }
QList<int> context() const { return m_context; }
void setName(const QString &name) { m_name = name; }
void setIcon(const QIcon &icon) { m_icon = icon; }
void setPriority(int priority) { m_priority = priority; }
void setWidget(QWidget *widget) { m_widget = widget; }
void setUniqueModeName(const char *uniqueModeName) { m_uniqueModeName = uniqueModeName; }
void setContext(const QList<int> &context) { m_context = context; }
private:
QString m_name;
QIcon m_icon;
int m_priority;
QWidget *m_widget;
const char * m_uniqueModeName;
QList<int> m_context;
};
} // namespace Core
#endif // BASEMODE_H

View File

@@ -0,0 +1,189 @@
/***************************************************************************
**
** 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 "baseview.h"
#include <extensionsystem/ExtensionSystemInterfaces>
using namespace Core;
/*!
\class BaseView
\mainclass
\ingroup qwb
\inheaderfile baseview.h
\brief A base implementation of IView.
The BaseView class can be used directly for most IView implementations.
It has setter functions for the views properties, and a convenience constructor
for the most important ones.
The ownership of the widget is given to the BaseView, so when the BaseView is destroyed it
deletes its widget.
A typical use case is to do the following in the init method of a plugin:
\code
bool MyPlugin::init(QString *error_message)
{
[...]
addObject(new Core::BaseView("myplugin.myview",
new MyWidget,
QList<int>() << myContextId,
Qt::LeftDockWidgetArea,
this));
[...]
}
\endcode
*/
/*!
\fn BaseView::BaseView()
Creates a View with empty view name, no widget, empty context, NoDockWidgetArea,
no menu group and empty default shortcut. You should use the setter functions
to give the view a meaning.
*/
BaseView::BaseView(QObject *parent)
: IView(parent),
m_viewName(""),
m_widget(0),
m_context(QList<int>()),
m_defaultPosition(IView::First)
{
}
/*!
\fn BaseView::BaseView(const char *name, QWidget *widget, const QList<int> &context, Qt::DockWidgetArea position, QObject *parent)
Creates a view with the given properties.
\a name
\a widget
\a context
\a position
\a parent
*/
BaseView::BaseView(const char *name, QWidget *widget, const QList<int> &context, IView::ViewPosition position, QObject *parent)
: IView(parent),
m_viewName(name),
m_widget(widget),
m_context(context),
m_defaultPosition(position)
{
}
/*!
\fn BaseView::~BaseView()
*/
BaseView::~BaseView()
{
delete m_widget;
}
/*!
\fn const QList<int> &BaseView::context() const
*/
QList<int> BaseView::context() const
{
return m_context;
}
/*!
\fn QWidget *BaseView::widget()
*/
QWidget *BaseView::widget()
{
return m_widget;
}
/*!
\fn const char *BaseView::uniqueViewName() const
*/
const char *BaseView::uniqueViewName() const
{
return m_viewName;
}
/*!
\fn IView::ViewPosition BaseView::defaultPosition() const
*/
IView::ViewPosition BaseView::defaultPosition() const
{
return m_defaultPosition;
}
/*!
\fn void BaseView::setUniqueViewName(const char *name)
\a name
*/
void BaseView::setUniqueViewName(const char *name)
{
m_viewName = name;
}
/*!
\fn QWidget *BaseView::setWidget(QWidget *widget)
The BaseView takes the ownership of the \a widget. The previously
set widget (if existent) is not deleted but returned, and responsibility
for deleting it moves to the caller of this method.
*/
QWidget *BaseView::setWidget(QWidget *widget)
{
QWidget *oldWidget = m_widget;
m_widget = widget;
return oldWidget;
}
/*!
\fn void BaseView::setContext(const QList<int> &context)
\a context
*/
void BaseView::setContext(const QList<int> &context)
{
m_context = context;
}
/*!
\fn void BaseView::setDefaultPosition(IView::ViewPosition position)
\a position
*/
void BaseView::setDefaultPosition(IView::ViewPosition position)
{
m_defaultPosition = position;
}

View File

@@ -0,0 +1,71 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef BASEVIEW_H
#define BASEVIEW_H
#include "core_global.h"
#include "iview.h"
#include <QtCore/QPointer>
namespace Core {
class CORE_EXPORT BaseView
: public IView
{
Q_OBJECT
public:
BaseView(QObject *parent = 0);
BaseView(const char *name, QWidget *widget, const QList<int> &context, IView::ViewPosition position, QObject *parent = 0);
~BaseView();
QList<int> context() const;
QWidget *widget();
const char *uniqueViewName() const;
IView::ViewPosition defaultPosition() const;
void setUniqueViewName(const char *name);
QWidget *setWidget(QWidget *widget);
void setContext(const QList<int> &context);
void setDefaultPosition(IView::ViewPosition position);
private:
const char *m_viewName;
QPointer<QWidget> m_widget;
QList<int> m_context;
IView::ViewPosition m_defaultPosition;
};
} // namespace Core
#endif // BASEVIEW_H

View File

@@ -0,0 +1,71 @@
<RCC>
<qresource prefix="/qworkbench" >
<file>html/images/bg_site_header_dark_grey.png</file>
<file>html/images/body_bg_circles_bottom_right.png</file>
<file>html/images/body_bg_gradient.png</file>
<file>html/images/btn_getting_started.png</file>
<file>html/images/btn_getting_started_hover.png</file>
<file>html/images/btn_restore_session.png</file>
<file>html/images/btn_restore_session_hover.png</file>
<file>html/images/list_bullet_arrow.png</file>
<file>html/images/mode_Project.png</file>
<file>html/images/nokia_logo.png</file>
<file>html/images/product_logo.png</file>
<file>html/images/qt_logo.png</file>
<file>html/images/rc_bottom_left.png</file>
<file>html/images/rc_bottom_mid.png</file>
<file>html/images/rc_bottom_right.png</file>
<file>html/images/rc_mid_left.png</file>
<file>html/images/rc_mid_mid.png</file>
<file>html/images/rc_mid_right.png</file>
<file>html/images/rc_top_left.png</file>
<file>html/images/rc_top_mid.png</file>
<file>html/images/rc_top_right.png</file>
<file>html/qt.css</file>
<file>html/recent_projects.html</file>
<file>html/recent_sessions.html</file>
<file>html/welcome.html</file>
<file>images/clean_pane_small.png</file>
<file>images/clear.png</file>
<file>images/closebutton.png</file>
<file>images/dir.png</file>
<file>images/editcopy.png</file>
<file>images/editcut.png</file>
<file>images/editpaste.png</file>
<file>images/empty14.png</file>
<file>images/filenew.png</file>
<file>images/fileopen.png</file>
<file>images/filesave.png</file>
<file>images/find.png</file>
<file>images/findnext.png</file>
<file>images/qtcreator_logo_128.png</file>
<file>images/qtcreator_logo_32.png</file>
<file>images/inputfield.png</file>
<file>images/inputfield_disabled.png</file>
<file>images/linkicon.png</file>
<file>images/locked.png</file>
<file>images/magnifier.png</file>
<file>images/minus.png</file>
<file>images/next.png</file>
<file>images/panel_button.png</file>
<file>images/panel_button_checked.png</file>
<file>images/panel_button_checked_hover.png</file>
<file>images/panel_button_hover.png</file>
<file>images/panel_button_pressed.png</file>
<file>images/plus.png</file>
<file>images/prev.png</file>
<file>images/pushbutton.png</file>
<file>images/pushbutton_hover.png</file>
<file>images/pushbutton_pressed.png</file>
<file>images/qtwatermark.png</file>
<file>images/redo.png</file>
<file>images/replace.png</file>
<file>images/reset.png</file>
<file>images/sidebaricon.png</file>
<file>images/splitbutton_horizontal.png</file>
<file>images/statusbar.png</file>
<file>images/undo.png</file>
<file>images/unknownfile.png</file>
<file>images/unlocked.png</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,57 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
/****************************************************************************
**
** Copyright (C) 1992-$THISYEAR$ Trolltech AS. All rights reserved.
**
** This file is part of the $MODULE$ of the Qt Toolkit.
**
** $LICENSE$
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#ifndef CORE_GLOBAL_H
#define CORE_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(CORE_LIBRARY)
# define CORE_EXPORT Q_DECL_EXPORT
#else
# define CORE_EXPORT Q_DECL_IMPORT
#endif
#endif // CORE_GLOBAL_H

View File

@@ -0,0 +1,224 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef CORECONSTANTS_H
#define CORECONSTANTS_H
#include <extensionsystem/ExtensionSystemInterfaces>
namespace Core {
namespace Constants {
#define IDE_VERSION_MAJOR 0
#define IDE_VERSION_MINOR 9
#define IDE_VERSION_RELEASE 1
#define STRINGIFY_INTERNAL(x) #x
#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
#define IDE_VERSION STRINGIFY(IDE_VERSION_MAJOR) \
"." STRINGIFY(IDE_VERSION_MINOR) \
"." STRINGIFY(IDE_VERSION_RELEASE)
const char * const IDE_VERSION_LONG = IDE_VERSION;
const char * const IDE_AUTHOR = "Nokia Corporation";
const char * const IDE_YEAR = "2008";
#ifdef IDE_REVISION
const char * const IDE_REVISION_STR = STRINGIFY(IDE_REVISION);
#else
const char * const IDE_REVISION_STR = "";
#endif
#undef IDE_VERSION
#undef STRINGIFY
#undef STRINGIFY_INTERNAL
//modes
const char * const MODE_WELCOME = "QtCreator.Mode.Welcome";
const char * const MODE_EDIT = "QtCreator.Mode.Edit";
const char * const MODE_OUTPUT = "QtCreator.Mode.Output";
const int P_MODE_WELCOME = 100;
const int P_MODE_EDIT = 90;
const int P_MODE_OUTPUT = 10;
//menubar
const char * const MENU_BAR = "QtCreator.MenuBar";
//menus
const char * const M_FILE = "QtCreator.Menu.File";
const char * const M_FILE_OPEN = "QtCreator.Menu.File.Open";
const char * const M_FILE_NEW = "QtCreator.Menu.File.New";
const char * const M_FILE_RECENTFILES = "QtCreator.Menu.File.RecentFiles";
const char * const M_EDIT = "QtCreator.Menu.Edit";
const char * const M_EDIT_ADVANCED = "QtCreator.Menu.Edit.Advanced";
const char * const M_TOOLS = "QtCreator.Menu.Tools";
const char * const M_WINDOW = "QtCreator.Menu.Window";
const char * const M_WINDOW_PANES = "QtCreator.Menu.Window.Panes";
const char * const M_HELP = "QtCreator.Menu.Help";
//contexts
const char * const C_GLOBAL = "Global Context";
const int C_GLOBAL_ID = 0;
const char * const C_WELCOME_MODE = "Core.WelcomeMode";
const char * const C_EDIT_MODE = "Core.EditMode";
const char * const C_EDITORMANAGER = "Core.EditorManager";
const char * const C_NAVIGATION_PANE = "Core.NavigationPane";
//default editor kind
const char * const K_DEFAULT_TEXT_EDITOR = "Plain Text Editor";
const char * const K_DEFAULT_BINARY_EDITOR = "Binary Editor";
//actions
const char * const UNDO = "QtCreator.Undo";
const char * const REDO = "QtCreator.Redo";
const char * const COPY = "QtCreator.Copy";
const char * const PASTE = "QtCreator.Paste";
const char * const CUT = "QtCreator.Cut";
const char * const SELECTALL = "QtCreator.SelectAll";
const char * const GOTO = "QtCreator.Goto";
const char * const NEW = "QtCreator.New";
const char * const OPEN = "QtCreator.Open";
const char * const OPEN_WITH = "QtCreator.OpenWith";
const char * const REVERTTOSAVED = "QtCreator.RevertToSaved";
const char * const SAVE = "QtCreator.Save";
const char * const SAVEAS = "QtCreator.SaveAs";
const char * const SAVEALL = "QtCreator.SaveAll";
const char * const PRINT = "QtCreator.Print";
const char * const EXIT = "QtCreator.Exit";
const char * const OPTIONS = "QtCreator.Options";
const char * const TOGGLE_SIDEBAR = "QtCreator.ToggleSidebar";
const char * const MINIMIZE_WINDOW = "QtCreator.MinimizeWindow";
const char * const ZOOM_WINDOW = "QtCreator.ZoomWindow";
const char * const HORIZONTAL = "QtCreator.Horizontal";
const char * const VERTICAL = "QtCreator.Vertical";
const char * const REMOVE = "QtCreator.Remove";
const char * const SAVEASDEFAULT = "QtCreator.SaveAsDefaultLayout";
const char * const RESTOREDEFAULT = "QtCreator.RestoreDefaultLayout";
const char * const CLOSE = "QtCreator.Close";
const char * const DUPLICATEDOCUMENT = "QtCreator.DuplicateDocument";
const char * const CLOSEALL = "QtCreator.CloseAll";
const char * const GOTONEXT = "QtCreator.GotoNext";
const char * const GOTOPREV = "QtCreator.GotoPrevious";
const char * const GOTONEXTINHISTORY = "QtCreator.GotoNextInHistory";
const char * const GOTOPREVINHISTORY = "QtCreator.GotoPreviousInHistory";
const char * const GO_BACK = "QtCreator.GoBack";
const char * const GO_FORWARD = "QtCreator.GoForward";
const char * const GOTOPREVIOUSGROUP = "QtCreator.GotoPreviousTabGroup";
const char * const GOTONEXTGROUP = "QtCreator.GotoNextTabGroup";
const char * const WINDOWSLIST = "QtCreator.WindowsList";
const char * const ABOUT_WORKBENCH = "QtCreator.AboutWorkbench";
const char * const ABOUT_PLUGINS = "QtCreator.AboutPlugins";
const char * const ABOUT_QT = "QtCreator.AboutQt";
const char * const S_RETURNTOEDITOR = "QtCreator.ReturnToEditor";
const char * const OPEN_IN_EXTERNAL_EDITOR = "QtCreattor.OpenInExternalEditor";
// default groups
const char * const G_DEFAULT_ONE = "QtCreator.Group.Default.One";
const char * const G_DEFAULT_TWO = "QtCreator.Group.Default.Two";
const char * const G_DEFAULT_THREE = "QtCreator.Group.Default.Three";
// main menu bar groups
const char * const G_FILE = "QtCreator.Group.File";
const char * const G_EDIT = "QtCreator.Group.Edit";
const char * const G_VIEW = "QtCreator.Group.View";
const char * const G_TOOLS = "QtCreator.Group.Tools";
const char * const G_WINDOW = "QtCreator.Group.Window";
const char * const G_HELP = "QtCreator.Group.Help";
// file menu groups
const char * const G_FILE_NEW = "QtCreator.Group.File.New";
const char * const G_FILE_OPEN = "QtCreator.Group.File.Open";
const char * const G_FILE_PROJECT = "QtCreator.Group.File.Project";
const char * const G_FILE_SAVE = "QtCreator.Group.File.Save";
const char * const G_FILE_CLOSE = "QtCreator.Group.File.Close";
const char * const G_FILE_PRINT = "QtCreator.Group.File.Print";
const char * const G_FILE_OTHER = "QtCreator.Group.File.Other";
// edit menu groups
const char * const G_EDIT_UNDOREDO = "QtCreator.Group.Edit.UndoRedo";
const char * const G_EDIT_COPYPASTE = "QtCreator.Group.Edit.CopyPaste";
const char * const G_EDIT_SELECTALL = "QtCreator.Group.Edit.SelectAll";
const char * const G_EDIT_FORMAT = "QtCreator.Group.Edit.Format";
const char * const G_EDIT_FIND = "QtCreator.Group.Edit.Find";
const char * const G_EDIT_OTHER = "QtCreator.Group.Edit.Other";
// window menu groups
const char * const G_WINDOW_SIZE = "QtCreator.Group.Window.Size";
const char * const G_WINDOW_PANES = "QtCreator.Group.Window.Panes";
const char * const G_WINDOW_SPLIT = "QtCreator.Group.Window.Split";
const char * const G_WINDOW_CLOSE = "QtCreator.Group.Window.Close";
const char * const G_WINDOW_NAVIGATE = "QtCreator.Group.Window.Navigate";
const char * const G_WINDOW_NAVIGATE_GROUPS = "QtCreator.Group.Window.Navigate.Groups";
const char * const G_WINDOW_OTHER = "QtCreator.Group.Window.Other";
const char * const G_WINDOW_LIST = "QtCreator.Group.Window.List";
// help groups (global)
const char * const G_HELP_HELP = "QtCreator.Group.Help.Help";
const char * const G_HELP_ABOUT = "QtCreator.Group.Help.About";
const char * const ICON_MINUS = ":/qworkbench/images/minus.png";
const char * const ICON_PLUS = ":/qworkbench/images/plus.png";
const char * const ICON_NEWFILE = ":/qworkbench/images/filenew.png";
const char * const ICON_OPENFILE = ":/qworkbench/images/fileopen.png";
const char * const ICON_SAVEFILE = ":/qworkbench/images/filesave.png";
const char * const ICON_UNDO = ":/qworkbench/images/undo.png";
const char * const ICON_REDO = ":/qworkbench/images/redo.png";
const char * const ICON_COPY = ":/qworkbench/images/editcopy.png";
const char * const ICON_PASTE = ":/qworkbench/images/editpaste.png";
const char * const ICON_CUT = ":/qworkbench/images/editcut.png";
const char * const ICON_NEXT = ":/qworkbench/images/next.png";
const char * const ICON_PREV = ":/qworkbench/images/prev.png";
const char * const ICON_DIR = ":/qworkbench/images/dir.png";
const char * const ICON_CLEAN_PANE = ":/qworkbench/images/clean_pane_small.png";
const char * const ICON_CLEAR = ":/qworkbench/images/clear.png";
const char * const ICON_FIND = ":/qworkbench/images/find.png";
const char * const ICON_FINDNEXT = ":/qworkbench/images/findnext.png";
const char * const ICON_REPLACE = ":/qworkbench/images/replace.png";
const char * const ICON_RESET = ":/qworkbench/images/reset.png";
const char * const ICON_MAGNIFIER = ":/qworkbench/images/magnifier.png";
const char * const ICON_TOGGLE_SIDEBAR = ":/qworkbench/images/sidebaricon.png";
// wizard kind
const char * const WIZARD_TYPE_FILE = "QtCreator::WizardType::File";
const char * const WIZARD_TYPE_CLASS = "QtCreator::WizardType::Class";
} // namespace Constants
} // namespace Core
#endif // CORECONSTANTS_H

View File

@@ -0,0 +1,211 @@
/***************************************************************************
**
** 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 "coreimpl.h"
#include <QtCore/QDir>
#include <QtCore/QCoreApplication>
using namespace Core;
using namespace Core::Internal;
CoreImpl *CoreImpl::m_instance = 0;
CoreImpl *CoreImpl::instance()
{
return m_instance;
}
CoreImpl::CoreImpl(MainWindow *mainwindow)
{
m_instance = this;
m_mainwindow = mainwindow;
}
QStringList CoreImpl::showNewItemDialog(const QString &title,
const QList<IWizard *> &wizards,
const QString &defaultLocation)
{
return m_mainwindow->showNewItemDialog(title, wizards, defaultLocation);
}
void CoreImpl::showOptionsDialog(const QString &group, const QString &page)
{
m_mainwindow->showOptionsDialog(group, page);
}
ActionManagerInterface *CoreImpl::actionManager() const
{
return m_mainwindow->actionManager();
}
FileManager *CoreImpl::fileManager() const
{
return m_mainwindow->fileManager();
}
UniqueIDManager *CoreImpl::uniqueIDManager() const
{
return m_mainwindow->uniqueIDManager();
}
MessageManager *CoreImpl::messageManager() const
{
return m_mainwindow->messageManager();
}
ViewManagerInterface *CoreImpl::viewManager() const
{
return m_mainwindow->viewManager();
}
ExtensionSystem::PluginManager *CoreImpl::pluginManager() const
{
return m_mainwindow->pluginManager();
}
EditorManager *CoreImpl::editorManager() const
{
return m_mainwindow->editorManager();
}
ProgressManagerInterface *CoreImpl::progressManager() const
{
return m_mainwindow->progressManager();
}
ScriptManagerInterface *CoreImpl::scriptManager() const
{
return m_mainwindow->scriptManager();
}
VariableManager *CoreImpl::variableManager() const
{
return m_mainwindow->variableManager();
}
VCSManager *CoreImpl::vcsManager() const
{
return m_mainwindow->vcsManager();
}
ModeManager *CoreImpl::modeManager() const
{
return m_mainwindow->modeManager();
}
MimeDatabase *CoreImpl::mimeDatabase() const
{
return m_mainwindow->mimeDatabase();
}
QSettings *CoreImpl::settings() const
{
return m_mainwindow->settings();
}
QPrinter *CoreImpl::printer() const
{
return m_mainwindow->printer();
}
QString CoreImpl::resourcePath() const
{
#if defined(Q_OS_MAC)
return QDir::cleanPath(QCoreApplication::applicationDirPath()+QLatin1String("/../Resources"));
#else
return QDir::cleanPath(QCoreApplication::applicationDirPath());
#endif
}
QString CoreImpl::libraryPath() const
{
#if defined(Q_OS_MAC)
return QDir::cleanPath(QCoreApplication::applicationDirPath()+QLatin1String("/../PlugIns"));
#else
return QDir::cleanPath(QCoreApplication::applicationDirPath()+QLatin1String("/../lib"));
#endif
}
IContext *CoreImpl::currentContextObject() const
{
return m_mainwindow->currentContextObject();
}
QMainWindow *CoreImpl::mainWindow() const
{
return m_mainwindow;
}
QStatusBar *CoreImpl::statusBar() const
{
return m_mainwindow->statusBar();
}
// adds and removes additional active contexts, this context is appended to the
// currently active contexts. call updateContext after changing
void CoreImpl::addAdditionalContext(int context)
{
m_mainwindow->addAdditionalContext(context);
}
void CoreImpl::removeAdditionalContext(int context)
{
m_mainwindow->removeAdditionalContext(context);
}
bool CoreImpl::hasContext(int context) const
{
return m_mainwindow->hasContext(context);
}
void CoreImpl::addContextObject(IContext *context)
{
m_mainwindow->addContextObject(context);
}
void CoreImpl::removeContextObject(IContext *context)
{
m_mainwindow->removeContextObject(context);
}
void CoreImpl::updateContext()
{
return m_mainwindow->updateContext();
}
void CoreImpl::openFiles(const QStringList &arguments)
{
m_mainwindow->openFiles(arguments);
}

View File

@@ -0,0 +1,105 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef COREIMPL_H
#define COREIMPL_H
#include "icore.h"
#include "mainwindow.h"
namespace Core {
namespace Internal {
class CoreImpl : public ICore
{
Q_OBJECT
public:
static CoreImpl *instance();
CoreImpl(MainWindow *mainwindow);
~CoreImpl() {}
QStringList showNewItemDialog(const QString &title,
const QList<IWizard *> &wizards,
const QString &defaultLocation = QString());
void showOptionsDialog(const QString &group = QString(),
const QString &page = QString());
ActionManagerInterface *actionManager() const;
FileManager *fileManager() const ;
UniqueIDManager *uniqueIDManager() const;
MessageManager *messageManager() const;
ViewManagerInterface *viewManager() const;
ExtensionSystem::PluginManager *pluginManager() const;
EditorManager *editorManager() const;
ProgressManagerInterface *progressManager() const;
ScriptManagerInterface *scriptManager() const;
VariableManager *variableManager() const;
VCSManager *vcsManager() const;
ModeManager *modeManager() const;
MimeDatabase *mimeDatabase() const;
QSettings *settings() const;
QPrinter *printer() const;
QString resourcePath() const;
QString libraryPath() const;
IContext *currentContextObject() const;
QMainWindow *mainWindow() const;
QStatusBar *statusBar() const;
// adds and removes additional active contexts, this context is appended to the
// currently active contexts. call updateContext after changing
void addAdditionalContext(int context);
void removeAdditionalContext(int context);
bool hasContext(int context) const;
void addContextObject(IContext *contex);
void removeContextObject(IContext *contex);
void updateContext();
void openFiles(const QStringList &fileNames);
private:
MainWindow *m_mainwindow;
friend class MainWindow;
static CoreImpl *m_instance;
};
} // namespace Internal
} // namespace Core
#endif // COREIMPL_H

View File

@@ -0,0 +1,111 @@
/***************************************************************************
**
** 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 "coreplugin.h"
#include "welcomemode.h"
#include "editmode.h"
#include "editormanager.h"
#include "mainwindow.h"
#include "modemanager.h"
#include "viewmanager.h"
#include "fileiconprovider.h"
#include <QtCore/qplugin.h>
#ifdef QT_WEBKIT
#include <QtGui/QApplication>
#include <QtWebKit/QWebSettings>
#endif
using namespace Core::Internal;
CorePlugin::CorePlugin() :
m_mainWindow(new MainWindow), m_welcomeMode(0), m_editMode(0), m_pm(0)
{
}
CorePlugin::~CorePlugin()
{
if (m_welcomeMode) {
removeObject(m_welcomeMode);
delete m_welcomeMode;
}
if (m_editMode) {
removeObject(m_editMode);
delete m_editMode;
}
// delete FileIconProvider singleton
delete FileIconProvider::instance();
delete m_mainWindow;
}
bool CorePlugin::initialize(const QStringList & /*arguments*/, QString *error_message)
{
m_pm = ExtensionSystem::PluginManager::instance();
const bool success = m_mainWindow->init(m_pm, error_message);
if (success) {
#ifdef QT_WEBKIT
QWebSettings *webSettings = QWebSettings::globalSettings();
const QFont applicationFont = QApplication::font();
webSettings->setFontFamily(QWebSettings::StandardFont, applicationFont.family());
//webSettings->setFontSize(QWebSettings::DefaultFontSize, applicationFont.pointSize());
#endif
m_welcomeMode = new WelcomeMode;
addObject(m_welcomeMode);
EditorManager *editorManager = qobject_cast<EditorManager*>(m_mainWindow->editorManager());
m_editMode = new EditMode(editorManager);
addObject(m_editMode);
}
return success;
}
void CorePlugin::extensionsInitialized()
{
m_mainWindow->modeManager()->activateMode(m_welcomeMode->uniqueModeName());
m_mainWindow->extensionsInitialized();
}
void CorePlugin::remoteArgument(const QString& arg)
{
// An empty argument is sent to trigger activation
// of the window via QtSingleApplication. It should be
// the last of a sequence.
if (arg.isEmpty()) {
m_mainWindow->activateWindow();
} else {
m_mainWindow->openFiles(QStringList(arg));
}
}
Q_EXPORT_PLUGIN(CorePlugin)

View File

@@ -0,0 +1,70 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef QWORKBENCHPLUGIN_H
#define QWORKBENCHPLUGIN_H
#include <extensionsystem/iplugin.h>
namespace Core {
namespace Internal {
class WelcomeMode;
class EditMode;
class MainWindow;
class CorePlugin : public ExtensionSystem::IPlugin
{
Q_OBJECT
public:
CorePlugin();
~CorePlugin();
bool initialize(const QStringList &arguments, QString *error_message = 0);
void extensionsInitialized();
public slots:
void remoteArgument(const QString&);
private:
MainWindow *m_mainWindow;
WelcomeMode *m_welcomeMode;
EditMode *m_editMode;
ExtensionSystem::PluginManager *m_pm;
};
} // namespace Internal
} // namespace Core
#endif // QWORKBENCHPLUGIN_H

View File

@@ -0,0 +1,3 @@
include(coreplugin_dependencies.pri)
LIBS *= -l$$qtLibraryTarget(Core)

View File

@@ -0,0 +1,169 @@
TEMPLATE = lib
TARGET = Core
DEFINES += CORE_LIBRARY
QT += xml \
script \
svg
include(../../qworkbenchplugin.pri)
include(../../libs/utils/utils.pri)
include(../../../shared/scriptwrapper/scriptwrapper.pri)
include(coreplugin_dependencies.pri)
INCLUDEPATH += dialogs \
actionmanager \
editormanager \
progressmanager \
scriptmanager
DEPENDPATH += dialogs \
actionmanager \
editormanager \
scriptmanager
SOURCES += mainwindow.cpp \
welcomemode.cpp \
editmode.cpp \
tabpositionindicator.cpp \
fancyactionbar.cpp \
fancytabwidget.cpp \
flowlayout.cpp \
generalsettings.cpp \
filemanager.cpp \
uniqueidmanager.cpp \
messagemanager.cpp \
messageoutputwindow.cpp \
outputpane.cpp \
vcsmanager.cpp \
viewmanager.cpp \
versiondialog.cpp \
editormanager/editorgroup.cpp \
editormanager/editormanager.cpp \
editormanager/stackededitorgroup.cpp \
editormanager/editorsplitter.cpp \
editormanager/openeditorsview.cpp \
editormanager/openeditorswindow.cpp \
actionmanager/actionmanager.cpp \
actionmanager/command.cpp \
actionmanager/actioncontainer.cpp \
actionmanager/commandsfile.cpp \
dialogs/saveitemsdialog.cpp \
dialogs/newdialog.cpp \
dialogs/settingsdialog.cpp \
dialogs/shortcutsettings.cpp \
dialogs/openwithdialog.cpp \
progressmanager/progressmanager.cpp \
progressmanager/progressview.cpp \
progressmanager/progresspie.cpp \
progressmanager/futureprogress.cpp \
scriptmanager/scriptmanager.cpp \
scriptmanager/qworkbench_wrapper.cpp \
basemode.cpp \
baseview.cpp \
coreplugin.cpp \
variablemanager.cpp \
modemanager.cpp \
coreimpl.cpp \
basefilewizard.cpp \
plugindialog.cpp \
stylehelper.cpp \
inavigationwidgetfactory.cpp \
navigationwidget.cpp \
manhattanstyle.cpp \
minisplitter.cpp \
styleanimator.cpp \
findplaceholder.cpp \
rightpane.cpp \
sidebar.cpp \
fileiconprovider.cpp \
mimedatabase.cpp
HEADERS += mainwindow.h \
welcomemode.h \
editmode.h \
tabpositionindicator.h \
fancyactionbar.h \
fancytabwidget.h \
flowlayout.h \
generalsettings.h \
filemanager.h \
uniqueidmanager.h \
messagemanager.h \
messageoutputwindow.h \
outputpane.h \
vcsmanager.h \
viewmanager.h \
editormanager/editorgroup.h \
editormanager/editormanager.h \
editormanager/stackededitorgroup.h \
editormanager/editorsplitter.h \
editormanager/openeditorsview.h \
editormanager/openeditorswindow.h \
editormanager/ieditor.h \
editormanager/ieditorfactory.h \
actionmanager/iactioncontainer.h \
actionmanager/actionmanagerinterface.h \
actionmanager/icommand.h \
actionmanager/actionmanager.h \
actionmanager/command.h \
actionmanager/actioncontainer.h \
actionmanager/commandsfile.h \
dialogs/saveitemsdialog.h \
dialogs/newdialog.h \
dialogs/settingsdialog.h \
dialogs/shortcutsettings.h \
dialogs/openwithdialog.h \
dialogs/iwizard.h \
dialogs/ioptionspage.h \
progressmanager/progressmanager.h \
progressmanager/progressview.h \
progressmanager/progresspie.h \
progressmanager/futureprogress.h \
progressmanager/progressmanagerinterface.h \
icontext.h \
icore.h \
ifile.h \
ifilefactory.h \
imode.h \
ioutputpane.h \
coreconstants.h \
iversioncontrol.h \
iview.h \
ifilewizardextension.h \
viewmanagerinterface.h \
icorelistener.h \
versiondialog.h \
scriptmanager/metatypedeclarations.h \
scriptmanager/qworkbench_wrapper.h \
scriptmanager/scriptmanagerinterface.h \
scriptmanager/scriptmanager.h \
core_global.h \
basemode.h \
baseview.h \
coreplugin.h \
variablemanager.h \
modemanager.h \
coreimpl.h \
basefilewizard.h \
plugindialog.h \
stylehelper.h \
inavigationwidgetfactory.h \
navigationwidget.h \
manhattanstyle.h \
minisplitter.h \
styleanimator.h \
findplaceholder.h \
rightpane.h \
sidebar.h \
fileiconprovider.h \
mimedatabase.h
FORMS += dialogs/newdialog.ui \
dialogs/settingsdialog.ui \
dialogs/shortcutsettings.ui \
dialogs/saveitemsdialog.ui \
dialogs/openwithdialog.ui \
editormanager/openeditorsview.ui \
generalsettings.ui
RESOURCES += core.qrc \
fancyactionbar.qrc
contains(QT_CONFIG, webkit): {
QT += webkit
DEFINES += QT_WEBKIT
}

View File

@@ -0,0 +1,2 @@
include(../../libs/extensionsystem/extensionsystem.pri)
include(../../libs/utils/utils.pri)

View File

@@ -0,0 +1,61 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef IOPTIONSPAGE_H
#define IOPTIONSPAGE_H
#include <coreplugin/core_global.h>
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtGui/QWidget>
namespace Core {
class CORE_EXPORT IOptionsPage : public QObject
{
Q_OBJECT
public:
IOptionsPage(QObject *parent = 0) : QObject(parent) {}
virtual ~IOptionsPage() {}
virtual QString name() const = 0;
virtual QString category() const = 0;
virtual QString trCategory() const = 0;
virtual QWidget *createPage(QWidget *parent) = 0;
virtual void finished(bool accepted) = 0;
};
} // namespace Core
#endif // IOPTIONSPAGE_H

View File

@@ -0,0 +1,70 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef IWIZARD_H
#define IWIZARD_H
#include <coreplugin/core_global.h>
#include <QtCore/QObject>
QT_BEGIN_NAMESPACE
class QIcon;
QT_END_NAMESPACE
namespace Core {
class CORE_EXPORT IWizard
: public QObject
{
Q_OBJECT
public:
enum Kind {
FileWizard,
ClassWizard,
ProjectWizard
};
IWizard(QObject *parent = 0) : QObject(parent) {}
virtual Kind kind() const = 0;
virtual QIcon icon() const = 0;
virtual QString description() const = 0;
virtual QString name() const = 0;
virtual QString category() const = 0;
virtual QString trCategory() const = 0;
virtual QStringList runWizard(const QString &path, QWidget *parent) = 0;
};
} // namespace Core
#endif // IWIZARD_H

View File

@@ -0,0 +1,150 @@
/***************************************************************************
**
** 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 "newdialog.h"
#include "ui_newdialog.h"
#include "basefilewizard.h"
#include <coreplugin/coreconstants.h>
#include <coreplugin/dialogs/iwizard.h>
#include <QtGui/QHeaderView>
#include <QtGui/QPushButton>
Q_DECLARE_METATYPE(Core::IWizard*)
static inline Core::IWizard *wizardOfItem(const QTreeWidgetItem *item = 0)
{
if (!item)
return 0;
return qVariantValue<Core::IWizard*>(item->data(0, Qt::UserRole));
}
using namespace Core;
using namespace Core::Internal;
NewDialog::NewDialog(QWidget *parent) :
QDialog(parent),
m_ui(new Core::Internal::Ui::NewDialog),
m_okButton(0)
{
typedef QMap<QString, QTreeWidgetItem *> CategoryItemMap;
m_ui->setupUi(this);
m_okButton = m_ui->buttonBox->button(QDialogButtonBox::Ok);
m_okButton->setDefault(true);
m_ui->watermark->setPixmap(BaseFileWizard::watermark());
m_ui->templatesTree->header()->hide();
connect(m_ui->templatesTree, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
this, SLOT(currentItemChanged(QTreeWidgetItem*)));
connect(m_ui->templatesTree, SIGNAL(itemActivated(QTreeWidgetItem*,int)), m_okButton, SLOT(animateClick()));
connect(m_okButton, SIGNAL(clicked()), this, SLOT(okButtonClicked()));
connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
}
void NewDialog::setWizards(const QList<IWizard*> wizards)
{
typedef QMap<QString, QTreeWidgetItem *> CategoryItemMap;
CategoryItemMap categories;
QVariant wizardPtr;
m_ui->templatesTree->clear();
foreach (IWizard *wizard, wizards) {
// ensure category root
const QString categoryName = wizard->category();
CategoryItemMap::iterator cit = categories.find(categoryName);
if (cit == categories.end()) {
QTreeWidgetItem *categoryItem = new QTreeWidgetItem(m_ui->templatesTree);
categoryItem->setFlags(Qt::ItemIsEnabled);
categoryItem->setText(0, wizard->trCategory());
qVariantSetValue<IWizard*>(wizardPtr, 0);
categoryItem->setData(0, Qt::UserRole, wizardPtr);
cit = categories.insert(categoryName, categoryItem);
}
// add item
QTreeWidgetItem *wizardItem = new QTreeWidgetItem(cit.value(), QStringList(wizard->name()));
wizardItem->setIcon(0, wizard->icon());
qVariantSetValue<IWizard*>(wizardPtr, wizard);
wizardItem->setData(0, Qt::UserRole, wizardPtr);
wizardItem->setFlags(Qt::ItemIsEnabled|Qt::ItemIsSelectable);
}
}
Core::IWizard *NewDialog::showDialog()
{
m_ui->templatesTree->expandAll();
if (QTreeWidgetItem *rootItem = m_ui->templatesTree->topLevelItem(0)) {
m_ui->templatesTree->scrollToItem(rootItem);
if (rootItem->childCount())
m_ui->templatesTree->setCurrentItem(rootItem->child(0));
}
updateOkButton();
if (exec() != Accepted)
return 0;
return currentWizard();
}
NewDialog::~NewDialog()
{
delete m_ui;
}
IWizard *NewDialog::currentWizard() const
{
return wizardOfItem(m_ui->templatesTree->currentItem());
}
void NewDialog::currentItemChanged(QTreeWidgetItem *cat)
{
if (const IWizard *wizard = wizardOfItem(cat))
m_ui->descLabel->setText(wizard->description());
else
m_ui->descLabel->setText(QString());
updateOkButton();
}
void NewDialog::okButtonClicked()
{
if (m_ui->templatesTree->currentItem())
accept();
}
void NewDialog::updateOkButton()
{
m_okButton->setEnabled(currentWizard() != 0);
}

View File

@@ -0,0 +1,82 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef NEWDIALOG_H
#define NEWDIALOG_H
#include <QtGui/QDialog>
#include <QtCore/QList>
QT_BEGIN_NAMESPACE
class QPushButton;
class QTreeWidgetItem;
class QStringList;
QT_END_NAMESPACE
namespace Core {
class IWizard;
namespace Internal {
namespace Ui {
class NewDialog;
}
class NewDialog : public QDialog
{
Q_OBJECT
public:
explicit NewDialog(QWidget *parent);
virtual ~NewDialog();
void setWizards(const QList<IWizard*> wizards);
Core::IWizard *showDialog();
private slots:
void currentItemChanged(QTreeWidgetItem *cat);
void okButtonClicked();
void updateOkButton();
private:
Core::IWizard *currentWizard() const;
Ui::NewDialog *m_ui;
QPushButton *m_okButton;
};
} // namespace Internal
} // namespace Core
#endif //NEWDIALOG_H

View File

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Core::Internal::NewDialog</class>
<widget class="QDialog" name="Core::Internal::NewDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>490</width>
<height>390</height>
</rect>
</property>
<property name="windowTitle">
<string>New Project</string>
</property>
<layout class="QVBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>9</number>
</property>
<item>
<layout class="QGridLayout">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="0" column="1">
<widget class="QTreeWidget" name="templatesTree">
<property name="minimumSize">
<size>
<width>400</width>
<height>301</height>
</size>
</property>
<column>
<property name="text">
<string>1</string>
</property>
</column>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="descLabel">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="watermark">
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,87 @@
/***************************************************************************
**
** 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 "openwithdialog.h"
#include <QtGui/QListWidget>
#include <QtGui/QPushButton>
#include <QtCore/QFileInfo>
using namespace Core;
using namespace Core::Internal;
OpenWithDialog::OpenWithDialog(const QString &fileName, QWidget *parent) :
QDialog(parent)
{
setupUi(this);
label->setText(tr("Open file '%1' with:").arg(QFileInfo(fileName).fileName()));
buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()),
this, SLOT(accept()));
connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()),
this, SLOT(reject()));
connect(editorListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
this, SLOT(accept()));
connect(editorListWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
this, SLOT(currentItemChanged(QListWidgetItem*,QListWidgetItem*)));
setOkButtonEnabled(false);
}
void OpenWithDialog::setOkButtonEnabled(bool v)
{
buttonBox->button(QDialogButtonBox::Ok)->setEnabled(v);
}
void OpenWithDialog::setEditors(const QStringList &editors)
{
foreach (const QString &e, editors)
editorListWidget->addItem(e);
}
QString OpenWithDialog::editor() const
{
if (const QListWidgetItem *item = editorListWidget->currentItem())
return item->text();
return QString();
}
void OpenWithDialog::setCurrentEditor(int index)
{
editorListWidget->setCurrentRow(index);
}
void OpenWithDialog::currentItemChanged(QListWidgetItem *current, QListWidgetItem *)
{
setOkButtonEnabled(current);
}

View File

@@ -0,0 +1,69 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef OPENWITHDIALOG_H
#define OPENWITHDIALOG_H
#include <QtGui/QDialog>
#include "ui_openwithdialog.h"
namespace Core {
class ICore;
namespace Internal {
// Present the user with a file name and a list of available
// editor kinds to choose from.
class OpenWithDialog : public QDialog, public Ui::OpenWithDialog
{
Q_OBJECT
public:
OpenWithDialog(const QString &fileName, QWidget *parent);
void setEditors(const QStringList &);
QString editor() const;
void setCurrentEditor(int index);
private slots:
void currentItemChanged(QListWidgetItem *, QListWidgetItem *);
private:
void setOkButtonEnabled(bool);
};
} // namespace Internal
} // namespace Core
#endif

View File

@@ -0,0 +1,46 @@
<ui version="4.0" >
<class>OpenWithDialog</class>
<widget class="QWidget" name="OpenWithDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>358</width>
<height>199</height>
</rect>
</property>
<property name="windowTitle" >
<string>Open File With...</string>
</property>
<layout class="QVBoxLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QLabel" name="label" >
<property name="text" >
<string>Open file extension with:</string>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="editorListWidget" />
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,207 @@
/***************************************************************************
**
** 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 "saveitemsdialog.h"
#include "mainwindow.h"
#include "vcsmanager.h"
#include <coreplugin/ifile.h>
#include <QtCore/QFileInfo>
#include <QtGui/QPushButton>
#include <QtGui/QTreeWidget>
#include <QtGui/QHeaderView>
#include <QtGui/QCheckBox>
#include <QtGui/QPushButton>
using namespace Core;
using namespace Core::Internal;
FileItem::FileItem(QTreeWidget *tree, bool supportOpen, bool open, const QString &text)
: QTreeWidgetItem(tree)
{
m_saveCheckBox = createCheckBox(tree, 0);
m_saveCheckBox->setChecked(true);
QFileInfo fi(text);
QString name = fi.fileName();
if (open)
name.append(tr(" [ReadOnly]"));
if (supportOpen) {
m_sccCheckBox = createCheckBox(tree, 1);
m_sccCheckBox->setEnabled(open);
m_sccCheckBox->setChecked(open);
connect(m_saveCheckBox, SIGNAL(stateChanged(int)),
this, SLOT(updateSCCCheckBox()));
setText(2, name);
setToolTip(2, text);
} else {
m_sccCheckBox = 0;
setText(2, name);
setToolTip(2, text);
}
}
QCheckBox *FileItem::createCheckBox(QTreeWidget *tree, int column)
{
QWidget *w = new QWidget();
QHBoxLayout *l = new QHBoxLayout(w);
l->setMargin(0);
l->setSpacing(0);
QCheckBox *box = new QCheckBox(w);
l->addWidget(box);
l->setAlignment(box, Qt::AlignCenter);
w->setLayout(l);
tree->setItemWidget(this, column, w);
return box;
}
void FileItem::updateSCCCheckBox()
{
if (!m_saveCheckBox->isChecked()) {
m_sccCheckBox->setEnabled(false);
m_sccCheckBox->setChecked(false);
} else {
m_sccCheckBox->setEnabled(true);
}
}
bool FileItem::shouldBeSaved() const
{
return m_saveCheckBox->isChecked();
}
void FileItem::setShouldBeSaved(bool s)
{
m_saveCheckBox->setChecked(s);
}
bool FileItem::shouldBeOpened() const
{
if (m_sccCheckBox)
return m_sccCheckBox->isChecked();
return false;
}
SaveItemsDialog::SaveItemsDialog(MainWindow *mainWindow,
QMap<IFile*, QString> items)
: QDialog(mainWindow)
{
m_ui.setupUi(this);
QPushButton *uncheckButton = m_ui.buttonBox->addButton(tr("Uncheck All"),
QDialogButtonBox::ActionRole);
QPushButton *discardButton = m_ui.buttonBox->addButton(tr("Discard All"),
QDialogButtonBox::DestructiveRole);
m_ui.buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
m_ui.buttonBox->button(QDialogButtonBox::Ok)->setFocus(Qt::TabFocusReason);
m_ui.treeWidget->header()->setMovable(false);
m_ui.treeWidget->setRootIsDecorated(false);
m_ui.treeWidget->setColumnCount(2);
QStringList headers;
headers << tr("Save") << tr("File Name");
const bool hasVersionControl = true;
if (hasVersionControl) {
m_ui.treeWidget->setColumnCount(3);
headers.insert(1, tr("Open with SCC"));
}
m_ui.treeWidget->setHeaderLabels(headers);
FileItem *itm;
QMap<IFile*, QString>::const_iterator it = items.constBegin();
while (it != items.constEnd()) {
QString directory = QFileInfo(it.key()->fileName()).absolutePath();
bool fileHasVersionControl = mainWindow->vcsManager()->findVersionControlForDirectory(directory) != 0;
itm = new FileItem(m_ui.treeWidget, fileHasVersionControl,
it.key()->isReadOnly(), it.value());
m_itemMap.insert(itm, it.key());
++it;
}
m_ui.treeWidget->resizeColumnToContents(0);
if (hasVersionControl)
m_ui.treeWidget->resizeColumnToContents(1);
connect(m_ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()),
this, SLOT(collectItemsToSave()));
connect(uncheckButton, SIGNAL(clicked()), this, SLOT(uncheckAll()));
connect(discardButton, SIGNAL(clicked()), this, SLOT(discardAll()));
}
void SaveItemsDialog::setMessage(const QString &msg)
{
m_ui.msgLabel->setText(msg);
}
void SaveItemsDialog::collectItemsToSave()
{
m_itemsToSave.clear();
m_itemsToOpen.clear();
QMap<FileItem*, IFile*>::const_iterator it = m_itemMap.constBegin();
while (it != m_itemMap.constEnd()) {
if (it.key()->shouldBeSaved())
m_itemsToSave << it.value();
if (it.key()->shouldBeOpened())
m_itemsToOpen.insert(it.value());
++it;
}
accept();
}
void SaveItemsDialog::discardAll()
{
uncheckAll();
collectItemsToSave();
}
QList<IFile*> SaveItemsDialog::itemsToSave() const
{
return m_itemsToSave;
}
QSet<IFile*> SaveItemsDialog::itemsToOpen() const
{
return m_itemsToOpen;
}
void SaveItemsDialog::uncheckAll()
{
for (int i=0; i<m_ui.treeWidget->topLevelItemCount(); ++i) {
FileItem *item = static_cast<FileItem*>(m_ui.treeWidget->topLevelItem(i));
item->setShouldBeSaved(false);
}
}

View File

@@ -0,0 +1,102 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef SAVEITEMSDIALOG_H
#define SAVEITEMSDIALOG_H
#include <QtCore/QMap>
#include <QtGui/QDialog>
#include "ui_saveitemsdialog.h"
QT_BEGIN_NAMESPACE
class QCheckBox;
QT_END_NAMESPACE
namespace Core {
class IFile;
class EditorManager;
namespace Internal {
class MainWindow;
class FileItem : public QObject, public QTreeWidgetItem
{
Q_OBJECT
public:
FileItem(QTreeWidget *tree, bool supportOpen,
bool open, const QString &text);
bool shouldBeSaved() const;
void setShouldBeSaved(bool s);
bool shouldBeOpened() const;
private slots:
void updateSCCCheckBox();
private:
QCheckBox *createCheckBox(QTreeWidget *tree, int column);
QCheckBox *m_saveCheckBox;
QCheckBox *m_sccCheckBox;
};
class SaveItemsDialog : public QDialog
{
Q_OBJECT
public:
SaveItemsDialog(MainWindow *mainWindow,
QMap<Core::IFile*, QString> items);
void setMessage(const QString &msg);
QList<Core::IFile*> itemsToSave() const;
QSet<Core::IFile*> itemsToOpen() const;
private slots:
void collectItemsToSave();
void uncheckAll();
void discardAll();
private:
Ui::SaveItemsDialog m_ui;
QMap<FileItem*, Core::IFile*> m_itemMap;
QList<Core::IFile*> m_itemsToSave;
QSet<Core::IFile*> m_itemsToOpen;
};
} // namespace Internal
} // namespace Core
#endif // SAVEITEMSDIALOG_H

View File

@@ -0,0 +1,66 @@
<ui version="4.0" >
<class>SaveItemsDialog</class>
<widget class="QDialog" name="SaveItemsDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>200</height>
</rect>
</property>
<property name="windowTitle" >
<string>Save Changes</string>
</property>
<layout class="QVBoxLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QLabel" name="msgLabel" >
<property name="text" >
<string>Save the changes of the following items:</string>
</property>
</widget>
</item>
<item>
<widget class="QTreeWidget" name="treeWidget" />
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>treeWidget</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SaveItemsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>199</x>
<y>174</y>
</hint>
<hint type="destinationlabel" >
<x>199</x>
<y>99</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -0,0 +1,138 @@
/***************************************************************************
**
** 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 "settingsdialog.h"
#include "coreimpl.h"
#include <QtGui/QHeaderView>
#include <QtGui/QPushButton>
using namespace Core;
using namespace Core::Internal;
SettingsDialog::SettingsDialog(QWidget *parent, const QString &initialCategory,
const QString &initialPage)
: QDialog(parent)
{
setupUi(this);
buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
pageTree->header()->setVisible(false);
connect(pageTree, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
this, SLOT(pageSelected(QTreeWidgetItem *)));
QMap<QString, QTreeWidgetItem *> categories;
QList<IOptionsPage*> pages =
CoreImpl::instance()->pluginManager()->getObjects<IOptionsPage>();
int index = 0;
foreach(IOptionsPage *page, pages) {
QTreeWidgetItem *item = new QTreeWidgetItem();
item->setText(0, page->name());
item->setData(0, Qt::UserRole, index);
QStringList categoriesId = page->category().split(QLatin1Char('|'));
QStringList trCategories = page->trCategory().split(QLatin1Char('|'));
QString currentCategory = categoriesId.at(0);
QTreeWidgetItem *treeitem;
if (!categories.contains(currentCategory)) {
treeitem = new QTreeWidgetItem(pageTree);
treeitem->setText(0, trCategories.at(0));
treeitem->setData(0, Qt::UserRole, index);
categories.insert(currentCategory, treeitem);
}
int catCount = 1;
while (catCount < categoriesId.count()) {
if(!categories.contains(currentCategory + QLatin1Char('|') + categoriesId.at(catCount))) {
treeitem = new QTreeWidgetItem(categories.value(currentCategory));
currentCategory += QLatin1Char('|') + categoriesId.at(catCount);
treeitem->setText(0, trCategories.at(catCount));
treeitem->setData(0, Qt::UserRole, index);
categories.insert(currentCategory, treeitem);
} else {
currentCategory += QLatin1Char('|') + categoriesId.at(catCount);
}
++catCount;
}
categories.value(currentCategory)->addChild(item);
m_pages.append(page);
stackedPages->addWidget(page->createPage(stackedPages));
if (page->name() == initialPage && currentCategory == initialCategory) {
stackedPages->setCurrentIndex(stackedPages->count());
pageTree->setCurrentItem(item);
}
index++;
}
QList<int> sizes;
sizes << 150 << 300;
splitter->setSizes(sizes);
splitter->setStretchFactor(splitter->indexOf(pageTree), 0);
splitter->setStretchFactor(splitter->indexOf(layoutWidget), 1);
}
SettingsDialog::~SettingsDialog()
{
}
void SettingsDialog::pageSelected(QTreeWidgetItem *)
{
QTreeWidgetItem *item = pageTree->currentItem();
int index = item->data(0, Qt::UserRole).toInt();
stackedPages->setCurrentIndex(index);
}
void SettingsDialog::accept()
{
foreach(IOptionsPage *page, m_pages) {
page->finished(true);
}
done(QDialog::Accepted);
}
void SettingsDialog::reject()
{
foreach(IOptionsPage *page, m_pages) {
page->finished(false);
}
done(QDialog::Rejected);
}

View File

@@ -0,0 +1,67 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef SETTINGSDIALOG_H
#define SETTINGSDIALOG_H
#include "ui_settingsdialog.h"
#include <QtCore/QList>
#include "coreplugin/dialogs/ioptionspage.h"
namespace Core {
namespace Internal {
class SettingsDialog : public QDialog, public ::Ui::SettingsDialog
{
Q_OBJECT
public:
SettingsDialog(QWidget *parent,
const QString &initialCategory = QString(),
const QString &initialPage = QString());
~SettingsDialog();
private slots:
void pageSelected(QTreeWidgetItem *cat);
void accept();
void reject();
private:
QList<Core::IOptionsPage*> m_pages;
};
} // namespace Internal
} // namespace Core
#endif // SETTINGSDIALOG_H

View File

@@ -0,0 +1,121 @@
<ui version="4.0" >
<class>SettingsDialog</class>
<widget class="QDialog" name="SettingsDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>697</width>
<height>476</height>
</rect>
</property>
<property name="windowTitle" >
<string>Options</string>
</property>
<layout class="QVBoxLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QSplitter" name="splitter" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<widget class="QTreeWidget" name="pageTree" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>7</hsizetype>
<vsizetype>7</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="columnCount" >
<number>1</number>
</property>
<column>
<property name="text" >
<string>0</string>
</property>
</column>
</widget>
<widget class="QWidget" name="layoutWidget" >
<layout class="QVBoxLayout" >
<property name="margin" >
<number>0</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
<widget class="QStackedWidget" name="stackedPages" >
<property name="minimumSize" >
<size>
<width>350</width>
<height>250</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SettingsDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<x>297</x>
<y>361</y>
</hint>
<hint type="destinationlabel" >
<x>297</x>
<y>193</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SettingsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<x>297</x>
<y>361</y>
</hint>
<hint type="destinationlabel" >
<x>297</x>
<y>193</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -0,0 +1,379 @@
/***************************************************************************
**
** 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 "shortcutsettings.h"
#include "ui_shortcutsettings.h"
#include "actionmanager.h"
#include "command.h"
#include "coreconstants.h"
#include "coreimpl.h"
#include "commandsfile.h"
#include "filemanager.h"
#include <coreplugin/uniqueidmanager.h>
#include <coreplugin/actionmanager/icommand.h>
#include <QtGui/QKeyEvent>
#include <QtGui/QShortcut>
#include <QtGui/QHeaderView>
#include <QtGui/QFileDialog>
#include <QtDebug>
Q_DECLARE_METATYPE(Core::Internal::ShortcutItem*);
using namespace Core;
using namespace Core::Internal;
ShortcutSettings::ShortcutSettings(QObject *parent)
: IOptionsPage(parent)
{
}
ShortcutSettings::~ShortcutSettings()
{
}
// IOptionsPage
QString ShortcutSettings::name() const
{
return tr("Keyboard");
}
QString ShortcutSettings::category() const
{
return QLatin1String("Environment");
}
QString ShortcutSettings::trCategory() const
{
return tr("Environment");
}
QWidget *ShortcutSettings::createPage(QWidget *parent)
{
m_keyNum = m_key[0] = m_key[1] = m_key[2] = m_key[3] = 0;
m_page = new Ui_ShortcutSettings();
QWidget *w = new QWidget(parent);
m_page->setupUi(w);
m_page->resetButton->setIcon(QIcon(Constants::ICON_RESET));
m_page->shortcutEdit->installEventFilter(this);
connect(m_page->resetButton, SIGNAL(clicked()),
this, SLOT(resetKeySequence()));
connect(m_page->removeButton, SIGNAL(clicked()),
this, SLOT(removeKeySequence()));
connect(m_page->exportButton, SIGNAL(clicked()),
this, SLOT(exportAction()));
connect(m_page->importButton, SIGNAL(clicked()),
this, SLOT(importAction()));
connect(m_page->defaultButton, SIGNAL(clicked()),
this, SLOT(defaultAction()));
initialize();
m_page->commandList->sortByColumn(0, Qt::AscendingOrder);
connect(m_page->filterEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString)));
connect(m_page->commandList, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
this, SLOT(commandChanged(QTreeWidgetItem *)));
connect(m_page->shortcutEdit, SIGNAL(textChanged(QString)), this, SLOT(keyChanged()));
QHeaderView *hv = m_page->commandList->header();
hv->resizeSection(0, 210);
hv->resizeSection(1, 110);
hv->setStretchLastSection(true);
commandChanged(0);
return w;
}
void ShortcutSettings::finished(bool accepted)
{
if (accepted) {
foreach(ShortcutItem *item, m_scitems) {
item->m_cmd->setKeySequence(item->m_key);
}
}
qDeleteAll(m_scitems);
m_scitems.clear();
}
bool ShortcutSettings::eventFilter(QObject *o, QEvent *e)
{
Q_UNUSED(o);
if ( e->type() == QEvent::KeyPress ) {
QKeyEvent *k = static_cast<QKeyEvent*>(e);
handleKeyEvent(k);
return true;
}
if ( e->type() == QEvent::Shortcut ||
e->type() == QEvent::ShortcutOverride ||
e->type() == QEvent::KeyRelease )
return true;
return false;
}
void ShortcutSettings::commandChanged(QTreeWidgetItem *current)
{
if (!current || !current->data(0, Qt::UserRole).isValid()) {
m_page->shortcutEdit->setText("");
m_page->seqGrp->setEnabled(false);
return;
}
m_page->seqGrp->setEnabled(true);
ShortcutItem *scitem = qVariantValue<ShortcutItem *>(current->data(0, Qt::UserRole));
setKeySequence(scitem->m_key);
}
void ShortcutSettings::filterChanged(const QString &f)
{
for (int i=0; i<m_page->commandList->topLevelItemCount(); ++i) {
QTreeWidgetItem *item = m_page->commandList->topLevelItem(i);
item->setHidden(filter(f, item));
}
}
void ShortcutSettings::keyChanged()
{
QTreeWidgetItem *current = m_page->commandList->currentItem();
if (current && current->data(0, Qt::UserRole).isValid()) {
ShortcutItem *scitem = qVariantValue<ShortcutItem *>(current->data(0, Qt::UserRole));
scitem->m_key = QKeySequence(m_key[0], m_key[1], m_key[2], m_key[3]);
current->setText(2, scitem->m_key);
}
}
void ShortcutSettings::setKeySequence(const QKeySequence &key)
{
m_keyNum = m_key[0] = m_key[1] = m_key[2] = m_key[3] = 0;
m_keyNum = key.count();
for (int i = 0; i < m_keyNum; ++i) {
m_key[i] = key[i];
}
m_page->shortcutEdit->setText(key);
}
bool ShortcutSettings::filter(const QString &f, const QTreeWidgetItem *item)
{
if (item->childCount() == 0) {
if (f.isEmpty())
return false;
for (int i = 0; i < item->columnCount(); ++i) {
if(item->text(i).contains(f, Qt::CaseInsensitive))
return false;
}
return true;
}
bool found = false;
for (int i = 0; i < item->childCount(); ++i) {
QTreeWidgetItem *citem = item->child(i);
if (filter(f, citem)) {
citem->setHidden(true);
} else {
citem->setHidden(false);
found = true;
}
}
return !found;
}
void ShortcutSettings::resetKeySequence()
{
QTreeWidgetItem *current = m_page->commandList->currentItem();
if (current && current->data(0, Qt::UserRole).isValid()) {
ShortcutItem *scitem = qVariantValue<ShortcutItem *>(current->data(0, Qt::UserRole));
setKeySequence(scitem->m_cmd->defaultKeySequence());
}
}
void ShortcutSettings::removeKeySequence()
{
m_keyNum = m_key[0] = m_key[1] = m_key[2] = m_key[3] = 0;
m_page->shortcutEdit->clear();
}
void ShortcutSettings::importAction()
{
UniqueIDManager *uidm =
CoreImpl::instance()->uniqueIDManager();
QString fileName = QFileDialog::getOpenFileName(0, tr("Import Keyboard Mapping Scheme"),
CoreImpl::instance()->resourcePath() + "/schemes/",
tr("Keyboard Mapping Scheme (*.kms)"));
if (!fileName.isEmpty()) {
CommandsFile cf(fileName);
QMap<QString, QKeySequence> mapping = cf.importCommands();
foreach(ShortcutItem *item, m_scitems) {
QString sid = uidm->stringForUniqueIdentifier(item->m_cmd->id());
if (mapping.contains(sid)) {
item->m_key = mapping.value(sid);
item->m_item->setText(2, item->m_key);
if (item->m_item == m_page->commandList->currentItem())
commandChanged(item->m_item);
}
}
}
}
void ShortcutSettings::defaultAction()
{
foreach(ShortcutItem *item, m_scitems) {
item->m_key = item->m_cmd->defaultKeySequence();
item->m_item->setText(2, item->m_key);
if (item->m_item == m_page->commandList->currentItem())
commandChanged(item->m_item);
}
}
void ShortcutSettings::exportAction()
{
QString fileName = CoreImpl::instance()->fileManager()->getSaveFileNameWithExtension(
tr("Export Keyboard Mapping Scheme"),
CoreImpl::instance()->resourcePath() + "/schemes/",
tr("Keyboard Mapping Scheme (*.kms)"),
".kms");
if (!fileName.isEmpty()) {
CommandsFile cf(fileName);
cf.exportCommands(m_scitems);
}
}
void ShortcutSettings::initialize()
{
QMap<QString, QTreeWidgetItem *> categories;
m_am = ActionManager::instance();
UniqueIDManager *uidm =
CoreImpl::instance()->uniqueIDManager();
QList<Command *> cmds = m_am->commands();
for (int i = 0; i < cmds.size(); ++i) {
Command *c = cmds.at(i);
if (c->hasAttribute(Command::CA_NonConfigureable))
continue;
if (c->action() && c->action()->isSeparator())
continue;
QTreeWidgetItem *item = 0;
ShortcutItem *s = new ShortcutItem;
m_scitems << s;
if (c->category().isEmpty()) {
item = new QTreeWidgetItem(m_page->commandList);
} else {
if (!categories.contains(c->category())) {
QTreeWidgetItem *cat = new QTreeWidgetItem(m_page->commandList);
cat->setText(0, c->category());
categories.insert(c->category(), cat);
cat->setExpanded(true);
}
item = new QTreeWidgetItem(categories.value(c->category()));
}
s->m_cmd = c;
s->m_item = item;
item->setText(0, uidm->stringForUniqueIdentifier(c->id()));
if (c->action()) {
QString text = c->hasAttribute(Command::CA_UpdateText) && !c->defaultText().isNull() ? c->defaultText() : c->action()->text();
s->m_key = c->action()->shortcut();
item->setText(1, text);
} else {
s->m_key = c->shortcut()->key();
item->setText(1, c->shortcut()->whatsThis());
}
item->setText(2, s->m_key);
item->setData(0, Qt::UserRole, qVariantFromValue(s));
}
}
void ShortcutSettings::handleKeyEvent(QKeyEvent *e)
{
int nextKey = e->key();
if ( m_keyNum > 3 ||
nextKey == Qt::Key_Control ||
nextKey == Qt::Key_Shift ||
nextKey == Qt::Key_Meta ||
nextKey == Qt::Key_Alt )
return;
nextKey |= translateModifiers(e->modifiers(), e->text());
switch (m_keyNum) {
case 0:
m_key[0] = nextKey;
break;
case 1:
m_key[1] = nextKey;
break;
case 2:
m_key[2] = nextKey;
break;
case 3:
m_key[3] = nextKey;
break;
default:
break;
}
m_keyNum++;
QKeySequence ks(m_key[0], m_key[1], m_key[2], m_key[3]);
m_page->shortcutEdit->setText(ks);
e->accept();
}
int ShortcutSettings::translateModifiers(Qt::KeyboardModifiers state,
const QString &text)
{
int result = 0;
// The shift modifier only counts when it is not used to type a symbol
// that is only reachable using the shift key anyway
if ((state & Qt::ShiftModifier) && (text.size() == 0
|| !text.at(0).isPrint()
|| text.at(0).isLetter()
|| text.at(0).isSpace()))
result |= Qt::SHIFT;
if (state & Qt::ControlModifier)
result |= Qt::CTRL;
if (state & Qt::MetaModifier)
result |= Qt::META;
if (state & Qt::AltModifier)
result |= Qt::ALT;
return result;
}

View File

@@ -0,0 +1,110 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef SHORTCUTSETTINGS_H
#define SHORTCUTSETTINGS_H
#include <coreplugin/dialogs/ioptionspage.h>
#include <QtCore/QObject>
#include <QtGui/QKeySequence>
#include <QtGui/QTreeWidgetItem>
#include <QtGui/QKeyEvent>
QT_BEGIN_NAMESPACE
class Ui_ShortcutSettings;
QT_END_NAMESPACE
namespace Core {
class ICommand;
namespace Internal {
class ActionManager;
class Command;
class MainWindow;
struct ShortcutItem {
ICommand *m_cmd;
QKeySequence m_key;
QTreeWidgetItem *m_item;
};
class ShortcutSettings : public Core::IOptionsPage
{
Q_OBJECT
public:
ShortcutSettings(QObject *parent = 0);
~ShortcutSettings();
// IOptionsPage
QString name() const;
QString category() const;
QString trCategory() const;
QWidget *createPage(QWidget *parent);
void finished(bool accepted);
protected:
bool eventFilter(QObject *o, QEvent *e);
private slots:
void commandChanged(QTreeWidgetItem *current);
void filterChanged(const QString &f);
void keyChanged();
void resetKeySequence();
void removeKeySequence();
void importAction();
void exportAction();
void defaultAction();
private:
void setKeySequence(const QKeySequence &key);
bool filter(const QString &f, const QTreeWidgetItem *item);
void initialize();
void handleKeyEvent(QKeyEvent *e);
int translateModifiers(Qt::KeyboardModifiers state, const QString &text);
QList<ShortcutItem *> m_scitems;
ActionManager *m_am;
int m_key[4], m_keyNum;
Ui_ShortcutSettings *m_page;
};
} // namespace Internal
} // namespace Core
#endif // SHORTCUTSETTINGS_H

View File

@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ShortcutSettings</class>
<widget class="QWidget" name="ShortcutSettings">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>568</width>
<height>451</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Keyboard Shortcuts</string>
</property>
<layout class="QVBoxLayout">
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel" name="filterLabel">
<property name="text">
<string>Filter:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="filterEdit"/>
</item>
</layout>
</item>
<item>
<widget class="QTreeWidget" name="commandList">
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<property name="columnCount">
<number>3</number>
</property>
<column>
<property name="text">
<string>Command</string>
</property>
</column>
<column>
<property name="text">
<string>Label</string>
</property>
</column>
<column>
<property name="text">
<string>Shortcut</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QPushButton" name="defaultButton">
<property name="text">
<string>Defaults</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="importButton">
<property name="text">
<string>Import...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="exportButton">
<property name="text">
<string>Export...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="seqGrp">
<property name="title">
<string>Key Sequence</string>
</property>
<layout class="QVBoxLayout">
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Shortcut:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="shortcutEdit"/>
</item>
<item>
<widget class="QToolButton" name="resetButton">
<property name="toolTip">
<string>Reset</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../core.qrc">
<normaloff>:/qworkbench/images/reset.png</normaloff>:/qworkbench/images/reset.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="removeButton">
<property name="toolTip">
<string>Remove</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../core.qrc">
<normaloff>:/qworkbench/images/clear.png</normaloff>:/qworkbench/images/clear.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="infoLabel">
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../core.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -0,0 +1,138 @@
/***************************************************************************
**
** 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 "editmode.h"
#include "editormanager.h"
#include "coreconstants.h"
#include "coreimpl.h"
#include "modemanager.h"
#include "uniqueidmanager.h"
#include "minisplitter.h"
#include "findplaceholder.h"
#include "outputpane.h"
#include "navigationwidget.h"
#include "rightpane.h"
#include <QtCore/QLatin1String>
#include <QtGui/QHBoxLayout>
#include <QtGui/QWidget>
#include <QtGui/QSplitter>
using namespace Core;
using namespace Core::Internal;
EditMode::EditMode(EditorManager *editorManager):
m_editorManager(editorManager),
m_splitter(new MiniSplitter),
m_rightSplitWidgetLayout(new QVBoxLayout)
{
m_rightSplitWidgetLayout->setSpacing(0);
m_rightSplitWidgetLayout->setMargin(0);
QWidget *rightSplitWidget = new QWidget;
rightSplitWidget->setLayout(m_rightSplitWidgetLayout);
m_rightSplitWidgetLayout->insertWidget(0, new Core::EditorManagerPlaceHolder(this));
m_rightSplitWidgetLayout->addWidget(new Core::FindToolBarPlaceHolder(this));
MiniSplitter *rightPaneSplitter = new MiniSplitter;
rightPaneSplitter->insertWidget(0, rightSplitWidget);
rightPaneSplitter->insertWidget(1, new RightPanePlaceHolder(this));
rightPaneSplitter->setStretchFactor(0, 1);
rightPaneSplitter->setStretchFactor(1, 0);
MiniSplitter *splitter = new MiniSplitter;
splitter->setOrientation(Qt::Vertical);
splitter->insertWidget(0, rightPaneSplitter);
splitter->insertWidget(1, new Core::OutputPanePlaceHolder(this));
splitter->setStretchFactor(0, 3);
splitter->setStretchFactor(1, 0);
m_splitter->insertWidget(0, new NavigationWidgetPlaceHolder(this));
m_splitter->insertWidget(1, splitter);
m_splitter->setStretchFactor(0, 0);
m_splitter->setStretchFactor(1, 1);
ModeManager *modeManager = ModeManager::instance();
connect(modeManager, SIGNAL(currentModeChanged(Core::IMode*)),
this, SLOT(grabEditorManager(Core::IMode*)));
m_splitter->setFocusProxy(m_editorManager);
}
EditMode::~EditMode()
{
// Make sure the editor manager does not get deleted
m_editorManager->setParent(0);
delete m_splitter;
}
QString EditMode::name() const
{
return QLatin1String("Edit");
}
QIcon EditMode::icon() const
{
return QIcon(QLatin1String(":/fancyactionbar/images/mode_Edit.png"));
}
int EditMode::priority() const
{
return Constants::P_MODE_EDIT;
}
QWidget* EditMode::widget()
{
return m_splitter;
}
const char* EditMode::uniqueModeName() const
{
return Constants::MODE_EDIT;
}
QList<int> EditMode::context() const
{
static QList<int> contexts = QList<int>() <<
CoreImpl::instance()->uniqueIDManager()->uniqueIdentifier(Constants::C_EDIT_MODE) <<
CoreImpl::instance()->uniqueIDManager()->uniqueIdentifier(Constants::C_EDITORMANAGER) <<
CoreImpl::instance()->uniqueIDManager()->uniqueIdentifier(Constants::C_NAVIGATION_PANE);
return contexts;
}
void EditMode::grabEditorManager(Core::IMode *mode)
{
if (mode != this)
return;
if (m_editorManager->currentEditor())
m_editorManager->currentEditor()->widget()->setFocus();
}

View File

@@ -0,0 +1,80 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef EDITMODE_H
#define EDITMODE_H
#include <coreplugin/imode.h>
#include <QtCore/QObject>
QT_BEGIN_NAMESPACE
class QSplitter;
class QWidget;
class QVBoxLayout;
QT_END_NAMESPACE
namespace Core {
class EditorManager;
namespace Internal {
class EditMode : public Core::IMode
{
Q_OBJECT
public:
EditMode(EditorManager *editorManager);
~EditMode();
// IMode
QString name() const;
QIcon icon() const;
int priority() const;
QWidget* widget();
const char* uniqueModeName() const;
QList<int> context() const;
private slots:
void grabEditorManager(Core::IMode *mode);
private:
EditorManager *m_editorManager;
QSplitter *m_splitter;
QVBoxLayout *m_rightSplitWidgetLayout;
};
} // namespace Internal
} // namespace Core
#endif // EDITMODE_H

View File

@@ -0,0 +1,337 @@
/***************************************************************************
**
** 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 "editorgroup.h"
#include "editormanager.h"
#include <coreplugin/coreconstants.h>
#include <QtCore/QDir>
#include <QtGui/QPainter>
#include <QtGui/QStyle>
#include <QtGui/QStyleOption>
#include <QtCore/QtDebug>
#ifdef Q_WS_MAC
#include <QtGui/QMacStyle>
#endif
Q_DECLARE_METATYPE(Core::IEditor*)
using namespace Core;
using namespace Core::Internal;
namespace Core {
namespace Internal {
class EditorList;
}
}
QDataStream &operator<<(QDataStream &out, const Core::Internal::EditorList &list);
QDataStream &operator>>(QDataStream &in, Core::Internal::EditorList &list);
namespace Core {
namespace Internal {
class EditorList
{
public:
quint32 currentEditorIndex;
void append(Core::IEditor *editor);
QString fileNameAt(int index);
QString editorKindAt(int index);
int count();
private:
QList<QPair<QString,QString> > editorinfo;
friend QDataStream &::operator<<(QDataStream &out, const EditorList &list);
friend QDataStream &::operator>>(QDataStream &in, EditorList &list);
};
} // namespace Internal
} // namespace Core
//================EditorModel====================
int EditorModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return 1;
}
int EditorModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return m_editors.count();
}
QModelIndex EditorModel::index(int row, int column, const QModelIndex &parent) const
{
Q_UNUSED(parent);
if (column != 0 || row < 0 || row >= m_editors.count())
return QModelIndex();
return createIndex(row, column);
}
QVariant EditorModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
IEditor *editor = m_editors.at(index.row());
Q_ASSERT(editor);
switch (role) {
case Qt::DisplayRole:
return editor->file()->isModified()
?editor->displayName()+QLatin1String("*")
:editor->displayName();
case Qt::DecorationRole:
return editor->file()->isReadOnly()
?QIcon(QLatin1String(":/qworkbench/images/locked.png"))
:QIcon();
case Qt::ToolTipRole:
return editor->file()->fileName().isEmpty()
?editor->displayName()
:QDir::toNativeSeparators(editor->file()->fileName());
case Qt::UserRole:
return qVariantFromValue(editor);
default:
return QVariant();
}
return QVariant();
}
QModelIndex EditorModel::indexOf(IEditor *editor) const
{
int idx = m_editors.indexOf(editor);
if (idx < 0)
return QModelIndex();
return createIndex(idx, 0);
}
//================EditorGroupContext===============
EditorGroupContext::EditorGroupContext(EditorGroup *editorGroup)
: IContext(editorGroup),
m_context(QList<int>() << Constants::C_GLOBAL_ID),
m_editorGroup(editorGroup)
{
}
QList<int> EditorGroupContext::context() const
{
return m_context;
}
QWidget *EditorGroupContext::widget()
{
return m_editorGroup;
}
EditorGroup *EditorGroupContext::editorGroup()
{
return m_editorGroup;
}
//================EditorGroup=================
EditorGroup::EditorGroup(QWidget *parent)
: QFrame(parent),
m_contextObject(new EditorGroupContext(this))
{
setFocusPolicy(Qt::StrongFocus);
m_model = new EditorModel(this);
}
QSize EditorGroup::minimumSizeHint() const
{
return QSize(10, 10);
}
void EditorGroup::focusInEvent(QFocusEvent *)
{
update();
}
void EditorGroup::focusOutEvent(QFocusEvent *)
{
update();
}
void EditorGroup::paintEvent(QPaintEvent *e)
{
QFrame::paintEvent(e);
if (editorCount() == 0) {
QPainter painter(this);
// Discreet indication where an editor would be
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(Qt::NoPen);
QColor shadeBrush(Qt::black);
shadeBrush.setAlpha(10);
painter.setBrush(shadeBrush);
const int r = 3;
painter.drawRoundedRect(rect().adjusted(r, r, -r, -r), r * 2, r * 2);
if (hasFocus()) {
#ifdef Q_WS_MAC
// With QMacStyle, we have to draw our own focus rect, since I didn't find
// a way to draw the nice mac focus rect _inside_ this widget
if (qobject_cast<QMacStyle *>(style())) {
painter.setPen(Qt::DotLine);
painter.setBrush(Qt::NoBrush);
painter.setOpacity(0.75);
painter.drawRect(rect());
} else {
#endif
QStyleOptionFocusRect option;
option.initFrom(this);
option.backgroundColor = palette().color(QPalette::Background);
// Some styles require a certain state flag in order to draw the focus rect
option.state |= QStyle::State_KeyboardFocusChange;
style()->drawPrimitive(QStyle::PE_FrameFocusRect, &option, &painter);
#ifdef Q_WS_MAC
}
#endif
}
}
}
void EditorGroup::moveEditorsFromGroup(EditorGroup *group)
{
foreach (IEditor *editor, group->editors()) {
group->removeEditor(editor);
addEditor(editor);
}
}
void EditorGroup::moveEditorFromGroup(EditorGroup *group, IEditor *editor)
{
group->removeEditor(editor);
addEditor(editor);
}
QByteArray EditorGroup::saveState() const
{
QByteArray bytes;
QDataStream stream(&bytes, QIODevice::WriteOnly);
EditorList editorinfo;
IEditor *curr = currentEditor();
QList<IEditor *> editors = editorsInNaturalOrder();
for (int j = 0; j < editors.count(); ++j) {
IEditor *editor = editors.at(j);
if (editor == curr)
editorinfo.currentEditorIndex = j;
editorinfo.append(editor);
}
stream << editorinfo;
return bytes;
}
bool EditorGroup::restoreState(const QByteArray &state)
{
QDataStream in(state);
EditorManager *em = EditorManager::instance();
EditorList editors;
in >> editors;
IEditor *currentEditor = 0;
IEditor *editor;
int savedIndex = editors.currentEditorIndex;
for (int j = 0; j < editors.count(); ++j) {
editor = em->restoreEditor(editors.fileNameAt(j), editors.editorKindAt(j), this);
if (j == savedIndex)
currentEditor = editor;
}
if (currentEditor)
setCurrentEditor(currentEditor);
return true;
}
void EditorGroup::addEditor(IEditor *editor)
{
m_model->addEditor(editor);
}
void EditorGroup::insertEditor(int i, IEditor *editor)
{
m_model->insertEditor(i, editor);
}
void EditorGroup::removeEditor(IEditor *editor)
{
m_model->removeEditor(editor);
}
void EditorGroup::showEditorInfoBar(const QString &, const QString &, const QString &, QObject *, const char *)
{
}
void EditorGroup::hideEditorInfoBar(const QString &)
{
}
void EditorList::append(IEditor *editor)
{
if (editor->file()->fileName().isEmpty())
return;
editorinfo << qMakePair(editor->file()->fileName(), QString(editor->kind()));
}
QDataStream &operator<<(QDataStream &out, const EditorList &list)
{
//todo: versioning
out << list.currentEditorIndex << list.editorinfo;
return out;
}
QDataStream &operator>>(QDataStream &in, EditorList &list)
{
//todo: versioning
in >> list.currentEditorIndex;
in >> list.editorinfo;
return in;
}
QString EditorList::fileNameAt(int index)
{
return editorinfo.at(index).first;
}
QString EditorList::editorKindAt(int index)
{
return editorinfo.at(index).second;
}
int EditorList::count()
{
return editorinfo.count();
}

View File

@@ -0,0 +1,165 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef EDITORGROUP_H
#define EDITORGROUP_H
#include <coreplugin/icontext.h>
#include <QtCore/QEvent>
#include <QtCore/QAbstractListModel>
#include <QtGui/QFrame>
#include <QtGui/QAbstractButton>
#include <QtGui/QPen>
namespace Core {
class IEditor;
class EditorGroup;
namespace Internal {
class EditorModel;
// Also used by the EditorManager
class EditorGroupContext : public IContext
{
Q_OBJECT
public:
EditorGroupContext(EditorGroup *editorGroup);
EditorGroup *editorGroup();
// IContext
QList<int> context() const;
QWidget *widget();
private:
QList<int> m_context;
EditorGroup *m_editorGroup;
};
} // namespace Internal
class CORE_EXPORT EditorGroup : public QFrame
{
Q_OBJECT
public:
EditorGroup(QWidget *parent);
virtual ~EditorGroup() {};
virtual IContext *contextObject() { return m_contextObject; }
virtual QWidget *widget() { return this; }
virtual int editorCount() const = 0;
virtual void addEditor(IEditor *editor);
virtual void insertEditor(int i, IEditor *editor);
virtual void removeEditor(IEditor *editor);
virtual QList<IEditor*> editors() const = 0;
virtual IEditor *currentEditor() const = 0;
virtual void setCurrentEditor(IEditor *editor) = 0;
virtual void moveEditorsFromGroup(EditorGroup *group);
virtual void moveEditorFromGroup(EditorGroup *group, IEditor *editor);
virtual QByteArray saveState() const;
virtual bool restoreState(const QByteArray &state);
virtual void showEditorInfoBar(const QString &kind,
const QString &infoText,
const QString &buttonText,
QObject *object, const char *member);
virtual void hideEditorInfoBar(const QString &kind);
QSize minimumSizeHint() const;
void focusInEvent(QFocusEvent *e);
void focusOutEvent(QFocusEvent *e);
void paintEvent(QPaintEvent *e);
signals:
void closeRequested(Core::IEditor *editor);
void editorRemoved(Core::IEditor *editor);
void editorAdded(Core::IEditor *editor);
protected:
virtual QList<IEditor *> editorsInNaturalOrder() const { return editors(); }
Internal::EditorModel *model() const { return m_model; }
private:
Internal::EditorGroupContext *m_contextObject;
Internal::EditorModel *m_model;
};
namespace Internal {
// Also used by StackedEditorGroup
class EditorModel : public QAbstractItemModel
{
public:
EditorModel(QObject *parent) : QAbstractItemModel(parent) {}
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
QModelIndex parent(const QModelIndex &/*index*/) const { return QModelIndex(); }
int rowCount(const QModelIndex &parent = QModelIndex()) const;
QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const;
void addEditor(IEditor *editor) { insertEditor(rowCount(), editor); }
void insertEditor(int index, IEditor *editor) {
beginInsertRows(QModelIndex(), index, index);
m_editors.insert(index, editor);
endInsertRows();
}
void removeEditor(IEditor *editor) {
int index = m_editors.indexOf(editor);
beginRemoveRows(QModelIndex(), index, index);
m_editors.removeAt(index);
endRemoveRows();
}
void emitDataChanged(IEditor *editor) {
int idx = m_editors.indexOf(editor);
QModelIndex mindex = index(idx, 0);
emit dataChanged(mindex, mindex);
}
QList<IEditor *> editors() const { return m_editors; }
QModelIndex indexOf(IEditor *editor) const;
private:
QList<IEditor *> m_editors;
};
} // namespace Internal
} // namespace Core
#endif // EDITORGROUP_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,229 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef EDITORMANAGER_H
#define EDITORMANAGER_H
#include "../core_global.h"
#include <coreplugin/icorelistener.h>
#include <QtGui/QWidget>
#include <QtCore/QList>
QT_BEGIN_NAMESPACE
class QSettings;
QT_END_NAMESPACE
namespace Core {
class EditorGroup;
class IContext;
class ICore;
class IEditor;
class IEditorFactory;
class MimeType;
class IFile;
class IMode;
enum MakeWritableResult {
OpenedWithVersionControl,
MadeWritable,
SavedAs,
Failed
};
struct EditorManagerPrivate;
namespace Internal {
class OpenEditorsWindow;
class EditorSplitter;
class EditorClosingCoreListener;
class OpenEditorsViewFactory;
} // namespace Internal
class CORE_EXPORT EditorManagerPlaceHolder : public QWidget
{
Q_OBJECT
public:
EditorManagerPlaceHolder(Core::IMode *mode, QWidget *parent = 0);
~EditorManagerPlaceHolder();
static EditorManagerPlaceHolder* current();
private slots:
void currentModeChanged(Core::IMode *);
private:
Core::IMode *m_mode;
static EditorManagerPlaceHolder* m_current;
};
class CORE_EXPORT EditorManager : public QWidget
{
Q_OBJECT
public:
typedef QList<IEditorFactory*> EditorFactoryList;
explicit EditorManager(ICore *core, QWidget *parent);
virtual ~EditorManager();
void init();
static EditorManager *instance() { return m_instance; }
IEditor *openEditor(const QString &fileName,
const QString &editorKind = QString(),
bool ignoreNavigationHistory = false);
QStringList getOpenFileNames() const;
QString getOpenWithEditorKind(const QString &fileName) const;
void ensureEditorManagerVisible();
IEditor *newFile(const QString &editorKind,
QString *titlePattern = 0,
const QString &contents = QString());
bool hasEditor(const QString &fileName) const;
QList<IEditor *> editorsForFileName(const QString &filename) const;
void setCurrentEditor(IEditor *editor, bool ignoreNavigationHistory = false);
IEditor *currentEditor() const;
EditorGroup *currentEditorGroup() const;
QList<IEditor*> openedEditors() const;
QList<IEditor*> editorsForFiles(QList<IFile*> files) const;
QList<EditorGroup *> editorGroups() const;
QList<IEditor*> editorHistory() const;
void addCurrentPositionToNavigationHistory(bool compress = false);
bool hasDuplicate(IEditor *editor) const;
bool saveEditor(IEditor *editor);
bool closeEditors(const QList<IEditor *> editorsToClose, bool askAboutModifiedEditors = true);
MakeWritableResult makeEditorWritable(IEditor *editor);
QByteArray saveState() const;
bool restoreState(const QByteArray &state);
IEditor *restoreEditor(QString fileName, QString editorKind, EditorGroup *group);
void saveSettings(QSettings *settings);
void readSettings(QSettings *settings);
QSize minimumSizeHint() const;
Internal::OpenEditorsWindow *windowPopup() const;
void showWindowPopup() const;
Internal::EditorSplitter *editorSplitter() const;
void showEditorInfoBar(const QString &kind,
const QString &infoText,
const QString &buttonText = QString(),
QObject *object = 0, const char *member = 0);
void hideEditorInfoBar(const QString &kind);
EditorFactoryList editorFactories(const MimeType &mimeType, bool bestMatchOnly = true) const;
void setExternalEditor(const QString &);
QString externalEditor() const;
QString externalEditorHelpText() const;
signals:
void currentEditorChanged(Core::IEditor *editor);
void editorCreated(Core::IEditor *editor, const QString &fileName);
void editorOpened(Core::IEditor *editor);
void editorAboutToClose(Core::IEditor *editor);
void editorsClosed(QList<Core::IEditor *> editors);
void editorGroupsChanged();
public slots:
bool closeAllEditors(bool askAboutModifiedEditors = true);
void openInExternalEditor();
private slots:
bool saveFile(Core::IEditor *editor = 0);
bool saveFileAs(Core::IEditor *editor = 0);
void closeEditor();
void closeEditor(Core::IEditor *editor);
void gotoNextDocHistory();
void gotoPreviousDocHistory();
void updateCurrentEditorAndGroup(Core::IContext *context);
void updateEditorHistory();
void updateActions();
void duplicateEditor();
void revertToSaved();
void goBackInNavigationHistory();
void goForwardInNavigationHistory();
void makeCurrentEditorWritable();
private:
QList<IFile *> filesForEditors(QList<IEditor *> editors) const;
IEditor *createEditor(const QString &mimeType = QString(),
const QString &fileName = QString());
void insertEditor(IEditor *editor, bool ignoreNavigationHistory = false, EditorGroup *group = 0);
bool registerEditor(IEditor *editor);
bool unregisterEditor(IEditor *editor);
EditorGroup *groupOfEditor(IEditor *editor) const;
void editorChanged(IEditor *editor);
void registerDuplicate(IEditor *original,
IEditor *duplicate);
void unregisterDuplicate(IEditor *editor);
QList<IEditor *> duplicates(IEditor *editor) const;
QByteArray saveOpenEditorList() const;
void restoreOpenEditorList(const QByteArray &state);
void restoreEditorState(IEditor *editor);
static EditorManager *m_instance;
EditorManagerPrivate *m_d;
};
//===================EditorClosingCoreListener======================
namespace Internal {
class EditorClosingCoreListener : public ICoreListener {
Q_OBJECT
public:
EditorClosingCoreListener(EditorManager *em);
bool editorAboutToClose(IEditor *editor);
bool coreAboutToClose();
private:
EditorManager *m_em;
};
} // namespace Internal
} // namespace Core
#endif // EDITORMANAGER_H

View File

@@ -0,0 +1,664 @@
/***************************************************************************
**
** 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 "editorsplitter.h"
#include "editormanager.h"
#include "openeditorswindow.h"
#include "stackededitorgroup.h"
#include "minisplitter.h"
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/uniqueidmanager.h>
#include <coreplugin/actionmanager/actionmanagerinterface.h>
#include <QtGui/QHBoxLayout>
#include <QtGui/QMenu>
#include <QtGui/QApplication>
using namespace Core;
using namespace Core::Internal;
EditorSplitter::EditorSplitter(ICore *core, QWidget *parent)
: QWidget(parent),
m_curGroup(0),
m_core(core)
{
registerActions();
createRootGroup();
updateActions();
}
EditorSplitter::~EditorSplitter()
{
}
void EditorSplitter::registerActions()
{
QList<int> gc = QList<int>() << Constants::C_GLOBAL_ID;
const QList<int> editorManagerContext =
QList<int>() << m_core->uniqueIDManager()->uniqueIdentifier(Constants::C_EDITORMANAGER);
ActionManagerInterface *am = m_core->actionManager();
IActionContainer *mwindow = am->actionContainer(Constants::M_WINDOW);
ICommand *cmd;
//Horizontal Action
m_horizontalSplitAction = new QAction(tr("Split Left/Right"), this);
cmd = am->registerAction(m_horizontalSplitAction, Constants::HORIZONTAL, editorManagerContext);
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
connect(m_horizontalSplitAction, SIGNAL(triggered()),
this, SLOT(splitHorizontal()));
//Vertical Action
m_verticalSplitAction = new QAction(tr("Split Top/Bottom"), this);
cmd = am->registerAction(m_verticalSplitAction, Constants::VERTICAL, editorManagerContext);
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
connect(m_verticalSplitAction, SIGNAL(triggered()),
this, SLOT(splitVertical()));
//Unsplit Action
m_unsplitAction = new QAction(tr("Unsplit"), this);
cmd = am->registerAction(m_unsplitAction, Constants::REMOVE, editorManagerContext);
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
connect(m_unsplitAction, SIGNAL(triggered()),
this, SLOT(unsplit()));
//Default Layout menu
IActionContainer *mLayout = am->createMenu("QtCreator.Menu.Window.Layout");
mwindow->addMenu(mLayout, Constants::G_WINDOW_SPLIT);
mLayout->menu()->setTitle(tr("Default Splitter Layout"));
//Set Current As Default
m_currentAsDefault = new QAction(tr("Save Current as Default"), this);
cmd = am->registerAction(m_currentAsDefault, Constants::SAVEASDEFAULT, editorManagerContext);
mLayout->addAction(cmd);
connect(m_currentAsDefault, SIGNAL(triggered()),
this, SLOT(saveCurrentLayout()));
//Restore Default
m_restoreDefault = new QAction(tr("Restore Default Layout"), this);
cmd = am->registerAction(m_restoreDefault, Constants::RESTOREDEFAULT, editorManagerContext);
mLayout->addAction(cmd);
connect(m_restoreDefault, SIGNAL(triggered()),
this, SLOT(restoreDefaultLayout()));
// TODO: The previous and next actions are removed, to be reenabled when they
// navigate according to code navigation history. And they need different shortcuts on the mac
// since Alt+Left/Right is jumping wordwise in editors
#if 0
// Goto Previous Action
m_gotoPreviousEditorAction = new QAction(QIcon(Constants::ICON_PREV), tr("Previous Document"), this);
cmd = am->registerAction(m_gotoPreviousEditorAction, Constants::GOTOPREV, editorManagerContext);
cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Left")));
mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE);
connect(m_gotoPreviousEditorAction, SIGNAL(triggered()), this, SLOT(gotoPreviousEditor()));
// Goto Next Action
m_gotoNextEditorAction = new QAction(QIcon(Constants::ICON_NEXT), tr("Next Document"), this);
cmd = am->registerAction(m_gotoNextEditorAction, Constants::GOTONEXT, editorManagerContext);
cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Right")));
mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE);
connect(m_gotoNextEditorAction, SIGNAL(triggered()), this, SLOT(gotoNextEditor()));
#endif
// Previous Group Action
m_gotoPreviousGroupAction = new QAction(tr("Previous Group"), this);
cmd = am->registerAction(m_gotoPreviousGroupAction, Constants::GOTOPREVIOUSGROUP, editorManagerContext);
mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE_GROUPS);
connect(m_gotoPreviousGroupAction, SIGNAL(triggered()), this, SLOT(selectPreviousGroup()));
// Next Group Action
m_gotoNextGroupAction = new QAction(tr("Next Group"), this);
cmd = am->registerAction(m_gotoNextGroupAction, Constants::GOTONEXTGROUP, editorManagerContext);
mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE_GROUPS);
connect(m_gotoNextGroupAction, SIGNAL(triggered()), this, SLOT(selectNextGroup()));
// Move to Previous Group
m_moveDocToPreviousGroupAction = new QAction(tr("Move Document to Previous Group"), this);
cmd = am->registerAction(m_moveDocToPreviousGroupAction, "QtCreator.DocumentToPreviousGroup", editorManagerContext);
mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE_GROUPS);
connect(m_moveDocToPreviousGroupAction, SIGNAL(triggered()), this, SLOT(moveDocToPreviousGroup()));
// Move to Next Group
m_moveDocToNextGroupAction = new QAction(tr("Move Document to Next Group"), this);
cmd = am->registerAction(m_moveDocToNextGroupAction, "QtCreator.DocumentToNextGroup", editorManagerContext);
mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE_GROUPS);
connect(m_moveDocToNextGroupAction, SIGNAL(triggered()), this, SLOT(moveDocToNextGroup()));
}
void EditorSplitter::updateActions()
{
const bool hasMultipleGroups = (qobject_cast<QSplitter*>(m_root) != 0);
Q_ASSERT(currentGroup());
const bool hasEditors = (currentGroup()->editorCount() != 0);
m_unsplitAction->setEnabled(hasMultipleGroups);
#if 0
const bool hasMultipleEditors = (editorCount() > 1);
m_gotoNextEditorAction->setEnabled(hasMultipleEditors);
m_gotoPreviousEditorAction->setEnabled(hasMultipleEditors);
#endif
m_gotoPreviousGroupAction->setEnabled(hasMultipleGroups);
m_gotoNextGroupAction->setEnabled(hasMultipleGroups);
m_moveDocToPreviousGroupAction->setEnabled(hasEditors && hasMultipleGroups);
m_moveDocToNextGroupAction->setEnabled(hasEditors && hasMultipleGroups);
}
int EditorSplitter::editorCount() const
{
int count = 0;
foreach (EditorGroup *group, groups()) {
count += group->editorCount();
}
return count;
}
void EditorSplitter::createRootGroup()
{
QHBoxLayout *l = new QHBoxLayout(this);
l->setMargin(0);
l->setSpacing(0);
EditorGroup *rootGroup = createGroup();
m_root = rootGroup->widget();
l->addWidget(m_root);
setCurrentGroup(rootGroup);
}
void EditorSplitter::splitHorizontal()
{
split(Qt::Horizontal);
}
void EditorSplitter::splitVertical()
{
split(Qt::Vertical);
}
void EditorSplitter::gotoNextEditor()
{
OpenEditorsWindow *dialog = EditorManager::instance()->windowPopup();
dialog->setMode(OpenEditorsWindow::ListMode);
dialog->selectNextEditor();
EditorManager::instance()->showWindowPopup();
}
void EditorSplitter::gotoPreviousEditor()
{
OpenEditorsWindow *dialog = EditorManager::instance()->windowPopup();
dialog->setMode(OpenEditorsWindow::ListMode);
dialog->selectPreviousEditor();
EditorManager::instance()->showWindowPopup();
}
void EditorSplitter::setCurrentGroup(EditorGroup *group)
{
if (!group || group == m_curGroup)
return;
m_curGroup = group;
if (m_curGroup->widget()->focusWidget() != QApplication::focusWidget())
m_curGroup->widget()->setFocus();
updateActions();
}
QList<EditorGroup*> EditorSplitter::groups() const
{
QList<EditorGroup*> grps;
collectGroups(m_root, grps);
return grps;
}
void EditorSplitter::collectGroups(QWidget *widget, QList<EditorGroup*> &groups) const
{
EditorGroup *group = qobject_cast<EditorGroup *>(widget);
if (group) {
groups += group;
return;
}
QSplitter *splitter = qobject_cast<QSplitter*>(widget);
Q_ASSERT(splitter);
collectGroups(splitter->widget(LEFT), groups);
collectGroups(splitter->widget(RIGHT), groups);
}
EditorGroup *EditorSplitter::currentGroup() const
{
return m_curGroup;
}
void EditorSplitter::split(Qt::Orientation orientation)
{
EditorGroup *curGroup = currentGroup();
IEditor *editor = curGroup->currentEditor();
split(orientation, 0);
if (editor) {
EditorGroup *otherGroup = currentGroup();
if (curGroup != otherGroup) {
curGroup->removeEditor(editor);
otherGroup->addEditor(editor);
}
}
emit editorGroupsChanged();
}
QSplitter *EditorSplitter::split(Qt::Orientation orientation, EditorGroup *group)
{
EditorGroup *curGroup = group;
if (!curGroup)
curGroup = currentGroup();
if (!curGroup)
return 0;
int oldSibling1 = -1;
int oldSibling2 = -1;
int idx = 1;
QWidget *curGroupWidget = curGroup->widget();
QSplitter *parentSplitter = qobject_cast<QSplitter*>(curGroupWidget->parentWidget());
if (parentSplitter) {
if (parentSplitter->orientation() == Qt::Vertical) {
oldSibling1 = parentSplitter->widget(LEFT)->height();
oldSibling2 = parentSplitter->widget(RIGHT)->height();
} else {
oldSibling1 = parentSplitter->widget(LEFT)->width();
oldSibling2 = parentSplitter->widget(RIGHT)->width();
}
idx = parentSplitter->indexOf(curGroupWidget);
}
QLayout *l = curGroupWidget->parentWidget()->layout();
curGroupWidget->setParent(0);
QSplitter *splitter = new MiniSplitter(0);
splitter->setOrientation(orientation);
EditorGroup *eg = createGroup();
splitter->addWidget(curGroupWidget);
splitter->addWidget(eg->widget());
if (curGroupWidget == m_root) {
l->addWidget(splitter);
m_root = splitter;
} else {
parentSplitter->insertWidget(idx, splitter);
}
if (parentSplitter)
parentSplitter->setSizes(QList<int>() << oldSibling1 << oldSibling2);
if (orientation == Qt::Vertical)
splitter->setSizes(QList<int>() << curGroupWidget->height()/2
<< curGroupWidget->height()/2);
else
splitter->setSizes(QList<int>() << curGroupWidget->width()/2
<< curGroupWidget->width()/2);
setCurrentGroup(eg);
return splitter;
}
void EditorSplitter::unsplit()
{
EditorGroup *curGroup = currentGroup();
if (!curGroup)
return;
QWidget *curGroupWidget = curGroup->widget();
Q_ASSERT(curGroupWidget);
IEditor *selectedEditor = curGroup->currentEditor();
QSplitter *parentSplitter = qobject_cast<QSplitter*>(curGroupWidget->parentWidget());
if (parentSplitter) {
int oldSibling1 = -1;
int oldSibling2 = -1;
EditorGroup *e1 = qobject_cast<EditorGroup *>(parentSplitter->widget(LEFT));
EditorGroup *e2 = qobject_cast<EditorGroup *>(parentSplitter->widget(RIGHT));
QWidget *w = parentSplitter->parentWidget();
QSplitter *grandParentSplitter = qobject_cast<QSplitter*>(w);
int idx = 0;
if (grandParentSplitter) {
idx = grandParentSplitter->indexOf(parentSplitter);
if (grandParentSplitter->orientation() == Qt::Vertical) {
oldSibling1 = grandParentSplitter->widget(LEFT)->height();
oldSibling2 = grandParentSplitter->widget(RIGHT)->height();
} else {
oldSibling1 = grandParentSplitter->widget(LEFT)->width();
oldSibling2 = grandParentSplitter->widget(RIGHT)->width();
}
}
if (e1 && e2) { // we are unsplitting a split that contains of groups directly not one or more additional splits
e1->moveEditorsFromGroup(e2);
parentSplitter->setParent(0);
if (grandParentSplitter) {
grandParentSplitter->insertWidget(idx, e1->widget());
} else {
w->layout()->addWidget(e1->widget());
m_root = e1->widget();
}
setCurrentGroup(e1);
deleteGroup(e2);
e2 = 0;
delete parentSplitter;
e1->setCurrentEditor(selectedEditor);
} else if (e1 || e2) {
parentSplitter->setParent(0);
QSplitter *s = 0;
if (e1) {
s = qobject_cast<QSplitter*>(parentSplitter->widget(RIGHT));
} else {
s = qobject_cast<QSplitter*>(parentSplitter->widget(LEFT));
e1 = e2;
}
if (grandParentSplitter) {
grandParentSplitter->insertWidget(idx, s);
} else {
w->layout()->addWidget(s);
m_root = s;
}
EditorGroup *leftMost = groupFarthestOnSide(s, LEFT);
leftMost->moveEditorsFromGroup(e1);
leftMost->setCurrentEditor(selectedEditor);
setCurrentGroup(leftMost);
deleteGroup(e1);
}
if (grandParentSplitter)
grandParentSplitter->setSizes(QList<int>() << oldSibling1 << oldSibling2);
emit editorGroupsChanged();
}
updateActions();
}
void EditorSplitter::unsplitAll()
{
QSplitter *rootSplit = qobject_cast<QSplitter *>(m_root);
if (!rootSplit)
return;
// first create and set the new root, then kill the original stuff
// this way we can avoid unnecessary signals/ context changes
rootSplit->setParent(0);
EditorGroup *rootGroup = createGroup();
QLayout *l = layout();
l->addWidget(rootGroup->widget());
m_root = rootGroup->widget();
setCurrentGroup(rootGroup);
// kill old hierarchy
QList<IEditor *> editors;
unsplitAll(rootSplit->widget(1), editors);
unsplitAll(rootSplit->widget(0), editors);
delete rootSplit;
rootSplit = 0;
foreach (IEditor *editor, editors) {
rootGroup->addEditor(editor);
}
}
void EditorSplitter::unsplitAll(QWidget *node, QList<IEditor*> &editors)
{
QSplitter *splitter = qobject_cast<QSplitter *>(node);
if (splitter) {
unsplitAll(splitter->widget(1), editors);
unsplitAll(splitter->widget(0), editors);
delete splitter;
splitter = 0;
} else {
EditorGroup *group = qobject_cast<EditorGroup *>(node);
editors << group->editors();
bool blocking = group->widget()->blockSignals(true);
foreach (IEditor *editor, group->editors()) {
group->removeEditor(editor);
}
group->widget()->blockSignals(blocking);
deleteGroup(group);
}
}
EditorGroup *EditorSplitter::groupFarthestOnSide(QWidget *node, Side side) const
{
QWidget *current = node;
QSplitter *split = 0;
while ((split = qobject_cast<QSplitter*>(current))) {
current = split->widget(side);
}
return qobject_cast<EditorGroup *>(current);
}
void EditorSplitter::selectNextGroup()
{
EditorGroup *curGroup = currentGroup();
Q_ASSERT(curGroup);
setCurrentGroup(nextGroup(curGroup, RIGHT));
}
void EditorSplitter::selectPreviousGroup()
{
EditorGroup *curGroup = currentGroup();
Q_ASSERT(curGroup);
setCurrentGroup(nextGroup(curGroup, LEFT));
}
EditorGroup *EditorSplitter::nextGroup(EditorGroup *curGroup, Side side) const
{
Q_ASSERT(curGroup);
QWidget *curWidget = curGroup->widget();
QWidget *parent = curWidget->parentWidget();
while (curWidget != m_root) {
QSplitter *splitter = qobject_cast<QSplitter *>(parent);
Q_ASSERT(splitter);
if (splitter->widget(side) != curWidget) {
curWidget = splitter->widget(side);
break;
}
curWidget = parent;
parent = curWidget->parentWidget();
}
return groupFarthestOnSide(curWidget, side==LEFT ? RIGHT : LEFT);
}
void EditorSplitter::moveDocToAdjacentGroup(Side side)
{
EditorGroup *curGroup = currentGroup();
Q_ASSERT(curGroup);
IEditor *editor = curGroup->currentEditor();
if (!editor)
return;
EditorGroup *next = nextGroup(curGroup, side);
next->moveEditorFromGroup(curGroup, editor);
setCurrentGroup(next);
}
void EditorSplitter::moveDocToNextGroup()
{
moveDocToAdjacentGroup(RIGHT);
}
void EditorSplitter::moveDocToPreviousGroup()
{
moveDocToAdjacentGroup(LEFT);
}
QWidget *EditorSplitter::recreateGroupTree(QWidget *node)
{
QSplitter *splitter = qobject_cast<QSplitter *>(node);
if (!splitter) {
EditorGroup *group = qobject_cast<EditorGroup *>(node);
Q_ASSERT(group);
IEditor *currentEditor = group->currentEditor();
EditorGroup *newGroup = createGroup();
bool block = newGroup->widget()->blockSignals(true);
foreach (IEditor *editor, group->editors()) {
newGroup->addEditor(editor);
}
newGroup->setCurrentEditor(currentEditor);
deleteGroup(group);
newGroup->widget()->blockSignals(block);
return newGroup->widget();
} else {
QByteArray splitterState = splitter->saveState();
QWidget *orig0 = splitter->widget(0);
QWidget *orig1 = splitter->widget(1);
QWidget *g0 = recreateGroupTree(orig0);
QWidget *g1 = recreateGroupTree(orig1);
splitter->insertWidget(0, g0);
splitter->insertWidget(1, g1);
splitter->restoreState(splitterState);
return node;
}
}
void EditorSplitter::saveCurrentLayout()
{
QSettings *settings = m_core->settings();
settings->setValue("EditorManager/Splitting", saveState());
}
void EditorSplitter::restoreDefaultLayout()
{
QSettings *settings = m_core->settings();
if (settings->contains("EditorManager/Splitting"))
restoreState(settings->value("EditorManager/Splitting").toByteArray());
}
void EditorSplitter::saveSettings(QSettings * /*settings*/) const
{
}
void EditorSplitter::readSettings(QSettings * /*settings*/)
{
restoreDefaultLayout();
}
QByteArray EditorSplitter::saveState() const
{
//todo: versioning
QByteArray bytes;
QDataStream stream(&bytes, QIODevice::WriteOnly);
saveState(m_root, stream);
return bytes;
}
bool EditorSplitter::restoreState(const QByteArray &state)
{
unsplitAll();
//todo: versioning
QDataStream stream(state);
EditorGroup *curGroup =
restoreState(qobject_cast<EditorGroup *>(m_root), stream);
setCurrentGroup(curGroup);
return true;
}
void EditorSplitter::saveState(QWidget *current, QDataStream &stream) const
{
QSplitter *splitter = qobject_cast<QSplitter *>(current);
quint8 type;
if (splitter) {
type = 0;
stream << type;
stream << splitter->saveState();
saveState(splitter->widget(0), stream);
saveState(splitter->widget(1), stream);
} else {
EditorGroup *group = qobject_cast<EditorGroup *>(current);
Q_ASSERT(group);
if (group != currentGroup())
type = 1;
else
type = 2;
stream << type;
}
}
EditorGroup *EditorSplitter::restoreState(EditorGroup *current,
QDataStream &stream)
{
EditorGroup *curGroup = 0;
EditorGroup *group;
quint8 type;
stream >> type;
if (type == 0) {
QSplitter *splitter = split(Qt::Horizontal, current);
QByteArray splitterState;
stream >> splitterState;
splitter->restoreState(splitterState);
group = restoreState(qobject_cast<EditorGroup *>(splitter->widget(0)),
stream);
if (group)
curGroup = group;
group = restoreState(qobject_cast<EditorGroup *>(splitter->widget(1)),
stream);
if (group)
curGroup = group;
} else {
if (type == 2)
return current;
}
return curGroup;
}
QMap<QString,EditorGroup *> EditorSplitter::pathGroupMap()
{
QMap<QString,EditorGroup *> map;
fillPathGroupMap(m_root, "", map);
return map;
}
void EditorSplitter::fillPathGroupMap(QWidget *current, QString currentPath,
QMap<QString,EditorGroup *> &map)
{
EditorGroup *group = qobject_cast<EditorGroup *>(current);
if (group) {
map.insert(currentPath, group);
} else {
QSplitter *splitter = qobject_cast<QSplitter *>(current);
Q_ASSERT(splitter);
fillPathGroupMap(splitter->widget(0), currentPath+"0", map);
fillPathGroupMap(splitter->widget(1), currentPath+"1", map);
}
}
EditorGroup *EditorSplitter::createGroup()
{
EditorGroup *group = new StackedEditorGroup(this);
connect(group, SIGNAL(closeRequested(Core::IEditor *)),
this, SIGNAL(closeRequested(Core::IEditor *)));
connect(group, SIGNAL(editorRemoved(Core::IEditor *)),
this, SLOT(updateActions()));
connect(group, SIGNAL(editorAdded(Core::IEditor *)),
this, SLOT(updateActions()));
m_core->addContextObject(group->contextObject());
return group;
}
void EditorSplitter::deleteGroup(EditorGroup *group)
{
m_core->removeContextObject(group->contextObject());
delete group;
}

View File

@@ -0,0 +1,136 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef EDITORSPLITTER_H
#define EDITORSPLITTER_H
#include <QtCore/QMap>
#include <QtCore/QList>
#include <QtCore/QString>
#include <QtCore/QSettings>
#include <QtGui/QWidget>
#include <QtGui/QAction>
#include <QtGui/QSplitter>
namespace Core {
class EditorGroup;
class ICore;
class IEditor;
namespace Internal {
class EditorSplitter : public QWidget
{
Q_OBJECT
public:
EditorSplitter(ICore *core, QWidget *parent = 0);
~EditorSplitter();
void setCurrentGroup(Core::EditorGroup *group);
EditorGroup *currentGroup() const;
QList<EditorGroup*> groups() const;
void split(Qt::Orientation orientation);
void saveSettings(QSettings *settings) const;
void readSettings(QSettings *settings);
QByteArray saveState() const;
bool restoreState(const QByteArray &state);
QMap<QString,EditorGroup *> pathGroupMap();
public slots:
void unsplit();
signals:
void closeRequested(Core::IEditor *editor);
void editorGroupsChanged();
private slots:
void splitHorizontal();
void splitVertical();
void gotoNextEditor();
void gotoPreviousEditor();
void updateActions();
void selectNextGroup();
void selectPreviousGroup();
void moveDocToNextGroup();
void moveDocToPreviousGroup();
void saveCurrentLayout();
void restoreDefaultLayout();
private:
enum Side {LEFT = 0, RIGHT = 1};
void registerActions();
void createRootGroup();
EditorGroup *createGroup();
void deleteGroup(EditorGroup *group);
void collectGroups(QWidget *widget, QList<EditorGroup*> &groups) const;
EditorGroup *groupFarthestOnSide(QWidget *node, Side side) const;
EditorGroup *nextGroup(EditorGroup *curGroup, Side side) const;
void moveDocToAdjacentGroup(Side side);
void saveState(QWidget *current, QDataStream &stream) const;
EditorGroup *restoreState(EditorGroup *current, QDataStream &stream);
QSplitter *split(Qt::Orientation orientation, EditorGroup *group);
void fillPathGroupMap(QWidget *current, QString currentPath,
QMap<QString,EditorGroup *> &map);
void unsplitAll();
void unsplitAll(QWidget *node, QList<IEditor *> &editors);
QWidget *recreateGroupTree(QWidget *node);
int editorCount() const;
QWidget *m_root;
EditorGroup *m_curGroup;
ICore *m_core;
QAction *m_horizontalSplitAction;
QAction *m_verticalSplitAction;
QAction *m_unsplitAction;
#if 0
QAction *m_gotoNextEditorAction;
QAction *m_gotoPreviousEditorAction;
#endif
QAction *m_gotoNextGroupAction;
QAction *m_gotoPreviousGroupAction;
QAction *m_moveDocToNextGroupAction;
QAction *m_moveDocToPreviousGroupAction;
QAction *m_currentAsDefault;
QAction *m_restoreDefault;
};
} // namespace Internal
} // namespace Core
#endif // EDITORSPLITTER_H

View File

@@ -0,0 +1,102 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef IEDITOR_H
#define IEDITOR_H
#include <coreplugin/core_global.h>
#include <coreplugin/icontext.h>
#include <coreplugin/ifile.h>
QT_BEGIN_NAMESPACE
class QToolBar;
QT_END_NAMESPACE
namespace Core {
/*!
\class Core::IEditor
\brief The IEditor is an interface for providing different editors for different file types.
Classes that implement this interface are for example the editors for
C++ files, ui-files and resource files.
Whenever a user wants to edit or create a file, the EditorManager scans all
EditorFactoryInterfaces for suitable editors. The selected EditorFactory
is then asked to create an editor, which must implement this interface.
Guidelines for implementing:
\list
\o displayName() is used as a user visible description of the document (usually filename w/o path).
\o kind() must be the same value as the kind() of the corresponding EditorFactory.
\o The changed() signal should be emitted when the modified state of the document changes
(so /bold{not} every time the document changes, but /bold{only once}).
\o If duplication is supported, you need to ensure that all duplicates
return the same file().
\endlist
\sa Core::EditorFactoryInterface Core::IContext
*/
class CORE_EXPORT IEditor : public IContext
{
Q_OBJECT
public:
IEditor(QObject *parent = 0) : IContext(parent) {}
virtual ~IEditor() {}
virtual bool createNew(const QString &contents = QString()) = 0;
virtual bool open(const QString &fileName = QString()) = 0;
virtual IFile *file() = 0;
virtual const char *kind() const = 0;
virtual QString displayName() const = 0;
virtual void setDisplayName(const QString &title) = 0;
virtual bool duplicateSupported() const = 0;
virtual IEditor *duplicate(QWidget *parent) = 0;
virtual QByteArray saveState() const = 0;
virtual bool restoreState(const QByteArray &state) = 0;
virtual int currentLine() const { return 0; };
virtual int currentColumn() const { return 0; };
virtual QToolBar *toolBar() = 0;
signals:
void changed();
};
} // namespace Core
#endif //IEDITOR_H

View File

@@ -0,0 +1,59 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef IEDITORFACTORY_H
#define IEDITORFACTORY_H
#include <coreplugin/ifilefactory.h>
#include <coreplugin/editormanager/ieditor.h>
#include <QtCore/QObject>
QT_BEGIN_NAMESPACE
class QWidget;
QT_END_NAMESPACE
namespace Core {
class CORE_EXPORT IEditorFactory : public Core::IFileFactory
{
Q_OBJECT
public:
IEditorFactory(QObject *parent = 0) : IFileFactory(parent) {}
virtual ~IEditorFactory() {}
virtual IEditor *createEditor(QWidget *parent) = 0;
};
} // namespace Core
#endif // IEDITORFACTORY_H

View File

@@ -0,0 +1,310 @@
/***************************************************************************
**
** 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 "openeditorsview.h"
#include "editorgroup.h"
#include "editormanager.h"
#include "coreimpl.h"
#include <coreplugin/coreconstants.h>
#include <coreplugin/filemanager.h>
#include <coreplugin/uniqueidmanager.h>
#include <QtCore/QTimer>
#include <QtGui/QMenu>
#include <QtGui/QPainter>
#include <QtGui/QStyle>
#include <QtGui/QStyleOption>
#include <QtGui/QHeaderView>
#include <QtGui/QKeyEvent>
#ifdef Q_WS_MAC
#include <qmacstyle_mac.h>
#endif
Q_DECLARE_METATYPE(Core::IEditor*)
using namespace Core;
using namespace Core::Internal;
OpenEditorsWidget::OpenEditorsWidget()
{
m_ui.setupUi(this);
setWindowTitle(tr("Open Documents"));
setWindowIcon(QIcon(Constants::ICON_DIR));
setFocusProxy(m_ui.editorList);
m_ui.editorList->setColumnCount(1);
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);
EditorManager *em = EditorManager::instance();
foreach(IEditor *editor, em->openedEditors()) {
registerEditor(editor);
}
connect(em, SIGNAL(editorOpened(Core::IEditor*)),
this, SLOT(registerEditor(Core::IEditor*)));
connect(em, SIGNAL(editorsClosed(QList<Core::IEditor*>)),
this, SLOT(unregisterEditors(QList<Core::IEditor*>)));
connect(em, SIGNAL(editorGroupsChanged()),
this, SLOT(updateEditorList()));
connect(em, SIGNAL(currentEditorChanged(Core::IEditor*)),
this, SLOT(updateCurrentItem()));
connect(m_ui.editorList, SIGNAL(itemActivated(QTreeWidgetItem*, int)),
this, SLOT(selectEditor(QTreeWidgetItem*)));
updateEditorList();
}
OpenEditorsWidget::~OpenEditorsWidget()
{
}
void OpenEditorsWidget::registerEditor(IEditor *editor)
{
connect(editor, SIGNAL(changed()), this, SLOT(updateEditor()));
updateEditorList();
}
void OpenEditorsWidget::unregisterEditors(QList<IEditor *> editors)
{
foreach (IEditor *editor, editors)
disconnect(editor, SIGNAL(changed()), this, SLOT(updateEditor()));
updateEditorList();
}
void OpenEditorsWidget::updateEditorList()
{
EditorManager *em = EditorManager::instance();
QList<EditorGroup *> groups = em->editorGroups();
IEditor *curEditor = em->currentEditor();
int oldNum = m_ui.editorList->topLevelItemCount();
QTreeWidgetItem *currentItem = 0;
int currItemIndex = 0;
for (int i = 0; i < groups.count(); ++i) {
QTreeWidgetItem *item;
if (groups.count() > 1) {
if (currItemIndex < oldNum) {
item = m_ui.editorList->topLevelItem(currItemIndex);
} else {
item = new QTreeWidgetItem(QStringList()<<"");
m_ui.editorList->addTopLevelItem(item);
}
currItemIndex++;
item->setIcon(0, QIcon());
item->setText(0, tr("---Group %1---").arg(i));
item->setFlags(0);
item->setToolTip(0, "");
item->setData(0, Qt::UserRole, QVariant());
item->setTextAlignment(0, Qt::AlignLeft);
}
foreach (IEditor *editor, groups.at(i)->editors()) {
if (currItemIndex < oldNum) {
item = m_ui.editorList->topLevelItem(currItemIndex);
} else {
item = new QTreeWidgetItem(QStringList()<<"");
m_ui.editorList->addTopLevelItem(item);
}
currItemIndex++;
updateItem(item, editor);
if (editor == curEditor)
currentItem = item;
}
}
for (int i = oldNum-1; i >= currItemIndex; --i) {
delete m_ui.editorList->takeTopLevelItem(i);
}
updateCurrentItem(currentItem);
}
void OpenEditorsWidget::updateCurrentItem(QTreeWidgetItem *currentItem)
{
EditorManager *em = EditorManager::instance();
IEditor *curEditor = em->currentEditor();
m_ui.editorList->clearSelection();
if (!currentItem && curEditor) {
int count = m_ui.editorList->topLevelItemCount();
for (int i = 0; i < count; ++i) {
if (m_ui.editorList->topLevelItem(i)->data(0, Qt::UserRole).value<IEditor *>()
== curEditor) {
currentItem = m_ui.editorList->topLevelItem(i);
break;
}
}
}
m_ui.editorList->setCurrentItem(currentItem);
if (currentItem)
m_ui.editorList->scrollTo(m_ui.editorList->currentIndex());
}
//todo: this is almost duplicated in openeditorswindow
void OpenEditorsWidget::updateItem(QTreeWidgetItem *item, IEditor *editor)
{
static const QIcon lockedIcon(QLatin1String(":/qworkbench/images/locked.png"));
static const QIcon emptyIcon(QLatin1String(":/qworkbench/images/empty14.png"));
QString title = editor->displayName();
if (editor->file()->isModified())
title += tr("*");
item->setIcon(0, editor->file()->isReadOnly() ? lockedIcon : emptyIcon);
item->setText(0, title);
item->setToolTip(0, editor->file()->fileName());
item->setData(0, Qt::UserRole, QVariant::fromValue(editor));
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
item->setTextAlignment(0, Qt::AlignLeft);
}
void OpenEditorsWidget::selectEditor(QTreeWidgetItem *item)
{
if (item == 0)
item = m_ui.editorList->currentItem();
if (item == 0)
return;
IEditor *editor = item->data(0, Qt::UserRole).value<IEditor*>();
EditorManager::instance()->setCurrentEditor(editor);
}
void OpenEditorsWidget::updateEditor()
{
IEditor *editor = qobject_cast<IEditor *>(sender());
Q_ASSERT(editor);
int num = m_ui.editorList->topLevelItemCount();
for (int i = 0; i < num; ++i) {
QTreeWidgetItem *item = m_ui.editorList->topLevelItem(i);
if (item->data(0, Qt::UserRole).value<IEditor *>()
== editor) {
updateItem(item, editor);
return;
}
}
}
void OpenEditorsWidget::closeEditors()
{
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 = CoreImpl::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->currentItem());
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()));
menu.addAction(tr("&Close"), this, SLOT(closeEditors()));
menu.addAction(tr("Close &All"), this, SLOT(closeAllEditors()));
if (m_ui.editorList->selectedItems().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()));
}
}
}
return false;
}
void OpenEditorsWidget::putFocusToEditorList()
{
m_ui.editorList->setFocus();
}
NavigationView OpenEditorsViewFactory::createWidget()
{
NavigationView n;
n.widget = new OpenEditorsWidget();
return n;
}
QString OpenEditorsViewFactory::displayName()
{
return "Open Documents";
}
QKeySequence OpenEditorsViewFactory::activationSequence()
{
return QKeySequence(Qt::ALT + Qt::Key_O);
}
OpenEditorsViewFactory::OpenEditorsViewFactory()
{
}
OpenEditorsViewFactory::~OpenEditorsViewFactory()
{
}

View File

@@ -0,0 +1,91 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef OPENEDITORSVIEW_H
#define OPENEDITORSVIEW_H
#include "ui_openeditorsview.h"
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/inavigationwidgetfactory.h>
#include <QtCore/QList>
#include <QtGui/QWidget>
#include <QtGui/QKeySequence>
#include <QtGui/QAbstractButton>
#include <QtGui/QTreeWidgetItem>
namespace Core {
namespace Internal {
class OpenEditorsWidget : public QWidget
{
Q_OBJECT
public:
OpenEditorsWidget();
~OpenEditorsWidget();
bool eventFilter(QObject *obj, QEvent *event);
private slots:
void registerEditor(Core::IEditor *editor);
void unregisterEditors(QList<Core::IEditor *> editors);
void updateEditorList();
void selectEditor(QTreeWidgetItem *item = 0);
void updateEditor();
void closeEditors();
void closeAllEditors();
void updateCurrentItem(QTreeWidgetItem *currentItem = 0);
void putFocusToEditorList();
private:
static void updateItem(QTreeWidgetItem *item, Core::IEditor *editor);
Ui::OpenEditorsView m_ui;
QWidget *m_widget;
};
class OpenEditorsViewFactory : public Core::INavigationWidgetFactory
{
public:
OpenEditorsViewFactory();
virtual ~OpenEditorsViewFactory();
QString displayName();
virtual QKeySequence activationSequence();
Core::NavigationView createWidget();
};
} // namespace Internal
} // namespace Core
#endif

View File

@@ -0,0 +1,39 @@
<ui version="4.0" >
<class>OpenEditorsView</class>
<widget class="QWidget" name="OpenEditorsView" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>263</width>
<height>217</height>
</rect>
</property>
<property name="minimumSize" >
<size>
<width>200</width>
<height>100</height>
</size>
</property>
<property name="windowTitle" >
<string>Form</string>
</property>
<layout class="QGridLayout" >
<property name="margin" >
<number>0</number>
</property>
<property name="spacing" >
<number>0</number>
</property>
<item row="0" column="0" >
<widget class="QTreeWidget" name="editorList" >
<property name="uniformRowHeights" >
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,351 @@
/***************************************************************************
**
** 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 "openeditorswindow.h"
#include "editorgroup.h"
#include "editormanager.h"
#include <QtGui/QHeaderView>
Q_DECLARE_METATYPE(Core::IEditor *)
using namespace Core;
using namespace Core::Internal;
const int OpenEditorsWindow::WIDTH = 300;
const int OpenEditorsWindow::HEIGHT = 200;
const int OpenEditorsWindow::MARGIN = 4;
OpenEditorsWindow::OpenEditorsWindow(QWidget *parent) :
QWidget(parent, Qt::Popup),
m_editorList(new QTreeWidget(this)),
m_mode(HistoryMode),
m_current(0)
{
resize(QSize(WIDTH, HEIGHT));
m_editorList->setColumnCount(1);
m_editorList->header()->hide();
m_editorList->setIndentation(0);
m_editorList->setSelectionMode(QAbstractItemView::SingleSelection);
m_editorList->setSelectionBehavior(QAbstractItemView::SelectItems);
m_editorList->setTextElideMode(Qt::ElideMiddle);
#ifdef Q_WS_MAC
m_editorList->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
#endif
m_editorList->installEventFilter(this);
m_editorList->setGeometry(MARGIN, MARGIN, WIDTH-2*MARGIN, HEIGHT-2*MARGIN);
connect(m_editorList, SIGNAL(itemClicked(QTreeWidgetItem*, int)),
this, SLOT(editorClicked(QTreeWidgetItem*)));
m_autoHide.setSingleShot(true);
connect(&m_autoHide, SIGNAL(timeout()), this, SLOT(selectAndHide()));
EditorManager *em = EditorManager::instance();
connect(em, SIGNAL(editorOpened(Core::IEditor *)),
this, SLOT(updateEditorList()));
connect(em, SIGNAL(editorsClosed(QList<Core::IEditor *>)),
this, SLOT(updateEditorList()));
connect(em, SIGNAL(editorGroupsChanged()),
this, SLOT(updateEditorList()));
connect(em, SIGNAL(currentEditorChanged(Core::IEditor*)),
this, SLOT(updateEditorList()));
}
void OpenEditorsWindow::selectAndHide()
{
selectEditor(m_editorList->currentItem());
setVisible(false);
}
void OpenEditorsWindow::setVisible(bool visible)
{
QWidget::setVisible(visible);
if (visible) {
updateEditorList(m_current);
m_autoHide.start(600);
setFocus();
}
}
bool OpenEditorsWindow::isCentering()
{
if (m_mode == OpenEditorsWindow::HistoryMode || m_editorList->topLevelItemCount() < 3)
return false;
int internalMargin = m_editorList->viewport()->mapTo(m_editorList, QPoint(0,0)).y();
QRect rect0 = m_editorList->visualItemRect(m_editorList->topLevelItem(0));
QRect rect1 = m_editorList->visualItemRect(m_editorList->topLevelItem(m_editorList->topLevelItemCount()-1));
int height = rect1.y() + rect1.height() - rect0.y();
height += 2*internalMargin + 2*MARGIN;
if (height > HEIGHT)
return true;
return false;
}
void OpenEditorsWindow::setMode(Mode mode)
{
m_mode = mode;
updateEditorList(m_current);
}
bool OpenEditorsWindow::event(QEvent *e) {
if (e->type() == QEvent::KeyRelease) {
QKeyEvent *ke = static_cast<QKeyEvent*>(e);
m_autoHide.stop();
if (ke->modifiers() == 0
/*HACK this is to overcome some event inconsistencies between platforms*/
|| (ke->modifiers() == Qt::AltModifier && (ke->key() == Qt::Key_Alt || ke->key() == -1))) {
selectAndHide();
}
}
return QWidget::event(e);
}
bool OpenEditorsWindow::eventFilter(QObject *obj, QEvent *e)
{
if (obj == m_editorList) {
if (e->type() == QEvent::KeyPress) {
QKeyEvent *ke = static_cast<QKeyEvent*>(e);
if (ke->key() == Qt::Key_Escape) {
m_current = EditorManager::instance()->currentEditor();
updateSelectedEditor();
setVisible(false);
return true;
}
if (ke->key() == Qt::Key_Return) {
selectEditor(m_editorList->currentItem());
return true;
}
}
}
return QWidget::eventFilter(obj, e);
}
void OpenEditorsWindow::focusInEvent(QFocusEvent *)
{
m_editorList->setFocus();
}
void OpenEditorsWindow::selectUpDown(bool up)
{
int itemCount = m_editorList->topLevelItemCount();
if (itemCount < 2)
return;
int index = m_editorList->indexOfTopLevelItem(m_editorList->currentItem());
if (index < 0)
return;
IEditor *editor = 0;
int count = 0;
while (!editor && count < itemCount) {
if (up) {
index--;
if (index < 0)
index = itemCount-1;
} else {
index++;
if (index >= itemCount)
index = 0;
}
editor = m_editorList->topLevelItem(index)
->data(0, Qt::UserRole).value<IEditor *>();
count++;
}
if (editor)
updateEditorList(editor);
}
void OpenEditorsWindow::selectPreviousEditor()
{
selectUpDown(m_mode == ListMode);
}
void OpenEditorsWindow::selectNextEditor()
{
selectUpDown(m_mode != ListMode);
}
void OpenEditorsWindow::updateEditorList(IEditor *editor)
{
if (!editor)
editor = EditorManager::instance()->currentEditor();
m_current = editor;
if (m_mode == ListMode)
updateList();
else if (m_mode == HistoryMode)
updateHistory();
}
void OpenEditorsWindow::updateHistory()
{
EditorManager *em = EditorManager::instance();
QList<IEditor *> history = em->editorHistory();
int oldNum = m_editorList->topLevelItemCount();
int num = history.count();
int common = qMin(oldNum, num);
int selectedIndex = -1;
QTreeWidgetItem *item;
for (int i = 0; i < common; ++i) {
item = m_editorList->topLevelItem(i);
updateItem(item, history.at(i));
if (history.at(i) == m_current)
selectedIndex = i;
}
for (int i = common; i < num; ++i) {
item = new QTreeWidgetItem(QStringList() << "");
updateItem(item, history.at(i));
m_editorList->addTopLevelItem(item);
if (history.at(i) == m_current)
selectedIndex = i;
}
for (int i = oldNum-1; i >= common; --i) {
delete m_editorList->takeTopLevelItem(i);
}
if (isCentering())
centerOnItem(selectedIndex);
updateSelectedEditor();
}
void OpenEditorsWindow::updateList()
{
EditorManager *em = EditorManager::instance();
QList<EditorGroup *> groups = em->editorGroups();
int oldNum = m_editorList->topLevelItemCount();
int curItem = 0;
int selectedIndex = -1;
QTreeWidgetItem *item;
for (int i = 0; i < groups.count(); ++i) {
if (groups.count() > 1) {
if (curItem < oldNum) {
item = m_editorList->topLevelItem(curItem);
} else {
item = new QTreeWidgetItem(QStringList()<<"");
m_editorList->addTopLevelItem(item);
}
curItem++;
item->setText(0, tr("---Group %1---").arg(i));
item->setFlags(0);
item->setData(0, Qt::UserRole, QVariant());
}
foreach (IEditor *editor, groups.at(i)->editors()) {
if (curItem < oldNum) {
item = m_editorList->topLevelItem(curItem);
} else {
item = new QTreeWidgetItem(QStringList()<<"");
m_editorList->addTopLevelItem(item);
}
updateItem(item, editor);
if (editor == m_current) {
m_editorList->setCurrentItem(item);
selectedIndex = curItem;
}
curItem++;
}
}
for (int i = oldNum-1; i >= curItem; --i) {
delete m_editorList->takeTopLevelItem(i);
}
if (isCentering())
centerOnItem(selectedIndex);
if (m_current == 0 && m_editorList->currentItem())
m_editorList->currentItem()->setSelected(false);
m_editorList->scrollTo(m_editorList->currentIndex(), QAbstractItemView::PositionAtCenter);
}
void OpenEditorsWindow::centerOnItem(int selectedIndex)
{
if (selectedIndex >= 0) {
QTreeWidgetItem *item;
int num = m_editorList->topLevelItemCount();
int rotate = selectedIndex-(num-1)/2;
for (int i = 0; i < rotate; ++i) {
item = m_editorList->takeTopLevelItem(0);
m_editorList->addTopLevelItem(item);
}
rotate = -rotate;
for (int i = 0; i < rotate; ++i) {
item = m_editorList->takeTopLevelItem(num-1);
m_editorList->insertTopLevelItem(0, item);
}
}
}
void OpenEditorsWindow::updateItem(QTreeWidgetItem *item, IEditor *editor)
{
static const QIcon lockedIcon(QLatin1String(":/qworkbench/images/locked.png"));
static const QIcon emptyIcon(QLatin1String(":/qworkbench/images/empty14.png"));
QString title = editor->displayName();
if (editor->file()->isModified())
title += tr("*");
item->setIcon(0, editor->file()->isReadOnly() ? lockedIcon : emptyIcon);
item->setText(0, title);
item->setToolTip(0, editor->file()->fileName());
item->setData(0, Qt::UserRole, QVariant::fromValue(editor));
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
item->setTextAlignment(0, Qt::AlignLeft);
}
void OpenEditorsWindow::selectEditor(QTreeWidgetItem *item)
{
IEditor *editor = 0;
if (item)
editor = item->data(0, Qt::UserRole).value<IEditor*>();
EditorManager::instance()->setCurrentEditor(editor);
}
void OpenEditorsWindow::editorClicked(QTreeWidgetItem *item)
{
selectEditor(item);
setFocus();
}
void OpenEditorsWindow::updateSelectedEditor()
{
if (m_current == 0 && m_editorList->currentItem()) {
m_editorList->currentItem()->setSelected(false);
return;
}
int num = m_editorList->topLevelItemCount();
for (int i = 0; i < num; ++i) {
IEditor *editor = m_editorList->topLevelItem(i)
->data(0, Qt::UserRole).value<IEditor *>();
if (editor == m_current) {
m_editorList->setCurrentItem(m_editorList->topLevelItem(i));
break;
}
}
m_editorList->scrollTo(m_editorList->currentIndex(), QAbstractItemView::PositionAtCenter);
}
void OpenEditorsWindow::setSelectedEditor(IEditor *editor)
{
updateEditorList(editor);
}

View File

@@ -0,0 +1,99 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef OPENEDITORSWINDOW_H
#define OPENEDITORSWINDOW_H
#include <QtCore/QTimer>
#include <QtGui/QWidget>
#include <QtGui/QKeyEvent>
#include <QtGui/QFocusEvent>
#include <QtGui/QTreeWidget>
#include <QtDebug>
namespace Core {
class IEditor;
namespace Internal {
class OpenEditorsWindow : public QWidget
{
Q_OBJECT
public:
enum Mode {ListMode, HistoryMode };
OpenEditorsWindow(QWidget *parent = 0);
~OpenEditorsWindow() {}
void setMode(Mode mode);
Mode mode() const { return m_mode; }
bool event(QEvent *e);
bool eventFilter(QObject *src, QEvent *e);
void focusInEvent(QFocusEvent *);
void setVisible(bool visible);
void setSelectedEditor(IEditor *editor);
void selectNextEditor();
void selectPreviousEditor();
IEditor *selectedEditor() const { return m_current; }
private slots:
void updateEditorList(IEditor *current = 0);
void editorClicked(QTreeWidgetItem *item);
void selectEditor(QTreeWidgetItem *item);
void selectAndHide();
private:
static const int WIDTH;
static const int HEIGHT;
static const int MARGIN;
static void updateItem(QTreeWidgetItem *item, IEditor *editor);
void updateList();
void updateHistory();
void updateSelectedEditor();
bool isCentering();
void centerOnItem(int selectedIndex);
void selectUpDown(bool up);
QTreeWidget *m_editorList;
Mode m_mode;
QTimer m_autoHide;
IEditor *m_current;
};
} // namespace Internal
} // namespace Core
#endif // OPENEDITORSWINDOW_H

View File

@@ -0,0 +1,375 @@
/***************************************************************************
**
** 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 "stackededitorgroup.h"
#include "editormanager.h"
#include "coreimpl.h"
#include <QtCore/QFileInfo>
#include <QtCore/QDir>
#include <QtCore/QMimeData>
#include <QtGui/QComboBox>
#include <QtGui/QHBoxLayout>
#include <QtGui/QPainter>
#include <QtGui/QStyle>
#include <QtGui/QStyleOption>
#include <QtGui/QMouseEvent>
#include <QtGui/QApplication>
#include <QtGui/QToolBar>
#include <QtGui/QToolButton>
#include <QtGui/QLabel>
#include <QtGui/QStackedWidget>
#include <QtDebug>
#ifdef Q_WS_MAC
#include <qmacstyle_mac.h>
#endif
Q_DECLARE_METATYPE(Core::IEditor *)
using namespace Core;
using namespace Core::Internal;
StackedEditorGroup::StackedEditorGroup(QWidget *parent) :
EditorGroup(parent),
m_toplevel(new QWidget),
m_toolBar(new QWidget),
m_container(new QStackedWidget(this)),
m_editorList(new QComboBox),
m_closeButton(new QToolButton),
m_lockButton(new QToolButton),
m_defaultToolBar(new QToolBar(this)),
m_infoWidget(new QFrame(this)),
m_editorForInfoWidget(0)
{
QVBoxLayout *tl = new QVBoxLayout(m_toplevel);
tl->setSpacing(0);
tl->setMargin(0);
{
m_editorList->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
m_editorList->setMinimumContentsLength(20);
m_proxyModel.setSourceModel(model());
m_proxyModel.sort(0);
m_editorList->setModel(&m_proxyModel);
m_editorList->setMaxVisibleItems(40);
QToolBar *editorListToolBar = new QToolBar;
editorListToolBar->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Ignored);
editorListToolBar->addWidget(m_editorList);
m_defaultToolBar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
m_activeToolBar = m_defaultToolBar;
QHBoxLayout *toolBarLayout = new QHBoxLayout;
toolBarLayout->setMargin(0);
toolBarLayout->setSpacing(0);
toolBarLayout->addWidget(m_defaultToolBar);
m_toolBar->setLayout(toolBarLayout);
m_lockButton->setAutoRaise(true);
m_lockButton->setProperty("type", QLatin1String("dockbutton"));
m_closeButton->setAutoRaise(true);
m_closeButton->setIcon(QIcon(":/qworkbench/images/closebutton.png"));
m_closeButton->setProperty("type", QLatin1String("dockbutton"));
QToolBar *rightToolBar = new QToolBar;
rightToolBar->setLayoutDirection(Qt::RightToLeft);
rightToolBar->addWidget(m_closeButton);
rightToolBar->addWidget(m_lockButton);
QHBoxLayout *toplayout = new QHBoxLayout;
toplayout->setSpacing(0);
toplayout->setMargin(0);
toplayout->addWidget(editorListToolBar);
toplayout->addWidget(m_toolBar, 1); // Custom toolbar stretches
toplayout->addWidget(rightToolBar);
QWidget *top = new QWidget;
QVBoxLayout *vlayout = new QVBoxLayout(top);
vlayout->setSpacing(0);
vlayout->setMargin(0);
vlayout->addLayout(toplayout);
tl->addWidget(top);
connect(m_editorList, SIGNAL(currentIndexChanged(int)), this, SLOT(listSelectionChanged(int)));
connect(m_lockButton, SIGNAL(clicked()), this, SLOT(makeEditorWritable()));
connect(m_closeButton, SIGNAL(clicked()), this, SLOT(sendCloseRequest()));
}
{
m_infoWidget->setFrameStyle(QFrame::Panel | QFrame::Raised);
m_infoWidget->setLineWidth(1);
m_infoWidget->setForegroundRole(QPalette::ToolTipText);
m_infoWidget->setBackgroundRole(QPalette::ToolTipBase);
m_infoWidget->setAutoFillBackground(true);
QHBoxLayout *hbox = new QHBoxLayout(m_infoWidget);
hbox->setMargin(2);
m_infoWidgetLabel = new QLabel("Placeholder");
m_infoWidgetLabel->setForegroundRole(QPalette::ToolTipText);
hbox->addWidget(m_infoWidgetLabel);
hbox->addStretch(1);
m_infoWidgetButton = new QToolButton;
m_infoWidgetButton->setText(tr("Placeholder"));
hbox->addWidget(m_infoWidgetButton);
QToolButton *closeButton = new QToolButton;
closeButton->setAutoRaise(true);
closeButton->setIcon(QIcon(":/qworkbench/images/clear.png"));
closeButton->setToolTip(tr("Close"));
connect(closeButton, SIGNAL(clicked()), m_infoWidget, SLOT(hide()));
hbox->addWidget(closeButton);
tl->addWidget(m_infoWidget);
}
tl->addWidget(m_container);
QHBoxLayout *l = new QHBoxLayout;
l->setSpacing(0);
l->setMargin(0);
l->addWidget(m_toplevel);
setLayout(l);
m_toplevel->setVisible(false);
}
void StackedEditorGroup::showEditorInfoBar(const QString &kind,
const QString &infoText,
const QString &buttonText,
QObject *object, const char *member)
{
m_infoWidgetKind = kind;
m_infoWidgetLabel->setText(infoText);
m_infoWidgetButton->setText(buttonText);
m_infoWidgetButton->disconnect();
if (object && member)
connect(m_infoWidgetButton, SIGNAL(clicked()), object, member);
m_infoWidget->setVisible(true);
m_editorForInfoWidget = currentEditor();
}
void StackedEditorGroup::hideEditorInfoBar(const QString &kind)
{
if (kind == m_infoWidgetKind)
m_infoWidget->setVisible(false);
}
StackedEditorGroup::~StackedEditorGroup()
{
}
void StackedEditorGroup::focusInEvent(QFocusEvent *e)
{
if (m_container->count() > 0) {
setEditorFocus(m_container->currentIndex());
} else {
EditorGroup::focusInEvent(e);
}
}
void StackedEditorGroup::setEditorFocus(int index)
{
QWidget *w = m_container->widget(index);
w->setFocus();
}
void StackedEditorGroup::addEditor(IEditor *editor)
{
insertEditor(editorCount(), editor);
}
void StackedEditorGroup::insertEditor(int index, IEditor *editor)
{
EditorGroup::insertEditor(index, editor);
if (m_container->indexOf(editor->widget()) != -1)
return;
m_container->insertWidget(index, editor->widget());
m_widgetEditorMap.insert(editor->widget(), editor);
QToolBar *toolBar = editor->toolBar();
if (toolBar)
m_toolBar->layout()->addWidget(toolBar);
connect(editor, SIGNAL(changed()), this, SLOT(updateEditorStatus()));
updateEditorStatus(editor);
updateToolBar(editor);
emit editorAdded(editor);
}
void StackedEditorGroup::sendCloseRequest()
{
emit closeRequested(currentEditor());
}
void StackedEditorGroup::removeEditor(IEditor *editor)
{
Q_ASSERT(editor);
EditorGroup::removeEditor(editor);
const int index = m_container->indexOf(editor->widget());
if (index != -1) {
m_container->removeWidget(editor->widget());
m_widgetEditorMap.remove(editor->widget());
editor->widget()->setParent(0);
disconnect(editor, SIGNAL(changed()), this, SLOT(updateEditorStatus()));
QToolBar *toolBar = editor->toolBar();
if (toolBar != 0) {
if (m_activeToolBar == toolBar) {
m_activeToolBar = m_defaultToolBar;
m_activeToolBar->setVisible(true);
}
m_toolBar->layout()->removeWidget(toolBar);
toolBar->setVisible(false);
toolBar->setParent(0);
}
if (m_container->count() == 0) {
m_toplevel->setVisible(false);
setFocus();
}
emit editorRemoved(editor);
}
}
IEditor *StackedEditorGroup::currentEditor() const
{
if (m_container->count() > 0)
return m_widgetEditorMap.value(m_container->currentWidget());
return 0;
}
void StackedEditorGroup::setCurrentEditor(IEditor *editor)
{
if (!editor || m_container->count() <= 0
|| m_container->indexOf(editor->widget()) == -1)
return;
m_toplevel->setVisible(true);
const int idx = m_container->indexOf(editor->widget());
Q_ASSERT(idx >= 0);
if (m_container->currentIndex() != idx) {
m_container->setCurrentIndex(idx);
const bool block = m_editorList->blockSignals(true);
m_editorList->setCurrentIndex(indexOf(editor));
m_editorList->blockSignals(block);
updateEditorStatus(editor);
updateToolBar(editor);
}
setEditorFocus(idx);
if (editor != m_editorForInfoWidget) {
m_infoWidget->hide();
m_editorForInfoWidget = 0;
}
}
void StackedEditorGroup::updateEditorStatus(IEditor *editor) {
if (!editor)
editor = qobject_cast<IEditor *>(sender());
Q_ASSERT(editor);
static const QIcon lockedIcon(QLatin1String(":/qworkbench/images/locked.png"));
static const QIcon unlockedIcon(QLatin1String(":/qworkbench/images/unlocked.png"));
if (editor->file()->isReadOnly()) {
m_lockButton->setIcon(lockedIcon);
m_lockButton->setEnabled(!editor->file()->fileName().isEmpty());
m_lockButton->setToolTip(tr("Make writable"));
} else {
m_lockButton->setIcon(unlockedIcon);
m_lockButton->setEnabled(false);
m_lockButton->setToolTip(tr("File is writable"));
}
if (currentEditor() == editor)
m_editorList->setToolTip(model()->data(model()->indexOf(editor), Qt::ToolTipRole).toString());
model()->emitDataChanged(editor);
}
void StackedEditorGroup::updateToolBar(IEditor *editor)
{
QToolBar *toolBar = editor->toolBar();
if (!toolBar)
toolBar = m_defaultToolBar;
if (m_activeToolBar == toolBar)
return;
m_activeToolBar->setVisible(false);
toolBar->setVisible(true);
m_activeToolBar = toolBar;
}
int StackedEditorGroup::editorCount() const
{
return model()->editors().count();
}
QList<IEditor *> StackedEditorGroup::editors() const
{
QAbstractItemModel *model = m_editorList->model();
QList<IEditor*> output;
int rows = model->rowCount();
for (int i = 0; i < rows; ++i)
output.append(model->data(model->index(i, 0), Qt::UserRole).value<IEditor*>());
return output;
}
QList<IEditor *> StackedEditorGroup::editorsInNaturalOrder() const
{
return model()->editors();
}
void StackedEditorGroup::makeEditorWritable()
{
CoreImpl::instance()->editorManager()->makeEditorWritable(currentEditor());
}
void StackedEditorGroup::listSelectionChanged(int index)
{
QAbstractItemModel *model = m_editorList->model();
setCurrentEditor(model->data(model->index(index, 0), Qt::UserRole).value<IEditor*>());
}
int StackedEditorGroup::indexOf(IEditor *editor)
{
QAbstractItemModel *model = m_editorList->model();
int rows = model->rowCount();
for (int i = 0; i < rows; ++i) {
if (editor == model->data(model->index(i, 0), Qt::UserRole).value<IEditor*>())
return i;
}
Q_ASSERT(false);
return 0;
}

View File

@@ -0,0 +1,111 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef STACKEDEDITORGROUP_H
#define STACKEDEDITORGROUP_H
#include "editorgroup.h"
#include <QtCore/QMap>
#include <QtGui/QSortFilterProxyModel>
QT_BEGIN_NAMESPACE
class QComboBox;
class QToolBar;
class QToolButton;
class QLabel;
class QStackedWidget;
QT_END_NAMESPACE
namespace Core {
namespace Internal {
class StackedEditorGroup : public EditorGroup
{
Q_OBJECT
public:
StackedEditorGroup(QWidget *parent = 0);
virtual ~StackedEditorGroup();
//EditorGroup
int editorCount() const;
void addEditor(IEditor *editor);
void insertEditor(int i, IEditor *editor);
void removeEditor(IEditor *editor);
IEditor *currentEditor() const;
void setCurrentEditor(IEditor *editor);
QList<IEditor *> editors() const;
void showEditorInfoBar(const QString &kind,
const QString &infoText,
const QString &buttonText,
QObject *object, const char *member);
void hideEditorInfoBar(const QString &kind);
void focusInEvent(QFocusEvent *e);
protected:
QList<IEditor *> editorsInNaturalOrder() const;
private slots:
void sendCloseRequest();
void updateEditorStatus(Core::IEditor *editor = 0);
void setEditorFocus(int index);
void makeEditorWritable();
void listSelectionChanged(int index);
private:
void updateToolBar(IEditor *editor);
int indexOf(IEditor *editor);
void checkProjectLoaded(IEditor *editor);
QWidget *m_toplevel;
QWidget *m_toolBar;
QToolBar *m_activeToolBar;
QStackedWidget *m_container;
QComboBox *m_editorList;
QToolButton *m_closeButton;
QToolButton *m_lockButton;
QToolBar *m_defaultToolBar;
QString m_infoWidgetKind;
QFrame *m_infoWidget;
QLabel *m_infoWidgetLabel;
QToolButton *m_infoWidgetButton;
IEditor *m_editorForInfoWidget;
QSortFilterProxyModel m_proxyModel;
QMap<QWidget *, IEditor *> m_widgetEditorMap;
};
} // namespace Internal
} // namespace Core
#endif // STACKEDEDITORGROUP_H

View File

@@ -0,0 +1,137 @@
/***************************************************************************
**
** 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 "fancyactionbar.h"
#include <QtGui/QHBoxLayout>
#include <QtGui/QPainter>
#include <QtGui/QPicture>
#include <QtGui/QVBoxLayout>
#include <QtSvg/QSvgRenderer>
using namespace Core;
using namespace Internal;
static const char* const svgIdButtonBase = "ButtonBase";
static const char* const svgIdButtonNormalBase = "ButtonNormalBase";
static const char* const svgIdButtonNormalOverlay = "ButtonNormalOverlay";
static const char* const svgIdButtonPressedBase = "ButtonPressedBase";
static const char* const svgIdButtonPressedOverlay = "ButtonPressedOverlay";
static const char* const svgIdButtonDisabledOverlay = "ButtonDisabledOverlay";
static const char* const svgIdButtonHoverOverlay = "ButtonHoverOverlay";
static const char* const elementsSvgIds[] = {
svgIdButtonBase,
svgIdButtonNormalBase,
svgIdButtonNormalOverlay,
svgIdButtonPressedBase,
svgIdButtonPressedOverlay,
svgIdButtonDisabledOverlay,
svgIdButtonHoverOverlay
};
const QMap<QString, QPicture> &buttonElementsMap()
{
static QMap<QString, QPicture> result;
if (result.isEmpty()) {
QSvgRenderer renderer(QLatin1String(":/fancyactionbar/images/fancytoolbutton.svg"));
for (size_t i = 0; i < sizeof(elementsSvgIds)/sizeof(elementsSvgIds[0]); i++) {
QString elementId(elementsSvgIds[i]);
QPicture elementPicture;
QPainter elementPainter(&elementPicture);
renderer.render(&elementPainter, elementId);
result.insert(elementId, elementPicture);
}
}
return result;
}
FancyToolButton::FancyToolButton(QWidget *parent)
: QToolButton(parent)
, m_buttonElements(buttonElementsMap())
{
setAttribute(Qt::WA_Hover, true);
}
void FancyToolButton::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter p(this);
p.drawPicture(0, 0, m_buttonElements.value(svgIdButtonBase));
p.drawPicture(0, 0, m_buttonElements.value(isDown() ? svgIdButtonPressedBase : svgIdButtonNormalBase));
#ifndef Q_WS_MAC // Mac UI's dont usually do hover
if (underMouse() && isEnabled())
p.drawPicture(0, 0, m_buttonElements.value(svgIdButtonHoverOverlay));
#endif
if (!icon().isNull()) {
icon().paint(&p, rect());
} else {
const int margin = 4;
p.drawText(rect().adjusted(margin, margin, -margin, -margin), Qt::AlignCenter | Qt::TextWordWrap, text());
}
if (!isEnabled())
p.drawPicture(0, 0, m_buttonElements.value(svgIdButtonDisabledOverlay));
p.drawPicture(0, 0, m_buttonElements.value(isDown() ? svgIdButtonPressedOverlay : svgIdButtonNormalOverlay));
}
void FancyActionBar::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
}
QSize FancyToolButton::sizeHint() const
{
return m_buttonElements.value(svgIdButtonBase).boundingRect().size();
}
FancyActionBar::FancyActionBar(QWidget *parent)
: QWidget(parent)
{
m_actionsLayout = new QVBoxLayout;
QHBoxLayout *centeringLayout = new QHBoxLayout;
centeringLayout->addStretch();
centeringLayout->addLayout(m_actionsLayout);
centeringLayout->addStretch();
setLayout(centeringLayout);
}
void FancyActionBar::insertAction(int index, QAction *action, QMenu *menu)
{
FancyToolButton *toolButton = new FancyToolButton(this);
toolButton->setDefaultAction(action);
if (menu) {
toolButton->setMenu(menu);
toolButton->setPopupMode(QToolButton::DelayedPopup);
}
m_actionsLayout->insertWidget(index, toolButton);
}

View File

@@ -0,0 +1,76 @@
/***************************************************************************
**
** 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.
**
***************************************************************************/
#ifndef FANCYACTIONBAR_H
#define FANCYACTIONBAR_H
#include <QtCore/QMap>
#include <QtGui/QToolButton>
QT_BEGIN_NAMESPACE
class QMenu;
class QVBoxLayout;
QT_END_NAMESPACE
namespace Core {
namespace Internal {
class FancyToolButton : public QToolButton
{
public:
FancyToolButton(QWidget *parent = 0);
void paintEvent(QPaintEvent *event);
QSize sizeHint() const;
private:
const QMap<QString, QPicture> &m_buttonElements;
};
class FancyActionBar : public QWidget
{
Q_OBJECT
public:
FancyActionBar(QWidget *parent = 0);
void paintEvent(QPaintEvent *event);
void insertAction(int index, QAction *action, QMenu *menu = 0);
private:
QVBoxLayout *m_actionsLayout;
};
} // namespace Internal
} // namespace Core
#endif // FANCYACTIONBAR_H

View File

@@ -0,0 +1,10 @@
<RCC>
<qresource prefix="/fancyactionbar" >
<file>images/fancytoolbutton.svg</file>
<file>images/mode_Debug.png</file>
<file>images/mode_Edit.png</file>
<file>images/mode_Output.png</file>
<file>images/mode_Project.png</file>
<file>images/mode_Reference.png</file>
</qresource>
</RCC>

Some files were not shown because too many files have changed in this diff Show More