Merge remote branch 'origin/2.2'

This commit is contained in:
Oswald Buddenhagen
2011-04-07 10:12:39 +02:00
21 changed files with 375 additions and 219 deletions

View File

@@ -174,26 +174,62 @@
Ubuntu or Debian?} Ubuntu or Debian?}
\code \code
@
sudo apt-get install libglib2.0-dev libSM-dev libxrender-dev libfontconfig1-dev libxext-dev sudo apt-get install libglib2.0-dev libSM-dev libxrender-dev libfontconfig1-dev libxext-dev
@
\endcode \endcode
If you use QtOpenGL, you also need: If you use QtOpenGL, you also need:
\code \code
@
sudo apt-get install libgl-dev libglu-dev sudo apt-get install libgl-dev libglu-dev
@
\endcode \endcode
\section1 Platform Releated Questions \section1 Platform Releated Questions
\bold {Can I develop Qt for Symbian applications with Qt Creator?} \bold {Where is application output shown in Qt Creator?}
Qt Creator comes with support for developing Qt applications that target \bold {On Unix (Linux and Mac OS):} \c qDebug() and related functions use
the Symbian platform. For more information, see the standard output and error output. When you run or debug the
\l{Creating a Mobile Application with Qt SDK}. application, you can view the output in the \gui{Application Output} pane.
For console applications that require input, select \gui {Projects > Run
Settings > Run in terminal}.
\bold {On Windows:} Output is displayed differently for \e{console
applications} and \e{GUI applications}.
The setting \c {CONFIG += console} in the .pro file specifies that the
application is built as a console application using some other runtime.
When you run a console application, you can view the output in the console
window of the calling application. If the
calling application is a GUI application (for example, a release-built
version of Qt Creator), a new console window is opened. For this
type of application, \c qDebug() and related functions use standard output
and error output.
We recommend that you select \gui {Projects > Run Settings > Run in
terminal} for console applications.
For GUI applications, \c qDebug() and related functions use the Windows API
function \c OutputDebugString(). The output is displayed in the
\gui{Application Output} pane. However, only one output pane tab may be
open at a time or the output is not displayed correctly. You can use an
external debug output viewer, such as the
\l{http://technet.microsoft.com/en-us/sysinternals/bb896647}{DebugView for Windows}
to display output from GUI applications.
\bold {On Symbian OS}: \c qDebug() and related functions use the native
\c RDebug::Print functionality.
When you use the Symbian emulator on Windows, the output is redirected to
standard debug output. To view it, you can use a Windows debug output
viewer, such as the DebugView for Windows.
On devices, the \c RDebug output is intercepted by \e CODA or \e {App TRK}
and then propagated to Qt Creator, which displays it in the
\gui {Application Output} pane.
Symbian OS provides no support for differentiating between standard output
and error output.
\section1 Questions about New Features \section1 Questions about New Features

View File

@@ -1024,17 +1024,48 @@
\title Developing Widget Based Applications \title Developing Widget Based Applications
Widgets and forms created with \QD are integrated seamlessly with programmed code, Widgets and forms created with \QD are integrated seamlessly with
using the Qt signals and slots mechanism, that lets you easily assign behavior to programmed code by using the Qt signals and slots mechanism that allows you
to easily assign behavior to
graphical elements. All properties set in \QD can be changed dynamically within the code. graphical elements. All properties set in \QD can be changed dynamically within the code.
Furthermore, features like widget promotion and custom plugins allow you to use your Furthermore, features such as widget promotion and custom plugins allow you to use your
own widgets with \QD. own widgets with \QD. For more information, see
\l{Adding Qt Designer Plugins}.
Qt Creator automatically opens all .ui files in \QD. Qt Creator automatically opens all .ui files in the integrated \QD, in
\gui Design mode.
\image qtcreator-formedit.png \image qtcreator-formedit.png
For more information about \QD, see the
\l{http://doc.qt.nokia.com/4.7/designer-manual.html}{Qt Designer Manual}.
Generally, the integrated \QD contains the same functions as the standalone
\QD. The following sections describe the differences.
\section1 Code Editor Integration
To switch between forms (\gui Design mode) and code (\gui Edit mode),
press \key Shift+F4.
You can use Qt Creator to create stub implementations of slot functions.
In the \gui Design mode, right-click a widget to open a context menu, and
then select \gui {Go to Slot...}. Select a signal in the list to go to an
existing slot function or to create a new slot function.
\section1 Managing Image Resources
In standalone \QD, image resources are created using the built-in
\gui {Resource Editor}. In Qt Creator, .ui files are usually part of a
project, which may contain several resource files (.qrc). They are created
and maintained by using the Qt Creator Resource Editor. The \QD
\gui {Resource Editor} is de-activated and the image resources are
displayed in the \QD \gui {Resource Browser}.
\section1 Specifying Settings for Qt Designer
To change the layout of \QD user interface elements: To change the layout of \QD user interface elements:
\list 1 \list 1
\o Select \gui Tools > \gui{Form Editor} > \gui Views > \o Select \gui Tools > \gui{Form Editor} > \gui Views >
\gui Locked. \gui Locked.
@@ -1044,29 +1075,50 @@
position. position.
\endlist \endlist
To change \QD properties, select \gui Tools > \gui Options... > To specify settings for \QD:
\gui Designer.
\list \list
\o Set the class properties and code generation preferences in \gui
{Class Generation}. \o Select \gui Tools > \gui Options... > \gui Designer.
\o Set an additional folder for saving templates in \gui{Template
Paths}. \o Specify settins for generating classes and code in \gui {Class
\o Set the grid settings and preview preferences in \gui Forms. To Generation}.
preview your form with skins, enable \gui{Print/Preview
Configuration} and select your skin. Otherwise default preview \o Specify embedded device profiles, that determine style, font, and
settings are used. screen resolution, for example, in \gui{Embedded Design}.
\o Specify settings for the grid and previewing forms in \gui Forms.
\o Specify an additional folder for saving templates in \gui{Template
Paths}.
To preview the settings, select \gui Tools > \gui{Form Editor} >
\gui Preview, or press \key Alt+Shift+R.
\o To specify embedded device profiles, such as style, font, and screen
resolution, select \gui{Embedded Design}.
\endlist \endlist
To switch between forms and code, use \key Shift+F4. To preview the settings, select \gui Tools > \gui{Form Editor} >
\gui Preview, or press \key Alt+Shift+R.
For more information on \QD, see \section1 Previewing Forms Using Device Skins
\l{http://doc.qt.nokia.com/4.7/designer-manual.html}{Qt Designer Manual}.
A \e {device skin} is a set of configuration files that describe a mobile
device. It includes a border image that surrounds the form and depicts a
mobile device with its buttons.
To preview your form using device skins:
\list 1
\o Select \gui Tools > \gui Options... > \gui Designer.
\o Select the \gui{Print/Preview Configuration} check box.
\o In the \gui {Device skin} field, select a device skin.
\o When the form is open in \gui Design mode, press \key Alt+Shift+R.
\o To end the preview, right-click the skin and select \gui Close in
the context menu.
\endlist
*/ */
@@ -5212,12 +5264,6 @@
(using the Certified Signed path or the manufacturer-specific channel). (using the Certified Signed path or the manufacturer-specific channel).
For more information, see \l{Deploying Applications to Symbian Devices}. For more information, see \l{Deploying Applications to Symbian Devices}.
\note At the time of writing this document, the distribution of Qt 4.7.x based
applications is supported by neither Ovi Store nor Smart Installer.
For up-to-date information about the packages available for distribution, see the
\l{http://wiki.forum.nokia.com/index.php/Nokia_Smart_Installer_for_Symbian}{Nokia Smart Installer for Symbian}
wiki.
To use the publishing wizard: To use the publishing wizard:
\list 1 \list 1
@@ -8826,13 +8872,6 @@
.qml file in your project. All the other files in the project are automatically added .qml file in your project. All the other files in the project are automatically added
to the application project. to the application project.
For example, you can open and run the
\l {http://doc.qt.nokia.com/4.7/qdeclarativeexamples.html} {QML examples and demos}
to learn how to use various aspects of QML. To run the examples in the QML Viewer
on the desktop, open them in the \gui Welcome mode. To view the examples on
mobile devices, use the \gui {Qt Quick Application} wizard to convert them into
Qt Quick Applications.
To import QML applications: To import QML applications:
\list 1 \list 1

View File

@@ -183,6 +183,28 @@ void Link::populateImportedTypes(TypeEnvironment *typeEnv, Document::Ptr doc)
// explicit imports, whether directories, files or libraries // explicit imports, whether directories, files or libraries
foreach (const ImportInfo &info, doc->bind()->imports()) { foreach (const ImportInfo &info, doc->bind()->imports()) {
ObjectValue *import = d->importCache.value(ImportCacheKey(info)); ObjectValue *import = d->importCache.value(ImportCacheKey(info));
//### Hack: if this document is in a library, and if there is an qmldir file in the same directory, and if the prefix is an import-path, the import means to import everything in this library.
if (info.ast() && info.ast()->fileName && info.ast()->fileName->asString() == QLatin1String(".")) {
const QString importInfoName(info.name());
if (QFileInfo(QDir(importInfoName), QLatin1String("qmldir")).exists()) {
foreach (const QString &importPath, d->importPaths) {
if (importInfoName.startsWith(importPath)) {
// Got it.
const QString cleanPath = QFileInfo(importInfoName).canonicalFilePath();
const QString forcedPackageName = cleanPath.mid(importPath.size() + 1).replace('/', '.').replace('\\', '.');
import = importNonFile(doc, info, forcedPackageName);
if (import)
d->importCache.insert(ImportCacheKey(info), import);
break;
}
}
}
}
//### End of hack.
if (!import) { if (!import) {
switch (info.type()) { switch (info.type()) {
case ImportInfo::FileImport: case ImportInfo::FileImport:
@@ -245,12 +267,12 @@ ObjectValue *Link::importFileOrDirectory(Document::Ptr doc, const ImportInfo &im
import Qt 4.6 as Xxx import Qt 4.6 as Xxx
(import com.nokia.qt is the same as the ones above) (import com.nokia.qt is the same as the ones above)
*/ */
ObjectValue *Link::importNonFile(Document::Ptr doc, const ImportInfo &importInfo) ObjectValue *Link::importNonFile(Document::Ptr doc, const ImportInfo &importInfo, const QString &forcedPackageName)
{ {
Q_D(Link); Q_D(Link);
ObjectValue *import = new ObjectValue(engine()); ObjectValue *import = new ObjectValue(engine());
const QString packageName = Bind::toString(importInfo.ast()->importUri, '.'); const QString packageName = forcedPackageName.isEmpty() ? Bind::toString(importInfo.ast()->importUri, '.') : forcedPackageName;
const ComponentVersion version = importInfo.version(); const ComponentVersion version = importInfo.version();
bool importFound = false; bool importFound = false;
@@ -277,7 +299,7 @@ ObjectValue *Link::importNonFile(Document::Ptr doc, const ImportInfo &importInfo
} }
} }
if (!importFound) { if (!importFound && importInfo.ast()) {
error(doc, locationFromRange(importInfo.ast()->firstSourceLocation(), error(doc, locationFromRange(importInfo.ast()->firstSourceLocation(),
importInfo.ast()->lastSourceLocation()), importInfo.ast()->lastSourceLocation()),
tr("package not found")); tr("package not found"));

View File

@@ -71,7 +71,7 @@ private:
void populateImportedTypes(Interpreter::TypeEnvironment *typeEnv, Document::Ptr doc); void populateImportedTypes(Interpreter::TypeEnvironment *typeEnv, Document::Ptr doc);
Interpreter::ObjectValue *importFileOrDirectory(Document::Ptr doc, const Interpreter::ImportInfo &importInfo); Interpreter::ObjectValue *importFileOrDirectory(Document::Ptr doc, const Interpreter::ImportInfo &importInfo);
Interpreter::ObjectValue *importNonFile(Document::Ptr doc, const Interpreter::ImportInfo &importInfo); Interpreter::ObjectValue *importNonFile(Document::Ptr doc, const Interpreter::ImportInfo &importInfo, const QString &forcedPackageName = QString::null);
void importObject(Bind *bind, const QString &name, Interpreter::ObjectValue *object, NameId *targetNamespace); void importObject(Bind *bind, const QString &name, Interpreter::ObjectValue *object, NameId *targetNamespace);
bool importLibrary(Document::Ptr doc, bool importLibrary(Document::Ptr doc,

View File

@@ -1705,9 +1705,15 @@ QList<MimeType> MimeDatabasePrivate::readUserModifiedMimeTypes()
void MimeDatabasePrivate::writeUserModifiedMimeTypes(const QList<MimeType> &mimeTypes) void MimeDatabasePrivate::writeUserModifiedMimeTypes(const QList<MimeType> &mimeTypes)
{ {
// Keep mime types modified which are already on file. // Keep mime types modified which are already on file, unless they are part of the current set.
QSet<QString> currentMimeTypes;
foreach (const MimeType &mimeType, mimeTypes)
currentMimeTypes.insert(mimeType.type());
const QList<MimeType> &inFileMimeTypes = readUserModifiedMimeTypes();
QList<MimeType> allModifiedMimeTypes = mimeTypes; QList<MimeType> allModifiedMimeTypes = mimeTypes;
allModifiedMimeTypes.append(readUserModifiedMimeTypes()); foreach (const MimeType &mimeType, inFileMimeTypes)
if (!currentMimeTypes.contains(mimeType.type()))
allModifiedMimeTypes.append(mimeType);
if (QFile::exists(kModifiedMimeTypesPath) || QDir().mkpath(kModifiedMimeTypesPath)) { if (QFile::exists(kModifiedMimeTypesPath) || QDir().mkpath(kModifiedMimeTypesPath)) {
QFile file(kModifiedMimeTypesPath + kModifiedMimeTypesFile); QFile file(kModifiedMimeTypesPath + kModifiedMimeTypesFile);

View File

@@ -204,7 +204,7 @@ void MimeTypeSettingsModel::updateKnownPatterns(const QStringList &oldPatterns,
} }
} }
// MimeTypeSettingsPagePrivate // MimeTypeSettingsPrivate
class MimeTypeSettingsPrivate : public QObject class MimeTypeSettingsPrivate : public QObject
{ {
Q_OBJECT Q_OBJECT
@@ -231,6 +231,7 @@ public:
void editMagicHeaderRowData(const int row, const MagicData &data); void editMagicHeaderRowData(const int row, const MagicData &data);
void updateMimeDatabase(); void updateMimeDatabase();
void resetState();
public slots: public slots:
void syncData(const QModelIndex &current, const QModelIndex &previous); void syncData(const QModelIndex &current, const QModelIndex &previous);
@@ -249,6 +250,7 @@ public:
int m_mimeForPatternSync; int m_mimeForPatternSync;
int m_mimeForMagicSync; int m_mimeForMagicSync;
bool m_reset; bool m_reset;
bool m_persist;
QList<int> m_modifiedMimeTypes; QList<int> m_modifiedMimeTypes;
Ui::MimeTypeSettingsPage m_ui; Ui::MimeTypeSettingsPage m_ui;
}; };
@@ -261,6 +263,7 @@ MimeTypeSettingsPrivate::MimeTypeSettingsPrivate()
, m_mimeForPatternSync(-1) , m_mimeForPatternSync(-1)
, m_mimeForMagicSync(-1) , m_mimeForMagicSync(-1)
, m_reset(false) , m_reset(false)
, m_persist(false)
{} {}
MimeTypeSettingsPrivate::~MimeTypeSettingsPrivate() MimeTypeSettingsPrivate::~MimeTypeSettingsPrivate()
@@ -507,22 +510,32 @@ void MimeTypeSettingsPrivate::editMagicHeader()
void MimeTypeSettingsPrivate::updateMimeDatabase() void MimeTypeSettingsPrivate::updateMimeDatabase()
{ {
MimeDatabase *db = ICore::instance()->mimeDatabase(); if (m_modifiedMimeTypes.isEmpty())
return;
// For this case it is a better approach to simply use a list and to remove duplicates // For this case it is a better approach to simply use a list and to remove duplicates
// afterwards than to keep a more complex data structure like a hash table. // afterwards than to keep a more complex data structure like a hash table.
qSort(m_modifiedMimeTypes.begin(), m_modifiedMimeTypes.end()); qSort(m_modifiedMimeTypes.begin(), m_modifiedMimeTypes.end());
m_modifiedMimeTypes.erase(std::unique(m_modifiedMimeTypes.begin(), m_modifiedMimeTypes.end()), m_modifiedMimeTypes.erase(std::unique(m_modifiedMimeTypes.begin(), m_modifiedMimeTypes.end()),
m_modifiedMimeTypes.end()); m_modifiedMimeTypes.end());
if (!m_modifiedMimeTypes.isEmpty()) {
QList<MimeType> allModified; MimeDatabase *db = ICore::instance()->mimeDatabase();
foreach (int index, m_modifiedMimeTypes) { QList<MimeType> allModified;
const MimeType &mimeType = m_model->m_mimeTypes.at(index); foreach (int index, m_modifiedMimeTypes) {
db->setGlobPatterns(mimeType.type(), mimeType.globPatterns()); const MimeType &mimeType = m_model->m_mimeTypes.at(index);
db->setMagicMatchers(mimeType.type(), mimeType.magicMatchers()); db->setGlobPatterns(mimeType.type(), mimeType.globPatterns());
allModified.append(mimeType); db->setMagicMatchers(mimeType.type(), mimeType.magicMatchers());
} allModified.append(mimeType);
db->writeUserModifiedMimeTypes(allModified);
} }
db->writeUserModifiedMimeTypes(allModified);
}
void MimeTypeSettingsPrivate::resetState()
{
clearSyncData();
m_modifiedMimeTypes.clear();
m_reset = false;
m_persist = false;
} }
void MimeTypeSettingsPrivate::resetMimeTypes() void MimeTypeSettingsPrivate::resetMimeTypes()
@@ -581,9 +594,7 @@ QWidget *MimeTypeSettings::createPage(QWidget *parent)
void MimeTypeSettings::apply() void MimeTypeSettings::apply()
{ {
if (m_d->m_reset) { if (!m_d->m_modifiedMimeTypes.isEmpty()) {
ICore::instance()->mimeDatabase()->clearUserModifiedMimeTypes();
} else if (!m_d->m_modifiedMimeTypes.isEmpty()) {
const QModelIndex &modelIndex = const QModelIndex &modelIndex =
m_d->m_ui.mimeTypesTableView->selectionModel()->currentIndex(); m_d->m_ui.mimeTypesTableView->selectionModel()->currentIndex();
if (modelIndex.isValid()) { if (modelIndex.isValid()) {
@@ -592,12 +603,23 @@ void MimeTypeSettings::apply()
if (m_d->m_mimeForMagicSync == modelIndex.row()) if (m_d->m_mimeForMagicSync == modelIndex.row())
m_d->syncMimeMagic(); m_d->syncMimeMagic();
} }
m_d->updateMimeDatabase(); m_d->clearSyncData();
} }
if (!m_d->m_persist)
m_d->m_persist = true;
} }
void MimeTypeSettings::finish() void MimeTypeSettings::finish()
{} {
if (m_d->m_persist) {
if (m_d->m_reset)
ICore::instance()->mimeDatabase()->clearUserModifiedMimeTypes();
else
m_d->updateMimeDatabase();
}
m_d->resetState();
}
} // Internal } // Internal
} // Core } // Core

View File

@@ -21,7 +21,14 @@
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2"> <item row="0" column="0" colspan="2">
<widget class="QTableView" name="mimeTypesTableView"/> <widget class="QTableView" name="mimeTypesTableView">
<property name="showGrid">
<bool>false</bool>
</property>
<property name="gridStyle">
<enum>Qt::NoPen</enum>
</property>
</widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QPushButton" name="resetButton"> <widget class="QPushButton" name="resetButton">
@@ -85,6 +92,12 @@
<height>100</height> <height>100</height>
</size> </size>
</property> </property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="gridStyle">
<enum>Qt::NoPen</enum>
</property>
<column> <column>
<property name="text"> <property name="text">
<string>Magic Header</string> <string>Magic Header</string>

View File

@@ -1661,8 +1661,7 @@ void GdbEngine::handleExecuteContinue(const GdbResponse &response)
return; return;
} }
QByteArray msg = response.data.findChild("msg").data(); QByteArray msg = response.data.findChild("msg").data();
if (msg.startsWith("Cannot find bounds of current function") if (msg.startsWith("Cannot find bounds of current function")) {
|| msg.startsWith("\"finish\" not meaningful in the outermost frame")) {
notifyInferiorRunFailed(); notifyInferiorRunFailed();
if (isDying()) if (isDying())
return; return;
@@ -1671,9 +1670,14 @@ void GdbEngine::handleExecuteContinue(const GdbResponse &response)
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
showStatusMessage(tr("Stopped."), 5000); showStatusMessage(tr("Stopped."), 5000);
reloadStack(true); reloadStack(true);
//showStatusMessage(tr("No debug information available. " } else if (msg.startsWith("\"finish\" not meaningful in the outermost frame")) {
// "Leaving function...")); notifyInferiorRunFailed();
//executeStepOut(); if (isDying())
return;
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
// FIXME: Fix translation in master.
showStatusMessage(QString::fromLocal8Bit(msg), 5000);
gotoLocation(stackHandler()->currentFrame());
} else { } else {
showExecutionError(QString::fromLocal8Bit(msg)); showExecutionError(QString::fromLocal8Bit(msg));
notifyInferiorIll(); notifyInferiorIll();

View File

@@ -83,9 +83,7 @@ FormEditorScene::~FormEditorScene()
void FormEditorScene::setupScene() void FormEditorScene::setupScene()
{ {
m_formLayerItem = new LayerItem(this); m_formLayerItem = new LayerItem(this);
qDebug() << "formLayerItem" << m_formLayerItem.data();
m_manipulatorLayerItem = new LayerItem(this); m_manipulatorLayerItem = new LayerItem(this);
qDebug() << "manipulatorLayerItem" << m_manipulatorLayerItem.data();
m_manipulatorLayerItem->setZValue(1.0); m_manipulatorLayerItem->setZValue(1.0);
m_formLayerItem->setZValue(0.0); m_formLayerItem->setZValue(0.0);
m_formLayerItem->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false); m_formLayerItem->setFlag(QGraphicsItem::ItemClipsChildrenToShape, false);

View File

@@ -81,7 +81,7 @@ void SiblingComboBox::setup()
//We currently have no instanceChildren(). //We currently have no instanceChildren().
//So we double check here if the instanceParents are equal. //So we double check here if the instanceParents are equal.
foreach (const QmlItemNode &node, m_itemList) foreach (const QmlItemNode &node, m_itemList)
if (node.instanceParent().modelNode() != m_itemNode.instanceParent().modelNode()) if (node.isValid() && (node.instanceParent().modelNode() != m_itemNode.instanceParent().modelNode()))
m_itemList.removeAll(node); m_itemList.removeAll(node);
disconnect(this, SIGNAL(currentIndexChanged (int)), this, SLOT(changeSelection(int))); disconnect(this, SIGNAL(currentIndexChanged (int)), this, SLOT(changeSelection(int)));

View File

@@ -67,7 +67,7 @@ void NodeAbstractProperty::reparentHere(const ModelNode &modelNode)
if (internalNode()->hasProperty(name()) && !internalNode()->property(name())->isNodeAbstractProperty()) if (internalNode()->hasProperty(name()) && !internalNode()->property(name())->isNodeAbstractProperty())
reparentHere(modelNode, isNodeListProperty()); reparentHere(modelNode, isNodeListProperty());
else else
reparentHere(modelNode, parentModelNode().metaInfo().propertyIsListProperty(name())); //we could use the metasystem instead? reparentHere(modelNode, parentModelNode().metaInfo().propertyIsListProperty(name()) || isDefaultProperty()); //we could use the metasystem instead?
} }
void NodeAbstractProperty::reparentHere(const ModelNode &modelNode, bool isNodeList) void NodeAbstractProperty::reparentHere(const ModelNode &modelNode, bool isNodeList)

View File

@@ -292,7 +292,7 @@ NodeInstance QmlModelView::instanceForModelNode(const ModelNode &modelNode)
bool QmlModelView::hasInstanceForModelNode(const ModelNode &modelNode) bool QmlModelView::hasInstanceForModelNode(const ModelNode &modelNode)
{ {
return nodeInstanceView()->hasInstanceForNode(modelNode); return nodeInstanceView() && nodeInstanceView()->hasInstanceForNode(modelNode);
} }
void QmlModelView::modelAttached(Model *model) void QmlModelView::modelAttached(Model *model)

View File

@@ -155,7 +155,7 @@ QList<QToolButton *> ItemLibrarySideBarItem::createToolBarWidgets()
void DocumentWarningWidget::goToError() void DocumentWarningWidget::goToError()
{ {
m_designModeWidget->textEditor()->gotoLine(m_error.line(), m_error.column()); m_designModeWidget->textEditor()->gotoLine(m_error.line(), m_error.column() - 1);
Core::ModeManager::instance()->activateMode(Core::Constants::MODE_EDIT); Core::ModeManager::instance()->activateMode(Core::Constants::MODE_EDIT);
} }

View File

@@ -336,7 +336,7 @@ bool QMakeStep::isQmlDebuggingLibrarySupported(QString *reason) const
return false; return false;
} }
if (qt4BuildConfiguration()->qtVersion()->qtVersion() < QtVersionNumber(4, 7 ,0)) { if (qt4BuildConfiguration()->qtVersion()->qtVersion() < QtVersionNumber(4, 7, 1)) {
if (reason) if (reason)
*reason = tr("Requires Qt 4.7.1 or newer."); *reason = tr("Requires Qt 4.7.1 or newer.");
return false; return false;
@@ -449,6 +449,7 @@ void QMakeStepConfigWidget::qtVersionChanged()
{ {
updateSummaryLabel(); updateSummaryLabel();
updateEffectiveQMakeCall(); updateEffectiveQMakeCall();
updateQmlDebuggingWarningsLabel();
} }
void QMakeStepConfigWidget::qmakeBuildConfigChanged() void QMakeStepConfigWidget::qmakeBuildConfigChanged()

View File

@@ -322,11 +322,13 @@ void S60DeployStep::stop()
void S60DeployStep::setupConnections() void S60DeployStep::setupConnections()
{ {
if (m_channel == S60DeployConfiguration::CommunicationTrkSerialConnection) { if (m_channel == S60DeployConfiguration::CommunicationTrkSerialConnection
|| m_channel == S60DeployConfiguration::CommunicationCodaSerialConnection)
connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(deviceRemoved(SymbianUtils::SymbianDevice)), connect(SymbianUtils::SymbianDeviceManager::instance(), SIGNAL(deviceRemoved(SymbianUtils::SymbianDevice)),
this, SLOT(deviceRemoved(SymbianUtils::SymbianDevice))); this, SLOT(deviceRemoved(SymbianUtils::SymbianDevice)));
connect(m_launcher, SIGNAL(finished()), this, SLOT(launcherFinished()));
if (m_channel == S60DeployConfiguration::CommunicationTrkSerialConnection) {
connect(m_launcher, SIGNAL(finished()), this, SLOT(launcherFinished()));
connect(m_launcher, SIGNAL(canNotConnect(QString)), this, SLOT(connectFailed(QString))); connect(m_launcher, SIGNAL(canNotConnect(QString)), this, SLOT(connectFailed(QString)));
connect(m_launcher, SIGNAL(copyingStarted(QString)), this, SLOT(printCopyingNotice(QString))); connect(m_launcher, SIGNAL(copyingStarted(QString)), this, SLOT(printCopyingNotice(QString)));
connect(m_launcher, SIGNAL(canNotCreateFile(QString,QString)), this, SLOT(createFileFailed(QString,QString))); connect(m_launcher, SIGNAL(canNotCreateFile(QString,QString)), this, SLOT(createFileFailed(QString,QString)));

View File

@@ -34,6 +34,12 @@
<property name="selectionBehavior"> <property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum> <enum>QAbstractItemView::SelectRows</enum>
</property> </property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="gridStyle">
<enum>Qt::NoPen</enum>
</property>
<property name="columnCount"> <property name="columnCount">
<number>3</number> <number>3</number>
</property> </property>

View File

@@ -50,6 +50,12 @@
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed</set> <set>QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed</set>
</property> </property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="gridStyle">
<enum>Qt::NoPen</enum>
</property>
</widget> </widget>
</item> </item>
<item> <item>

View File

@@ -909,7 +909,8 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProBlock(
case TokCondition: case TokCondition:
if (!m_skipLevel && okey != or_op) { if (!m_skipLevel && okey != or_op) {
if (curr.size() != 1) { if (curr.size() != 1) {
evalError(fL1S("Conditional must expand to exactly one word.")); if (!m_cumulative || !curr.isEmpty())
evalError(fL1S("Conditional must expand to exactly one word."));
okey = false; okey = false;
} else { } else {
okey = isActiveConfig(curr.at(0).toQString(m_tmp2), true) ^ invert; okey = isActiveConfig(curr.at(0).toQString(m_tmp2), true) ^ invert;
@@ -922,7 +923,8 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProBlock(
case TokTestCall: case TokTestCall:
if (!m_skipLevel && okey != or_op) { if (!m_skipLevel && okey != or_op) {
if (curr.size() != 1) { if (curr.size() != 1) {
evalError(fL1S("Test name must expand to exactly one word.")); if (!m_cumulative || !curr.isEmpty())
evalError(fL1S("Test name must expand to exactly one word."));
skipExpression(tokPtr); skipExpression(tokPtr);
okey = false; okey = false;
} else { } else {
@@ -1067,7 +1069,8 @@ void ProFileEvaluator::Private::visitProVariable(
if (curr.size() != 1) { if (curr.size() != 1) {
skipExpression(tokPtr); skipExpression(tokPtr);
evalError(fL1S("Left hand side of assignment must expand to exactly one word.")); if (!m_cumulative || !curr.isEmpty())
evalError(fL1S("Left hand side of assignment must expand to exactly one word."));
return; return;
} }
const ProString &varName = map(curr.first()); const ProString &varName = map(curr.first());

View File

@@ -115,13 +115,7 @@ void ProFileParser::initialize()
} }
ProFileParser::ProFileParser(ProFileCache *cache, ProFileParserHandler *handler) ProFileParser::ProFileParser(ProFileCache *cache, ProFileParserHandler *handler)
: m_lineNo(0) : m_cache(cache)
, m_state(StNew)
, m_markLine(0)
, m_canElse(false)
, m_invert(false)
, m_operator(NoOperator)
, m_cache(cache)
, m_handler(handler) , m_handler(handler)
{ {
// So that single-threaded apps don't have to call initialize() for now. // So that single-threaded apps don't have to call initialize() for now.
@@ -241,7 +235,7 @@ void ProFileParser::finalizeHashStr(ushort *buf, uint len)
bool ProFileParser::read(ProFile *pro, const QString &in) bool ProFileParser::read(ProFile *pro, const QString &in)
{ {
m_fileName = pro->fileName(); m_proFile = pro;
m_lineNo = 1; m_lineNo = 1;
// Final precompiled token stream buffer // Final precompiled token stream buffer
@@ -275,7 +269,7 @@ bool ProFileParser::read(ProFile *pro, const QString &in)
// Expression precompiler buffer. // Expression precompiler buffer.
QString xprBuff; QString xprBuff;
xprBuff.reserve(tokBuff.capacity()); // Excessive, but simple xprBuff.reserve(tokBuff.capacity()); // Excessive, but simple
ushort *buf = (ushort *)xprBuff.constData(); ushort * const buf = (ushort *)xprBuff.constData();
// Parser state // Parser state
m_blockstack.clear(); m_blockstack.clear();
@@ -292,15 +286,14 @@ bool ProFileParser::read(ProFile *pro, const QString &in)
m_invert = false; m_invert = false;
m_operator = NoOperator; m_operator = NoOperator;
m_markLine = m_lineNo; m_markLine = m_lineNo;
m_inError = false;
Context context = CtxTest; Context context = CtxTest;
int parens = 0; // Braces in value context int parens = 0; // Braces in value context
int argc = 0; int argc = 0;
int litCount = 0; int wordCount = 0; // Number of words in currently accumulated expression
int expCount = 0;
bool inError = false;
bool putSpace = false; // Only ever true inside quoted string bool putSpace = false; // Only ever true inside quoted string
bool lineMarked = true; // For in-expression markers bool lineMarked = true; // For in-expression markers
ushort needSep = 0; // Complementary to putSpace: separator outside quotes ushort needSep = TokNewStr; // Complementary to putSpace: separator outside quotes
ushort quote = 0; ushort quote = 0;
ushort term = 0; ushort term = 0;
@@ -308,44 +301,53 @@ bool ProFileParser::read(ProFile *pro, const QString &in)
ptr += 4; ptr += 4;
ushort *xprPtr = ptr; ushort *xprPtr = ptr;
ushort *oldTokPtr = tokPtr; #define FLUSH_LHS_LITERAL() \
#define FLUSH_LHS_LITERAL(setSep) \
do { \ do { \
if ((tlen = ptr - xprPtr)) { \ if ((tlen = ptr - xprPtr)) { \
if (needSep) \
goto extraChars; \
finalizeHashStr(xprPtr, tlen); \ finalizeHashStr(xprPtr, tlen); \
if (setSep) \ if (needSep) { \
needSep = TokNewStr; \ wordCount++; \
needSep = 0; \
} \
} else { \ } else { \
ptr -= 4; \ ptr -= 4; \
if (setSep && ptr != buf) \
needSep = TokNewStr; \
} \ } \
} while (0) } while (0)
#define FLUSH_RHS_LITERAL(setSep) \ #define FLUSH_RHS_LITERAL() \
do { \ do { \
if ((tlen = ptr - xprPtr)) { \ if ((tlen = ptr - xprPtr)) { \
xprPtr[-2] = TokLiteral | needSep; \ xprPtr[-2] = TokLiteral | needSep; \
xprPtr[-1] = tlen; \ xprPtr[-1] = tlen; \
if (setSep) \ if (needSep) { \
needSep = TokNewStr; \ wordCount++; \
litCount++; \ needSep = 0; \
} \
} else { \ } else { \
ptr -= 2; \ ptr -= 2; \
if (setSep && ptr != ((context == CtxValue) ? tokPtr : buf)) \
needSep = TokNewStr; \
} \ } \
} while (0) } while (0)
#define FLUSH_LITERAL(setSep) \ #define FLUSH_LITERAL() \
do { \ do { \
if (context == CtxTest) \ if (context == CtxTest) \
FLUSH_LHS_LITERAL(setSep); \ FLUSH_LHS_LITERAL(); \
else \ else \
FLUSH_RHS_LITERAL(setSep); \ FLUSH_RHS_LITERAL(); \
} while (0)
#define FLUSH_VALUE_LIST() \
do { \
if (wordCount > 1) { \
xprPtr = tokPtr; \
if (*xprPtr == TokLine) \
xprPtr += 2; \
tokPtr[-1] = ((*xprPtr & TokMask) == TokLiteral) ? wordCount : 0; \
} else { \
tokPtr[-1] = 0; \
} \
tokPtr = ptr; \
putTok(tokPtr, TokValueTerminator); \
} while (0) } while (0)
forever { forever {
@@ -356,14 +358,9 @@ bool ProFileParser::read(ProFile *pro, const QString &in)
c = *cur; c = *cur;
if (c == '\n') { if (c == '\n') {
++cur; ++cur;
if (!inError) goto flushLine;
goto flushLine;
++m_lineNo;
goto freshLine;
} else if (!c) { } else if (!c) {
if (!inError) goto flushLine;
goto flushLine;
goto flushFile;
} else if (c != ' ' && c != '\t' && c != '\r') { } else if (c != ' ' && c != '\t' && c != '\r') {
break; break;
} }
@@ -417,11 +414,10 @@ bool ProFileParser::read(ProFile *pro, const QString &in)
--end; --end;
} }
if (!inError) {
// Finally, do the tokenization // Finally, do the tokenization
ushort tok, rtok; ushort tok, rtok;
int tlen; int tlen;
newToken: newWord:
do { do {
if (cur == end) if (cur == end)
goto lineEnd; goto lineEnd;
@@ -435,27 +431,7 @@ bool ProFileParser::read(ProFile *pro, const QString &in)
putSpace = false; putSpace = false;
*ptr++ = ' '; *ptr++ = ' ';
} }
tlen = ptr - xprPtr; FLUSH_LITERAL();
if (context == CtxTest) {
if (needSep) {
extraChars:
parseError(fL1S("Extra characters after test expression."));
goto parseErr;
}
if (tlen)
finalizeHashStr(xprPtr, tlen);
else
ptr -= 4;
} else {
if (tlen) {
xprPtr[-2] = TokLiteral | needSep;
xprPtr[-1] = tlen;
needSep = 0;
litCount++;
} else {
ptr -= 2;
}
}
if (!lineMarked) { if (!lineMarked) {
lineMarked = true; lineMarked = true;
*ptr++ = TokLine; *ptr++ = TokLine;
@@ -499,9 +475,10 @@ bool ProFileParser::read(ProFile *pro, const QString &in)
notfunc: notfunc:
if (quote) if (quote)
tok |= TokQuoted; tok |= TokQuoted;
tok |= needSep; if (needSep) {
needSep = 0; tok |= needSep;
expCount++; wordCount++;
}
tlen = ptr - xprPtr; tlen = ptr - xprPtr;
if (rtok == TokVariable) { if (rtok == TokVariable) {
xprPtr[-4] = tok; xprPtr[-4] = tok;
@@ -523,8 +500,7 @@ bool ProFileParser::read(ProFile *pro, const QString &in)
top.terminator = term; top.terminator = term;
top.context = context; top.context = context;
top.argc = argc; top.argc = argc;
top.litCount = litCount; top.wordCount = wordCount;
top.expCount = expCount;
} }
parens = 0; parens = 0;
quote = 0; quote = 0;
@@ -532,9 +508,12 @@ bool ProFileParser::read(ProFile *pro, const QString &in)
argc = 1; argc = 1;
context = CtxArgs; context = CtxArgs;
nextToken: nextToken:
wordCount = 0;
nextWord:
ptr += (context == CtxTest) ? 4 : 2; ptr += (context == CtxTest) ? 4 : 2;
xprPtr = ptr; xprPtr = ptr;
goto newToken; needSep = TokNewStr;
goto newWord;
} }
if (term) { if (term) {
cur++; cur++;
@@ -543,17 +522,17 @@ bool ProFileParser::read(ProFile *pro, const QString &in)
parseError(fL1S("Missing %1 terminator [found %2]") parseError(fL1S("Missing %1 terminator [found %2]")
.arg(QChar(term)) .arg(QChar(term))
.arg(c ? QString(c) : QString::fromLatin1("end-of-line"))); .arg(c ? QString(c) : QString::fromLatin1("end-of-line")));
parseErr:
pro->setOk(false); pro->setOk(false);
xprStack.resize(0); m_inError = true;
tokPtr = oldTokPtr; if (c)
inError = true; cur--;
goto skip; // Just parse on, as if there was a terminator ...
} }
} }
joinToken: joinToken:
ptr += (context == CtxTest) ? 4 : 2; ptr += (context == CtxTest) ? 4 : 2;
xprPtr = ptr; xprPtr = ptr;
needSep = 0;
goto nextChr; goto nextChr;
} }
} else if (c == '\\' && cur != end) { } else if (c == '\\' && cur != end) {
@@ -582,15 +561,15 @@ bool ProFileParser::read(ProFile *pro, const QString &in)
quote = c; quote = c;
goto nextChr; goto nextChr;
} else if (c == ' ' || c == '\t') { } else if (c == ' ' || c == '\t') {
FLUSH_LITERAL(true); FLUSH_LITERAL();
goto nextToken; goto nextWord;
} else if (context == CtxArgs) { } else if (context == CtxArgs) {
// Function arg context // Function arg context
if (c == '(') { if (c == '(') {
++parens; ++parens;
} else if (c == ')') { } else if (c == ')') {
if (--parens < 0) { if (--parens < 0) {
FLUSH_RHS_LITERAL(false); FLUSH_RHS_LITERAL();
*ptr++ = TokFuncTerminator; *ptr++ = TokFuncTerminator;
int theargc = argc; int theargc = argc;
{ {
@@ -600,74 +579,71 @@ bool ProFileParser::read(ProFile *pro, const QString &in)
term = top.terminator; term = top.terminator;
context = top.context; context = top.context;
argc = top.argc; argc = top.argc;
litCount = top.litCount; wordCount = top.wordCount;
expCount = top.expCount;
xprStack.resize(xprStack.size() - 1); xprStack.resize(xprStack.size() - 1);
} }
if (term == ':') { if (term == ':') {
finalizeCall(tokPtr, buf, ptr, theargc); finalizeCall(tokPtr, buf, ptr, theargc);
needSep = TokNewStr;
goto nextItem; goto nextItem;
} else if (term == '}') { } else if (term == '}') {
c = (cur == end) ? 0 : *cur++; c = (cur == end) ? 0 : *cur++;
needSep = 0;
goto checkTerm; goto checkTerm;
} else { } else {
Q_ASSERT(!term); Q_ASSERT(!term);
needSep = 0;
goto joinToken; goto joinToken;
} }
} }
} else if (!parens && c == ',') { } else if (!parens && c == ',') {
FLUSH_RHS_LITERAL(false); FLUSH_RHS_LITERAL();
*ptr++ = TokArgSeparator; *ptr++ = TokArgSeparator;
argc++; argc++;
needSep = 0;
goto nextToken; goto nextToken;
} }
} else if (context == CtxTest) { } else if (context == CtxTest) {
// Test or LHS context // Test or LHS context
if (c == '(') { if (c == '(') {
FLUSH_LHS_LITERAL(false); FLUSH_LHS_LITERAL();
if (ptr == buf) { if (wordCount != 1) {
parseError(fL1S("Opening parenthesis without prior test name.")); if (wordCount)
goto parseErr; parseError(fL1S("Extra characters after test expression."));
else
parseError(fL1S("Opening parenthesis without prior test name."));
pro->setOk(false);
ptr = buf; // Put empty function name
} }
*ptr++ = TokTestCall; *ptr++ = TokTestCall;
term = ':'; term = ':';
needSep = 0;
goto funcCall; goto funcCall;
} else if (c == '!' && ptr == xprPtr) { } else if (c == '!' && ptr == xprPtr) {
m_invert ^= true; m_invert ^= true;
goto nextChr; goto nextChr;
} else if (c == ':') { } else if (c == ':') {
FLUSH_LHS_LITERAL(false); FLUSH_LHS_LITERAL();
finalizeCond(tokPtr, buf, ptr); finalizeCond(tokPtr, buf, ptr, wordCount);
if (m_state == StNew) if (m_state == StNew)
parseError(fL1S("And operator without prior condition.")); parseError(fL1S("And operator without prior condition."));
else else
m_operator = AndOperator; m_operator = AndOperator;
nextItem: nextItem:
ptr = buf; ptr = buf;
needSep = 0;
goto nextToken; goto nextToken;
} else if (c == '|') { } else if (c == '|') {
FLUSH_LHS_LITERAL(false); FLUSH_LHS_LITERAL();
finalizeCond(tokPtr, buf, ptr); finalizeCond(tokPtr, buf, ptr, wordCount);
if (m_state != StCond) if (m_state != StCond)
parseError(fL1S("Or operator without prior condition.")); parseError(fL1S("Or operator without prior condition."));
else else
m_operator = OrOperator; m_operator = OrOperator;
goto nextItem; goto nextItem;
} else if (c == '{') { } else if (c == '{') {
FLUSH_LHS_LITERAL(false); FLUSH_LHS_LITERAL();
finalizeCond(tokPtr, buf, ptr); finalizeCond(tokPtr, buf, ptr, wordCount);
flushCond(tokPtr); flushCond(tokPtr);
++m_blockstack.top().braceLevel; ++m_blockstack.top().braceLevel;
goto nextItem; goto nextItem;
} else if (c == '}') { } else if (c == '}') {
FLUSH_LHS_LITERAL(false); FLUSH_LHS_LITERAL();
finalizeCond(tokPtr, buf, ptr); finalizeCond(tokPtr, buf, ptr, wordCount);
flushScopes(tokPtr); flushScopes(tokPtr);
closeScope: closeScope:
if (!m_blockstack.top().braceLevel) { if (!m_blockstack.top().braceLevel) {
@@ -699,19 +675,19 @@ bool ProFileParser::read(ProFile *pro, const QString &in)
} else if (c == '=') { } else if (c == '=') {
tok = TokAssign; tok = TokAssign;
doOp: doOp:
FLUSH_LHS_LITERAL(false); FLUSH_LHS_LITERAL();
flushCond(tokPtr); flushCond(tokPtr);
putLineMarker(tokPtr); putLineMarker(tokPtr);
if (!(tlen = ptr - buf)) { if (wordCount != 1) {
parseError(fL1S("Assignment operator without prior variable name.")); parseError(fL1S("Assignment needs exactly one word on the left hand side."));
goto parseErr; pro->setOk(false);
// Put empty variable name.
} else {
putBlock(tokPtr, buf, ptr - buf);
} }
putBlock(tokPtr, buf, tlen);
putTok(tokPtr, tok); putTok(tokPtr, tok);
context = CtxValue; context = CtxValue;
ptr = ++tokPtr; ptr = ++tokPtr;
litCount = expCount = 0;
needSep = 0;
goto nextToken; goto nextToken;
} }
} else { // context == CtxValue } else { // context == CtxValue
@@ -719,10 +695,8 @@ bool ProFileParser::read(ProFile *pro, const QString &in)
++parens; ++parens;
} else if (c == '}') { } else if (c == '}') {
if (!parens) { if (!parens) {
FLUSH_RHS_LITERAL(false); FLUSH_RHS_LITERAL();
tokPtr[-1] = litCount ? litCount + expCount : 0; FLUSH_VALUE_LIST();
tokPtr = ptr;
putTok(tokPtr, TokValueTerminator);
context = CtxTest; context = CtxTest;
goto closeScope; goto closeScope;
} }
@@ -745,7 +719,8 @@ bool ProFileParser::read(ProFile *pro, const QString &in)
if (quote) { if (quote) {
putSpace = true; putSpace = true;
} else { } else {
FLUSH_LITERAL(true); FLUSH_LITERAL();
needSep = TokNewStr;
ptr += (context == CtxTest) ? 4 : 2; ptr += (context == CtxTest) ? 4 : 2;
xprPtr = ptr; xprPtr = ptr;
} }
@@ -753,29 +728,37 @@ bool ProFileParser::read(ProFile *pro, const QString &in)
c = '\n'; c = '\n';
cur = cptr; cur = cptr;
flushLine: flushLine:
FLUSH_LITERAL(false); FLUSH_LITERAL();
if (quote) { if (quote) {
parseError(fL1S("Missing closing %1 quote").arg(QChar(quote))); parseError(fL1S("Missing closing %1 quote").arg(QChar(quote)));
goto parseErr; if (!xprStack.isEmpty()) {
} context = xprStack.at(0).context;
if (!xprStack.isEmpty()) { xprStack.clear();
}
goto flErr;
} else if (!xprStack.isEmpty()) {
parseError(fL1S("Missing closing parenthesis in function call")); parseError(fL1S("Missing closing parenthesis in function call"));
goto parseErr; context = xprStack.at(0).context;
} xprStack.clear();
if (context == CtxValue) { flErr:
tokPtr[-1] = litCount ? litCount + expCount : 0; pro->setOk(false);
tokPtr = ptr; if (context == CtxValue) {
putTok(tokPtr, TokValueTerminator); tokPtr[-1] = 0; // sizehint
putTok(tokPtr, TokValueTerminator);
} else {
bogusTest(tokPtr);
}
} else if (context == CtxValue) {
FLUSH_VALUE_LIST();
} else { } else {
finalizeCond(tokPtr, buf, ptr); finalizeCond(tokPtr, buf, ptr, wordCount);
} }
if (!c) if (!c)
break; break;
++m_lineNo; ++m_lineNo;
goto freshLine; goto freshLine;
} }
} // !inError
skip:
if (!lineCont) { if (!lineCont) {
cur = cptr; cur = cptr;
++m_lineNo; ++m_lineNo;
@@ -787,7 +770,6 @@ bool ProFileParser::read(ProFile *pro, const QString &in)
++m_lineNo; ++m_lineNo;
} }
flushFile:
flushScopes(tokPtr); flushScopes(tokPtr);
if (m_blockstack.size() > 1) { if (m_blockstack.size() > 1) {
parseError(fL1S("Missing closing brace(s).")); parseError(fL1S("Missing closing brace(s)."));
@@ -799,6 +781,7 @@ bool ProFileParser::read(ProFile *pro, const QString &in)
*pro->itemsRef() = QString(tokBuff.constData(), tokPtr - (ushort *)tokBuff.constData()); *pro->itemsRef() = QString(tokBuff.constData(), tokPtr - (ushort *)tokBuff.constData());
return true; return true;
#undef FLUSH_VALUE_LIST
#undef FLUSH_LITERAL #undef FLUSH_LITERAL
#undef FLUSH_LHS_LITERAL #undef FLUSH_LHS_LITERAL
#undef FLUSH_RHS_LITERAL #undef FLUSH_RHS_LITERAL
@@ -883,10 +866,25 @@ void ProFileParser::finalizeTest(ushort *&tokPtr)
m_canElse = true; m_canElse = true;
} }
void ProFileParser::finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr) void ProFileParser::bogusTest(ushort *&tokPtr)
{ {
if (ptr == uc) flushScopes(tokPtr);
m_operator = NoOperator;
m_invert = false;
m_state = StCond;
m_canElse = true;
m_proFile->setOk(false);
}
void ProFileParser::finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount)
{
if (wordCount != 1) {
if (wordCount) {
parseError(fL1S("Extra characters after test expression."));
bogusTest(tokPtr);
}
return; return;
}
// Check for magic tokens // Check for magic tokens
if (*uc == TokHashLiteral) { if (*uc == TokHashLiteral) {
@@ -950,7 +948,7 @@ void ProFileParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int a
parseError(fL1S("Unexpected operator in front of for().")); parseError(fL1S("Unexpected operator in front of for()."));
return; return;
} }
if (*uce == TokLiteral) { if (*uce == (TokLiteral|TokNewStr)) {
nlen = uce[1]; nlen = uce[1];
uc = uce + 2 + nlen; uc = uce + 2 + nlen;
if (*uc == TokFuncTerminator) { if (*uc == TokFuncTerminator) {
@@ -998,7 +996,7 @@ void ProFileParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int a
parseError(fL1S("Unexpected operator in front of function definition.")); parseError(fL1S("Unexpected operator in front of function definition."));
return; return;
} }
if (*uce == TokLiteral) { if (*uce == (TokLiteral|TokNewStr)) {
uint nlen = uce[1]; uint nlen = uce[1];
if (uce[nlen + 2] == TokFuncTerminator) { if (uce[nlen + 2] == TokFuncTerminator) {
if (m_operator != NoOperator) { if (m_operator != NoOperator) {
@@ -1024,8 +1022,8 @@ void ProFileParser::finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int a
void ProFileParser::parseError(const QString &msg) const void ProFileParser::parseError(const QString &msg) const
{ {
if (m_handler) if (!m_inError && m_handler)
m_handler->parseError(m_fileName, m_lineNo, msg); m_handler->parseError(m_proFile->fileName(), m_lineNo, msg);
} }
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@@ -81,9 +81,7 @@ public:
private: private:
struct BlockScope { struct BlockScope {
BlockScope() : start(0), braceLevel(0), special(false), inBranch(false) {} BlockScope() : start(0), braceLevel(0), special(false), inBranch(false) {}
BlockScope(BlockScope &other) : BlockScope(const BlockScope &other) { *this = other; }
start(other.start), braceLevel(other.braceLevel),
special(other.special), inBranch(other.inBranch) {}
ushort *start; // Where this block started; store length here ushort *start; // Where this block started; store length here
int braceLevel; // Nesting of braces in scope int braceLevel; // Nesting of braces in scope
bool special; // Single-line conditionals inside loops, etc. cannot have else branches bool special; // Single-line conditionals inside loops, etc. cannot have else branches
@@ -100,8 +98,7 @@ private:
struct ParseCtx { struct ParseCtx {
int parens; // Nesting of non-functional parentheses int parens; // Nesting of non-functional parentheses
int argc; // Number of arguments in current function call int argc; // Number of arguments in current function call
int litCount; // Number of literals in current expression int wordCount; // Number of words in current expression
int expCount; // Number of expansions in current expression
Context context; Context context;
ushort quote; // Enclosing quote type ushort quote; // Enclosing quote type
ushort terminator; // '}' if replace function call is braced, ':' if test function ushort terminator; // '}' if replace function call is braced, ':' if test function
@@ -116,9 +113,10 @@ private:
void putHashStr(ushort *&pTokPtr, const ushort *buf, uint len); void putHashStr(ushort *&pTokPtr, const ushort *buf, uint len);
void finalizeHashStr(ushort *buf, uint len); void finalizeHashStr(ushort *buf, uint len);
void putLineMarker(ushort *&tokPtr); void putLineMarker(ushort *&tokPtr);
void finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr); void finalizeCond(ushort *&tokPtr, ushort *uc, ushort *ptr, int wordCount);
void finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int argc); void finalizeCall(ushort *&tokPtr, ushort *uc, ushort *ptr, int argc);
void finalizeTest(ushort *&tokPtr); void finalizeTest(ushort *&tokPtr);
void bogusTest(ushort *&tokPtr);
void enterScope(ushort *&tokPtr, bool special, ScopeState state); void enterScope(ushort *&tokPtr, bool special, ScopeState state);
void leaveScope(ushort *&tokPtr); void leaveScope(ushort *&tokPtr);
void flushCond(ushort *&tokPtr); void flushCond(ushort *&tokPtr);
@@ -127,12 +125,13 @@ private:
void parseError(const QString &msg) const; void parseError(const QString &msg) const;
// Current location // Current location
QString m_fileName; ProFile *m_proFile;
int m_lineNo; int m_lineNo;
QStack<BlockScope> m_blockstack; QStack<BlockScope> m_blockstack;
ScopeState m_state; ScopeState m_state;
int m_markLine; // Put marker for this line int m_markLine; // Put marker for this line
bool m_inError; // Current line had a parsing error; suppress followup error messages
bool m_canElse; // Conditionals met on previous line, but no scope was opened bool m_canElse; // Conditionals met on previous line, but no scope was opened
bool m_invert; // Pending conditional is negated bool m_invert; // Pending conditional is negated
enum { NoOperator, AndOperator, OrOperator } m_operator; // Pending conditional is ORed/ANDed enum { NoOperator, AndOperator, OrOperator } m_operator; // Pending conditional is ORed/ANDed

View File

@@ -169,6 +169,7 @@ int main(int argc, char **argv)
} props[] = { } props[] = {
{ "QT_INSTALL_DATA", QLibraryInfo::DataPath }, { "QT_INSTALL_DATA", QLibraryInfo::DataPath },
{ "QT_INSTALL_LIBS", QLibraryInfo::LibrariesPath }, { "QT_INSTALL_LIBS", QLibraryInfo::LibrariesPath },
{ "QT_INSTALL_IMPORTS", QLibraryInfo::ImportsPath },
{ "QT_INSTALL_HEADERS", QLibraryInfo::HeadersPath }, { "QT_INSTALL_HEADERS", QLibraryInfo::HeadersPath },
{ "QT_INSTALL_DEMOS", QLibraryInfo::DemosPath }, { "QT_INSTALL_DEMOS", QLibraryInfo::DemosPath },
{ "QT_INSTALL_EXAMPLES", QLibraryInfo::ExamplesPath }, { "QT_INSTALL_EXAMPLES", QLibraryInfo::ExamplesPath },