forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/3.1'
This commit is contained in:
@@ -353,6 +353,7 @@ class Dumper(DumperBase):
|
|||||||
self.childEventAddress = None
|
self.childEventAddress = None
|
||||||
self.typesReported = {}
|
self.typesReported = {}
|
||||||
self.typesToReport = {}
|
self.typesToReport = {}
|
||||||
|
self.qtNamespaceToReport = None
|
||||||
|
|
||||||
def run(self, args):
|
def run(self, args):
|
||||||
self.output = []
|
self.output = []
|
||||||
@@ -494,6 +495,10 @@ class Dumper(DumperBase):
|
|||||||
self.output.append(']')
|
self.output.append(']')
|
||||||
self.typesToReport = {}
|
self.typesToReport = {}
|
||||||
|
|
||||||
|
if self.qtNamespaceToReport:
|
||||||
|
self.output.append(',qtnamespace="%s"' % self.qtNamespaceToReport)
|
||||||
|
self.qtNamespaceToReport = None
|
||||||
|
|
||||||
return "".join(self.output)
|
return "".join(self.output)
|
||||||
|
|
||||||
def enterSubItem(self, item):
|
def enterSubItem(self, item):
|
||||||
@@ -833,6 +838,17 @@ class Dumper(DumperBase):
|
|||||||
def extractByte(self, addr):
|
def extractByte(self, addr):
|
||||||
return struct.unpack("b", self.readRawMemory(addr, 1))[0]
|
return struct.unpack("b", self.readRawMemory(addr, 1))[0]
|
||||||
|
|
||||||
|
def findSymbol(self, symbolName):
|
||||||
|
try:
|
||||||
|
result = gdb.lookup_global_symbol(symbolName)
|
||||||
|
return result.value() if result else 0
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
# Older GDB ~7.4
|
||||||
|
try:
|
||||||
|
return gdb.parse_and_eval(symbolName)
|
||||||
|
except:
|
||||||
|
return 0
|
||||||
|
|
||||||
def extractStaticMetaObjectHelper(self, typeName):
|
def extractStaticMetaObjectHelper(self, typeName):
|
||||||
"""
|
"""
|
||||||
@@ -844,15 +860,7 @@ class Dumper(DumperBase):
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
staticMetaObjectName = typeName + "::staticMetaObject"
|
staticMetaObjectName = typeName + "::staticMetaObject"
|
||||||
if hasattr(gdb, 'lookup_global_symbol'):
|
result = self.findSymbol(staticMetaObjectName)
|
||||||
result = gdb.lookup_global_symbol(staticMetaObjectName)
|
|
||||||
result = result.value() if result else 0
|
|
||||||
else:
|
|
||||||
# Older GDB...
|
|
||||||
try:
|
|
||||||
result = gdb.parse_and_eval(staticMetaObjectName)
|
|
||||||
except:
|
|
||||||
result = 0
|
|
||||||
|
|
||||||
# We need to distinguish Q_OBJECT from Q_GADGET:
|
# We need to distinguish Q_OBJECT from Q_GADGET:
|
||||||
# a Q_OBJECT SMO has a non-null superdata (unless it's QObject itself),
|
# a Q_OBJECT SMO has a non-null superdata (unless it's QObject itself),
|
||||||
@@ -1564,8 +1572,13 @@ class Dumper(DumperBase):
|
|||||||
pos2 = out.find("QString::Null")
|
pos2 = out.find("QString::Null")
|
||||||
if pos1 > -1 and pos2 > -1:
|
if pos1 > -1 and pos2 > -1:
|
||||||
namespace = out[pos1:pos2]
|
namespace = out[pos1:pos2]
|
||||||
|
|
||||||
|
# Doesn't work
|
||||||
|
#gdb.write('=qt-namespace-detected,ns="%s"' % namespace)
|
||||||
|
self.qtNamespaceToReport = namespace
|
||||||
|
|
||||||
self.cachedQtNamespace = namespace
|
self.cachedQtNamespace = namespace
|
||||||
self.ns = lambda: self.cachedQtNamespace
|
self.qtNamespace = lambda: self.cachedQtNamespace
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -659,6 +659,7 @@ class Dumper(DumperBase):
|
|||||||
|
|
||||||
self.executable_ = args['executable']
|
self.executable_ = args['executable']
|
||||||
self.startMode_ = args.get('startMode', 1)
|
self.startMode_ = args.get('startMode', 1)
|
||||||
|
self.breakOnMain_ = args.get('breakOnMain', 0)
|
||||||
self.processArgs_ = args.get('processArgs', [])
|
self.processArgs_ = args.get('processArgs', [])
|
||||||
self.processArgs_ = map(lambda x: self.hexdecode(x), self.processArgs_)
|
self.processArgs_ = map(lambda x: self.hexdecode(x), self.processArgs_)
|
||||||
self.attachPid_ = args.get('attachPid', 0)
|
self.attachPid_ = args.get('attachPid', 0)
|
||||||
@@ -716,6 +717,8 @@ class Dumper(DumperBase):
|
|||||||
launchInfo.SetWorkingDirectory(os.getcwd())
|
launchInfo.SetWorkingDirectory(os.getcwd())
|
||||||
environmentList = [key + "=" + value for key,value in os.environ.items()]
|
environmentList = [key + "=" + value for key,value in os.environ.items()]
|
||||||
launchInfo.SetEnvironmentEntries(environmentList, False)
|
launchInfo.SetEnvironmentEntries(environmentList, False)
|
||||||
|
if self.breakOnMain_:
|
||||||
|
self.createBreakpointAtMain()
|
||||||
self.process = self.target.Launch(launchInfo, error)
|
self.process = self.target.Launch(launchInfo, error)
|
||||||
if not error.Success():
|
if not error.Success():
|
||||||
self.reportError(error)
|
self.reportError(error)
|
||||||
@@ -1323,6 +1326,10 @@ class Dumper(DumperBase):
|
|||||||
result += '],'
|
result += '],'
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def createBreakpointAtMain(self):
|
||||||
|
return self.target.BreakpointCreateByName(
|
||||||
|
"main", self.target.GetExecutable().GetFilename())
|
||||||
|
|
||||||
def addBreakpoint(self, args):
|
def addBreakpoint(self, args):
|
||||||
bpType = args["type"]
|
bpType = args["type"]
|
||||||
if bpType == BreakpointByFileAndLine:
|
if bpType == BreakpointByFileAndLine:
|
||||||
@@ -1333,8 +1340,7 @@ class Dumper(DumperBase):
|
|||||||
elif bpType == BreakpointByAddress:
|
elif bpType == BreakpointByAddress:
|
||||||
bpNew = self.target.BreakpointCreateByAddress(args["address"])
|
bpNew = self.target.BreakpointCreateByAddress(args["address"])
|
||||||
elif bpType == BreakpointAtMain:
|
elif bpType == BreakpointAtMain:
|
||||||
bpNew = self.target.BreakpointCreateByName(
|
bpNew = self.createBreakpointAtMain()
|
||||||
"main", self.target.GetExecutable().GetFilename())
|
|
||||||
elif bpType == BreakpointByFunction:
|
elif bpType == BreakpointByFunction:
|
||||||
bpNew = self.target.BreakpointCreateByName(args["function"])
|
bpNew = self.target.BreakpointCreateByName(args["function"])
|
||||||
elif bpType == BreakpointAtThrow:
|
elif bpType == BreakpointAtThrow:
|
||||||
|
|||||||
@@ -829,8 +829,11 @@ void Preprocessor::handleDefined(PPToken *tk)
|
|||||||
pushToken(tk);
|
pushToken(tk);
|
||||||
|
|
||||||
QByteArray result(1, '0');
|
QByteArray result(1, '0');
|
||||||
if (m_env->resolve(idToken.asByteArrayRef()))
|
const ByteArrayRef macroName = idToken.asByteArrayRef();
|
||||||
|
if (macroDefinition(macroName, idToken.offset + m_state.m_offsetRef,
|
||||||
|
idToken.lineno, m_env, m_client)) {
|
||||||
result[0] = '1';
|
result[0] = '1';
|
||||||
|
}
|
||||||
*tk = generateToken(T_NUMERIC_LITERAL, result.constData(), result.size(), lineno, false);
|
*tk = generateToken(T_NUMERIC_LITERAL, result.constData(), result.size(), lineno, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -969,7 +972,7 @@ bool Preprocessor::handleIdentifier(PPToken *tk)
|
|||||||
// their corresponding argument in macro substitution. For expanded tokens which are
|
// their corresponding argument in macro substitution. For expanded tokens which are
|
||||||
// generated, this information must be taken from somewhere else. What we do is to keep
|
// generated, this information must be taken from somewhere else. What we do is to keep
|
||||||
// a "reference" line initialize set to the line where expansion happens.
|
// a "reference" line initialize set to the line where expansion happens.
|
||||||
unsigned baseLine = idTk.lineno;
|
unsigned baseLine = idTk.lineno - m_state.m_lineRef + 1;
|
||||||
|
|
||||||
QVector<PPToken> body = macro->definitionTokens();
|
QVector<PPToken> body = macro->definitionTokens();
|
||||||
|
|
||||||
|
|||||||
@@ -30,13 +30,14 @@
|
|||||||
#include "execmenu.h"
|
#include "execmenu.h"
|
||||||
#include "fancylineedit.h"
|
#include "fancylineedit.h"
|
||||||
#include "historycompleter.h"
|
#include "historycompleter.h"
|
||||||
|
#include "hostosinfo.h"
|
||||||
#include "qtcassert.h"
|
#include "qtcassert.h"
|
||||||
|
|
||||||
#include <QAbstractItemView>
|
#include <QAbstractItemView>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QPainter>
|
#include <QStylePainter>
|
||||||
#include <QPropertyAnimation>
|
#include <QPropertyAnimation>
|
||||||
#include <QStyle>
|
#include <QStyle>
|
||||||
|
|
||||||
@@ -184,6 +185,11 @@ bool FancyLineEdit::isButtonVisible(Side side) const
|
|||||||
return d->m_iconEnabled[side];
|
return d->m_iconEnabled[side];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QAbstractButton *FancyLineEdit::button(FancyLineEdit::Side side) const
|
||||||
|
{
|
||||||
|
return d->m_iconbutton[side];
|
||||||
|
}
|
||||||
|
|
||||||
void FancyLineEdit::iconClicked()
|
void FancyLineEdit::iconClicked()
|
||||||
{
|
{
|
||||||
IconButton *button = qobject_cast<IconButton *>(sender());
|
IconButton *button = qobject_cast<IconButton *>(sender());
|
||||||
@@ -480,7 +486,7 @@ IconButton::IconButton(QWidget *parent)
|
|||||||
|
|
||||||
void IconButton::paintEvent(QPaintEvent *)
|
void IconButton::paintEvent(QPaintEvent *)
|
||||||
{
|
{
|
||||||
QPainter painter(this);
|
QStylePainter painter(this);
|
||||||
QRect pixmapRect = QRect(0, 0, m_pixmap.width(), m_pixmap.height());
|
QRect pixmapRect = QRect(0, 0, m_pixmap.width(), m_pixmap.height());
|
||||||
pixmapRect.moveCenter(rect().center());
|
pixmapRect.moveCenter(rect().center());
|
||||||
|
|
||||||
@@ -488,6 +494,18 @@ void IconButton::paintEvent(QPaintEvent *)
|
|||||||
painter.setOpacity(m_iconOpacity);
|
painter.setOpacity(m_iconOpacity);
|
||||||
|
|
||||||
painter.drawPixmap(pixmapRect, m_pixmap);
|
painter.drawPixmap(pixmapRect, m_pixmap);
|
||||||
|
|
||||||
|
if (hasFocus()) {
|
||||||
|
QStyleOptionFocusRect focusOption;
|
||||||
|
focusOption.initFrom(this);
|
||||||
|
focusOption.rect = pixmapRect;
|
||||||
|
if (HostOsInfo::isMacHost()) {
|
||||||
|
focusOption.rect.adjust(-4, -4, 4, 4);
|
||||||
|
painter.drawControl(QStyle::CE_FocusFrame, focusOption);
|
||||||
|
} else {
|
||||||
|
painter.drawPrimitive(QStyle::PE_FrameFocusRect, focusOption);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IconButton::animateShow(bool visible)
|
void IconButton::animateShow(bool visible)
|
||||||
@@ -505,4 +523,20 @@ void IconButton::animateShow(bool visible)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IconButton::keyPressEvent(QKeyEvent *ke)
|
||||||
|
{
|
||||||
|
QAbstractButton::keyPressEvent(ke);
|
||||||
|
if (!ke->modifiers() && (ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Return))
|
||||||
|
click();
|
||||||
|
// do not forward to line edit
|
||||||
|
ke->accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IconButton::keyReleaseEvent(QKeyEvent *ke)
|
||||||
|
{
|
||||||
|
QAbstractButton::keyReleaseEvent(ke);
|
||||||
|
// do not forward to line edit
|
||||||
|
ke->accept();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
|
|||||||
@@ -60,6 +60,11 @@ public:
|
|||||||
|
|
||||||
void setAutoHide(bool hide) { m_autoHide = hide; }
|
void setAutoHide(bool hide) { m_autoHide = hide; }
|
||||||
bool hasAutoHide() const { return m_autoHide; }
|
bool hasAutoHide() const { return m_autoHide; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void keyPressEvent(QKeyEvent *ke);
|
||||||
|
void keyReleaseEvent(QKeyEvent *ke);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float m_iconOpacity;
|
float m_iconOpacity;
|
||||||
bool m_autoHide;
|
bool m_autoHide;
|
||||||
@@ -89,6 +94,7 @@ public:
|
|||||||
|
|
||||||
void setButtonVisible(Side side, bool visible);
|
void setButtonVisible(Side side, bool visible);
|
||||||
bool isButtonVisible(Side side) const;
|
bool isButtonVisible(Side side) const;
|
||||||
|
QAbstractButton *button(Side side) const;
|
||||||
|
|
||||||
void setButtonToolTip(Side side, const QString &);
|
void setButtonToolTip(Side side, const QString &);
|
||||||
void setButtonFocusPolicy(Side side, Qt::FocusPolicy policy);
|
void setButtonFocusPolicy(Side side, Qt::FocusPolicy policy);
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ QTCREATOR_UTILS_EXPORT QString winErrorMessage(unsigned long error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
static inline QString msgCannotLoad(const char *lib, const QString &why)
|
static inline QString msgCannotLoad(const char *lib, const QString &why)
|
||||||
{
|
{
|
||||||
return QString::fromLatin1("Unable load %1: %2").arg(QLatin1String(lib), why);
|
return QString::fromLatin1("Unable load %1: %2").arg(QLatin1String(lib), why);
|
||||||
@@ -75,6 +76,7 @@ static inline QString msgCannotResolve(const char *lib)
|
|||||||
{
|
{
|
||||||
return QString::fromLatin1("Unable to resolve all required symbols in %1").arg(QLatin1String(lib));
|
return QString::fromLatin1("Unable to resolve all required symbols in %1").arg(QLatin1String(lib));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
QTCREATOR_UTILS_EXPORT QString winGetDLLVersion(WinDLLVersionType t,
|
QTCREATOR_UTILS_EXPORT QString winGetDLLVersion(WinDLLVersionType t,
|
||||||
const QString &name,
|
const QString &name,
|
||||||
|
|||||||
@@ -42,10 +42,12 @@
|
|||||||
|
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
#include <utils/flowlayout.h>
|
#include <utils/flowlayout.h>
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <QCompleter>
|
#include <QCompleter>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
@@ -100,14 +102,15 @@ FindToolBar::FindToolBar(FindPlugin *plugin, CurrentDocumentFind *currentDocumen
|
|||||||
m_ui.findEdit->setSpecialCompleter(m_findCompleter);
|
m_ui.findEdit->setSpecialCompleter(m_findCompleter);
|
||||||
m_ui.replaceEdit->setSpecialCompleter(m_replaceCompleter);
|
m_ui.replaceEdit->setSpecialCompleter(m_replaceCompleter);
|
||||||
|
|
||||||
QMenu *lineEditMenu = new QMenu(m_ui.findEdit);
|
|
||||||
m_ui.findEdit->setButtonMenu(Utils::FancyLineEdit::Left, lineEditMenu);
|
|
||||||
m_ui.findEdit->setButtonVisible(Utils::FancyLineEdit::Left, true);
|
m_ui.findEdit->setButtonVisible(Utils::FancyLineEdit::Left, true);
|
||||||
m_ui.findEdit->setFiltering(true);
|
m_ui.findEdit->setFiltering(true);
|
||||||
m_ui.findEdit->setPlaceholderText(QString());
|
m_ui.findEdit->setPlaceholderText(QString());
|
||||||
|
m_ui.findEdit->button(Utils::FancyLineEdit::Left)->setFocusPolicy(Qt::TabFocus);
|
||||||
m_ui.replaceEdit->setPlaceholderText(QString());
|
m_ui.replaceEdit->setPlaceholderText(QString());
|
||||||
|
|
||||||
connect(m_ui.findEdit, SIGNAL(textChanged(QString)), this, SLOT(invokeFindIncremental()));
|
connect(m_ui.findEdit, SIGNAL(textChanged(QString)), this, SLOT(invokeFindIncremental()));
|
||||||
|
connect(m_ui.findEdit, SIGNAL(leftButtonClicked()),
|
||||||
|
this, SLOT(findEditButtonClicked()));
|
||||||
|
|
||||||
// invoke{Find,Replace}Helper change the completion model. QueuedConnection is used to perform these
|
// invoke{Find,Replace}Helper change the completion model. QueuedConnection is used to perform these
|
||||||
// changes only after the completer's activated() signal is handled (QTCREATORBUG-8408)
|
// changes only after the completer's activated() signal is handled (QTCREATORBUG-8408)
|
||||||
@@ -222,8 +225,7 @@ FindToolBar::FindToolBar(FindPlugin *plugin, CurrentDocumentFind *currentDocumen
|
|||||||
m_caseSensitiveAction->setChecked(false);
|
m_caseSensitiveAction->setChecked(false);
|
||||||
cmd = Core::ActionManager::registerAction(m_caseSensitiveAction, Constants::CASE_SENSITIVE, globalcontext);
|
cmd = Core::ActionManager::registerAction(m_caseSensitiveAction, Constants::CASE_SENSITIVE, globalcontext);
|
||||||
mfind->addAction(cmd, Constants::G_FIND_FLAGS);
|
mfind->addAction(cmd, Constants::G_FIND_FLAGS);
|
||||||
connect(m_caseSensitiveAction, SIGNAL(triggered(bool)), this, SLOT(setCaseSensitive(bool)));
|
connect(m_caseSensitiveAction, SIGNAL(toggled(bool)), this, SLOT(setCaseSensitive(bool)));
|
||||||
lineEditMenu->addAction(m_caseSensitiveAction);
|
|
||||||
|
|
||||||
m_wholeWordAction = new QAction(tr("Whole Words Only"), this);
|
m_wholeWordAction = new QAction(tr("Whole Words Only"), this);
|
||||||
m_wholeWordAction->setIcon(QIcon(QLatin1String(":/find/images/wholewords.png")));
|
m_wholeWordAction->setIcon(QIcon(QLatin1String(":/find/images/wholewords.png")));
|
||||||
@@ -231,8 +233,7 @@ FindToolBar::FindToolBar(FindPlugin *plugin, CurrentDocumentFind *currentDocumen
|
|||||||
m_wholeWordAction->setChecked(false);
|
m_wholeWordAction->setChecked(false);
|
||||||
cmd = Core::ActionManager::registerAction(m_wholeWordAction, Constants::WHOLE_WORDS, globalcontext);
|
cmd = Core::ActionManager::registerAction(m_wholeWordAction, Constants::WHOLE_WORDS, globalcontext);
|
||||||
mfind->addAction(cmd, Constants::G_FIND_FLAGS);
|
mfind->addAction(cmd, Constants::G_FIND_FLAGS);
|
||||||
connect(m_wholeWordAction, SIGNAL(triggered(bool)), this, SLOT(setWholeWord(bool)));
|
connect(m_wholeWordAction, SIGNAL(toggled(bool)), this, SLOT(setWholeWord(bool)));
|
||||||
lineEditMenu->addAction(m_wholeWordAction);
|
|
||||||
|
|
||||||
m_regularExpressionAction = new QAction(tr("Use Regular Expressions"), this);
|
m_regularExpressionAction = new QAction(tr("Use Regular Expressions"), this);
|
||||||
m_regularExpressionAction->setIcon(QIcon(QLatin1String(":/find/images/regexp.png")));
|
m_regularExpressionAction->setIcon(QIcon(QLatin1String(":/find/images/regexp.png")));
|
||||||
@@ -240,8 +241,7 @@ FindToolBar::FindToolBar(FindPlugin *plugin, CurrentDocumentFind *currentDocumen
|
|||||||
m_regularExpressionAction->setChecked(false);
|
m_regularExpressionAction->setChecked(false);
|
||||||
cmd = Core::ActionManager::registerAction(m_regularExpressionAction, Constants::REGULAR_EXPRESSIONS, globalcontext);
|
cmd = Core::ActionManager::registerAction(m_regularExpressionAction, Constants::REGULAR_EXPRESSIONS, globalcontext);
|
||||||
mfind->addAction(cmd, Constants::G_FIND_FLAGS);
|
mfind->addAction(cmd, Constants::G_FIND_FLAGS);
|
||||||
connect(m_regularExpressionAction, SIGNAL(triggered(bool)), this, SLOT(setRegularExpressions(bool)));
|
connect(m_regularExpressionAction, SIGNAL(toggled(bool)), this, SLOT(setRegularExpressions(bool)));
|
||||||
lineEditMenu->addAction(m_regularExpressionAction);
|
|
||||||
|
|
||||||
m_preserveCaseAction = new QAction(tr("Preserve Case when Replacing"), this);
|
m_preserveCaseAction = new QAction(tr("Preserve Case when Replacing"), this);
|
||||||
m_preserveCaseAction->setIcon(QPixmap(QLatin1String(":/find/images/preservecase.png")));
|
m_preserveCaseAction->setIcon(QPixmap(QLatin1String(":/find/images/preservecase.png")));
|
||||||
@@ -249,8 +249,7 @@ FindToolBar::FindToolBar(FindPlugin *plugin, CurrentDocumentFind *currentDocumen
|
|||||||
m_preserveCaseAction->setChecked(false);
|
m_preserveCaseAction->setChecked(false);
|
||||||
cmd = Core::ActionManager::registerAction(m_preserveCaseAction, Constants::PRESERVE_CASE, globalcontext);
|
cmd = Core::ActionManager::registerAction(m_preserveCaseAction, Constants::PRESERVE_CASE, globalcontext);
|
||||||
mfind->addAction(cmd, Constants::G_FIND_FLAGS);
|
mfind->addAction(cmd, Constants::G_FIND_FLAGS);
|
||||||
connect(m_preserveCaseAction, SIGNAL(triggered(bool)), this, SLOT(setPreserveCase(bool)));
|
connect(m_preserveCaseAction, SIGNAL(toggled(bool)), this, SLOT(setPreserveCase(bool)));
|
||||||
lineEditMenu->addAction(m_preserveCaseAction);
|
|
||||||
|
|
||||||
connect(m_currentDocumentFind, SIGNAL(candidateChanged()), this, SLOT(adaptToCandidate()));
|
connect(m_currentDocumentFind, SIGNAL(candidateChanged()), this, SLOT(adaptToCandidate()));
|
||||||
connect(m_currentDocumentFind, SIGNAL(changed()), this, SLOT(updateToolBar()));
|
connect(m_currentDocumentFind, SIGNAL(changed()), this, SLOT(updateToolBar()));
|
||||||
@@ -554,6 +553,12 @@ void FindToolBar::findFlagsChanged()
|
|||||||
m_currentDocumentFind->highlightAll(getFindText(), effectiveFindFlags());
|
m_currentDocumentFind->highlightAll(getFindText(), effectiveFindFlags());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FindToolBar::findEditButtonClicked()
|
||||||
|
{
|
||||||
|
OptionsPopup *popup = new OptionsPopup(m_ui.findEdit);
|
||||||
|
popup->show();
|
||||||
|
}
|
||||||
|
|
||||||
void FindToolBar::updateIcons()
|
void FindToolBar::updateIcons()
|
||||||
{
|
{
|
||||||
FindFlags effectiveFlags = effectiveFindFlags();
|
FindFlags effectiveFlags = effectiveFindFlags();
|
||||||
@@ -685,11 +690,16 @@ void FindToolBar::findPreviousSelected()
|
|||||||
|
|
||||||
bool FindToolBar::focusNextPrevChild(bool next)
|
bool FindToolBar::focusNextPrevChild(bool next)
|
||||||
{
|
{
|
||||||
// close tab order change
|
QAbstractButton *optionsButton = m_ui.findEdit->button(Utils::FancyLineEdit::Left);
|
||||||
|
// close tab order
|
||||||
if (next && m_ui.advancedButton->hasFocus())
|
if (next && m_ui.advancedButton->hasFocus())
|
||||||
|
optionsButton->setFocus(Qt::TabFocusReason);
|
||||||
|
else if (next && optionsButton->hasFocus())
|
||||||
m_ui.findEdit->setFocus(Qt::TabFocusReason);
|
m_ui.findEdit->setFocus(Qt::TabFocusReason);
|
||||||
else if (!next && m_ui.findEdit->hasFocus())
|
else if (!next && optionsButton->hasFocus())
|
||||||
m_ui.advancedButton->setFocus(Qt::TabFocusReason);
|
m_ui.advancedButton->setFocus(Qt::TabFocusReason);
|
||||||
|
else if (!next && m_ui.findEdit->hasFocus())
|
||||||
|
optionsButton->setFocus(Qt::TabFocusReason);
|
||||||
else
|
else
|
||||||
return Utils::StyledBar::focusNextPrevChild(next);
|
return Utils::StyledBar::focusNextPrevChild(next);
|
||||||
return true;
|
return true;
|
||||||
@@ -778,3 +788,69 @@ void FindToolBar::setBackward(bool backward)
|
|||||||
{
|
{
|
||||||
setFindFlag(FindBackward, backward);
|
setFindFlag(FindBackward, backward);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OptionsPopup::OptionsPopup(QWidget *parent)
|
||||||
|
: QWidget(parent, Qt::Popup)
|
||||||
|
{
|
||||||
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||||
|
layout->setContentsMargins(2, 2, 2, 2);
|
||||||
|
layout->setSpacing(2);
|
||||||
|
setLayout(layout);
|
||||||
|
QCheckBox *firstCheckBox = createCheckboxForCommand(Constants::CASE_SENSITIVE);
|
||||||
|
layout->addWidget(firstCheckBox);
|
||||||
|
layout->addWidget(createCheckboxForCommand(Constants::WHOLE_WORDS));
|
||||||
|
layout->addWidget(createCheckboxForCommand(Constants::REGULAR_EXPRESSIONS));
|
||||||
|
layout->addWidget(createCheckboxForCommand(Constants::PRESERVE_CASE));
|
||||||
|
firstCheckBox->setFocus();
|
||||||
|
move(parent->mapToGlobal(QPoint(0, -sizeHint().height())));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OptionsPopup::event(QEvent *ev)
|
||||||
|
{
|
||||||
|
if (ev->type() == QEvent::ShortcutOverride) {
|
||||||
|
QKeyEvent *ke = static_cast<QKeyEvent *>(ev);
|
||||||
|
if (ke->key() == Qt::Key_Escape && !ke->modifiers()) {
|
||||||
|
ev->accept();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QWidget::event(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OptionsPopup::eventFilter(QObject *obj, QEvent *ev)
|
||||||
|
{
|
||||||
|
QCheckBox *checkbox = qobject_cast<QCheckBox *>(obj);
|
||||||
|
if (ev->type() == QEvent::KeyPress && checkbox) {
|
||||||
|
QKeyEvent *ke = static_cast<QKeyEvent *>(ev);
|
||||||
|
if (!ke->modifiers() && (ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Return)) {
|
||||||
|
checkbox->click();
|
||||||
|
ev->accept();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QWidget::eventFilter(obj, ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OptionsPopup::actionChanged()
|
||||||
|
{
|
||||||
|
QAction *action = qobject_cast<QAction *>(sender());
|
||||||
|
QTC_ASSERT(action, return);
|
||||||
|
QCheckBox *checkbox = m_checkboxMap.value(action);
|
||||||
|
QTC_ASSERT(checkbox, return);
|
||||||
|
checkbox->setEnabled(action->isEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
QCheckBox *OptionsPopup::createCheckboxForCommand(Id id)
|
||||||
|
{
|
||||||
|
QAction *action = ActionManager::command(id)->action();
|
||||||
|
QCheckBox *checkbox = new QCheckBox(action->text());
|
||||||
|
checkbox->setToolTip(action->toolTip());
|
||||||
|
checkbox->setChecked(action->isChecked());
|
||||||
|
checkbox->setEnabled(action->isEnabled());
|
||||||
|
checkbox->installEventFilter(this); // enter key handling
|
||||||
|
QObject::connect(checkbox, SIGNAL(clicked(bool)), action, SLOT(setChecked(bool)));
|
||||||
|
QObject::connect(action, SIGNAL(changed()), this, SLOT(actionChanged()));
|
||||||
|
m_checkboxMap.insert(action, checkbox);
|
||||||
|
return checkbox;
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,10 +33,15 @@
|
|||||||
#include "ui_findwidget.h"
|
#include "ui_findwidget.h"
|
||||||
#include "currentdocumentfind.h"
|
#include "currentdocumentfind.h"
|
||||||
|
|
||||||
|
#include <coreplugin/id.h>
|
||||||
#include <utils/styledbar.h>
|
#include <utils/styledbar.h>
|
||||||
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QCheckBox;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
class FindToolBarPlaceHolder;
|
class FindToolBarPlaceHolder;
|
||||||
@@ -44,6 +49,26 @@ class FindPlugin;
|
|||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
class OptionsPopup : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit OptionsPopup(QWidget *parent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool event(QEvent *ev);
|
||||||
|
bool eventFilter(QObject *obj, QEvent *ev);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void actionChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QCheckBox *createCheckboxForCommand(Id id);
|
||||||
|
|
||||||
|
QMap<QAction *, QCheckBox *> m_checkboxMap;
|
||||||
|
};
|
||||||
|
|
||||||
class FindToolBar : public Utils::StyledBar
|
class FindToolBar : public Utils::StyledBar
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -85,6 +110,7 @@ private slots:
|
|||||||
void updateFindAction();
|
void updateFindAction();
|
||||||
void updateToolBar();
|
void updateToolBar();
|
||||||
void findFlagsChanged();
|
void findFlagsChanged();
|
||||||
|
void findEditButtonClicked();
|
||||||
|
|
||||||
void setCaseSensitive(bool sensitive);
|
void setCaseSensitive(bool sensitive);
|
||||||
void setWholeWord(bool wholeOnly);
|
void setWholeWord(bool wholeOnly);
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ void CodepasterPlugin::post(QString data, const QString &mimeType)
|
|||||||
|
|
||||||
const QString username = m_settings->username;
|
const QString username = m_settings->username;
|
||||||
|
|
||||||
PasteView view(m_protocols, mimeType, ICore::mainWindow());
|
PasteView view(m_protocols, mimeType, ICore::dialogParent());
|
||||||
view.setProtocol(m_settings->protocol);
|
view.setProtocol(m_settings->protocol);
|
||||||
|
|
||||||
const FileDataList diffChunks = splitDiffToFiles(data);
|
const FileDataList diffChunks = splitDiffToFiles(data);
|
||||||
@@ -274,7 +274,7 @@ void CodepasterPlugin::fetchUrl()
|
|||||||
QUrl url;
|
QUrl url;
|
||||||
do {
|
do {
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
url = QUrl(QInputDialog::getText(0, tr("Fetch from URL"), tr("Enter URL:"), QLineEdit::Normal, QString(), &ok));
|
url = QUrl(QInputDialog::getText(ICore::dialogParent(), tr("Fetch from URL"), tr("Enter URL:"), QLineEdit::Normal, QString(), &ok));
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return;
|
return;
|
||||||
} while (!url.isValid());
|
} while (!url.isValid());
|
||||||
@@ -283,7 +283,7 @@ void CodepasterPlugin::fetchUrl()
|
|||||||
|
|
||||||
void CodepasterPlugin::fetch()
|
void CodepasterPlugin::fetch()
|
||||||
{
|
{
|
||||||
PasteSelectDialog dialog(m_protocols, ICore::mainWindow());
|
PasteSelectDialog dialog(m_protocols, ICore::dialogParent());
|
||||||
dialog.setProtocol(m_settings->protocol);
|
dialog.setProtocol(m_settings->protocol);
|
||||||
|
|
||||||
if (dialog.exec() != QDialog::Accepted)
|
if (dialog.exec() != QDialog::Accepted)
|
||||||
|
|||||||
@@ -4608,56 +4608,6 @@ void GdbEngine::handleInferiorPrepared()
|
|||||||
void GdbEngine::finishInferiorSetup()
|
void GdbEngine::finishInferiorSetup()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
|
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
|
||||||
// Extract Qt namespace.
|
|
||||||
QString fileName;
|
|
||||||
{
|
|
||||||
QTemporaryFile symbols(QDir::tempPath() + _("/gdb_ns_"));
|
|
||||||
symbols.open();
|
|
||||||
fileName = symbols.fileName();
|
|
||||||
}
|
|
||||||
postCommand("maint print msymbols \"" + fileName.toLocal8Bit() + '"',
|
|
||||||
CB(handleNamespaceExtraction), fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GdbEngine::handleDebugInfoLocation(const GdbResponse &response)
|
|
||||||
{
|
|
||||||
if (response.resultClass == GdbResultDone) {
|
|
||||||
const QByteArray debugInfoLocation = startParameters().debugInfoLocation.toLocal8Bit();
|
|
||||||
if (QFile::exists(QString::fromLocal8Bit(debugInfoLocation))) {
|
|
||||||
const QByteArray curDebugInfoLocations = response.consoleStreamOutput.split('"').value(1);
|
|
||||||
if (curDebugInfoLocations.isEmpty()) {
|
|
||||||
postCommand("set debug-file-directory " + debugInfoLocation);
|
|
||||||
} else {
|
|
||||||
postCommand("set debug-file-directory " + debugInfoLocation
|
|
||||||
+ HostOsInfo::pathListSeparator().toLatin1()
|
|
||||||
+ curDebugInfoLocations);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GdbEngine::handleNamespaceExtraction(const GdbResponse &response)
|
|
||||||
{
|
|
||||||
QFile file(response.cookie.toString());
|
|
||||||
file.open(QIODevice::ReadOnly);
|
|
||||||
QByteArray ba = file.readAll();
|
|
||||||
file.close();
|
|
||||||
file.remove();
|
|
||||||
QByteArray ns;
|
|
||||||
int pos = ba.indexOf("7QString16fromAscii_helper");
|
|
||||||
if (pos > -1) {
|
|
||||||
int pos1 = pos - 1;
|
|
||||||
while (pos1 > 0 && ba.at(pos1) != 'N' && ba.at(pos1) > '@')
|
|
||||||
--pos1;
|
|
||||||
++pos1;
|
|
||||||
ns = ba.mid(pos1, pos - pos1);
|
|
||||||
}
|
|
||||||
if (ns.isEmpty()) {
|
|
||||||
showMessage(_("FOUND NON-NAMESPACED QT"));
|
|
||||||
} else {
|
|
||||||
showMessage(_("FOUND NAMESPACED QT: " + ns));
|
|
||||||
setQtNamespace(ns + "::");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (startParameters().startMode == AttachCore) {
|
if (startParameters().startMode == AttachCore) {
|
||||||
notifyInferiorSetupOk(); // No breakpoints in core files.
|
notifyInferiorSetupOk(); // No breakpoints in core files.
|
||||||
@@ -4679,6 +4629,23 @@ void GdbEngine::handleNamespaceExtraction(const GdbResponse &response)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GdbEngine::handleDebugInfoLocation(const GdbResponse &response)
|
||||||
|
{
|
||||||
|
if (response.resultClass == GdbResultDone) {
|
||||||
|
const QByteArray debugInfoLocation = startParameters().debugInfoLocation.toLocal8Bit();
|
||||||
|
if (QFile::exists(QString::fromLocal8Bit(debugInfoLocation))) {
|
||||||
|
const QByteArray curDebugInfoLocations = response.consoleStreamOutput.split('"').value(1);
|
||||||
|
if (curDebugInfoLocations.isEmpty()) {
|
||||||
|
postCommand("set debug-file-directory " + debugInfoLocation);
|
||||||
|
} else {
|
||||||
|
postCommand("set debug-file-directory " + debugInfoLocation
|
||||||
|
+ HostOsInfo::pathListSeparator().toLatin1()
|
||||||
|
+ curDebugInfoLocations);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GdbEngine::handleBreakOnQFatal(const GdbResponse &response)
|
void GdbEngine::handleBreakOnQFatal(const GdbResponse &response)
|
||||||
{
|
{
|
||||||
if (response.resultClass == GdbResultDone) {
|
if (response.resultClass == GdbResultDone) {
|
||||||
@@ -5074,6 +5041,12 @@ void GdbEngine::handleStackFramePython(const GdbResponse &response)
|
|||||||
all.fromStringMultiple(out);
|
all.fromStringMultiple(out);
|
||||||
GdbMi data = all["data"];
|
GdbMi data = all["data"];
|
||||||
|
|
||||||
|
GdbMi ns = all["qtnamespace"];
|
||||||
|
if (ns.isValid()) {
|
||||||
|
setQtNamespace(ns.data());
|
||||||
|
showMessage(_("FOUND NAMESPACED QT: " + ns.data()));
|
||||||
|
}
|
||||||
|
|
||||||
WatchHandler *handler = watchHandler();
|
WatchHandler *handler = watchHandler();
|
||||||
QList<WatchData> list;
|
QList<WatchData> list;
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,6 @@ protected: ////////// Gdb Process Management //////////
|
|||||||
void startGdb(const QStringList &args = QStringList());
|
void startGdb(const QStringList &args = QStringList());
|
||||||
void handleInferiorShutdown(const GdbResponse &response);
|
void handleInferiorShutdown(const GdbResponse &response);
|
||||||
void handleGdbExit(const GdbResponse &response);
|
void handleGdbExit(const GdbResponse &response);
|
||||||
void handleNamespaceExtraction(const GdbResponse &response);
|
|
||||||
|
|
||||||
void loadInitScript();
|
void loadInitScript();
|
||||||
|
|
||||||
|
|||||||
@@ -208,6 +208,7 @@ void LldbEngine::setupInferior()
|
|||||||
Command cmd("setupInferior");
|
Command cmd("setupInferior");
|
||||||
cmd.arg("executable", executable);
|
cmd.arg("executable", executable);
|
||||||
cmd.arg("startMode", sp.startMode); // directly relying on this is brittle wrt. insertions, so check it here
|
cmd.arg("startMode", sp.startMode); // directly relying on this is brittle wrt. insertions, so check it here
|
||||||
|
cmd.arg("breakOnMain", sp.breakOnMain);
|
||||||
cmd.beginList("processArgs");
|
cmd.beginList("processArgs");
|
||||||
foreach (const QString &arg, args.toUnixArgs())
|
foreach (const QString &arg, args.toUnixArgs())
|
||||||
cmd.arg(arg.toUtf8().toHex());
|
cmd.arg(arg.toUtf8().toHex());
|
||||||
|
|||||||
@@ -1241,6 +1241,11 @@ QVariant WatchModel::headerData(int section, Qt::Orientation orientation, int ro
|
|||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline QString msgArrayFormat(int n)
|
||||||
|
{
|
||||||
|
return WatchModel::tr("Array of %n items", 0, n);
|
||||||
|
}
|
||||||
|
|
||||||
QStringList WatchModel::typeFormatList(const WatchData &data) const
|
QStringList WatchModel::typeFormatList(const WatchData &data) const
|
||||||
{
|
{
|
||||||
if (data.origaddr || isPointerType(data.type))
|
if (data.origaddr || isPointerType(data.type))
|
||||||
@@ -1251,10 +1256,10 @@ QStringList WatchModel::typeFormatList(const WatchData &data) const
|
|||||||
<< tr("Local 8bit string")
|
<< tr("Local 8bit string")
|
||||||
<< tr("UTF16 string")
|
<< tr("UTF16 string")
|
||||||
<< tr("UCS4 string")
|
<< tr("UCS4 string")
|
||||||
<< tr("Array of %1 items").arg(10)
|
<< msgArrayFormat(10)
|
||||||
<< tr("Array of %1 items").arg(100)
|
<< msgArrayFormat(100)
|
||||||
<< tr("Array of %1 items").arg(1000)
|
<< msgArrayFormat(1000)
|
||||||
<< tr("Array of %1 items").arg(10000);
|
<< msgArrayFormat(10000);
|
||||||
if (data.type.contains("char[") || data.type.contains("char ["))
|
if (data.type.contains("char[") || data.type.contains("char ["))
|
||||||
return QStringList()
|
return QStringList()
|
||||||
<< tr("Latin1 string")
|
<< tr("Latin1 string")
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ HEADERS += diffeditor_global.h \
|
|||||||
diffeditormanager.h \
|
diffeditormanager.h \
|
||||||
diffeditorplugin.h \
|
diffeditorplugin.h \
|
||||||
differ.h \
|
differ.h \
|
||||||
|
diffutils.h \
|
||||||
sidebysidediffeditorwidget.h
|
sidebysidediffeditorwidget.h
|
||||||
|
|
||||||
SOURCES += diffeditor.cpp \
|
SOURCES += diffeditor.cpp \
|
||||||
@@ -21,6 +22,7 @@ SOURCES += diffeditor.cpp \
|
|||||||
diffeditormanager.cpp \
|
diffeditormanager.cpp \
|
||||||
diffeditorplugin.cpp \
|
diffeditorplugin.cpp \
|
||||||
differ.cpp \
|
differ.cpp \
|
||||||
|
diffutils.cpp \
|
||||||
sidebysidediffeditorwidget.cpp
|
sidebysidediffeditorwidget.cpp
|
||||||
|
|
||||||
RESOURCES +=
|
RESOURCES +=
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ QtcPlugin {
|
|||||||
"diffeditorplugin.h",
|
"diffeditorplugin.h",
|
||||||
"differ.cpp",
|
"differ.cpp",
|
||||||
"differ.h",
|
"differ.h",
|
||||||
|
"diffutils.cpp",
|
||||||
|
"diffutils.h",
|
||||||
"sidebysidediffeditorwidget.cpp",
|
"sidebysidediffeditorwidget.cpp",
|
||||||
"sidebysidediffeditorwidget.h",
|
"sidebysidediffeditorwidget.h",
|
||||||
]
|
]
|
||||||
|
|||||||
351
src/plugins/diffeditor/diffutils.cpp
Normal file
351
src/plugins/diffeditor/diffutils.cpp
Normal file
@@ -0,0 +1,351 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "diffutils.h"
|
||||||
|
#include "differ.h"
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
namespace DiffEditor {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
static QList<TextLineData> assemblyRows(const QStringList &lines,
|
||||||
|
const QMap<int, int> &lineSpans)
|
||||||
|
{
|
||||||
|
QList<TextLineData> data;
|
||||||
|
|
||||||
|
const int lineCount = lines.count();
|
||||||
|
for (int i = 0; i <= lineCount; i++) {
|
||||||
|
for (int j = 0; j < lineSpans.value(i); j++)
|
||||||
|
data.append(TextLineData(TextLineData::Separator));
|
||||||
|
if (i < lineCount)
|
||||||
|
data.append(lines.at(i));
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool lastLinesEqual(const QStringList &leftLines,
|
||||||
|
const QStringList &rightLines)
|
||||||
|
{
|
||||||
|
const bool leftLineEqual = leftLines.count()
|
||||||
|
? leftLines.last().isEmpty()
|
||||||
|
: true;
|
||||||
|
const bool rightLineEqual = rightLines.count()
|
||||||
|
? rightLines.last().isEmpty()
|
||||||
|
: true;
|
||||||
|
return leftLineEqual && rightLineEqual;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handleLine(const QStringList &newLines,
|
||||||
|
int line,
|
||||||
|
QStringList *lines,
|
||||||
|
int *lineNumber,
|
||||||
|
int *charNumber)
|
||||||
|
{
|
||||||
|
if (line < newLines.count()) {
|
||||||
|
const QString text = newLines.at(line);
|
||||||
|
if (lines->isEmpty() || line > 0) {
|
||||||
|
if (line > 0)
|
||||||
|
++*lineNumber;
|
||||||
|
lines->append(text);
|
||||||
|
} else {
|
||||||
|
lines->last() += text;
|
||||||
|
}
|
||||||
|
*charNumber += text.count();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handleDifference(const QString &text,
|
||||||
|
QStringList *lines,
|
||||||
|
QMap<int, int> *changedPositions,
|
||||||
|
int *lineNumber,
|
||||||
|
int *charNumber)
|
||||||
|
{
|
||||||
|
const int oldPosition = *lineNumber + *charNumber;
|
||||||
|
const QStringList newLeftLines = text.split(QLatin1Char('\n'));
|
||||||
|
for (int line = 0; line < newLeftLines.count(); ++line)
|
||||||
|
handleLine(newLeftLines, line, lines, lineNumber, charNumber);
|
||||||
|
const int newPosition = *lineNumber + *charNumber;
|
||||||
|
changedPositions->insert(oldPosition, newPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* leftDiffList can contain only deletions and equalities,
|
||||||
|
* while rightDiffList can contain only insertions and equalities.
|
||||||
|
* The number of equalities on both lists must be the same.
|
||||||
|
*/
|
||||||
|
ChunkData calculateOriginalData(const QList<Diff> &leftDiffList,
|
||||||
|
const QList<Diff> &rightDiffList)
|
||||||
|
{
|
||||||
|
ChunkData chunkData;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
|
||||||
|
QStringList leftLines;
|
||||||
|
QStringList rightLines;
|
||||||
|
|
||||||
|
// <line number, span count>
|
||||||
|
QMap<int, int> leftSpans;
|
||||||
|
QMap<int, int> rightSpans;
|
||||||
|
// <left line number, right line number>
|
||||||
|
QMap<int, int> equalLines;
|
||||||
|
|
||||||
|
int leftLineNumber = 0;
|
||||||
|
int rightLineNumber = 0;
|
||||||
|
int leftCharNumber = 0;
|
||||||
|
int rightCharNumber = 0;
|
||||||
|
int leftLineAligned = -1;
|
||||||
|
int rightLineAligned = -1;
|
||||||
|
bool lastLineEqual = true;
|
||||||
|
|
||||||
|
while (i <= leftDiffList.count() && j <= rightDiffList.count()) {
|
||||||
|
const Diff leftDiff = i < leftDiffList.count()
|
||||||
|
? leftDiffList.at(i)
|
||||||
|
: Diff(Diff::Equal);
|
||||||
|
const Diff rightDiff = j < rightDiffList.count()
|
||||||
|
? rightDiffList.at(j)
|
||||||
|
: Diff(Diff::Equal);
|
||||||
|
|
||||||
|
if (leftDiff.command == Diff::Delete) {
|
||||||
|
// process delete
|
||||||
|
handleDifference(leftDiff.text, &leftLines, &chunkData.changedLeftPositions, &leftLineNumber, &leftCharNumber);
|
||||||
|
lastLineEqual = lastLinesEqual(leftLines, rightLines);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (rightDiff.command == Diff::Insert) {
|
||||||
|
// process insert
|
||||||
|
handleDifference(rightDiff.text, &rightLines, &chunkData.changedRightPositions, &rightLineNumber, &rightCharNumber);
|
||||||
|
lastLineEqual = lastLinesEqual(leftLines, rightLines);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
if (leftDiff.command == Diff::Equal && rightDiff.command == Diff::Equal) {
|
||||||
|
// process equal
|
||||||
|
const QStringList newLeftLines = leftDiff.text.split(QLatin1Char('\n'));
|
||||||
|
const QStringList newRightLines = rightDiff.text.split(QLatin1Char('\n'));
|
||||||
|
|
||||||
|
int line = 0;
|
||||||
|
|
||||||
|
while (line < qMax(newLeftLines.count(), newRightLines.count())) {
|
||||||
|
handleLine(newLeftLines, line, &leftLines, &leftLineNumber, &leftCharNumber);
|
||||||
|
handleLine(newRightLines, line, &rightLines, &rightLineNumber, &rightCharNumber);
|
||||||
|
|
||||||
|
const int commonLineCount = qMin(newLeftLines.count(), newRightLines.count());
|
||||||
|
if (line < commonLineCount) {
|
||||||
|
// try to align
|
||||||
|
const int leftDifference = leftLineNumber - leftLineAligned;
|
||||||
|
const int rightDifference = rightLineNumber - rightLineAligned;
|
||||||
|
|
||||||
|
if (leftDifference && rightDifference) {
|
||||||
|
bool doAlign = true;
|
||||||
|
if (line == 0 // omit alignment when first lines of equalities are empty
|
||||||
|
&& (newLeftLines.at(0).isEmpty() || newRightLines.at(0).isEmpty())) {
|
||||||
|
doAlign = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line == commonLineCount - 1) {
|
||||||
|
// omit alignment when last lines of equalities are empty
|
||||||
|
if (leftLines.last().isEmpty() || rightLines.last().isEmpty())
|
||||||
|
doAlign = false;
|
||||||
|
|
||||||
|
// unless it's the last dummy line (don't omit in that case)
|
||||||
|
if (i == leftDiffList.count() && j == rightDiffList.count())
|
||||||
|
doAlign = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doAlign) {
|
||||||
|
// align here
|
||||||
|
leftLineAligned = leftLineNumber;
|
||||||
|
rightLineAligned = rightLineNumber;
|
||||||
|
|
||||||
|
// insert separators if needed
|
||||||
|
if (rightDifference > leftDifference)
|
||||||
|
leftSpans.insert(leftLineNumber, rightDifference - leftDifference);
|
||||||
|
else if (leftDifference > rightDifference)
|
||||||
|
rightSpans.insert(rightLineNumber, leftDifference - rightDifference);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if lines are equal
|
||||||
|
if ((line < commonLineCount - 1) // before the last common line in equality
|
||||||
|
|| (line == commonLineCount - 1 // or the last common line in equality
|
||||||
|
&& i == leftDiffList.count() // and it's the last iteration
|
||||||
|
&& j == rightDiffList.count())) {
|
||||||
|
if (line > 0 || lastLineEqual)
|
||||||
|
equalLines.insert(leftLineNumber, rightLineNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line > 0)
|
||||||
|
lastLineEqual = true;
|
||||||
|
|
||||||
|
line++;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<TextLineData> leftData = assemblyRows(leftLines,
|
||||||
|
leftSpans);
|
||||||
|
QList<TextLineData> rightData = assemblyRows(rightLines,
|
||||||
|
rightSpans);
|
||||||
|
|
||||||
|
// fill ending separators
|
||||||
|
for (int i = leftData.count(); i < rightData.count(); i++)
|
||||||
|
leftData.append(TextLineData(TextLineData::Separator));
|
||||||
|
for (int i = rightData.count(); i < leftData.count(); i++)
|
||||||
|
rightData.append(TextLineData(TextLineData::Separator));
|
||||||
|
|
||||||
|
const int visualLineCount = leftData.count();
|
||||||
|
int leftLine = -1;
|
||||||
|
int rightLine = -1;
|
||||||
|
for (int i = 0; i < visualLineCount; i++) {
|
||||||
|
const TextLineData &leftTextLine = leftData.at(i);
|
||||||
|
const TextLineData &rightTextLine = rightData.at(i);
|
||||||
|
RowData row(leftTextLine, rightTextLine);
|
||||||
|
|
||||||
|
if (leftTextLine.textLineType == TextLineData::TextLine)
|
||||||
|
++leftLine;
|
||||||
|
if (rightTextLine.textLineType == TextLineData::TextLine)
|
||||||
|
++rightLine;
|
||||||
|
if (equalLines.value(leftLine, -1) == rightLine)
|
||||||
|
row.equal = true;
|
||||||
|
|
||||||
|
chunkData.rows.append(row);
|
||||||
|
}
|
||||||
|
return chunkData;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileData calculateContextData(const ChunkData &originalData, int contextLinesNumber)
|
||||||
|
{
|
||||||
|
if (contextLinesNumber < 0)
|
||||||
|
return FileData(originalData);
|
||||||
|
|
||||||
|
const int joinChunkThreshold = 1;
|
||||||
|
|
||||||
|
FileData fileData;
|
||||||
|
QMap<int, bool> hiddenRows;
|
||||||
|
int i = 0;
|
||||||
|
while (i < originalData.rows.count()) {
|
||||||
|
const RowData &row = originalData.rows[i];
|
||||||
|
if (row.equal) {
|
||||||
|
// count how many equal
|
||||||
|
int equalRowStart = i;
|
||||||
|
i++;
|
||||||
|
while (i < originalData.rows.count()) {
|
||||||
|
const RowData originalRow = originalData.rows.at(i);
|
||||||
|
if (!originalRow.equal)
|
||||||
|
break;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
const bool first = equalRowStart == 0; // includes first line?
|
||||||
|
const bool last = i == originalData.rows.count(); // includes last line?
|
||||||
|
|
||||||
|
const int firstLine = first ? 0 : equalRowStart + contextLinesNumber;
|
||||||
|
const int lastLine = last ? originalData.rows.count() : i - contextLinesNumber;
|
||||||
|
|
||||||
|
if (firstLine < lastLine - joinChunkThreshold) {
|
||||||
|
for (int j = firstLine; j < lastLine; j++) {
|
||||||
|
hiddenRows.insert(j, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// iterate to the next row
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
int leftCharCounter = 0;
|
||||||
|
int rightCharCounter = 0;
|
||||||
|
QMap<int, int>::ConstIterator leftChangedIt = originalData.changedLeftPositions.constBegin();
|
||||||
|
QMap<int, int>::ConstIterator rightChangedIt = originalData.changedRightPositions.constBegin();
|
||||||
|
const QMap<int, int>::ConstIterator leftChangedItEnd = originalData.changedLeftPositions.constEnd();
|
||||||
|
const QMap<int, int>::ConstIterator rightChangedItEnd = originalData.changedRightPositions.constEnd();
|
||||||
|
while (i < originalData.rows.count()) {
|
||||||
|
if (!hiddenRows.contains(i)) {
|
||||||
|
ChunkData chunkData;
|
||||||
|
int leftOffset = leftCharCounter;
|
||||||
|
int rightOffset = rightCharCounter;
|
||||||
|
chunkData.contextChunk = false;
|
||||||
|
while (i < originalData.rows.count()) {
|
||||||
|
if (hiddenRows.contains(i))
|
||||||
|
break;
|
||||||
|
RowData rowData = originalData.rows.at(i);
|
||||||
|
chunkData.rows.append(rowData);
|
||||||
|
|
||||||
|
if (rowData.leftLine.textLineType == TextLineData::TextLine)
|
||||||
|
leftCharCounter += rowData.leftLine.text.count() + 1; // +1 for '\n'
|
||||||
|
if (rowData.rightLine.textLineType == TextLineData::TextLine)
|
||||||
|
rightCharCounter += rowData.rightLine.text.count() + 1; // +1 for '\n'
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
while (leftChangedIt != leftChangedItEnd) {
|
||||||
|
if (leftChangedIt.key() < leftOffset
|
||||||
|
|| leftChangedIt.key() > leftCharCounter)
|
||||||
|
break;
|
||||||
|
|
||||||
|
const int startPos = leftChangedIt.key();
|
||||||
|
const int endPos = leftChangedIt.value();
|
||||||
|
chunkData.changedLeftPositions.insert(startPos - leftOffset, endPos - leftOffset);
|
||||||
|
leftChangedIt++;
|
||||||
|
}
|
||||||
|
while (rightChangedIt != rightChangedItEnd) {
|
||||||
|
if (rightChangedIt.key() < rightOffset
|
||||||
|
|| rightChangedIt.key() > rightCharCounter)
|
||||||
|
break;
|
||||||
|
|
||||||
|
const int startPos = rightChangedIt.key();
|
||||||
|
const int endPos = rightChangedIt.value();
|
||||||
|
chunkData.changedRightPositions.insert(startPos - rightOffset, endPos - rightOffset);
|
||||||
|
rightChangedIt++;
|
||||||
|
}
|
||||||
|
fileData.chunks.append(chunkData);
|
||||||
|
} else {
|
||||||
|
ChunkData chunkData;
|
||||||
|
chunkData.contextChunk = true;
|
||||||
|
while (i < originalData.rows.count()) {
|
||||||
|
if (!hiddenRows.contains(i))
|
||||||
|
break;
|
||||||
|
RowData rowData = originalData.rows.at(i);
|
||||||
|
chunkData.rows.append(rowData);
|
||||||
|
|
||||||
|
if (rowData.leftLine.textLineType == TextLineData::TextLine)
|
||||||
|
leftCharCounter += rowData.leftLine.text.count() + 1; // +1 for '\n'
|
||||||
|
if (rowData.rightLine.textLineType == TextLineData::TextLine)
|
||||||
|
rightCharCounter += rowData.rightLine.text.count() + 1; // +1 for '\n'
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
fileData.chunks.append(chunkData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fileData;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace DiffEditor
|
||||||
96
src/plugins/diffeditor/diffutils.h
Normal file
96
src/plugins/diffeditor/diffutils.h
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef DIFFUTILS_H
|
||||||
|
#define DIFFUTILS_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QMap>
|
||||||
|
#include "diffeditorcontroller.h"
|
||||||
|
|
||||||
|
namespace DiffEditor {
|
||||||
|
|
||||||
|
class Diff;
|
||||||
|
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class TextLineData {
|
||||||
|
public:
|
||||||
|
enum TextLineType {
|
||||||
|
TextLine,
|
||||||
|
Separator,
|
||||||
|
Invalid
|
||||||
|
};
|
||||||
|
TextLineData() : textLineType(Invalid) {}
|
||||||
|
TextLineData(const QString &txt) : textLineType(TextLine), text(txt) {}
|
||||||
|
TextLineData(TextLineType t) : textLineType(t) {}
|
||||||
|
TextLineType textLineType;
|
||||||
|
QString text;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RowData {
|
||||||
|
public:
|
||||||
|
RowData() : equal(false) {}
|
||||||
|
RowData(const TextLineData &l)
|
||||||
|
: leftLine(l), rightLine(l), equal(true) {}
|
||||||
|
RowData(const TextLineData &l, const TextLineData &r)
|
||||||
|
: leftLine(l), rightLine(r), equal(false) {}
|
||||||
|
TextLineData leftLine;
|
||||||
|
TextLineData rightLine;
|
||||||
|
bool equal;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ChunkData {
|
||||||
|
public:
|
||||||
|
ChunkData() : contextChunk(false) {}
|
||||||
|
QList<RowData> rows;
|
||||||
|
bool contextChunk;
|
||||||
|
// start position, end position, TextLineData::Separator lines not taken into account
|
||||||
|
QMap<int, int> changedLeftPositions; // counting from the beginning of the chunk
|
||||||
|
QMap<int, int> changedRightPositions; // counting from the beginning of the chunk
|
||||||
|
};
|
||||||
|
|
||||||
|
class FileData {
|
||||||
|
public:
|
||||||
|
FileData() {}
|
||||||
|
FileData(const ChunkData &chunkData) { chunks.append(chunkData); }
|
||||||
|
QList<ChunkData> chunks;
|
||||||
|
DiffEditorController::DiffFileInfo leftFileInfo;
|
||||||
|
DiffEditorController::DiffFileInfo rightFileInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
ChunkData calculateOriginalData(const QList<Diff> &leftDiffList,
|
||||||
|
const QList<Diff> &rightDiffList);
|
||||||
|
FileData calculateContextData(const ChunkData &originalData,
|
||||||
|
int contextLinesNumber);
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace DiffEditor
|
||||||
|
|
||||||
|
#endif // DIFFUTILS_H
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include "sidebysidediffeditorwidget.h"
|
#include "sidebysidediffeditorwidget.h"
|
||||||
#include "diffeditorguicontroller.h"
|
#include "diffeditorguicontroller.h"
|
||||||
|
#include "diffutils.h"
|
||||||
|
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
@@ -66,260 +67,7 @@ using namespace TextEditor;
|
|||||||
|
|
||||||
namespace DiffEditor {
|
namespace DiffEditor {
|
||||||
|
|
||||||
class TextLineData {
|
using namespace Internal;
|
||||||
public:
|
|
||||||
enum TextLineType {
|
|
||||||
TextLine,
|
|
||||||
Separator,
|
|
||||||
Invalid
|
|
||||||
};
|
|
||||||
TextLineData() : textLineType(Invalid) {}
|
|
||||||
TextLineData(const QString &txt) : textLineType(TextLine), text(txt) {}
|
|
||||||
TextLineData(TextLineType t) : textLineType(t) {}
|
|
||||||
TextLineType textLineType;
|
|
||||||
QString text;
|
|
||||||
};
|
|
||||||
|
|
||||||
class RowData {
|
|
||||||
public:
|
|
||||||
RowData() : equal(false) {}
|
|
||||||
RowData(const TextLineData &l)
|
|
||||||
: leftLine(l), rightLine(l), equal(true) {}
|
|
||||||
RowData(const TextLineData &l, const TextLineData &r)
|
|
||||||
: leftLine(l), rightLine(r), equal(false) {}
|
|
||||||
TextLineData leftLine;
|
|
||||||
TextLineData rightLine;
|
|
||||||
bool equal;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ChunkData {
|
|
||||||
public:
|
|
||||||
ChunkData() : contextChunk(false) {}
|
|
||||||
QList<RowData> rows;
|
|
||||||
bool contextChunk;
|
|
||||||
// start position, end position, TextLineData::Separator lines not taken into account
|
|
||||||
QMap<int, int> changedLeftPositions; // counting from the beginning of the chunk
|
|
||||||
QMap<int, int> changedRightPositions; // counting from the beginning of the chunk
|
|
||||||
};
|
|
||||||
|
|
||||||
class FileData {
|
|
||||||
public:
|
|
||||||
FileData() {}
|
|
||||||
FileData(const ChunkData &chunkData) { chunks.append(chunkData); }
|
|
||||||
QList<ChunkData> chunks;
|
|
||||||
DiffEditorController::DiffFileInfo leftFileInfo;
|
|
||||||
DiffEditorController::DiffFileInfo rightFileInfo;
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////
|
|
||||||
|
|
||||||
static QList<TextLineData> assemblyRows(const QStringList &lines,
|
|
||||||
const QMap<int, int> &lineSpans)
|
|
||||||
{
|
|
||||||
QList<TextLineData> data;
|
|
||||||
|
|
||||||
const int lineCount = lines.count();
|
|
||||||
for (int i = 0; i <= lineCount; i++) {
|
|
||||||
for (int j = 0; j < lineSpans.value(i); j++)
|
|
||||||
data.append(TextLineData(TextLineData::Separator));
|
|
||||||
if (i < lineCount)
|
|
||||||
data.append(lines.at(i));
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handleLine(const QStringList &newLines,
|
|
||||||
int line,
|
|
||||||
QStringList *lines,
|
|
||||||
int *lineNumber,
|
|
||||||
int *charNumber)
|
|
||||||
{
|
|
||||||
if (line < newLines.count()) {
|
|
||||||
const QString text = newLines.at(line);
|
|
||||||
if (lines->isEmpty() || line > 0) {
|
|
||||||
if (line > 0)
|
|
||||||
++*lineNumber;
|
|
||||||
lines->append(text);
|
|
||||||
} else {
|
|
||||||
lines->last() += text;
|
|
||||||
}
|
|
||||||
*charNumber += text.count();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handleDifference(const QString &text,
|
|
||||||
QStringList *lines,
|
|
||||||
QMap<int, int> *changedPositions,
|
|
||||||
int *lineNumber,
|
|
||||||
int *charNumber)
|
|
||||||
{
|
|
||||||
const int oldPosition = *lineNumber + *charNumber;
|
|
||||||
const QStringList newLeftLines = text.split(QLatin1Char('\n'));
|
|
||||||
for (int line = 0; line < newLeftLines.count(); ++line)
|
|
||||||
handleLine(newLeftLines, line, lines, lineNumber, charNumber);
|
|
||||||
const int newPosition = *lineNumber + *charNumber;
|
|
||||||
changedPositions->insert(oldPosition, newPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool lastLinesEqual(const QStringList &leftLines,
|
|
||||||
const QStringList &rightLines)
|
|
||||||
{
|
|
||||||
const bool leftLineEqual = leftLines.count()
|
|
||||||
? leftLines.last().isEmpty()
|
|
||||||
: true;
|
|
||||||
const bool rightLineEqual = rightLines.count()
|
|
||||||
? rightLines.last().isEmpty()
|
|
||||||
: true;
|
|
||||||
return leftLineEqual && rightLineEqual;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* leftDiffList can contain only deletions and equalities,
|
|
||||||
* while rightDiffList can contain only insertions and equalities.
|
|
||||||
* The number of equalities on both lists must be the same.
|
|
||||||
*/
|
|
||||||
static ChunkData calculateOriginalData(const QList<Diff> &leftDiffList,
|
|
||||||
const QList<Diff> &rightDiffList)
|
|
||||||
{
|
|
||||||
ChunkData chunkData;
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
int j = 0;
|
|
||||||
|
|
||||||
QStringList leftLines;
|
|
||||||
QStringList rightLines;
|
|
||||||
|
|
||||||
// <line number, span count>
|
|
||||||
QMap<int, int> leftSpans;
|
|
||||||
QMap<int, int> rightSpans;
|
|
||||||
// <left line number, right line number>
|
|
||||||
QMap<int, int> equalLines;
|
|
||||||
|
|
||||||
int leftLineNumber = 0;
|
|
||||||
int rightLineNumber = 0;
|
|
||||||
int leftCharNumber = 0;
|
|
||||||
int rightCharNumber = 0;
|
|
||||||
int leftLineAligned = -1;
|
|
||||||
int rightLineAligned = -1;
|
|
||||||
bool lastLineEqual = true;
|
|
||||||
|
|
||||||
while (i <= leftDiffList.count() && j <= rightDiffList.count()) {
|
|
||||||
const Diff leftDiff = i < leftDiffList.count()
|
|
||||||
? leftDiffList.at(i)
|
|
||||||
: Diff(Diff::Equal);
|
|
||||||
const Diff rightDiff = j < rightDiffList.count()
|
|
||||||
? rightDiffList.at(j)
|
|
||||||
: Diff(Diff::Equal);
|
|
||||||
|
|
||||||
if (leftDiff.command == Diff::Delete) {
|
|
||||||
// process delete
|
|
||||||
handleDifference(leftDiff.text, &leftLines, &chunkData.changedLeftPositions, &leftLineNumber, &leftCharNumber);
|
|
||||||
lastLineEqual = lastLinesEqual(leftLines, rightLines);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
if (rightDiff.command == Diff::Insert) {
|
|
||||||
// process insert
|
|
||||||
handleDifference(rightDiff.text, &rightLines, &chunkData.changedRightPositions, &rightLineNumber, &rightCharNumber);
|
|
||||||
lastLineEqual = lastLinesEqual(leftLines, rightLines);
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
if (leftDiff.command == Diff::Equal && rightDiff.command == Diff::Equal) {
|
|
||||||
// process equal
|
|
||||||
const QStringList newLeftLines = leftDiff.text.split(QLatin1Char('\n'));
|
|
||||||
const QStringList newRightLines = rightDiff.text.split(QLatin1Char('\n'));
|
|
||||||
|
|
||||||
int line = 0;
|
|
||||||
|
|
||||||
while (line < qMax(newLeftLines.count(), newRightLines.count())) {
|
|
||||||
handleLine(newLeftLines, line, &leftLines, &leftLineNumber, &leftCharNumber);
|
|
||||||
handleLine(newRightLines, line, &rightLines, &rightLineNumber, &rightCharNumber);
|
|
||||||
|
|
||||||
const int commonLineCount = qMin(newLeftLines.count(), newRightLines.count());
|
|
||||||
if (line < commonLineCount) {
|
|
||||||
// try to align
|
|
||||||
const int leftDifference = leftLineNumber - leftLineAligned;
|
|
||||||
const int rightDifference = rightLineNumber - rightLineAligned;
|
|
||||||
|
|
||||||
if (leftDifference && rightDifference) {
|
|
||||||
bool doAlign = true;
|
|
||||||
if (line == 0 // omit alignment when first lines of equalities are empty
|
|
||||||
&& (newLeftLines.at(0).isEmpty() || newRightLines.at(0).isEmpty())) {
|
|
||||||
doAlign = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line == commonLineCount - 1) {
|
|
||||||
// omit alignment when last lines of equalities are empty
|
|
||||||
if (leftLines.last().isEmpty() || rightLines.last().isEmpty())
|
|
||||||
doAlign = false;
|
|
||||||
|
|
||||||
// unless it's the last dummy line (don't omit in that case)
|
|
||||||
if (i == leftDiffList.count() && j == rightDiffList.count())
|
|
||||||
doAlign = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (doAlign) {
|
|
||||||
// align here
|
|
||||||
leftLineAligned = leftLineNumber;
|
|
||||||
rightLineAligned = rightLineNumber;
|
|
||||||
|
|
||||||
// insert separators if needed
|
|
||||||
if (rightDifference > leftDifference)
|
|
||||||
leftSpans.insert(leftLineNumber, rightDifference - leftDifference);
|
|
||||||
else if (leftDifference > rightDifference)
|
|
||||||
rightSpans.insert(rightLineNumber, leftDifference - rightDifference);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if lines are equal
|
|
||||||
if ((line < commonLineCount - 1) // before the last common line in equality
|
|
||||||
|| (line == commonLineCount - 1 // or the last common line in equality
|
|
||||||
&& i == leftDiffList.count() // and it's the last iteration
|
|
||||||
&& j == rightDiffList.count())) {
|
|
||||||
if (line > 0 || lastLineEqual)
|
|
||||||
equalLines.insert(leftLineNumber, rightLineNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line > 0)
|
|
||||||
lastLineEqual = true;
|
|
||||||
|
|
||||||
line++;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<TextLineData> leftData = assemblyRows(leftLines,
|
|
||||||
leftSpans);
|
|
||||||
QList<TextLineData> rightData = assemblyRows(rightLines,
|
|
||||||
rightSpans);
|
|
||||||
|
|
||||||
// fill ending separators
|
|
||||||
for (int i = leftData.count(); i < rightData.count(); i++)
|
|
||||||
leftData.append(TextLineData(TextLineData::Separator));
|
|
||||||
for (int i = rightData.count(); i < leftData.count(); i++)
|
|
||||||
rightData.append(TextLineData(TextLineData::Separator));
|
|
||||||
|
|
||||||
const int visualLineCount = leftData.count();
|
|
||||||
int leftLine = -1;
|
|
||||||
int rightLine = -1;
|
|
||||||
for (int i = 0; i < visualLineCount; i++) {
|
|
||||||
const TextLineData &leftTextLine = leftData.at(i);
|
|
||||||
const TextLineData &rightTextLine = rightData.at(i);
|
|
||||||
RowData row(leftTextLine, rightTextLine);
|
|
||||||
|
|
||||||
if (leftTextLine.textLineType == TextLineData::TextLine)
|
|
||||||
++leftLine;
|
|
||||||
if (rightTextLine.textLineType == TextLineData::TextLine)
|
|
||||||
++rightLine;
|
|
||||||
if (equalLines.value(leftLine, -1) == rightLine)
|
|
||||||
row.equal = true;
|
|
||||||
|
|
||||||
chunkData.rows.append(row);
|
|
||||||
}
|
|
||||||
return chunkData;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////
|
//////////////////////
|
||||||
|
|
||||||
@@ -1076,6 +824,7 @@ void SideBySideDiffEditorWidget::setDiff(const QList<DiffList> &diffList)
|
|||||||
m_diffList = diffList;
|
m_diffList = diffList;
|
||||||
m_originalChunkData.clear();
|
m_originalChunkData.clear();
|
||||||
m_contextFileData.clear();
|
m_contextFileData.clear();
|
||||||
|
const int contextLinesNumber = m_guiController ? m_guiController->contextLinesNumber() : 3;
|
||||||
|
|
||||||
for (int i = 0; i < m_diffList.count(); i++) {
|
for (int i = 0; i < m_diffList.count(); i++) {
|
||||||
const DiffList &dl = m_diffList.at(i);
|
const DiffList &dl = m_diffList.at(i);
|
||||||
@@ -1084,7 +833,7 @@ void SideBySideDiffEditorWidget::setDiff(const QList<DiffList> &diffList)
|
|||||||
handleWhitespaces(dl.diffList, &leftDiffs, &rightDiffs);
|
handleWhitespaces(dl.diffList, &leftDiffs, &rightDiffs);
|
||||||
ChunkData chunkData = calculateOriginalData(leftDiffs, rightDiffs);
|
ChunkData chunkData = calculateOriginalData(leftDiffs, rightDiffs);
|
||||||
m_originalChunkData.append(chunkData);
|
m_originalChunkData.append(chunkData);
|
||||||
FileData fileData = calculateContextData(chunkData);
|
FileData fileData = calculateContextData(chunkData, contextLinesNumber);
|
||||||
fileData.leftFileInfo = dl.leftFileInfo;
|
fileData.leftFileInfo = dl.leftFileInfo;
|
||||||
fileData.rightFileInfo = dl.rightFileInfo;
|
fileData.rightFileInfo = dl.rightFileInfo;
|
||||||
m_contextFileData.append(fileData);
|
m_contextFileData.append(fileData);
|
||||||
@@ -1110,10 +859,11 @@ void SideBySideDiffEditorWidget::handleWhitespaces(const QList<Diff> &input,
|
|||||||
void SideBySideDiffEditorWidget::setContextLinesNumber(int lines)
|
void SideBySideDiffEditorWidget::setContextLinesNumber(int lines)
|
||||||
{
|
{
|
||||||
Q_UNUSED(lines)
|
Q_UNUSED(lines)
|
||||||
|
const int contextLinesNumber = m_guiController ? m_guiController->contextLinesNumber() : 3;
|
||||||
|
|
||||||
for (int i = 0; i < m_contextFileData.count(); i++) {
|
for (int i = 0; i < m_contextFileData.count(); i++) {
|
||||||
const FileData oldFileData = m_contextFileData.at(i);
|
const FileData oldFileData = m_contextFileData.at(i);
|
||||||
FileData newFileData = calculateContextData(m_originalChunkData.at(i));
|
FileData newFileData = calculateContextData(m_originalChunkData.at(i), contextLinesNumber);
|
||||||
newFileData.leftFileInfo = oldFileData.leftFileInfo;
|
newFileData.leftFileInfo = oldFileData.leftFileInfo;
|
||||||
newFileData.rightFileInfo = oldFileData.rightFileInfo;
|
newFileData.rightFileInfo = oldFileData.rightFileInfo;
|
||||||
m_contextFileData[i] = newFileData;
|
m_contextFileData[i] = newFileData;
|
||||||
@@ -1147,112 +897,6 @@ void SideBySideDiffEditorWidget::setCurrentDiffFileIndex(int diffFileIndex)
|
|||||||
m_rightEditor->centerCursor();
|
m_rightEditor->centerCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
FileData SideBySideDiffEditorWidget::calculateContextData(const ChunkData &originalData) const
|
|
||||||
{
|
|
||||||
const int contextLinesNumber = m_guiController ? m_guiController->contextLinesNumber() : 3;
|
|
||||||
if (contextLinesNumber < 0)
|
|
||||||
return FileData(originalData);
|
|
||||||
|
|
||||||
const int joinChunkThreshold = 1;
|
|
||||||
|
|
||||||
FileData fileData;
|
|
||||||
QMap<int, bool> hiddenRows;
|
|
||||||
int i = 0;
|
|
||||||
while (i < originalData.rows.count()) {
|
|
||||||
const RowData &row = originalData.rows[i];
|
|
||||||
if (row.equal) {
|
|
||||||
// count how many equal
|
|
||||||
int equalRowStart = i;
|
|
||||||
i++;
|
|
||||||
while (i < originalData.rows.count()) {
|
|
||||||
const RowData originalRow = originalData.rows.at(i);
|
|
||||||
if (!originalRow.equal)
|
|
||||||
break;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
const bool first = equalRowStart == 0; // includes first line?
|
|
||||||
const bool last = i == originalData.rows.count(); // includes last line?
|
|
||||||
|
|
||||||
const int firstLine = first ? 0 : equalRowStart + contextLinesNumber;
|
|
||||||
const int lastLine = last ? originalData.rows.count() : i - contextLinesNumber;
|
|
||||||
|
|
||||||
if (firstLine < lastLine - joinChunkThreshold) {
|
|
||||||
for (int j = firstLine; j < lastLine; j++) {
|
|
||||||
hiddenRows.insert(j, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// iterate to the next row
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i = 0;
|
|
||||||
int leftCharCounter = 0;
|
|
||||||
int rightCharCounter = 0;
|
|
||||||
QMap<int, int>::ConstIterator leftChangedIt = originalData.changedLeftPositions.constBegin();
|
|
||||||
QMap<int, int>::ConstIterator rightChangedIt = originalData.changedRightPositions.constBegin();
|
|
||||||
const QMap<int, int>::ConstIterator leftChangedItEnd = originalData.changedLeftPositions.constEnd();
|
|
||||||
const QMap<int, int>::ConstIterator rightChangedItEnd = originalData.changedRightPositions.constEnd();
|
|
||||||
while (i < originalData.rows.count()) {
|
|
||||||
if (!hiddenRows.contains(i)) {
|
|
||||||
ChunkData chunkData;
|
|
||||||
int leftOffset = leftCharCounter;
|
|
||||||
int rightOffset = rightCharCounter;
|
|
||||||
chunkData.contextChunk = false;
|
|
||||||
while (i < originalData.rows.count()) {
|
|
||||||
if (hiddenRows.contains(i))
|
|
||||||
break;
|
|
||||||
RowData rowData = originalData.rows.at(i);
|
|
||||||
chunkData.rows.append(rowData);
|
|
||||||
|
|
||||||
if (rowData.leftLine.textLineType == TextLineData::TextLine)
|
|
||||||
leftCharCounter += rowData.leftLine.text.count() + 1; // +1 for '\n'
|
|
||||||
if (rowData.rightLine.textLineType == TextLineData::TextLine)
|
|
||||||
rightCharCounter += rowData.rightLine.text.count() + 1; // +1 for '\n'
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
while (leftChangedIt != leftChangedItEnd) {
|
|
||||||
if (leftChangedIt.key() < leftOffset
|
|
||||||
|| leftChangedIt.key() > leftCharCounter)
|
|
||||||
break;
|
|
||||||
|
|
||||||
const int startPos = leftChangedIt.key();
|
|
||||||
const int endPos = leftChangedIt.value();
|
|
||||||
chunkData.changedLeftPositions.insert(startPos - leftOffset, endPos - leftOffset);
|
|
||||||
leftChangedIt++;
|
|
||||||
}
|
|
||||||
while (rightChangedIt != rightChangedItEnd) {
|
|
||||||
if (rightChangedIt.key() < rightOffset
|
|
||||||
|| rightChangedIt.key() > rightCharCounter)
|
|
||||||
break;
|
|
||||||
|
|
||||||
const int startPos = rightChangedIt.key();
|
|
||||||
const int endPos = rightChangedIt.value();
|
|
||||||
chunkData.changedRightPositions.insert(startPos - rightOffset, endPos - rightOffset);
|
|
||||||
rightChangedIt++;
|
|
||||||
}
|
|
||||||
fileData.chunks.append(chunkData);
|
|
||||||
} else {
|
|
||||||
ChunkData chunkData;
|
|
||||||
chunkData.contextChunk = true;
|
|
||||||
while (i < originalData.rows.count()) {
|
|
||||||
if (!hiddenRows.contains(i))
|
|
||||||
break;
|
|
||||||
RowData rowData = originalData.rows.at(i);
|
|
||||||
chunkData.rows.append(rowData);
|
|
||||||
|
|
||||||
if (rowData.leftLine.textLineType == TextLineData::TextLine)
|
|
||||||
leftCharCounter += rowData.leftLine.text.count() + 1; // +1 for '\n'
|
|
||||||
if (rowData.rightLine.textLineType == TextLineData::TextLine)
|
|
||||||
rightCharCounter += rowData.rightLine.text.count() + 1; // +1 for '\n'
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
fileData.chunks.append(chunkData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fileData;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SideBySideDiffEditorWidget::showDiff()
|
void SideBySideDiffEditorWidget::showDiff()
|
||||||
{
|
{
|
||||||
// TODO: remember the line number of the line in the middle
|
// TODO: remember the line number of the line in the middle
|
||||||
|
|||||||
@@ -46,11 +46,13 @@ QT_END_NAMESPACE
|
|||||||
|
|
||||||
|
|
||||||
namespace DiffEditor {
|
namespace DiffEditor {
|
||||||
|
|
||||||
class DiffEditorGuiController;
|
class DiffEditorGuiController;
|
||||||
class SideDiffEditorWidget;
|
class SideDiffEditorWidget;
|
||||||
|
|
||||||
|
namespace Internal {
|
||||||
class ChunkData;
|
class ChunkData;
|
||||||
class FileData;
|
class FileData;
|
||||||
|
}
|
||||||
|
|
||||||
class DIFFEDITOR_EXPORT SideBySideDiffEditorWidget : public QWidget
|
class DIFFEDITOR_EXPORT SideBySideDiffEditorWidget : public QWidget
|
||||||
{
|
{
|
||||||
@@ -101,8 +103,7 @@ private:
|
|||||||
QList<QTextEdit::ExtraSelection> colorPositions(const QTextCharFormat &format,
|
QList<QTextEdit::ExtraSelection> colorPositions(const QTextCharFormat &format,
|
||||||
QTextCursor &cursor,
|
QTextCursor &cursor,
|
||||||
const QMap<int, int> &positions) const;
|
const QMap<int, int> &positions) const;
|
||||||
void colorDiff(const QList<FileData> &fileDataList);
|
void colorDiff(const QList<Internal::FileData> &fileDataList);
|
||||||
FileData calculateContextData(const ChunkData &originalData) const;
|
|
||||||
void showDiff();
|
void showDiff();
|
||||||
void synchronizeFoldings(SideDiffEditorWidget *source, SideDiffEditorWidget *destination);
|
void synchronizeFoldings(SideDiffEditorWidget *source, SideDiffEditorWidget *destination);
|
||||||
void jumpToOriginalFile(const QString &fileName, int lineNumber, int columnNumber);
|
void jumpToOriginalFile(const QString &fileName, int lineNumber, int columnNumber);
|
||||||
@@ -114,8 +115,8 @@ private:
|
|||||||
QSplitter *m_splitter;
|
QSplitter *m_splitter;
|
||||||
|
|
||||||
QList<DiffList> m_diffList; // list of original outputs from differ
|
QList<DiffList> m_diffList; // list of original outputs from differ
|
||||||
QList<ChunkData> m_originalChunkData; // one big chunk for every file, ignoreWhitespace taken into account
|
QList<Internal::ChunkData> m_originalChunkData; // one big chunk for every file, ignoreWhitespace taken into account
|
||||||
QList<FileData> m_contextFileData; // ultimate data to be shown, contextLinesNumber taken into account
|
QList<Internal::FileData> m_contextFileData; // ultimate data to be shown, contextLinesNumber taken into account
|
||||||
|
|
||||||
bool m_foldingBlocker;
|
bool m_foldingBlocker;
|
||||||
QString m_source;
|
QString m_source;
|
||||||
|
|||||||
@@ -2876,8 +2876,8 @@ QString GitClient::extendedShowDescription(const QString &workingDirectory, cons
|
|||||||
// If there are more than 20 branches, list first 10 followed by a hint
|
// If there are more than 20 branches, list first 10 followed by a hint
|
||||||
if (branchCount > 20) {
|
if (branchCount > 20) {
|
||||||
const int leave = 10;
|
const int leave = 10;
|
||||||
//: Displayed after the untranslated message "Branches: branch1, branch2 'and %n more'" in git show.
|
//: Displayed after the untranslated message "Branches: branch1, branch2 'and %1 more'" in git show.
|
||||||
moreBranches = QLatin1Char(' ') + tr("and %n more", 0, branchCount - leave);
|
moreBranches = QLatin1Char(' ') + tr("and %1 more", 0, branchCount - leave);
|
||||||
branches.erase(branches.begin() + leave, branches.end());
|
branches.erase(branches.begin() + leave, branches.end());
|
||||||
}
|
}
|
||||||
if (!branches.isEmpty()) {
|
if (!branches.isEmpty()) {
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
#include <coreplugin/mimedatabase.h>
|
#include <coreplugin/mimedatabase.h>
|
||||||
#include <cpptools/cppmodelmanagerinterface.h>
|
#include <cpptools/cppmodelmanagerinterface.h>
|
||||||
#include <projectexplorer/buildenvironmentwidget.h>
|
#include <projectexplorer/buildenvironmentwidget.h>
|
||||||
|
#include <projectexplorer/buildmanager.h>
|
||||||
#include <projectexplorer/buildtargetinfo.h>
|
#include <projectexplorer/buildtargetinfo.h>
|
||||||
#include <projectexplorer/deploymentdata.h>
|
#include <projectexplorer/deploymentdata.h>
|
||||||
#include <projectexplorer/kit.h>
|
#include <projectexplorer/kit.h>
|
||||||
@@ -382,6 +383,12 @@ void QbsProject::parseCurrentBuildConfiguration(bool force)
|
|||||||
if (!m_forceParsing)
|
if (!m_forceParsing)
|
||||||
m_forceParsing = force;
|
m_forceParsing = force;
|
||||||
|
|
||||||
|
// Qbs does update the build graph during the build. So we cannot
|
||||||
|
// start to parse while a build is running or we will lose information.
|
||||||
|
// Just return since the qbsbuildstep will trigger a reparse after the build.
|
||||||
|
if (ProjectExplorer::BuildManager::isBuilding(this))
|
||||||
|
return;
|
||||||
|
|
||||||
if (!activeTarget())
|
if (!activeTarget())
|
||||||
return;
|
return;
|
||||||
QbsBuildConfiguration *bc = qobject_cast<QbsBuildConfiguration *>(activeTarget()->activeBuildConfiguration());
|
QbsBuildConfiguration *bc = qobject_cast<QbsBuildConfiguration *>(activeTarget()->activeBuildConfiguration());
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ BarDescriptorEditorEntryPointWidget::BarDescriptorEditorEntryPointWidget(QWidget
|
|||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
m_ui->iconFilePath->setExpectedKind(Utils::PathChooser::File);
|
m_ui->iconFilePath->setExpectedKind(Utils::PathChooser::File);
|
||||||
|
m_ui->iconFilePath->setHistoryCompleter(QLatin1String("Qmake.Icon.History"));
|
||||||
m_ui->iconFilePath->setPromptDialogFilter(tr("Images (*.jpg *.png)"));
|
m_ui->iconFilePath->setPromptDialogFilter(tr("Images (*.jpg *.png)"));
|
||||||
|
|
||||||
m_ui->iconWarningLabel->setVisible(false);
|
m_ui->iconWarningLabel->setVisible(false);
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ BlackBerryDebugTokenRequestDialog::BlackBerryDebugTokenRequestDialog(
|
|||||||
m_ui->progressBar->hide();
|
m_ui->progressBar->hide();
|
||||||
m_ui->status->clear();
|
m_ui->status->clear();
|
||||||
m_ui->debugTokenPath->setExpectedKind(Utils::PathChooser::SaveFile);
|
m_ui->debugTokenPath->setExpectedKind(Utils::PathChooser::SaveFile);
|
||||||
|
m_ui->debugTokenPath->setHistoryCompleter(QLatin1String("BB.DebugToken.History"));
|
||||||
m_ui->debugTokenPath->setPromptDialogTitle(tr("Request Debug Token"));
|
m_ui->debugTokenPath->setPromptDialogTitle(tr("Request Debug Token"));
|
||||||
m_ui->debugTokenPath->setPromptDialogFilter(tr("BAR Files (*.bar)"));
|
m_ui->debugTokenPath->setPromptDialogFilter(tr("BAR Files (*.bar)"));
|
||||||
|
|
||||||
|
|||||||
@@ -56,10 +56,12 @@ BlackBerryDeployConfigurationWidget::BlackBerryDeployConfigurationWidget(BlackBe
|
|||||||
|
|
||||||
PathChooserDelegate *appDescriptorPathDelegate = new PathChooserDelegate(this);
|
PathChooserDelegate *appDescriptorPathDelegate = new PathChooserDelegate(this);
|
||||||
appDescriptorPathDelegate->setExpectedKind(Utils::PathChooser::File);
|
appDescriptorPathDelegate->setExpectedKind(Utils::PathChooser::File);
|
||||||
|
appDescriptorPathDelegate->setHistoryCompleter(QLatin1String("BB.BarXml.History"));
|
||||||
appDescriptorPathDelegate->setPromptDialogFilter(QLatin1String("*.xml"));
|
appDescriptorPathDelegate->setPromptDialogFilter(QLatin1String("*.xml"));
|
||||||
|
|
||||||
PathChooserDelegate *barPathDelegate = new PathChooserDelegate(this);
|
PathChooserDelegate *barPathDelegate = new PathChooserDelegate(this);
|
||||||
barPathDelegate->setExpectedKind(Utils::PathChooser::File);
|
barPathDelegate->setExpectedKind(Utils::PathChooser::File);
|
||||||
|
barPathDelegate->setHistoryCompleter(QLatin1String("BB.AppBar.History"));
|
||||||
barPathDelegate->setPromptDialogFilter(QLatin1String("*.bar"));
|
barPathDelegate->setPromptDialogFilter(QLatin1String("*.bar"));
|
||||||
|
|
||||||
m_ui->deployPackagesView->setItemDelegateForColumn(1, appDescriptorPathDelegate);
|
m_ui->deployPackagesView->setItemDelegateForColumn(1, appDescriptorPathDelegate);
|
||||||
|
|||||||
@@ -263,6 +263,7 @@ void BlackBerryDeviceConfigurationWidget::updateDeviceFromUi()
|
|||||||
void BlackBerryDeviceConfigurationWidget::initGui()
|
void BlackBerryDeviceConfigurationWidget::initGui()
|
||||||
{
|
{
|
||||||
ui->keyFileLineEdit->setExpectedKind(Utils::PathChooser::File);
|
ui->keyFileLineEdit->setExpectedKind(Utils::PathChooser::File);
|
||||||
|
ui->keyFileLineEdit->setHistoryCompleter(QLatin1String("BB.Key.History"));
|
||||||
ui->keyFileLineEdit->lineEdit()->setMinimumWidth(0);
|
ui->keyFileLineEdit->lineEdit()->setMinimumWidth(0);
|
||||||
|
|
||||||
const QSsh::SshConnectionParameters &sshParams = deviceConfiguration()->sshParameters();
|
const QSsh::SshConnectionParameters &sshParams = deviceConfiguration()->sshParameters();
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ BlackBerryImportCertificateDialog::BlackBerryImportCertificateDialog(
|
|||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
m_ui->certPath->setExpectedKind(Utils::PathChooser::File);
|
m_ui->certPath->setExpectedKind(Utils::PathChooser::File);
|
||||||
|
m_ui->certPath->setHistoryCompleter(QLatin1String("BB.Certificate.History"));
|
||||||
m_ui->certPath->setPromptDialogTitle(tr("Import Certificate"));
|
m_ui->certPath->setPromptDialogTitle(tr("Import Certificate"));
|
||||||
m_ui->certPath->setPromptDialogFilter(tr("PKCS 12 Archives (*.p12)"));
|
m_ui->certPath->setPromptDialogFilter(tr("PKCS 12 Archives (*.p12)"));
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ NdkPathChooser::NdkPathChooser(Mode mode, QWidget *parent)
|
|||||||
: Utils::PathChooser(parent)
|
: Utils::PathChooser(parent)
|
||||||
, m_mode(mode)
|
, m_mode(mode)
|
||||||
{
|
{
|
||||||
|
setHistoryCompleter(QLatin1String("Qnx.NdkPath.History"));
|
||||||
if (m_mode == NdkPathChooser::InstallMode) {
|
if (m_mode == NdkPathChooser::InstallMode) {
|
||||||
setExpectedKind(Utils::PathChooser::Directory);
|
setExpectedKind(Utils::PathChooser::Directory);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ QWidget *PathChooserDelegate::createEditor(QWidget *parent, const QStyleOptionVi
|
|||||||
|
|
||||||
Utils::PathChooser *editor = new Utils::PathChooser(parent);
|
Utils::PathChooser *editor = new Utils::PathChooser(parent);
|
||||||
|
|
||||||
|
editor->setHistoryCompleter(m_historyKey);
|
||||||
editor->setAutoFillBackground(true); // To hide the text beneath the editor widget
|
editor->setAutoFillBackground(true); // To hide the text beneath the editor widget
|
||||||
editor->lineEdit()->setMinimumWidth(0);
|
editor->lineEdit()->setMinimumWidth(0);
|
||||||
|
|
||||||
@@ -97,6 +98,11 @@ void PathChooserDelegate::updateEditorGeometry(QWidget *editor, const QStyleOpti
|
|||||||
editor->setGeometry(option.rect);
|
editor->setGeometry(option.rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PathChooserDelegate::setHistoryCompleter(const QString &key)
|
||||||
|
{
|
||||||
|
m_historyKey = key;
|
||||||
|
}
|
||||||
|
|
||||||
void PathChooserDelegate::emitCommitData()
|
void PathChooserDelegate::emitCommitData()
|
||||||
{
|
{
|
||||||
emit commitData(qobject_cast<QWidget*>(sender()));
|
emit commitData(qobject_cast<QWidget*>(sender()));
|
||||||
|
|||||||
@@ -60,12 +60,15 @@ public:
|
|||||||
void updateEditorGeometry(QWidget *editor,
|
void updateEditorGeometry(QWidget *editor,
|
||||||
const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||||
|
|
||||||
|
void setHistoryCompleter(const QString &key);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void emitCommitData();
|
void emitCommitData();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Utils::PathChooser::Kind m_kind;
|
Utils::PathChooser::Kind m_kind;
|
||||||
QString m_filter;
|
QString m_filter;
|
||||||
|
QString m_historyKey;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ QnxBaseQtConfigWidget::QnxBaseQtConfigWidget(QnxAbstractQtVersion *version)
|
|||||||
m_ui->sdkLabel->setText(version->sdkDescription());
|
m_ui->sdkLabel->setText(version->sdkDescription());
|
||||||
|
|
||||||
m_ui->sdkPath->setExpectedKind(Utils::PathChooser::ExistingDirectory);
|
m_ui->sdkPath->setExpectedKind(Utils::PathChooser::ExistingDirectory);
|
||||||
|
m_ui->sdkPath->setHistoryCompleter(QLatin1String("Qnx.Sdk.History"));
|
||||||
m_ui->sdkPath->setPath(version->sdkPath());
|
m_ui->sdkPath->setPath(version->sdkPath());
|
||||||
|
|
||||||
connect(m_ui->sdkPath, SIGNAL(changed(QString)), this, SLOT(updateSdkPath(QString)));
|
connect(m_ui->sdkPath, SIGNAL(changed(QString)), this, SLOT(updateSdkPath(QString)));
|
||||||
|
|||||||
@@ -210,10 +210,12 @@ QnxToolChainConfigWidget::QnxToolChainConfigWidget(QnxToolChain *tc)
|
|||||||
, m_abiWidget(new AbiWidget)
|
, m_abiWidget(new AbiWidget)
|
||||||
{
|
{
|
||||||
m_compilerCommand->setExpectedKind(Utils::PathChooser::ExistingCommand);
|
m_compilerCommand->setExpectedKind(Utils::PathChooser::ExistingCommand);
|
||||||
|
m_compilerCommand->setHistoryCompleter(QLatin1String("Qnx.ToolChain.History"));
|
||||||
m_compilerCommand->setFileName(tc->compilerCommand());
|
m_compilerCommand->setFileName(tc->compilerCommand());
|
||||||
m_compilerCommand->setEnabled(!tc->isAutoDetected());
|
m_compilerCommand->setEnabled(!tc->isAutoDetected());
|
||||||
|
|
||||||
m_ndkPath->setExpectedKind(Utils::PathChooser::ExistingDirectory);
|
m_ndkPath->setExpectedKind(Utils::PathChooser::ExistingDirectory);
|
||||||
|
m_ndkPath->setHistoryCompleter(QLatin1String("Qnx.Ndk.History"));
|
||||||
m_ndkPath->setPath(tc->ndkPath());
|
m_ndkPath->setPath(tc->ndkPath());
|
||||||
m_ndkPath->setEnabled(!tc->isAutoDetected());
|
m_ndkPath->setEnabled(!tc->isAutoDetected());
|
||||||
|
|
||||||
|
|||||||
@@ -165,6 +165,10 @@ void LinuxDeviceDebugSupport::startExecution()
|
|||||||
|
|
||||||
QStringList args = arguments();
|
QStringList args = arguments();
|
||||||
QString command;
|
QString command;
|
||||||
|
|
||||||
|
if (d->qmlDebugging)
|
||||||
|
args.prepend(QString::fromLatin1("-qmljsdebugger=port:%1,block").arg(d->qmlPort));
|
||||||
|
|
||||||
if (d->qmlDebugging && !d->cppDebugging) {
|
if (d->qmlDebugging && !d->cppDebugging) {
|
||||||
command = remoteFilePath();
|
command = remoteFilePath();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -251,8 +251,6 @@ void ColorSchemeEdit::changeForeColor()
|
|||||||
const QColor newColor = QColorDialog::getColor(color, m_ui->boldCheckBox->window());
|
const QColor newColor = QColorDialog::getColor(color, m_ui->boldCheckBox->window());
|
||||||
if (!newColor.isValid())
|
if (!newColor.isValid())
|
||||||
return;
|
return;
|
||||||
QPalette p = m_ui->foregroundToolButton->palette();
|
|
||||||
p.setColor(QPalette::Active, QPalette::Button, newColor);
|
|
||||||
m_ui->foregroundToolButton->setStyleSheet(colorButtonStyleSheet(newColor));
|
m_ui->foregroundToolButton->setStyleSheet(colorButtonStyleSheet(newColor));
|
||||||
m_ui->eraseForegroundToolButton->setEnabled(true);
|
m_ui->eraseForegroundToolButton->setEnabled(true);
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,8 @@
|
|||||||
#include <projectexplorer/projectexplorerconstants.h>
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
#include <qtsupport/qtkitinformation.h>
|
#include <qtsupport/qtkitinformation.h>
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
|
|
||||||
namespace WinRt {
|
namespace WinRt {
|
||||||
@@ -46,6 +48,23 @@ static const char appxDeployConfigurationC[] = "WinRTAppxDeployConfiguration";
|
|||||||
static const char phoneDeployConfigurationC[] = "WinRTPhoneDeployConfiguration";
|
static const char phoneDeployConfigurationC[] = "WinRTPhoneDeployConfiguration";
|
||||||
static const char emulatorDeployConfigurationC[] = "WinRTEmulatorDeployConfiguration";
|
static const char emulatorDeployConfigurationC[] = "WinRTEmulatorDeployConfiguration";
|
||||||
|
|
||||||
|
static QString msgDeployConfigurationDisplayName(const Core::Id &id)
|
||||||
|
{
|
||||||
|
if (id == appxDeployConfigurationC) {
|
||||||
|
return QCoreApplication::translate("WinRt::Internal::WinRtDeployConfiguration",
|
||||||
|
"Deploy locally");
|
||||||
|
}
|
||||||
|
if (id == phoneDeployConfigurationC) {
|
||||||
|
return QCoreApplication::translate("WinRt::Internal::WinRtDeployConfiguration",
|
||||||
|
"Deploy to Windows Phone");
|
||||||
|
}
|
||||||
|
if (id == emulatorDeployConfigurationC) {
|
||||||
|
return QCoreApplication::translate("WinRt::Internal::WinRtDeployConfiguration",
|
||||||
|
"Deploy to Windows Phone Emulator");
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
WinRtDeployConfigurationFactory::WinRtDeployConfigurationFactory(QObject *parent)
|
WinRtDeployConfigurationFactory::WinRtDeployConfigurationFactory(QObject *parent)
|
||||||
: DeployConfigurationFactory(parent)
|
: DeployConfigurationFactory(parent)
|
||||||
{
|
{
|
||||||
@@ -53,13 +72,7 @@ WinRtDeployConfigurationFactory::WinRtDeployConfigurationFactory(QObject *parent
|
|||||||
|
|
||||||
QString WinRtDeployConfigurationFactory::displayNameForId(const Core::Id id) const
|
QString WinRtDeployConfigurationFactory::displayNameForId(const Core::Id id) const
|
||||||
{
|
{
|
||||||
if (id == appxDeployConfigurationC)
|
return msgDeployConfigurationDisplayName(id);
|
||||||
return tr("Deploy locally");
|
|
||||||
if (id == phoneDeployConfigurationC)
|
|
||||||
return tr("Deploy to Windows Phone");
|
|
||||||
if (id == emulatorDeployConfigurationC)
|
|
||||||
return tr("Deploy to Windows Phone Emulator");
|
|
||||||
return QString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Core::Id> WinRtDeployConfigurationFactory::availableCreationIds(Target *parent) const
|
QList<Core::Id> WinRtDeployConfigurationFactory::availableCreationIds(Target *parent) const
|
||||||
@@ -144,8 +157,10 @@ QList<Core::Id> WinRtDeployStepFactory::availableCreationIds(BuildStepList *pare
|
|||||||
|
|
||||||
QString WinRtDeployStepFactory::displayNameForId(const Core::Id id) const
|
QString WinRtDeployStepFactory::displayNameForId(const Core::Id id) const
|
||||||
{
|
{
|
||||||
if (id == Constants::WINRT_BUILD_STEP_DEPLOY)
|
if (id == Constants::WINRT_BUILD_STEP_DEPLOY) {
|
||||||
return tr("Deploy Qt binaries and application files");
|
return QCoreApplication::translate("WinRt::Internal::WinRtDeployStepFactory",
|
||||||
|
"Deploy Qt binaries and application files");
|
||||||
|
}
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,12 +208,7 @@ BuildStep *WinRtDeployStepFactory::clone(BuildStepList *parent, BuildStep *sourc
|
|||||||
WinRtDeployConfiguration::WinRtDeployConfiguration(Target *target, Core::Id id)
|
WinRtDeployConfiguration::WinRtDeployConfiguration(Target *target, Core::Id id)
|
||||||
: DeployConfiguration(target, id)
|
: DeployConfiguration(target, id)
|
||||||
{
|
{
|
||||||
if (id == appxDeployConfigurationC)
|
setDefaultDisplayName(msgDeployConfigurationDisplayName(id));
|
||||||
setDefaultDisplayName(tr("Deploy locally"));
|
|
||||||
if (id == phoneDeployConfigurationC)
|
|
||||||
setDefaultDisplayName(tr("Deploy to Windows Phone Device"));
|
|
||||||
if (id == emulatorDeployConfigurationC)
|
|
||||||
setDefaultDisplayName(tr("Deploy to Windows Phone Emulator"));
|
|
||||||
|
|
||||||
stepList()->insertStep(0, new WinRtPackageDeploymentStep(stepList()));
|
stepList()->insertStep(0, new WinRtPackageDeploymentStep(stepList()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -588,6 +588,7 @@ void tst_Preprocessor::macro_uses_lines()
|
|||||||
QCOMPARE(client.macroUsesLine().value("NOTHING"), QList<unsigned>() << 13U);
|
QCOMPARE(client.macroUsesLine().value("NOTHING"), QList<unsigned>() << 13U);
|
||||||
QCOMPARE(client.macroUsesLine().value("ENABLE"), QList<unsigned>() << 18U << 22U << 23U);
|
QCOMPARE(client.macroUsesLine().value("ENABLE"), QList<unsigned>() << 18U << 22U << 23U);
|
||||||
QCOMPARE(client.macroUsesLine().value("ENABLE_COOL"), QList<unsigned>() << 21U);
|
QCOMPARE(client.macroUsesLine().value("ENABLE_COOL"), QList<unsigned>() << 21U);
|
||||||
|
QCOMPARE(client.definitionsResolvedFromLines().value("ENABLE_COOL"), QList<unsigned>() << 18U);
|
||||||
QCOMPARE(client.expandedMacrosOffset(), QList<unsigned>()
|
QCOMPARE(client.expandedMacrosOffset(), QList<unsigned>()
|
||||||
<< buffer.lastIndexOf("FOO\n")
|
<< buffer.lastIndexOf("FOO\n")
|
||||||
<< buffer.lastIndexOf("HEADER")
|
<< buffer.lastIndexOf("HEADER")
|
||||||
@@ -1098,13 +1099,19 @@ void tst_Preprocessor::defined_usage()
|
|||||||
"#endif\n"
|
"#endif\n"
|
||||||
"#ifndef ABSENT2\n"
|
"#ifndef ABSENT2\n"
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
|
"#if defined(ABSENT3)\n"
|
||||||
|
"#endif\n"
|
||||||
|
"#if defined(X)\n"
|
||||||
|
"#endif\n"
|
||||||
|
"#if defined(X) || defined(Y)\n"
|
||||||
|
"#endif\n"
|
||||||
;
|
;
|
||||||
pp.run(QLatin1String("<stdin>"), source);
|
pp.run(QLatin1String("<stdin>"), source);
|
||||||
QHash<QByteArray, QList<unsigned> > definitionsResolvedFromLines =
|
QHash<QByteArray, QList<unsigned> > definitionsResolvedFromLines =
|
||||||
client.definitionsResolvedFromLines();
|
client.definitionsResolvedFromLines();
|
||||||
QCOMPARE(definitionsResolvedFromLines["X"], QList<unsigned>() << 3 << 7);
|
QCOMPARE(definitionsResolvedFromLines["X"], QList<unsigned>() << 3 << 7 << 17 << 19);
|
||||||
QCOMPARE(definitionsResolvedFromLines["Y"], QList<unsigned>() << 5 << 9);
|
QCOMPARE(definitionsResolvedFromLines["Y"], QList<unsigned>() << 5 << 9 << 19);
|
||||||
QCOMPARE(client.unresolvedDefines(), QSet<QByteArray>() << "ABSENT" << "ABSENT2");
|
QCOMPARE(client.unresolvedDefines(), QSet<QByteArray>() << "ABSENT" << "ABSENT2" << "ABSENT3");
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_Preprocessor::dont_eagerly_expand_data()
|
void tst_Preprocessor::dont_eagerly_expand_data()
|
||||||
|
|||||||
@@ -1446,15 +1446,14 @@
|
|||||||
"pem.cpp" "8"
|
"pem.cpp" "8"
|
||||||
"cryptobox" "6"
|
"cryptobox" "6"
|
||||||
"cryptobox.cpp" "7"
|
"cryptobox.cpp" "7"
|
||||||
"engine" "6"
|
"engine/def_engine" "6"
|
||||||
"def_engine" "7"
|
"def_mode.cpp" "7"
|
||||||
"def_mode.cpp" "8"
|
"def_pk_ops.cpp" "7"
|
||||||
"def_pk_ops.cpp" "8"
|
"def_powm.cpp" "7"
|
||||||
"def_powm.cpp" "8"
|
"lookup_block.cpp" "7"
|
||||||
"lookup_block.cpp" "8"
|
"lookup_hash.cpp" "7"
|
||||||
"lookup_hash.cpp" "8"
|
"lookup_mac.cpp" "7"
|
||||||
"lookup_mac.cpp" "8"
|
"lookup_stream.cpp" "7"
|
||||||
"lookup_stream.cpp" "8"
|
|
||||||
"entropy" "6"
|
"entropy" "6"
|
||||||
"cryptoapi_rng" "7"
|
"cryptoapi_rng" "7"
|
||||||
"es_capi.cpp" "8"
|
"es_capi.cpp" "8"
|
||||||
@@ -6796,9 +6795,9 @@
|
|||||||
"qmakestep.ui" "4"
|
"qmakestep.ui" "4"
|
||||||
"qt4projectconfigwidget.ui" "4"
|
"qt4projectconfigwidget.ui" "4"
|
||||||
"Resources" "3"
|
"Resources" "3"
|
||||||
|
"qt4projectmanager.qrc" "4"
|
||||||
"wizards" "4"
|
"wizards" "4"
|
||||||
"wizards.qrc" "5"
|
"wizards.qrc" "5"
|
||||||
"qt4projectmanager.qrc" "4"
|
|
||||||
"Other files" "3"
|
"Other files" "3"
|
||||||
"Qt4ProjectManager.mimetypes.xml" "4"
|
"Qt4ProjectManager.mimetypes.xml" "4"
|
||||||
"qtcreator" "2"
|
"qtcreator" "2"
|
||||||
|
|||||||
|
Reference in New Issue
Block a user