forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/3.1'
Conflicts: qtcreator.pri qtcreator.qbs src/shared/qbs Change-Id: Iba59e41db72e2afdf594f1f7003215d7d8d1e6d3
This commit is contained in:
Vendored
+52
@@ -0,0 +1,52 @@
|
||||
Qt Creator version 3.1.2 is a bugfix release.
|
||||
|
||||
The most important changes are listed in this document. For a complete
|
||||
list of changes, see the Git log for the Qt Creator sources that
|
||||
you can check out from the public Git repository. For example:
|
||||
|
||||
git clone git://gitorious.org/qt-creator/qt-creator.git
|
||||
git log --cherry-pick --pretty=oneline v3.1.1..v3.1.2
|
||||
|
||||
General
|
||||
* Fixed restoring of output pane button visibility
|
||||
|
||||
Editing
|
||||
* Fixed crash with highlight definitions and indentation based folding enabled
|
||||
(QTCREATORBUG-12172)
|
||||
* Fixed setting current file when clicking on split view (QTCREATORBUG-12264)
|
||||
|
||||
Help
|
||||
* Fixed that pressing F1 twice would not go to Help mode
|
||||
(QTCREATORBUG-9093)
|
||||
* Fixed filtering in topic chooser
|
||||
|
||||
QMake Projects
|
||||
* Fixed adding files through context menu in case of multiple
|
||||
resource files (QTCREATORBUG-12297)
|
||||
* Fixed that resource files were no longer appearing in
|
||||
Locator and search
|
||||
|
||||
Debugging
|
||||
* GDB
|
||||
* Worked around GDB crash with large object names
|
||||
(QTCREATORBUG-12330)
|
||||
|
||||
C++ Support
|
||||
* Fixed crash with anonymous unions with __attribute__
|
||||
(QTCREATORBUG-12345)
|
||||
|
||||
Code Paster
|
||||
* Fixed crash in case of invalid protocol setting (QTCREATORBUG-12364)
|
||||
|
||||
Beautifier
|
||||
* Fixed problem on Mac when starting Qt Creator from Finder
|
||||
(QTCREATORBUG-12057)
|
||||
|
||||
Platform Specific
|
||||
|
||||
Windows
|
||||
* Fixed matching of paths in Locator (QTCREATORBUG-12007)
|
||||
|
||||
QNX
|
||||
* Fixed font path on devices
|
||||
|
||||
Vendored
-3
@@ -1,5 +1,2 @@
|
||||
[Paths]
|
||||
# prefix must be one up because Qt makes it relative to the app's Contents/ path,
|
||||
# even if that doesn't exist!
|
||||
Prefix = ..
|
||||
Plugins = ../../PlugIns
|
||||
|
||||
@@ -2263,6 +2263,9 @@
|
||||
|
||||
\endlist
|
||||
|
||||
If locator does not find some files, you can add them to the \c OTHER_FILES
|
||||
variable in the .pro file to make them known to \QC.
|
||||
|
||||
\section1 Configuring Locator Filters
|
||||
|
||||
If the default filters do not match your use case, you can check whether you
|
||||
|
||||
@@ -199,6 +199,11 @@
|
||||
|
||||
\endlist
|
||||
|
||||
You can make additional files known to \QC, so that they become visible in
|
||||
the \gui Projects view and known to the locator and search, but do not
|
||||
affect the build system. Add the paths to the files to the \c OTHER_FILES
|
||||
variable in the .pro file.
|
||||
|
||||
\section2 Viewing the File System
|
||||
|
||||
If you cannot see a file in the \gui Projects view, switch to the
|
||||
|
||||
+6
-6
@@ -2003,12 +2003,6 @@ bool Parser::parseClassSpecifier(SpecifierListAST *&node)
|
||||
NameAST *name = 0;
|
||||
parseName(name);
|
||||
|
||||
if (! name && LA() == T_LBRACE && (LA(0) == T_CLASS || LA(0) == T_STRUCT || LA(0) == T_UNION || LA(0) == T_ENUM)) {
|
||||
AnonymousNameAST *ast = new (_pool) AnonymousNameAST;
|
||||
ast->class_token = classkey_token;
|
||||
name = ast;
|
||||
}
|
||||
|
||||
bool parsed = false;
|
||||
|
||||
const bool previousInFunctionBody = _inFunctionBody;
|
||||
@@ -2025,6 +2019,12 @@ bool Parser::parseClassSpecifier(SpecifierListAST *&node)
|
||||
}
|
||||
|
||||
if (LA() == T_COLON || LA() == T_LBRACE) {
|
||||
if (!name) {
|
||||
AnonymousNameAST *ast = new (_pool) AnonymousNameAST;
|
||||
ast->class_token = classkey_token;
|
||||
name = ast;
|
||||
}
|
||||
|
||||
BaseSpecifierListAST *base_clause_list = 0;
|
||||
|
||||
if (LA() == T_COLON) {
|
||||
|
||||
@@ -216,8 +216,6 @@ DocumentManager::DocumentManager(QObject *parent)
|
||||
{
|
||||
d = new DocumentManagerPrivate;
|
||||
m_instance = this;
|
||||
connect(ICore::instance(), SIGNAL(contextChanged(QList<Core::IContext*>,Core::Context)),
|
||||
this, SLOT(syncWithEditor(QList<Core::IContext*>)));
|
||||
qApp->installEventFilter(this);
|
||||
|
||||
readSettings();
|
||||
@@ -1129,22 +1127,6 @@ void DocumentManager::checkForReload()
|
||||
// dump();
|
||||
}
|
||||
|
||||
void DocumentManager::syncWithEditor(const QList<Core::IContext *> &context)
|
||||
{
|
||||
if (context.isEmpty())
|
||||
return;
|
||||
|
||||
Core::IEditor *editor = Core::EditorManager::currentEditor();
|
||||
if (!editor || editor->document()->isTemporary())
|
||||
return;
|
||||
foreach (IContext *c, context) {
|
||||
if (editor->widget() == c->widget()) {
|
||||
setCurrentFile(editor->document()->filePath());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Adds the \a fileName to the list of recent files. Associates the file to
|
||||
be reopened with the editor that has the specified \a editorId, if possible.
|
||||
|
||||
@@ -163,7 +163,6 @@ private slots:
|
||||
void checkForNewFileName();
|
||||
void checkForReload();
|
||||
void changedFile(const QString &file);
|
||||
void syncWithEditor(const QList<Core::IContext *> &context);
|
||||
|
||||
private:
|
||||
explicit DocumentManager(QObject *parent);
|
||||
|
||||
@@ -526,6 +526,8 @@ void EditorManager::handleContextChange(const QList<Core::IContext *> &context)
|
||||
d->m_scheduledCurrentEditor = editor;
|
||||
QTimer::singleShot(0, m_instance, SLOT(setCurrentEditorFromContextChange()));
|
||||
} else {
|
||||
if (editor && !editor->document()->isTemporary())
|
||||
DocumentManager::setCurrentFile(editor->document()->filePath());
|
||||
updateActions();
|
||||
}
|
||||
}
|
||||
@@ -1027,6 +1029,9 @@ void EditorManager::setCurrentEditorFromContextChange()
|
||||
IEditor *newCurrent = d->m_scheduledCurrentEditor;
|
||||
d->m_scheduledCurrentEditor = 0;
|
||||
setCurrentEditor(newCurrent);
|
||||
if (!newCurrent->document()->isTemporary())
|
||||
DocumentManager::setCurrentFile(newCurrent->document()->filePath());
|
||||
|
||||
}
|
||||
|
||||
void EditorManager::closeEditor(Core::IEditor *editor, bool askAboutModifiedEditors)
|
||||
|
||||
@@ -49,14 +49,14 @@ QList<LocatorFilterEntry> BaseFileFilter::matchesFor(QFutureInterface<Core::Loca
|
||||
updateFiles();
|
||||
QList<LocatorFilterEntry> betterEntries;
|
||||
QList<LocatorFilterEntry> goodEntries;
|
||||
QString needle = trimWildcards(origEntry);
|
||||
QString needle = trimWildcards(QDir::fromNativeSeparators(origEntry));
|
||||
const QString lineNoSuffix = EditorManager::splitLineNumber(&needle);
|
||||
QStringMatcher matcher(needle, Qt::CaseInsensitive);
|
||||
const QChar asterisk = QLatin1Char('*');
|
||||
QRegExp regexp(asterisk + needle+ asterisk, Qt::CaseInsensitive, QRegExp::Wildcard);
|
||||
if (!regexp.isValid())
|
||||
return betterEntries;
|
||||
const QChar pathSeparator = QDir::separator();
|
||||
const QChar pathSeparator(QLatin1Char('/'));
|
||||
const bool hasPathSeparator = needle.contains(pathSeparator);
|
||||
const bool hasWildcard = needle.contains(asterisk) || needle.contains(QLatin1Char('?'));
|
||||
QStringList searchListPaths;
|
||||
|
||||
@@ -105,9 +105,9 @@ void Core::Internal::CorePlugin::test_basefilefilter_data()
|
||||
const QChar pathSeparator = QDir::separator();
|
||||
const MyTestDataDir testDir(QLatin1String("testdata_basic"));
|
||||
const QStringList testFiles = QStringList()
|
||||
<< QDir::toNativeSeparators(testDir.file(QLatin1String("file.cpp")))
|
||||
<< QDir::toNativeSeparators(testDir.file(QLatin1String("main.cpp")))
|
||||
<< QDir::toNativeSeparators(testDir.file(QLatin1String("subdir/main.cpp")));
|
||||
<< QDir::fromNativeSeparators(testDir.file(QLatin1String("file.cpp")))
|
||||
<< QDir::fromNativeSeparators(testDir.file(QLatin1String("main.cpp")))
|
||||
<< QDir::fromNativeSeparators(testDir.file(QLatin1String("subdir/main.cpp")));
|
||||
QStringList testFilesShort;
|
||||
foreach (const QString &file, testFiles)
|
||||
testFilesShort << Utils::FileUtils::shortNativePath(Utils::FileName::fromString(file));
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "protocol.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QSettings>
|
||||
@@ -112,6 +113,7 @@ void PasteView::contentChanged()
|
||||
|
||||
void PasteView::protocolChanged(int p)
|
||||
{
|
||||
QTC_ASSERT(p >= 0 && p < m_protocols.size(), return);
|
||||
const unsigned caps = m_protocols.at(p)->capabilities();
|
||||
m_ui.uiDescription->setEnabled(caps & Protocol::PostDescriptionCapability);
|
||||
m_ui.uiUsername->setEnabled(caps & Protocol::PostUserNameCapability);
|
||||
@@ -215,6 +217,8 @@ void PasteView::accept()
|
||||
void PasteView::setProtocol(const QString &protocol)
|
||||
{
|
||||
const int index = m_ui.protocolBox->findText(protocol);
|
||||
if (index < 0)
|
||||
return;
|
||||
m_ui.protocolBox->setCurrentIndex(index);
|
||||
if (index == m_ui.protocolBox->currentIndex())
|
||||
protocolChanged(index); // Force enabling
|
||||
|
||||
@@ -1857,6 +1857,20 @@ void CppToolsPlugin::test_completion_data()
|
||||
<< QLatin1String("val2")
|
||||
<< QLatin1String("val3"));
|
||||
|
||||
QTest::newRow("nested_anonymous_with___attribute__") << _(
|
||||
"struct Enclosing\n"
|
||||
"{\n"
|
||||
" struct __attribute__((aligned(8)))\n"
|
||||
" {\n"
|
||||
" int i;\n"
|
||||
" };\n"
|
||||
"};\n"
|
||||
"Enclosing e;\n"
|
||||
"@\n"
|
||||
) << _("e.") << (QStringList()
|
||||
<< QLatin1String("Enclosing")
|
||||
<< QLatin1String("i"));
|
||||
|
||||
QTest::newRow("enum_inside_namespace") << _(
|
||||
"namespace Ns\n"
|
||||
"{\n"
|
||||
|
||||
@@ -852,7 +852,7 @@ void MiniProjectTargetSelector::doLayout(bool keepSize)
|
||||
|
||||
int oldSummaryLabelY = m_summaryLabel->y();
|
||||
|
||||
int kitAreaHeight = m_kitAreaWidget->isVisible() ? m_kitAreaWidget->sizeHint().height() : 0;
|
||||
int kitAreaHeight = m_kitAreaWidget->isVisibleTo(this) ? m_kitAreaWidget->sizeHint().height() : 0;
|
||||
|
||||
// 1. Calculate the summary label height
|
||||
int summaryLabelY = 1 + kitAreaHeight;
|
||||
@@ -959,11 +959,9 @@ void MiniProjectTargetSelector::doLayout(bool keepSize)
|
||||
setFixedSize(m_summaryLabel->width() + 1, heightWithoutKitArea + kitAreaHeight); //1 extra pixel for the border
|
||||
}
|
||||
|
||||
if (isVisibleTo(parentWidget())) {
|
||||
QPoint moveTo = statusBar->mapToGlobal(QPoint(0,0));
|
||||
moveTo -= QPoint(0, height());
|
||||
move(moveTo);
|
||||
}
|
||||
QPoint moveTo = statusBar->mapToGlobal(QPoint(0,0));
|
||||
moveTo -= QPoint(0, height());
|
||||
move(moveTo);
|
||||
}
|
||||
|
||||
void MiniProjectTargetSelector::setActiveTarget(ProjectExplorer::ProjectConfiguration *pc)
|
||||
@@ -1403,10 +1401,10 @@ void MiniProjectTargetSelector::activeRunConfigurationChanged(ProjectExplorer::R
|
||||
|
||||
void MiniProjectTargetSelector::setVisible(bool visible)
|
||||
{
|
||||
doLayout(false);
|
||||
QWidget::setVisible(visible);
|
||||
m_projectAction->setChecked(visible);
|
||||
if (visible) {
|
||||
doLayout(false);
|
||||
if (!focusWidget() || !focusWidget()->isVisibleTo(this)) { // Does the second part actually work?
|
||||
if (m_projectListWidget->isVisibleTo(this))
|
||||
m_projectListWidget->setFocus();
|
||||
|
||||
@@ -1070,7 +1070,7 @@ bool QmakePriFileNode::renameFile(const QString &filePath, const QString &newFil
|
||||
ProjectExplorer::FolderNode::AddNewInformation QmakePriFileNode::addNewInformation(const QStringList &files, Node *context) const
|
||||
{
|
||||
Q_UNUSED(files)
|
||||
return ProjectExplorer::FolderNode::AddNewInformation(QFileInfo(path()).fileName(), context == this ? 120 : 90);
|
||||
return ProjectExplorer::FolderNode::AddNewInformation(QFileInfo(path()).fileName(), context && context->projectNode() == this ? 120 : 90);
|
||||
}
|
||||
|
||||
bool QmakePriFileNode::priFileWritable(const QString &path)
|
||||
@@ -1577,7 +1577,7 @@ bool QmakeProFileNode::showInSimpleTree() const
|
||||
ProjectExplorer::FolderNode::AddNewInformation QmakeProFileNode::addNewInformation(const QStringList &files, Node *context) const
|
||||
{
|
||||
Q_UNUSED(files)
|
||||
return AddNewInformation(QFileInfo(path()).fileName(), context == this ? 120 : 100);
|
||||
return AddNewInformation(QFileInfo(path()).fileName(), context && context->projectNode() == this ? 120 : 100);
|
||||
}
|
||||
|
||||
bool QmakeProFileNode::showInSimpleTree(QmakeProjectType projectType) const
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
#include <qtsupport/profilereader.h>
|
||||
#include <qtsupport/qtkitinformation.h>
|
||||
#include <qtsupport/uicodemodelsupport.h>
|
||||
#include <resourceeditor/resourcenode.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
@@ -255,6 +256,9 @@ void ProjectFilesVisitor::visitProjectNode(ProjectNode *projectNode)
|
||||
|
||||
void ProjectFilesVisitor::visitFolderNode(FolderNode *folderNode)
|
||||
{
|
||||
if (qobject_cast<ResourceEditor::ResourceTopLevelNode *>(folderNode))
|
||||
m_files->files[ResourceType].push_back(folderNode->path());
|
||||
|
||||
foreach (FileNode *fileNode, folderNode->fileNodes()) {
|
||||
const QString path = fileNode->path();
|
||||
const int type = fileNode->fileType();
|
||||
|
||||
@@ -266,7 +266,7 @@ ProjectExplorer::FolderNode::AddNewInformation ResourceTopLevelNode::addNewInfor
|
||||
// two nodes would be responsible for '/'
|
||||
// Thus also return a high priority for it
|
||||
if (ResourceFolderNode *rfn = qobject_cast<ResourceFolderNode *>(context))
|
||||
if (rfn->prefix() == QLatin1String("/"))
|
||||
if (rfn->prefix() == QLatin1String("/") && rfn->parentFolderNode() == this)
|
||||
p = 150;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ TopicChooser::TopicChooser(QWidget *parent, const QString &keyword,
|
||||
ui.setupUi(this);
|
||||
|
||||
setFocusProxy(ui.lineEdit);
|
||||
ui.lineEdit->setFiltering(true);
|
||||
ui.lineEdit->installEventFilter(this);
|
||||
ui.lineEdit->setPlaceholderText(tr("Filter"));
|
||||
ui.label->setText(tr("Choose a topic for <b>%1</b>:").arg(keyword));
|
||||
|
||||
@@ -914,8 +914,11 @@ void QMakeEvaluator::visitProVariable(
|
||||
m_featureRoots = 0;
|
||||
else if (varName == statics.strQMAKESPEC) {
|
||||
if (!values(varName).isEmpty()) {
|
||||
m_qmakespec = values(varName).first().toQString();
|
||||
m_featureRoots = 0;
|
||||
QString spec = values(varName).first().toQString();
|
||||
if (IoUtils::isAbsolutePath(spec)) {
|
||||
m_qmakespec = spec;
|
||||
m_featureRoots = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef PROEVALUATOR_FULL
|
||||
@@ -1129,8 +1132,11 @@ bool QMakeEvaluator::loadSpecInternal()
|
||||
// the source of the qmake.conf at the end of the default/qmake.conf in
|
||||
// the QMAKESPEC_ORIGINAL variable.
|
||||
const ProString &orig_spec = first(ProKey("QMAKESPEC_ORIGINAL"));
|
||||
if (!orig_spec.isEmpty())
|
||||
m_qmakespec = orig_spec.toQString();
|
||||
if (!orig_spec.isEmpty()) {
|
||||
QString spec = orig_spec.toQString();
|
||||
if (IoUtils::isAbsolutePath(spec))
|
||||
m_qmakespec = spec;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
valuesRef(ProKey("QMAKESPEC")) = ProString(m_qmakespec);
|
||||
|
||||
@@ -183,6 +183,8 @@ private slots:
|
||||
void q_enum_1();
|
||||
|
||||
void incomplete_ast();
|
||||
void unnamed_class();
|
||||
void unnamed_class_data();
|
||||
};
|
||||
|
||||
void tst_AST::gcc_attributes_1()
|
||||
@@ -1743,6 +1745,43 @@ void tst_AST::incomplete_ast()
|
||||
QVERIFY(ast);
|
||||
}
|
||||
|
||||
static ClassSpecifierAST *classSpecifierInSimpleDeclaration(SimpleDeclarationAST *simpleDeclaration)
|
||||
{
|
||||
Q_ASSERT(simpleDeclaration);
|
||||
SpecifierListAST *specifier = simpleDeclaration->decl_specifier_list;
|
||||
Q_ASSERT(specifier);
|
||||
Q_ASSERT(specifier->value);
|
||||
return specifier->value->asClassSpecifier();
|
||||
}
|
||||
|
||||
void tst_AST::unnamed_class()
|
||||
{
|
||||
QFETCH(QByteArray, source);
|
||||
QVERIFY(!source.isEmpty());
|
||||
|
||||
QSharedPointer<TranslationUnit> unit(parseDeclaration(source));
|
||||
QVERIFY(unit->ast());
|
||||
SimpleDeclarationAST *simpleDeclaration = unit->ast()->asSimpleDeclaration();
|
||||
QVERIFY(simpleDeclaration);
|
||||
ClassSpecifierAST *clazz = classSpecifierInSimpleDeclaration(simpleDeclaration);
|
||||
|
||||
QVERIFY(clazz);
|
||||
QVERIFY(clazz->name);
|
||||
QVERIFY(clazz->name->asAnonymousName());
|
||||
|
||||
QCOMPARE(diag.errorCount, 0);
|
||||
}
|
||||
|
||||
void tst_AST::unnamed_class_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("source");
|
||||
|
||||
typedef QByteArray _;
|
||||
QTest::newRow("unnamed-only") << _("class {};");
|
||||
QTest::newRow("unnamed-derived") << _("class : B {};");
|
||||
QTest::newRow("unnamed-__attribute__") << _("class __attribute__((aligned(8))){};");
|
||||
}
|
||||
|
||||
void tst_AST::initTestCase()
|
||||
{
|
||||
control.setDiagnosticClient(&diag);
|
||||
|
||||
@@ -131,7 +131,6 @@
|
||||
:Qt Creator.Compile Output_Core::OutputWindow {type='Core::OutputWindow' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow' windowTitle='Compile Output'}
|
||||
:Qt Creator.DebugModeWidget_QSplitter {name='DebugModeWidget' type='QSplitter' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
|
||||
:Qt Creator.Go to Help Mode_QToolButton {text='Go to Help Mode' type='QToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
|
||||
:Qt Creator.Help_Search for:_QLineEdit {leftWidget=':Qt Creator.Search for:_QLabel' type='QLineEdit' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
|
||||
:Qt Creator.Issues_QListView {type='QListView' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow' windowTitle='Issues'}
|
||||
:Qt Creator.Project.Menu.File_QMenu {name='Project.Menu.File' type='QMenu'}
|
||||
:Qt Creator.Project.Menu.Folder_QMenu {name='Project.Menu.Folder' type='QMenu' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
|
||||
@@ -139,7 +138,6 @@
|
||||
:Qt Creator.ReRun_QToolButton {toolTip='Re-run this run-configuration' type='QToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
|
||||
:Qt Creator.Replace All_QToolButton {name='replaceAllButton' text='Replace All' type='QToolButton' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
|
||||
:Qt Creator.Replace_QToolButton {name='replaceButton' text='Replace' type='QToolButton' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
|
||||
:Qt Creator.Search for:_QLabel {text='Search for:' type='QLabel' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
|
||||
:Qt Creator.Stop_QToolButton {text='Stop' type='QToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
|
||||
:Qt Creator.replaceEdit_Utils::FilterLineEdit {name='replaceEdit' type='Utils::FancyLineEdit' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
|
||||
:Qt Creator.scrollArea_QScrollArea {name='scrollArea' type='QScrollArea' visible='1' window=':Qt Creator_Core::Internal::MainWindow'}
|
||||
|
||||
@@ -84,8 +84,7 @@ def waitForCompile(timeout=60000):
|
||||
|
||||
def dumpBuildIssues(listModel):
|
||||
issueDump = []
|
||||
for row in range(listModel.rowCount()):
|
||||
index = listModel.index(row, 0)
|
||||
for index in dumpIndices(listModel):
|
||||
issueDump.extend([map(lambda role: index.data(role).toString(),
|
||||
range(Qt.UserRole, Qt.UserRole + 6))])
|
||||
return issueDump
|
||||
@@ -165,8 +164,8 @@ def iterateBuildConfigs(kitCount, filter = ""):
|
||||
def selectBuildConfig(targetCount, currentTarget, configName, afterSwitchTo=ViewConstants.EDIT):
|
||||
switchViewTo(ViewConstants.PROJECTS)
|
||||
switchToBuildOrRunSettingsFor(targetCount, currentTarget, ProjectSettings.BUILD)
|
||||
selectFromCombo(":scrollArea.Edit build configuration:_QComboBox", configName)
|
||||
progressBarWait(30000)
|
||||
if selectFromCombo(":scrollArea.Edit build configuration:_QComboBox", configName) or targetCount > 1:
|
||||
progressBarWait(30000)
|
||||
return getQtInformationForBuildSettings(targetCount, True, afterSwitchTo)
|
||||
|
||||
# This will not trigger a rebuild. If needed, caller has to do this.
|
||||
|
||||
@@ -81,7 +81,7 @@ def setBreakpointsForCurrentProject(filesAndLines):
|
||||
for curFile,curLine in current.iteritems():
|
||||
if not openDocument(curFile):
|
||||
return False
|
||||
editor = getEditorForFileSuffix(curFile)
|
||||
editor = getEditorForFileSuffix(curFile, True)
|
||||
if not placeCursorToLine(editor, curLine, True):
|
||||
return False
|
||||
invokeMenuItem("Debug", "Toggle Breakpoint")
|
||||
|
||||
@@ -255,7 +255,7 @@ def verifyProperties(properties, expectedProps):
|
||||
result[key] = None
|
||||
return result
|
||||
|
||||
def getEditorForFileSuffix(curFile):
|
||||
def getEditorForFileSuffix(curFile, treeViewSyntax=False):
|
||||
cppEditorSuffixes = ["cpp", "cc", "CC", "h", "H", "cp", "cxx", "C", "c++", "inl", "moc", "qdoc",
|
||||
"tcc", "tpp", "t++", "c", "cu", "m", "mm", "hh", "hxx", "h++", "hpp", "hp"]
|
||||
qmlEditorSuffixes = ["qml", "qmlproject", "js", "qs", "qtt"]
|
||||
@@ -263,6 +263,13 @@ def getEditorForFileSuffix(curFile):
|
||||
glslEditorSuffixes= ["frag", "vert", "fsh", "vsh", "glsl", "shader", "gsh"]
|
||||
pytEditorSuffixes = ["py", "pyw", "wsgi"]
|
||||
suffix = __getFileSuffix__(curFile)
|
||||
expected = os.path.basename(curFile)
|
||||
if treeViewSyntax:
|
||||
expected = simpleFileName(curFile)
|
||||
mainWindow = waitForObject(":Qt Creator_Core::Internal::MainWindow")
|
||||
if not waitFor("expected in str(mainWindow.windowTitle)", 5000):
|
||||
test.fatal("Window title (%s) did not switch to expected file (%s)."
|
||||
% (str(mainWindow.windowTitle), expected))
|
||||
try:
|
||||
if suffix in cppEditorSuffixes:
|
||||
editor = waitForObject(":Qt Creator_CppEditor::Internal::CPPEditorWidget")
|
||||
|
||||
@@ -603,7 +603,12 @@ def readFile(filename):
|
||||
return content
|
||||
|
||||
def simpleFileName(navigatorFileName):
|
||||
return ".".join(navigatorFileName.split(".")[-2:]).replace("\\","")
|
||||
# try to find the last part of the given name, assume it's inside a (folder) structure
|
||||
search = re.search(".*[^\\\\]\.(.*)$", navigatorFileName)
|
||||
if search:
|
||||
return search.group(1).replace("\\", "")
|
||||
# it's just the filename
|
||||
return navigatorFileName.replace("\\", "")
|
||||
|
||||
def clickOnTab(tabBarStr, tabText, timeout=5000):
|
||||
if not waitFor("object.exists(tabBarStr)", timeout):
|
||||
|
||||
@@ -96,10 +96,13 @@ def main():
|
||||
mouseClick(waitForObject("{column='0' container=':Qt Creator_QHelpContentWidget' "
|
||||
"text='Qt Reference Documentation' type='QModelIndex'}"))
|
||||
# try to search keyword from list
|
||||
searchLineEdit = getChildByClass(waitForObject("{type='QHelpSearchQueryWidget' unnamed='1' visible='1' "
|
||||
"window=':Qt Creator_Core::Internal::MainWindow'}"),
|
||||
"QLineEdit")
|
||||
for searchKeyword,shouldFind in searchKeywordDictionary.items():
|
||||
mouseClick(waitForObject(":Qt Creator.Help_Search for:_QLineEdit"))
|
||||
replaceEditorContent(":Qt Creator.Help_Search for:_QLineEdit", searchKeyword)
|
||||
type(waitForObject(":Qt Creator.Help_Search for:_QLineEdit"), "<Return>")
|
||||
mouseClick(searchLineEdit)
|
||||
replaceEditorContent(searchLineEdit, searchKeyword)
|
||||
type(searchLineEdit, "<Return>")
|
||||
progressBarWait(warn=False)
|
||||
if shouldFind:
|
||||
test.verify(waitFor("re.match('[1-9]\d* - [1-9]\d* of [1-9]\d* Hits',"
|
||||
@@ -153,7 +156,7 @@ def main():
|
||||
test.verify("sql" in str(__getSelectedText__()).lower(),
|
||||
"sql advanced search result can be found")
|
||||
# verify if simple search is properly disabled
|
||||
test.verify(findObject(":Qt Creator.Help_Search for:_QLineEdit").enabled == False,
|
||||
test.verify(not searchLineEdit.enabled,
|
||||
"Verifying if simple search is not active in advanced mode.")
|
||||
# exit
|
||||
invokeMenuItem("File", "Exit")
|
||||
|
||||
@@ -7,6 +7,6 @@ HOOK_SUB_PROCESSES=false
|
||||
IMPLICITAUTSTART=0
|
||||
LANGUAGE=Python
|
||||
OBJECTMAP=../objects.map
|
||||
TEST_CASES=tst_basic_cpp_support tst_delete_externally tst_edit_externally tst_memberoperator tst_modify_readonly tst_qml_editor tst_qml_indent tst_rename_macros tst_revert_changes tst_select_all
|
||||
TEST_CASES=tst_basic_cpp_support tst_delete_externally tst_edit_externally tst_generic_highlighter tst_memberoperator tst_modify_readonly tst_qml_editor tst_qml_indent tst_rename_macros tst_revert_changes tst_select_all
|
||||
VERSION=2
|
||||
WRAPPERS=Qt
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
#############################################################################
|
||||
##
|
||||
## 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.
|
||||
##
|
||||
#############################################################################
|
||||
|
||||
source("../../shared/qtcreator.py")
|
||||
|
||||
def createFile(folder, filename):
|
||||
__createProjectOrFileSelectType__(" General", "Text File", isProject = False)
|
||||
replaceEditorContent(waitForObject("{name='nameLineEdit' visible='1' "
|
||||
"type='Utils::FileNameValidatingLineEdit'}"), filename)
|
||||
replaceEditorContent(waitForObject("{type='Utils::FancyLineEdit' unnamed='1' visible='1' "
|
||||
"window=':New Text File_Utils::FileWizardDialog'}"), folder)
|
||||
clickButton(waitForObject(":Next_QPushButton"))
|
||||
__createProjectHandleLastPage__()
|
||||
|
||||
def clickTableGetPatternLineEdit(table, row):
|
||||
clickItem(table, "%d/0" % row, 5, 5, 0, Qt.LeftButton)
|
||||
return waitForObject("{name='patternsLineEdit' type='QLineEdit' visible='1'}")
|
||||
|
||||
def getOrModifyFilePatternsFor(mimeType, filter='', toBePresent=None):
|
||||
toSuffixArray = lambda x : [pat.replace("*", "") for pat in x.split(";")]
|
||||
|
||||
result = []
|
||||
invokeMenuItem("Tools", "Options...")
|
||||
waitForObjectItem(":Options_QListView", "Environment")
|
||||
clickItem(":Options_QListView", "Environment", 14, 15, 0, Qt.LeftButton)
|
||||
waitForObject("{container=':Options.qt_tabwidget_tabbar_QTabBar' type='TabItem' "
|
||||
"text='MIME Types'}")
|
||||
clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "MIME Types")
|
||||
replaceEditorContent(waitForObject("{name='filterLineEdit' type='QLineEdit' visible='1'}"),
|
||||
filter)
|
||||
mimeTypeTable = waitForObject("{name='mimeTypesTableView' type='QTableView' visible='1'}")
|
||||
model = mimeTypeTable.model()
|
||||
if filter == '':
|
||||
for row in range(model.rowCount()):
|
||||
if str(model.data(model.index(row, 0)).toString()) == mimeType:
|
||||
result = toSuffixArray(str(clickTableGetPatternLineEdit(mimeTypeTable, row).text))
|
||||
break
|
||||
clickButton(":Options.Cancel_QPushButton")
|
||||
if result == ['']:
|
||||
test.warning("MIME type '%s' seems to have no file patterns." % mimeType)
|
||||
return result
|
||||
waitFor('model.rowCount() == 1', 2000)
|
||||
if model.rowCount() == 1:
|
||||
patternsLineEd = clickTableGetPatternLineEdit(mimeTypeTable, 0)
|
||||
patterns = str(patternsLineEd.text)
|
||||
if toBePresent:
|
||||
actualSuffixes = toSuffixArray(patterns)
|
||||
toBeAddedSet = set(toBePresent).difference(set(actualSuffixes))
|
||||
if toBeAddedSet:
|
||||
patterns += ";*" + ";*".join(toBeAddedSet)
|
||||
replaceEditorContent(patternsLineEd, patterns)
|
||||
clickButton(":Options.OK_QPushButton")
|
||||
try:
|
||||
mBox = waitForObject("{type='QMessageBox' unnamed='1' visible='1' "
|
||||
"text?='Conflicting pattern*'}", 2000)
|
||||
conflictingSet = set(str(mBox.detailedText).replace("*", "").splitlines())
|
||||
sendEvent("QCloseEvent", mBox)
|
||||
if toBeAddedSet.intersection(conflictingSet):
|
||||
test.fatal("At least one of the patterns to be added is already in use "
|
||||
"for another MIME type.",
|
||||
"Conflicting patterns: %s" % str(conflictingSet))
|
||||
if conflictingSet.difference(toBeAddedSet):
|
||||
test.fail("MIME type handling failed. (QTCREATORBUG-12149?)",
|
||||
"Conflicting patterns: %s" % str(conflictingSet))
|
||||
# re-check the patterns
|
||||
result = getOrModifyFilePatternsFor(mimeType)
|
||||
except:
|
||||
result = toSuffixArray(patterns)
|
||||
test.passes("Added suffixes")
|
||||
return result
|
||||
else:
|
||||
result = toSuffixArray(patterns)
|
||||
elif model.rowCount() > 1:
|
||||
test.warning("MIME type '%s' has ambiguous results." % mimeType)
|
||||
else:
|
||||
test.log("MIME type '%s' seems to be unknown to the system." % mimeType)
|
||||
clickButton(":Options.Cancel_QPushButton")
|
||||
return result
|
||||
|
||||
def uncheckGenericHighlighterFallback():
|
||||
invokeMenuItem("Tools", "Options...")
|
||||
waitForObjectItem(":Options_QListView", "Text Editor")
|
||||
clickItem(":Options_QListView", "Text Editor", 14, 15, 0, Qt.LeftButton)
|
||||
waitForObject("{container=':Options.qt_tabwidget_tabbar_QTabBar' type='TabItem' "
|
||||
"text='Generic Highlighter'}")
|
||||
clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "Generic Highlighter")
|
||||
ensureChecked("{name='useFallbackLocation' text='Use fallback location' type='QCheckBox' "
|
||||
"visible='1'}", False)
|
||||
clickButton(":Options.OK_QPushButton")
|
||||
|
||||
def addHighlighterDefinition(language):
|
||||
global tmpSettingsDir
|
||||
test.log("Adding highlighter definitions for '%s'." % language)
|
||||
invokeMenuItem("Tools", "Options...")
|
||||
waitForObjectItem(":Options_QListView", "Text Editor")
|
||||
clickItem(":Options_QListView", "Text Editor", 14, 15, 0, Qt.LeftButton)
|
||||
waitForObject("{container=':Options.qt_tabwidget_tabbar_QTabBar' type='TabItem' "
|
||||
"text='Generic Highlighter'}")
|
||||
clickOnTab(":Options.qt_tabwidget_tabbar_QTabBar", "Generic Highlighter")
|
||||
clickButton("{text='Download Definitions...' type='QPushButton' unnamed='1' visible='1'}")
|
||||
table = waitForObject("{name='definitionsTable' type='QTableWidget' visible='1'}")
|
||||
model = table.model()
|
||||
for row in range(model.rowCount()):
|
||||
if str(model.data(model.index(row, 0)).toString()) == language:
|
||||
clickItem(table, "%d/0" % row, 5, 5, 0, Qt.LeftButton)
|
||||
clickButton("{name='downloadButton' text='Download Selected Definitions' "
|
||||
"type='QPushButton' visible='1'}")
|
||||
# downloading happens asynchronously
|
||||
languageFile = os.path.join(tmpSettingsDir, "QtProject", "qtcreator",
|
||||
"generic-highlighter", "%s.xml" % language.lower())
|
||||
test.verify(waitFor("os.path.exists(languageFile)", 10000),
|
||||
"Verifying whether file has been downloaded and placed to settings.")
|
||||
clickButton("{text='Download Definitions...' type='QPushButton' unnamed='1' "
|
||||
"visible='1'}")
|
||||
table = waitForObject("{name='definitionsTable' type='QTableWidget' visible='1'}")
|
||||
model = table.model()
|
||||
test.verify(str(model.data(model.index(row, 1))) != "",
|
||||
"Verifying a definition has been downloaded.")
|
||||
clickButton("{text='Close' type='QPushButton' unnamed='1' visible='1'}")
|
||||
clickButton(":Options.OK_QPushButton")
|
||||
return True
|
||||
test.fail("Could not find the specified language (%s) to download a highlighter definition"
|
||||
% language)
|
||||
clickButton("{text='Close' type='QPushButton' unnamed='1' visible='1'}")
|
||||
clickButton(":Options.OK_QPushButton")
|
||||
return False
|
||||
|
||||
def hasSuffix(fileName, suffixPatterns):
|
||||
for suffix in suffixPatterns:
|
||||
if fileName.endswith(suffix):
|
||||
return True
|
||||
return False
|
||||
|
||||
def main():
|
||||
miss = "A highlight definition was not found for this file. Would you like to try to find one?"
|
||||
startApplication("qtcreator" + SettingsPath)
|
||||
if not startedWithoutPluginError():
|
||||
return
|
||||
uncheckGenericHighlighterFallback()
|
||||
patterns = getOrModifyFilePatternsFor("text/x-haskell", "haskell")
|
||||
folder = tempDir()
|
||||
filesToTest = ["Main.lhs", "Main.hs"]
|
||||
code = ['module Main where', '', 'main :: IO ()', '', 'main = putStrLn "Hello World!"']
|
||||
|
||||
for current in filesToTest:
|
||||
createFile(folder, current)
|
||||
editor = getEditorForFileSuffix(current)
|
||||
expectHint = hasSuffix(current, patterns)
|
||||
mssg = "Verifying whether hint for missing highlight definition is present. (expected: %s)"
|
||||
try:
|
||||
waitForObject("{text='%s' type='QLabel' unnamed='1' visible='1' "
|
||||
"window=':Qt Creator_Core::Internal::MainWindow'}" % miss, 2000)
|
||||
test.verify(expectHint, mssg % str(expectHint))
|
||||
except:
|
||||
test.verify(not expectHint, mssg % str(expectHint))
|
||||
# literate haskell: first character must be '>' otherwise it's a comment
|
||||
if current.endswith(".lhs"):
|
||||
typeLines(editor, [">" + line for line in code])
|
||||
else:
|
||||
typeLines(editor, code)
|
||||
|
||||
invokeMenuItem("File", "Save All")
|
||||
invokeMenuItem("File", "Close All")
|
||||
addedHighlighterDefinition = addHighlighterDefinition("Haskell")
|
||||
patterns = getOrModifyFilePatternsFor('text/x-haskell', 'haskell', ['.lhs', '.hs'])
|
||||
|
||||
home = os.path.expanduser("~")
|
||||
for current in filesToTest:
|
||||
recentFile = os.path.join(folder, current)
|
||||
if recentFile.startswith(home) and platform.system() in ('Linux', 'Darwin'):
|
||||
recentFile = recentFile.replace(home, "~", 1)
|
||||
invokeMenuItem("File", "Recent Files", recentFile)
|
||||
editor = getEditorForFileSuffix(current)
|
||||
try:
|
||||
waitForObject("{text='%s' type='QLabel' unnamed='1' visible='1' "
|
||||
"window=':Qt Creator_Core::Internal::MainWindow'}" % miss, 2000)
|
||||
test.verify(not addedHighlighterDefinition and hasSuffix(current, patterns),
|
||||
"Hint for missing highlight definition was present.")
|
||||
except:
|
||||
test.verify(addedHighlighterDefinition or not hasSuffix(current, patterns),
|
||||
"Hint for missing highlight definition is not shown.")
|
||||
placeCursorToLine(editor, '.*%s' % code[-1], True)
|
||||
for _ in range(23):
|
||||
type(editor, "<Left>")
|
||||
type(editor, "<Return>")
|
||||
if current.endswith(".lhs"):
|
||||
type(editor, ">")
|
||||
type(editor, "<Tab>")
|
||||
|
||||
invokeMenuItem("File", "Save All")
|
||||
invokeMenuItem("File", "Exit")
|
||||
@@ -58,7 +58,7 @@ def main():
|
||||
test.fatal("Could not open file '%s'" % simpleFileName(file))
|
||||
continue
|
||||
test.log("Changing file '%s'" % simpleFileName(file))
|
||||
typeLines(getEditorForFileSuffix(file), "")
|
||||
typeLines(getEditorForFileSuffix(file, True), "")
|
||||
# try to compile
|
||||
clickButton(waitForObject(":*Qt Creator.Build Project_Core::Internal::FancyToolButton"))
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user