Merge remote-tracking branch 'origin/2.4'

Conflicts:
	share/qtcreator/welcomescreen/widgets/ExampleDelegate.qml
	src/plugins/qtsupport/exampleslistmodel.cpp
	src/plugins/qtsupport/exampleslistmodel.h
	src/plugins/qtsupport/gettingstartedwelcomepage.cpp
	src/plugins/qtsupport/gettingstartedwelcomepage.h

Change-Id: I268072db01064d71bc4828942d71fc772ddd3539
This commit is contained in:
Eike Ziller
2011-11-28 08:34:37 +01:00
12 changed files with 183 additions and 71 deletions

View File

@@ -33,7 +33,7 @@
the device. Command-line output is visible in the \QC
\gui {Application Output} view.
Choose \gui Projects > Maemo Run} to view the settings for deploying the
Choose \gui {Projects > Maemo Run} to view the settings for deploying the
application on the connected device and creating the installation package.
For more information, see
\l{Specifying Run Settings for Maemo and MeeGo Harmattan Devices}.

View File

@@ -53,25 +53,6 @@ using TextEditor::TabSettings;
namespace CppTools {
namespace Internal {
class LegacySettings
{
public:
LegacySettings()
: m_legacyTransformed(false)
{ }
void fromMap(const QString &prefix, const QVariantMap &map)
{
m_fallbackId = map.value(prefix + QLatin1String("CurrentFallback")).toString();
m_legacyTransformed = map.value(prefix + QLatin1String("LegacyTransformed"), false).toBool();
}
void toMap(const QString &prefix, QVariantMap *map) const
{
map->insert(prefix + QLatin1String("LegacyTransformed"), true);
}
QString m_fallbackId;
bool m_legacyTransformed;
};
class CppToolsSettingsPrivate
{
public:
@@ -176,40 +157,51 @@ CppToolsSettings::CppToolsSettings(QObject *parent)
if (QSettings *s = Core::ICore::instance()->settings()) {
d->m_globalCodeStyle->fromSettings(CppTools::Constants::CPP_SETTINGS_ID, s);
// legacy handling start (Qt Creator <= 2.3)
Internal::LegacySettings legacySettings;
// legacy handling start (Qt Creator Version < 2.4)
const bool legacyTransformed =
s->value(QLatin1String("CppCodeStyleSettings/LegacyTransformed"), false).toBool();
if (!legacyTransformed) {
// creator 2.4 didn't mark yet the transformation (first run of creator 2.4)
// we need to transform the settings only if at least one from
// below settings was already written - otherwise we use
// defaults like it would be the first run of creator 2.4 without stored settings
const QStringList groups = s->childGroups();
const bool needTransform = groups.contains(QLatin1String("textTabPreferences")) ||
groups.contains(QLatin1String("CppTabPreferences")) ||
groups.contains(QLatin1String("CppCodeStyleSettings"));
if (needTransform) {
CppCodeStyleSettings legacyCodeStyleSettings;
if (groups.contains(QLatin1String("CppCodeStyleSettings"))) {
Utils::fromSettings(QLatin1String("CppCodeStyleSettings"),
QString(), s, &legacyCodeStyleSettings);
}
const QString currentFallback = s->value(QLatin1String("CppTabPreferences/CurrentFallback")).toString();
TabSettings legacyTabSettings;
Utils::fromSettings(QLatin1String("TabPreferences"),
QLatin1String("Cpp"), s, &legacySettings);
if (legacySettings.m_fallbackId == QLatin1String("CppGlobal")) {
Utils::fromSettings(QLatin1String("TabPreferences"),
QLatin1String("Cpp"), s, &legacyTabSettings);
if (currentFallback == QLatin1String("CppGlobal")) {
// no delegate, global overwritten
Utils::fromSettings(QLatin1String("CppTabPreferences"),
QString(), s, &legacyTabSettings);
} else {
// delegating to global
legacyTabSettings = textEditorSettings->codeStyle()->currentTabSettings();
}
CppCodeStyleSettings legacyCodeStyleSettings;
Utils::fromSettings(QLatin1String("CodeStyleSettings"),
QLatin1String("Cpp"), s, &legacySettings);
if (!legacySettings.m_legacyTransformed
&& legacySettings.m_fallbackId == QLatin1String("CppGlobal")) {
Utils::fromSettings(QLatin1String("CodeStyleSettings"),
QLatin1String("Cpp"), s, &legacyCodeStyleSettings);
// create custom code style out of old settings
QVariant v;
v.setValue(legacyCodeStyleSettings);
TextEditor::ICodeStylePreferences *oldCreator = pool->createCodeStyle(
QLatin1String("legacy"), legacyTabSettings,
v, tr("Old Creator"));
// change the current delegate and save
d->m_globalCodeStyle->setCurrentDelegate(oldCreator);
d->m_globalCodeStyle->toSettings(CppTools::Constants::CPP_SETTINGS_ID, s);
// mark old settings as transformed,
// we create only once "Old Creator" custom settings
Utils::toSettings(QLatin1String("CodeStyleSettings"),
QLatin1String("Cpp"), s, &legacySettings);
}
// mark old settings as transformed
s->setValue(QLatin1String("CppCodeStyleSettings/LegacyTransformed"), true);
}
// legacy handling stop
}

View File

@@ -213,6 +213,7 @@ SearchResultWindow::SearchResultWindow(QWidget *newSearchPanel)
QScrollArea *newSearchArea = new QScrollArea(d->m_widget);
newSearchArea->setFrameStyle(QFrame::NoFrame);
newSearchArea->setWidget(newSearchPanel);
newSearchArea->setFocusProxy(newSearchPanel);
d->m_widget->addWidget(newSearchArea);
d->m_currentIndex = 0;

View File

@@ -39,6 +39,7 @@
#include <texteditor/tabsettings.h>
#include <texteditor/codestylepool.h>
#include <utils/settingsutils.h>
#include <utils/qtcassert.h>
#include <coreplugin/icore.h>
@@ -108,8 +109,48 @@ QmlJSToolsSettings::QmlJSToolsSettings(QObject *parent)
pool->loadCustomCodeStyles();
// load global settings (after built-in settings are added to the pool)
if (const QSettings *s = Core::ICore::instance()->settings()) {
if (QSettings *s = Core::ICore::instance()->settings()) {
d->m_globalCodeStyle->fromSettings(QmlJSTools::Constants::QML_JS_SETTINGS_ID, s);
// legacy handling start (Qt Creator Version < 2.4)
const bool legacyTransformed =
s->value(QLatin1String("QmlJSTabPreferences/LegacyTransformed"), false).toBool();
if (!legacyTransformed) {
// creator 2.4 didn't mark yet the transformation (first run of creator 2.4)
// we need to transform the settings only if at least one from
// below settings was already written - otherwise we use
// defaults like it would be the first run of creator 2.4 without stored settings
const QStringList groups = s->childGroups();
const bool needTransform = groups.contains(QLatin1String("textTabPreferences")) ||
groups.contains(QLatin1String("QmlJSTabPreferences"));
if (needTransform) {
const QString currentFallback = s->value(QLatin1String("QmlJSTabPreferences/CurrentFallback")).toString();
TabSettings legacyTabSettings;
if (currentFallback == QLatin1String("QmlJSGlobal")) {
// no delegate, global overwritten
Utils::fromSettings(QLatin1String("QmlJSTabPreferences"),
QString(), s, &legacyTabSettings);
} else {
// delegating to global
legacyTabSettings = textEditorSettings->codeStyle()->currentTabSettings();
}
// create custom code style out of old settings
TextEditor::ICodeStylePreferences *oldCreator = pool->createCodeStyle(
QLatin1String("legacy"), legacyTabSettings,
QVariant(), tr("Old Creator"));
// change the current delegate and save
d->m_globalCodeStyle->setCurrentDelegate(oldCreator);
d->m_globalCodeStyle->toSettings(QmlJSTools::Constants::QML_JS_SETTINGS_ID, s);
}
// mark old settings as transformed
s->setValue(QLatin1String("QmlJSTabPreferences/LegacyTransformed"), true);
}
// legacy handling stop
}
// mimetypes to be handled

View File

@@ -65,6 +65,7 @@ ExamplesListModel::ExamplesListModel(QObject *parent) :
roleNames[Difficulty] = "difficulty";
roleNames[Type] = "type";
roleNames[HasSourceCode] = "hasSourceCode";
roleNames[Dependencies] = "dependencies";
roleNames[IsVideo] = "isVideo";
roleNames[VideoUrl] = "videoUrl";
roleNames[VideoLength] = "videoLength";
@@ -76,7 +77,7 @@ ExamplesListModel::ExamplesListModel(QObject *parent) :
SLOT(helpInitialized()));
}
static inline QString fixSTringForTags(const QString &string)
static inline QString fixStringForTags(const QString &string)
{
QString returnString = string;
returnString.remove(QLatin1String("<i>"));
@@ -107,7 +108,9 @@ QList<ExampleItem> ExamplesListModel::parseExamples(QXmlStreamReader* reader, co
} else if (reader->name() == QLatin1String("fileToOpen")) {
item.filesToOpen.append(projectsOffset + '/' + reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement));
} else if (reader->name() == QLatin1String("description")) {
item.description = fixSTringForTags(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement));
item.description = fixStringForTags(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement));
} else if (reader->name() == QLatin1String("dependency")) {
item.dependencies.append(projectsOffset + '/' + reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement));
} else if (reader->name() == QLatin1String("tags")) {
item.tags = reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement).split(",");
m_tags.append(item.tags);
@@ -147,7 +150,9 @@ QList<ExampleItem> ExamplesListModel::parseDemos(QXmlStreamReader* reader, const
} else if (reader->name() == QLatin1String("fileToOpen")) {
item.filesToOpen.append(projectsOffset + '/' + reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement));
} else if (reader->name() == QLatin1String("description")) {
item.description = fixSTringForTags(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement));
item.description = fixStringForTags(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement));
} else if (reader->name() == QLatin1String("dependency")) {
item.dependencies.append(projectsOffset + '/' + reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement));
} else if (reader->name() == QLatin1String("tags")) {
item.tags = reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement).split(",");
}
@@ -194,7 +199,9 @@ QList<ExampleItem> ExamplesListModel::parseTutorials(QXmlStreamReader* reader, c
} else if (reader->name() == QLatin1String("fileToOpen")) {
item.filesToOpen.append(projectsOffset + '/' + reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement));
} else if (reader->name() == QLatin1String("description")) {
item.description = fixSTringForTags(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement));
item.description = fixStringForTags(reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement));
} else if (reader->name() == QLatin1String("dependency")) {
item.dependencies.append(projectsOffset + '/' + reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement));
} else if (reader->name() == QLatin1String("tags")) {
item.tags = reader->readElementText(QXmlStreamReader::ErrorOnUnexpectedElement).split(",");
}
@@ -371,6 +378,8 @@ QVariant ExamplesListModel::data(const QModelIndex &index, int role) const
return item.tags;
case Difficulty:
return item.difficulty;
case Dependencies:
return item.dependencies;
case HasSourceCode:
return item.hasSourceCode;
case Type:

View File

@@ -42,7 +42,8 @@ namespace QtSupport {
namespace Internal {
enum ExampleRoles { Name=Qt::UserRole, ProjectPath, Description, ImageUrl,
DocUrl, FilesToOpen, Tags, Difficulty, HasSourceCode, Type, IsVideo, VideoUrl, VideoLength };
DocUrl, FilesToOpen, Tags, Difficulty, HasSourceCode,
Type, Dependencies, IsVideo, VideoUrl, VideoLength };
enum InstructionalType { Example=0, Demo, Tutorial };
@@ -56,6 +57,7 @@ struct ExampleItem {
QString docUrl;
QStringList filesToOpen;
QStringList tags;
QStringList dependencies;
int difficulty;
bool hasSourceCode;
bool isVideo;

View File

@@ -304,7 +304,7 @@ QStringList ExamplesWelcomePage::tagList() const
return examplesModel()->tags();
}
QString ExamplesWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileInfo, QStringList &filesToOpen)
QString ExamplesWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileInfo, QStringList &filesToOpen, const QStringList& dependencies)
{
const QString projectDir = proFileInfo.canonicalPath();
QDialog d(Core::ICore::instance()->mainWindow());
@@ -359,6 +359,15 @@ QString ExamplesWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileI
for (it = filesToOpen.begin(); it != filesToOpen.end(); ++it)
it->replace(projectDir, targetDir);
foreach (const QString &dependency, dependencies) {
QString dirName = QDir(dependency).dirName();
if (!Utils::FileUtils::copyRecursively(dependency, targetDir + QDir::separator()+ dirName, &error)) {
QMessageBox::warning(Core::ICore::instance()->mainWindow(), tr("Cannot Copy Project"), error);
// do not fail, just warn;
}
}
return targetDir+ '/' + proFileInfo.fileName();
} else {
QMessageBox::warning(Core::ICore::instance()->mainWindow(), tr("Cannot Copy Project"), error);
@@ -370,7 +379,8 @@ QString ExamplesWelcomePage::copyToAlternativeLocation(const QFileInfo& proFileI
}
void ExamplesWelcomePage::openProject(const QString &projectFile, const QStringList &additionalFilesToOpen, const QUrl &help)
void ExamplesWelcomePage::openProject(const QString &projectFile, const QStringList &additionalFilesToOpen,
const QUrl &help, const QStringList &dependencies)
{
QString proFile = projectFile;
if (proFile.isEmpty())
@@ -380,7 +390,7 @@ void ExamplesWelcomePage::openProject(const QString &projectFile, const QStringL
QFileInfo proFileInfo(proFile);
// If the Qt is a distro Qt on Linux, it will not be writable, hence compilation will fail
if (!proFileInfo.isWritable())
proFile = copyToAlternativeLocation(proFileInfo, filesToOpen);
proFile = copyToAlternativeLocation(proFileInfo, filesToOpen, dependencies);
// don't try to load help and files if loading the help request is being cancelled
QString errorMessage;

View File

@@ -85,12 +85,13 @@ signals:
public slots:
void openSplitHelp(const QUrl &help);
void openHelp(const QUrl &help);
void openProject(const QString& projectFile, const QStringList& additionalFilesToOpen, const QUrl& help);
void openProject(const QString& projectFile, const QStringList& additionalFilesToOpen,
const QUrl& help, const QStringList &dependencies);
void updateTagsModel();
private:
ExamplesListModel *examplesModel() const;
QString copyToAlternativeLocation(const QFileInfo &fileInfo, QStringList &filesToOpen);
QString copyToAlternativeLocation(const QFileInfo &fileInfo, QStringList &filesToOpen, const QStringList &dependencies);
QDeclarativeEngine *m_engine;
bool m_showExamples;
};

View File

@@ -19,7 +19,7 @@ def modifyRunSettingsForHookInto(projectName, port):
if result:
clickButton(waitForObject("{container=':Qt Creator.scrollArea_QScrollArea' text='Details' "
"type='Utils::DetailsButton' unnamed='1' visible='1' "
"leftWidget={type='QLabel' text='Using <b>Build Environment</b>' unnamed='1' visible='1'}}"))
"leftWidget={type='QLabel' text~='Us(e|ing) <b>Build Environment</b>' unnamed='1' visible='1'}}"))
envVarsTableView = waitForObject("{type='QTableView' visible='1' unnamed='1'}")
model = envVarsTableView.model()
for row in range(model.rowCount()):

View File

@@ -83,7 +83,14 @@ def __chooseTargets__(targets=QtQuickConstants.Targets.DESKTOP):
if mustCheck:
test.fail("Failed to check target '%s'" % QtQuickConstants.getStringForTarget(current))
def runAndCloseApp(withHookInto=False, executable=None, port=None):
# run and close a Qt Quick application
# withHookInto - if set to True the function tries to attach to the sub-process instead of simply pressing Stop inside Creator
# executable - must be defined when using hook-into
# port - must be defined when using hook-into
# function - can be a string holding a function name or a reference to the function itself - this function will be called on
# the sub-process when hooking-into has been successful - if its missing simply closing the Qt Quick app will be done
# ATTENTION! Make sure this function won't fail and the sub-process will end when the function returns
def runAndCloseApp(withHookInto=False, executable=None, port=None, function=None):
global processStarted, processExited
processStarted = processExited = False
installLazySignalHandler("{type='ProjectExplorer::ApplicationLaucher'}", "processStarted()", "__handleProcessStarted__")
@@ -102,7 +109,7 @@ def runAndCloseApp(withHookInto=False, executable=None, port=None):
invokeMenuItem("File", "Exit")
return False
if withHookInto and not executable in ("", None):
__closeSubprocessByHookingIntoQmlApplicationViewer__(executable, port)
__closeSubprocessByHookingIntoQmlApplicationViewer__(executable, port, function)
else:
__closeSubprocessByPushingStop__()
return True
@@ -115,7 +122,7 @@ def __closeSubprocessByPushingStop__():
test.verify(playButton.enabled)
test.compare(stopButton.enabled, False)
def __closeSubprocessByHookingIntoQmlApplicationViewer__(executable, port):
def __closeSubprocessByHookingIntoQmlApplicationViewer__(executable, port, function):
global processExited
ensureChecked(":Qt Creator_Core::Internal::OutputPaneToggleButton")
output = waitForObject("{type='Core::OutputWindow' visible='1' windowTitle='Application Output Window'}", 20000)
@@ -124,9 +131,28 @@ def __closeSubprocessByHookingIntoQmlApplicationViewer__(executable, port):
else:
waitFor("'Listening on port %d for incoming connectionsdone' in str(output.plainText)" % port, 5000)
attachToApplication(executable)
if function == None:
sendEvent("QCloseEvent", "{type='QmlApplicationViewer' unnamed='1' visible='1'}")
waitFor("processExited==True", 10000)
setApplicationContext(applicationContext("qtcreator"))
else:
try:
if isinstance(function, (str, unicode)):
globals()[function]()
else:
function()
except:
test.fatal("Function to execute on sub-process could not be found.",
"Using fallback of pushing STOP inside Creator.")
setApplicationContext(applicationContext("qtcreator"))
__closeSubprocessByPushingStop__()
waitFor("processExited==True", 10000)
if not processExited:
test.warning("Sub-process seems not to have closed properly.")
try:
setApplicationContext(applicationContext("qtcreator"))
__closeSubprocessByPushingStop__()
except:
pass
return True
def runAndCloseQtQuickUI():

View File

@@ -23,7 +23,7 @@ def main():
result = addExecutableAsAttachableAUT(projectName, 11223)
allowAppThroughWinFW(workingDir, projectName)
if result:
result = runAndCloseApp(True, projectName, 11223)
result = runAndCloseApp(True, projectName, 11223, "subprocessFunction")
else:
result = runAndCloseApp()
removeExecutableAsAttachableAUT(projectName, 11223)
@@ -35,6 +35,12 @@ def main():
invokeMenuItem("File", "Exit")
def subprocessFunction():
helloWorldText = waitForObject("{container={type='QmlApplicationViewer' visible='1' unnamed='1'} "
"enabled='true' text='Hello World' type='Text' unnamed='1' visible='true'}")
test.log("Clicking 'Hello World' Text to close QmlApplicationViewer")
mouseClick(helloWorldText, 5, 5, 0, Qt.LeftButton)
def cleanup():
global workingDir
# waiting for a clean exit - for a full-remove of the temp directory

View File

@@ -12,10 +12,11 @@ def main():
# using a temporary directory won't mess up an eventually exisiting
workingDir = tempDir()
prepareTemplate(sourceExample)
createNewQtQuickApplication(workingDir, None, templateDir + "/qml/textselection.qml")
projectName = createNewQtQuickApplication(workingDir, None, templateDir + "/qml/textselection.qml")
# wait for parsing to complete
waitForSignal("{type='CppTools::Internal::CppModelManager' unnamed='1'}", "sourceFilesRefreshed(QStringList)", 30000)
test.log("Building project")
result = modifyRunSettingsForHookInto(projectName, 11223)
invokeMenuItem("Build","Build All")
waitForSignal("{type='ProjectExplorer::BuildManager' unnamed='1'}", "buildQueueFinished(bool)", 300000)
if not checkCompile():
@@ -23,10 +24,33 @@ def main():
else:
checkLastBuild()
test.log("Running project (includes build)")
if runAndCloseApp():
if result:
result = addExecutableAsAttachableAUT(projectName, 11223)
allowAppThroughWinFW(workingDir, projectName)
if result:
result = runAndCloseApp(True, projectName, 11223, subprocessFunction)
else:
result = runAndCloseApp()
removeExecutableAsAttachableAUT(projectName, 11223)
deleteAppFromWinFW(workingDir, projectName)
else:
result = runAndCloseApp()
if result:
logApplicationOutput()
invokeMenuItem("File", "Exit")
def subprocessFunction():
textEdit = waitForObject("{container={type='QmlApplicationViewer' unnamed='1' visible='1'} "
"enabled='true' type='TextEdit' unnamed='1' visible='true'}")
test.log("Test dragging")
dragItemBy(textEdit, 30, 30, 50, 50, 0, Qt.LeftButton)
test.log("Test editing")
textEdit.cursorPosition = 0
type(textEdit, "This text is entered by Squish...")
type(textEdit, "<Return>")
test.log("Closing QmlApplicationViewer")
sendEvent("QCloseEvent", "{type='QmlApplicationViewer' unnamed='1' visible='1'}")
def prepareTemplate(sourceExample):
global templateDir
templateDir = tempDir()