Merge remote-tracking branch 'origin/2.8'

Conflicts:
	qtcreator.pri
	qtcreator.qbs
	src/libs/extensionsystem/pluginmanager.cpp
	src/plugins/coreplugin/documentmanager.cpp
	src/plugins/fakevim/fakevimhandler.cpp

Change-Id: Ibc2adc40bad6f10df94c50d66e78dc3f4bcb84c0
This commit is contained in:
Eike Ziller
2013-06-05 14:19:43 +02:00
343 changed files with 5210 additions and 9384 deletions

7
dist/changes-2.8.0 vendored
View File

@@ -90,17 +90,14 @@ C++ Support
source (QTCREATORBUG-516) source (QTCREATORBUG-516)
* Added refactoring action that assigns a function return value or new expression * Added refactoring action that assigns a function return value or new expression
to local variable (QTCREATORBUG-9052) to local variable (QTCREATORBUG-9052)
* Added refactoring action that adds implementations for pure virtual methods * Added refactoring action that adds implementations for virtual methods
* Fixed parsing of try-catch in constructor initializer (QTCREATORBUG-9064) * Fixed parsing of try-catch in constructor initializer (QTCREATORBUG-9064)
* Fixed handling of non-arguments in function parameter scope (QTCREATORBUG-8316) * Fixed handling of non-arguments in function parameter scope (QTCREATORBUG-8316)
* Fixed crash when adding include for undefined identifier in file that * Fixed crash when adding include for undefined identifier in file that
has no other include (QTCREATORBUG-8799) has no other include (QTCREATORBUG-8799)
* Fixed that system headers were not reparsed when project configuration
changes (QTCREATORBUG-9056)
* Fixed highlighting for template parameters for function calls * Fixed highlighting for template parameters for function calls
* Improved support for anonymous classes * Improved support for anonymous classes
(QTCREATORBUG-6497, QTCREATORBUG-8963, QTCREATORBUG-3610, QTCREATORBUG-7579) (QTCREATORBUG-6497, QTCREATORBUG-8963, QTCREATORBUG-3610, QTCREATORBUG-7579)
* Fixed support for typedef of templated typedefs (QTCREATORBUG-8375)
* Fixed code completion with 'using' declaration inside functions (QTCREATORBUG-2668) * Fixed code completion with 'using' declaration inside functions (QTCREATORBUG-2668)
* Fixed highlighting of types when there is 'using Namespace::TypeName' (QTCREATORBUG-7903) * Fixed highlighting of types when there is 'using Namespace::TypeName' (QTCREATORBUG-7903)
@@ -116,7 +113,6 @@ Diff Viewer
* Added file list combo box * Added file list combo box
Version Control Systems Version Control Systems
* Added "Select All" to clean dialog
* Git * Git
* Added new side-by-side diff viewer * Added new side-by-side diff viewer
* Added support for interactive rebase * Added support for interactive rebase
@@ -131,6 +127,7 @@ Version Control Systems
* Added tags to branches dialog * Added tags to branches dialog
* Added ability to save repository location for Gerrit * Added ability to save repository location for Gerrit
* Added graph toggle button for log viewer * Added graph toggle button for log viewer
* Added "Select All" to clean dialog
* ClearCase * ClearCase
* Removed useless hijack button for dynamic view * Removed useless hijack button for dynamic view

View File

@@ -36,7 +36,7 @@
\QC usually uses the latest stable release of Qt, \QC usually uses the latest stable release of Qt,
you can see the exact minimum requirement at the top of \QC's qtcreator.pro. you can see the exact minimum requirement at the top of \QC's qtcreator.pro.
(You can find the current version in our source repository here: (You can find the current version in our source repository here:
\l{https://qt.gitorious.org/qt-creator/qt-creator/blobs/master/qtcreator.pro}.) \l{http://qt.gitorious.org/qt-creator/qt-creator/blobs/master/qtcreator.pro}.)
You find the sources for the different Qt versions for example on our gitorious repository You find the sources for the different Qt versions for example on our gitorious repository
\l{http://qt.gitorious.org/qt}. \l{http://qt.gitorious.org/qt}.

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 74 KiB

View File

@@ -231,7 +231,7 @@
\note The Mac OS X Snow Leopard (10.6) has a bug that might cause the \note The Mac OS X Snow Leopard (10.6) has a bug that might cause the
application to crash. For a workaround, see: application to crash. For a workaround, see:
\l{https://bugreports.qt-project.org/browse/QTBUG-4962}{QTBUG-4962}. \l{http://bugreports.qt-project.org/browse/QTBUG-4962}{QTBUG-4962}.
\endtable \endtable

View File

@@ -1322,7 +1322,7 @@
existing process or use the \gui {Run in terminal} option in \QC. existing process or use the \gui {Run in terminal} option in \QC.
The reasons for this are described in The reasons for this are described in
\l{https://wiki.ubuntu.com/SecurityTeam/Roadmap/KernelHardening#ptrace%20Protection} \l{http://wiki.ubuntu.com/SecurityTeam/Roadmap/KernelHardening#ptrace%20Protection}
{KernelHardening}. {KernelHardening}.
However, the usefulness of this security measure seems dubious, However, the usefulness of this security measure seems dubious,

View File

@@ -57,14 +57,27 @@
select \gui {Sort Alphabetically} to arrange the symbols in alphabetic select \gui {Sort Alphabetically} to arrange the symbols in alphabetic
order. order.
To jump to a line and column in the current file, select the line and column
indicator (3) or press \key {Ctrl+L} (or \key {Cmd+L} on Mac OS X) to open
the locator. Enter the line number and column number in the locator,
separated by a colon (:).
To show the file encoding of the current file on the editor toolbar (4),
select \gui Tools > \gui Options > \gui {Text Editor} > \gui Display >
\gui {Display file encoding}.
\note Other convenient ways of navigating in \QC are provided by the
\l{Searching with the Locator}{locator}, \l{Keyboard Shortcuts}
{keyboard shortcuts}, and the \l{Browsing Project Contents}{sidebar}.
\section1 Splitting the Editor View \section1 Splitting the Editor View
Split the editor view when you want to work on and view multiple files on Split the editor view or open the editor in a new window when you want to
the same screen. work on and view multiple files on the same screen or on multiple screens.
\image qtcreator-spliteditorview.png \image qtcreator-spliteditorview.png
You can split the editor view in the following ways: You can view multiple files simultaneously in the following ways:
\list \list
@@ -82,10 +95,17 @@
Side by side split command creates views to the right of the Side by side split command creates views to the right of the
currently active editor view. currently active editor view.
\li To open the editor in a detached window, press \key{Ctrl+E, 4}, or
select \gui Window > \gui {Open in New Window}.
The new window behaves basically in the same way as the editor area
in the main window. For example, you can split this window, as well.
Documents are opened in the currently active editor window.
\endlist \endlist
To move between split views, select \gui Window > \gui{Go to Next Split} or To move between split views and detached editor windows, select \gui Window
press \key{Ctrl+E, O}. > \gui{Go to Next Split or Window} or press \key{Ctrl+E, O}.
To remove a split view, place the cursor within the view you want to To remove a split view, place the cursor within the view you want to
remove and select \gui Window > \gui{Remove Current Split}, press remove and select \gui Window > \gui{Remove Current Split}, press
@@ -138,14 +158,15 @@
\key {Shift+F2} or right-click the symbol and select \gui {Switch Between \key {Shift+F2} or right-click the symbol and select \gui {Switch Between
Method Declaration/Definition}. Method Declaration/Definition}.
Links are opened in the same split by default. Every operation can also be opened in Links are opened in the same split by default. To open links in the next
the next split by prebending \key {Ctrl+E} to the shortcut. For example \key {Ctrl+E,F2} split, prepend \key {Ctrl+E} to the shortcut. For example, press \key {Ctrl+E,F2}
to follow the symbol in the next split. If currently is just one editor open a split will be to follow the symbol in the next split. If necessary, the view is
automatically opened. The default behavior could also be changed in automatically split. To change the default behavior, select \gui Tools >
\gui Tools > \gui{Options} > \gui{Text Editor} > \gui Display, by checking \gui{Options} > \gui{Text Editor} > \gui Display, and then select
\gui{Always Open Links in Next Split}. Additional symbols and switching between definition \gui{Always Open Links in Next Split}. Additional symbols are displayed and
and decleration is opened in another split. If you change the default behavior the shortcuts switching between definition and declaration is done in another split.
for open in next split are used to open the target in the current split. If you change the default behavior, the shortcuts for opening link targets
in the next split are used to open them in the current split.
\section1 Using Update Code Model \section1 Using Update Code Model

View File

@@ -2044,11 +2044,24 @@
\title Searching with the Locator \title Searching with the Locator
You can find the locator in the bottom left of the \QC window. You can find the locator in the bottom left of the \QC window.
To activate the locator, press \key Ctrl+K (\key Cmd+K on Mac OS X) or
select \gui Tools > \gui Locate.
\image qtcreator-locator.png \image qtcreator-locator.png
To activate the locator:
\list
\li Press \key Ctrl+K (\key Cmd+K on Mac OS X).
\li Select \gui Tools > \gui Locate.
\li Select \gui Edit > \gui {Go to Line}.
\li Click the line and column indicator on the
\l{Using the Editor Toolbar}{editor toolbar}.
\endlist
To edit the currently open project's main.cpp file using the locator: To edit the currently open project's main.cpp file using the locator:
\list 1 \list 1
@@ -2108,7 +2121,8 @@
\li Locating class and method definitions in the current document \li Locating class and method definitions in the current document
\li Locating a specific line in the document displayed in your editor \li Locating a specific line and column in the document displayed in
your editor
\li Opening help topics, including Qt documentation \li Opening help topics, including Qt documentation
@@ -2148,7 +2162,7 @@
\list \list
\li Going to a line in the current file (l). \li Going to a line and column in the current file (l).
\li Going to an open file (o). \li Going to an open file (o).

View File

@@ -120,6 +120,24 @@
Open the projects and files that were open when you last exited \QC. Open the projects and files that were open when you last exited \QC.
For more information about managing sessions, see \l{Managing Sessions}. For more information about managing sessions, see \l{Managing Sessions}.
\row
\li -block
\li Open files in editors in a running \QC instance and block the
command line until the first editor is closed.
\endtable \endtable
\section1 Using Custom Styles
\QC is a \l{http://qt-project.org/doc/qt-5.0/qtwidgets/qapplication.html#QApplication}
{Qt application}, and therefore, it accepts the command line options
that all Qt applications accept. For example, you can use the \c {-style} and
\c {-stylesheet} options to apply custom styles and
\l{http://qt-project.org/doc/qt-5.0/qtwidgets/stylesheet.html}{stylesheets}.
The styling is only applied during the current session.
Exercise caution when applying styles, as overriding the existing styling
may make some items difficult to see. Also, setting a stylesheet may affect
the \l{Specifying Text Editor Settings}{text editor color scheme} and the
styling of the integrated \QD.
*/ */

View File

@@ -66,6 +66,9 @@
modes, click the icons, or use the \l{keyboard-shortcuts} modes, click the icons, or use the \l{keyboard-shortcuts}
{corresponding keyboard shortcut}. {corresponding keyboard shortcut}.
To hide the mode selector and to save space on the display, select
\gui Window > \gui {Show Mode Selector}.
The following image displays an example application in \gui Edit mode (1) The following image displays an example application in \gui Edit mode (1)
and \gui Design mode (2). and \gui Design mode (2).

View File

@@ -63,6 +63,7 @@
\row \row
\li Subversion \li Subversion
\li \l{http://subversion.apache.org/} \li \l{http://subversion.apache.org/}
\li Subversion version 1.6.17 and later
\li \li
\endtable \endtable

View File

@@ -98,7 +98,7 @@
\b {Has a reported issue been addressed?} \b {Has a reported issue been addressed?}
You can look up any issue in the You can look up any issue in the
\l{https://bugreports.qt-project.org/}{Qt bug tracker}. \l{http://bugreports.qt-project.org/}{Qt bug tracker}.
\if defined(qcmanual) \if defined(qcmanual)
\include widgets/creator-faq-qtdesigner.qdocinc \include widgets/creator-faq-qtdesigner.qdocinc

View File

@@ -42,7 +42,7 @@
You can upload free applications as Debian packages to You can upload free applications as Debian packages to
\l{http://wiki.maemo.org/Extras-devel}{Extras-devel} at Maemo.org to share \l{http://wiki.maemo.org/Extras-devel}{Extras-devel} at Maemo.org to share
new updates to your application and to start the community QA process. new updates to your application and to start the community QA process.
You need a \l{https://garage.maemo.org/}{Garage} account for the uploads, You need a \l{http://garage.maemo.org/}{Garage} account for the uploads,
but the package itself does not need to be hosted in the Garage. but the package itself does not need to be hosted in the Garage.
You can use the \gui {Publish for Fremantle Extras-devel Free Repository} You can use the \gui {Publish for Fremantle Extras-devel Free Repository}

View File

@@ -68,7 +68,7 @@
Only needed if you develop on Windows and if you use a USB connection Only needed if you develop on Windows and if you use a USB connection
to run applications on the device. The drivers are to run applications on the device. The drivers are
installed as part of the Qt 4 SDK. You can also download them from installed as part of the Qt 4 SDK. You can also download them from
\l{https://garage.maemo.org/frs/?group_id=801&release_id=2655}{PC Connectivity} \l{http://garage.maemo.org/frs/?group_id=801&release_id=2655}{PC Connectivity}
on the Maemo web site. Download and install the latest on the Maemo web site. Download and install the latest
PC_Connectivity_<version>.exe (at the time of writing, PC_Connectivity_<version>.exe (at the time of writing,
PC_Connectivity_0.9.4.exe). PC_Connectivity_0.9.4.exe).

View File

@@ -35,7 +35,7 @@
bugs. bugs.
For a list of fixed issues and added features, see the changelog file in For a list of fixed issues and added features, see the changelog file in
the \c{qtcreator\dist} folder or the \l{https://bugreports.qt-project.org} the \c{qtcreator\dist} folder or the \l{http://bugreports.qt-project.org}
{Qt Bug Tracker}. {Qt Bug Tracker}.
\section1 General Issues \section1 General Issues
@@ -56,7 +56,7 @@
\li Qt 4.7.4 is known to contain a bug exposed by g++ 4.6 which triggers \li Qt 4.7.4 is known to contain a bug exposed by g++ 4.6 which triggers
a crash in \QC. For more information, see a crash in \QC. For more information, see
\l{https://bugreports.qt-project.org/browse/QTBUG-21265}{QTBUG-21265} \l{http://bugreports.qt-project.org/browse/QTBUG-21265}{QTBUG-21265}
\li The Okteta KDE custom widget plugin might be installed as part of \li The Okteta KDE custom widget plugin might be installed as part of
some Linux distributions. It can cause Qt Designer to crash. For some Linux distributions. It can cause Qt Designer to crash. For
@@ -64,10 +64,10 @@
\list \list
\li \l{https://bugs.launchpad.net/ubuntu/+source/kdeutils/+bug/662005} \li \l{http://bugs.launchpad.net/ubuntu/+source/kdeutils/+bug/662005}
{Ubuntu bug 662005} {Ubuntu bug 662005}
\li \l{https://bugreports.qt-project.org/browse/QTBUG-12025} \li \l{http://bugreports.qt-project.org/browse/QTBUG-12025}
{QTBUG-12025} {QTBUG-12025}
\endlist \endlist

View File

@@ -315,6 +315,11 @@
\endlist \endlist
\li Python
Python class and source files that you can use to create Python
classes and scripts with UTF-8 encoding.
\endlist \endlist
\section2 Creating C++ Classes \section2 Creating C++ Classes

View File

@@ -79,5 +79,9 @@
\QC parses all the source files in the project and performs a semantic \QC parses all the source files in the project and performs a semantic
analysis to build up the information that it needs for functions such as analysis to build up the information that it needs for functions such as
navigation and finding usages. A progress bar is displayed during parsing. navigation and finding usages. A progress bar is displayed during parsing.
To show or hide detailed progress information, select
\gui {Toggle Progress Details} (1).
\image creator-toggle-progress-bar.png "Toggle Progress Details button"
*/ */

View File

@@ -57,7 +57,7 @@
To tailor your BAR packages, you will have to manually edit the application To tailor your BAR packages, you will have to manually edit the application
descriptor file. For a full reference, see descriptor file. For a full reference, see
\l{https://bdsc.webapps.blackberry.com/native/documentation/com.qnx.doc.native_sdk.devguide/com.qnx.doc.native_sdk.devguide/topic/r_blackberry_tablet_dtd_intro.html} \l{http://bdsc.webapps.blackberry.com/native/documentation/com.qnx.doc.native_sdk.devguide/com.qnx.doc.native_sdk.devguide/topic/r_blackberry_tablet_dtd_intro.html}
{Document Type Definition (DTD) for the application descriptor file}. {Document Type Definition (DTD) for the application descriptor file}.
\section1 Deploying to QNX Neutrino Devices \section1 Deploying to QNX Neutrino Devices

View File

@@ -24,7 +24,6 @@
\page creator-developing-bb10.html \page creator-developing-bb10.html
\nextpage creator-developing-generic-linux.html \nextpage creator-developing-generic-linux.html
\title Connecting BlackBerry 10 Devices \title Connecting BlackBerry 10 Devices
\QC provides a plugin that enables you to develop for QNX and BlackBerry 10 platforms. \QC provides a plugin that enables you to develop for QNX and BlackBerry 10 platforms.
@@ -35,9 +34,9 @@
Before starting to develop for BlackBerry 10 you need to download the following tools: Before starting to develop for BlackBerry 10 you need to download the following tools:
\list \list
\li \l {https://developer.blackberry.com/native/} {The BlackBerry 10 Native SDK} \li \l {http://developer.blackberry.com/native/} {The BlackBerry 10 Native SDK}
\li \l {https://developer.blackberry.com/native/} {The BlackBerry 10 Dev Alpha Simulator} if you do not have a BlackBerry DevAlpha device \li \l {http://developer.blackberry.com/native/} {The BlackBerry 10 Dev Alpha Simulator} if you do not have a BlackBerry DevAlpha device
\li \l {https://www.blackberry.com/SignedKeys/} {BlackBerry signing code keys} \li BlackBerry code signing keys (https://www.blackberry.com/SignedKeys/)
\endlist \endlist

View File

@@ -118,7 +118,7 @@ def listOfLocals(varList):
for symbol in block: for symbol in block:
name = symbol.print_name name = symbol.print_name
if name == "__in_chrg": if name == "__in_chrg" or name == "__PRETTY_FUNCTION__":
continue continue
# "NotImplementedError: Symbol type not yet supported in # "NotImplementedError: Symbol type not yet supported in
@@ -382,6 +382,9 @@ def registerDumper(function):
def bbsetup(args = ''): def bbsetup(args = ''):
global qqDumpers, qqFormats, qqEditable, typeCache global qqDumpers, qqFormats, qqEditable, typeCache
qqDumpers = {}
qqFormats = {}
qqEditable = {}
typeCache = {} typeCache = {}
module = sys.modules[__name__] module = sys.modules[__name__]

View File

@@ -136,7 +136,7 @@ def registerDumper(function):
pass pass
def warn(message): def warn(message):
print 'XXX="%s",' % message.encode("latin1").replace('"', "'") print '\nWARNING="%s",\n' % message.encode("latin1").replace('"', "'")
def showException(msg, exType, exValue, exTraceback): def showException(msg, exType, exValue, exTraceback):
warn("**** CAUGHT EXCEPTION: %s ****" % msg) warn("**** CAUGHT EXCEPTION: %s ****" % msg)
@@ -147,27 +147,9 @@ def showException(msg, exType, exValue, exTraceback):
def registerCommand(name, func): def registerCommand(name, func):
pass pass
def currentFrame():
currentThread = self.process.GetThreadAtIndex(0)
return currentThread.GetFrameAtIndex(0)
def fileName(file): def fileName(file):
return str(file) if file.IsValid() else '' return str(file) if file.IsValid() else ''
def breakpoint_function_wrapper(baton, process, frame, bp_loc):
result = '*stopped'
result += ',line="%s"' % frame.line_entry.line
result += ',file="%s"' % frame.line_entry.file
warn("WRAPPER: %s " %result)
return result
def onBreak():
db.debugger.HandleCommand("settings set frame-format ''")
db.debugger.HandleCommand("settings set thread-format ''")
result = "*stopped,frame={....}"
print result
PointerCode = None PointerCode = None
ArrayCode = None ArrayCode = None
@@ -334,7 +316,12 @@ def simpleEncoding(typeobj):
# return Hex2EncodedInt1 # return Hex2EncodedInt1
#if code == IntCode: #if code == IntCode:
if code == lldb.eTypeClassBuiltin: if code == lldb.eTypeClassBuiltin:
if str(typeobj).find("unsigned") >= 0: name = str(typeobj)
if name == "float":
return Hex2EncodedFloat4
if name == "double":
return Hex2EncodedFloat8
if name.find("unsigned") >= 0:
if size == 1: if size == 1:
return Hex2EncodedUInt1 return Hex2EncodedUInt1
if size == 2: if size == 2:
@@ -352,11 +339,6 @@ def simpleEncoding(typeobj):
return Hex2EncodedInt4 return Hex2EncodedInt4
if size == 8: if size == 8:
return Hex2EncodedInt8 return Hex2EncodedInt8
#if code == FloatCode:
# if size == 4:
# return Hex2EncodedFloat4
# if size == 8:
# return Hex2EncodedFloat8
return None return None
class Children: class Children:
@@ -495,9 +477,7 @@ class Dumper:
self.debugger.HandleCommand("settings set auto-confirm on") self.debugger.HandleCommand("settings set auto-confirm on")
self.process = None self.process = None
self.target = None self.target = None
self.pid = None
self.eventState = lldb.eStateInvalid self.eventState = lldb.eStateInvalid
self.listener = None
self.options = {} self.options = {}
self.expandedINames = {} self.expandedINames = {}
self.passExceptions = True self.passExceptions = True
@@ -505,7 +485,7 @@ class Dumper:
self.ns = "" self.ns = ""
self.autoDerefPointers = True self.autoDerefPointers = True
self.useDynamicType = True self.useDynamicType = True
self.useLoop = True self.useFancy = True
self.currentIName = None self.currentIName = None
self.currentValuePriority = -100 self.currentValuePriority = -100
@@ -518,6 +498,7 @@ class Dumper:
self.currentPrintsAddress = None self.currentPrintsAddress = None
self.currentChildType = None self.currentChildType = None
self.currentChildNumChild = None self.currentChildNumChild = None
self.currentWatchers = {}
self.executable_ = None self.executable_ = None
self.charType_ = None self.charType_ = None
@@ -526,11 +507,12 @@ class Dumper:
self.charPtrType_ = None self.charPtrType_ = None
self.voidType_ = None self.voidType_ = None
self.isShuttingDown_ = False self.isShuttingDown_ = False
self.dummyValue = None
def extractTemplateArgument(self, typename, index): def extractTemplateArgument(self, typename, index):
level = 0 level = 0
skipSpace = False skipSpace = False
inner = "" inner = ''
for c in typename[typename.find('<') + 1 : -1]: for c in typename[typename.find('<') + 1 : -1]:
if c == '<': if c == '<':
inner += c inner += c
@@ -543,7 +525,7 @@ class Dumper:
if index == 0: if index == 0:
return inner return inner
index -= 1 index -= 1
inner = "" inner = ''
else: else:
inner += c inner += c
skipSpace = True skipSpace = True
@@ -624,11 +606,29 @@ class Dumper:
return True return True
return self.stripNamespaceFromType(type.GetName()) in movableTypes return self.stripNamespaceFromType(type.GetName()) in movableTypes
def putIntItem(self, name, value):
with SubItem(self, name):
self.putValue(value)
self.putType("int")
self.putNumChild(0)
def putBoolItem(self, name, value):
with SubItem(self, name):
self.putValue(value)
self.putType("bool")
self.putNumChild(0)
def putNumChild(self, numchild): def putNumChild(self, numchild):
#warn("NUM CHILD: '%s' '%s'" % (numchild, self.currentChildNumChild)) #warn("NUM CHILD: '%s' '%s'" % (numchild, self.currentChildNumChild))
#if numchild != self.currentChildNumChild: #if numchild != self.currentChildNumChild:
self.put('numchild="%s",' % numchild) self.put('numchild="%s",' % numchild)
def putEmptyValue(self, priority = -10):
if priority >= self.currentValuePriority:
self.currentValue = ""
self.currentValuePriority = priority
self.currentValueEncoding = None
def putValue(self, value, encoding = None, priority = 0): def putValue(self, value, encoding = None, priority = 0):
# Higher priority values override lower ones. # Higher priority values override lower ones.
if priority >= self.currentValuePriority: if priority >= self.currentValuePriority:
@@ -681,6 +681,13 @@ class Dumper:
return xrange(0, self.currentNumChild) return xrange(0, self.currentNumChild)
return xrange(min(self.currentMaxNumChild, self.currentNumChild)) return xrange(min(self.currentMaxNumChild, self.currentNumChild))
def putPlainChildren(self, value):
self.putEmptyValue(-99)
self.putNumChild(1)
if self.currentIName in self.expandedINames:
with Children(self):
self.putFields(value)
def lookupType(self, name): def lookupType(self, name):
#warn("LOOKUP: %s" % self.target.FindFirstType(name)) #warn("LOOKUP: %s" % self.target.FindFirstType(name))
return self.target.FindFirstType(name) return self.target.FindFirstType(name)
@@ -690,15 +697,6 @@ class Dumper:
self.executable_ = executable self.executable_ = executable
error = lldb.SBError() error = lldb.SBError()
self.target = self.debugger.CreateTarget(executable, None, None, True, error) self.target = self.debugger.CreateTarget(executable, None, None, True, error)
self.listener = self.target.GetDebugger().GetListener()
self.process = self.target.Launch(self.listener, None, None,
None, None, None,
None, 0, True, error)
self.broadcaster = self.process.GetBroadcaster()
rc = self.broadcaster.AddListener(self.listener, 15)
if rc != 15:
warn("ADDING LISTENER FAILED: %s" % rc)
self.importDumpers() self.importDumpers()
if self.target.IsValid(): if self.target.IsValid():
@@ -706,22 +704,26 @@ class Dumper:
else: else:
self.report('state="inferiorsetupfailed",msg="%s",exe="%s"' % (error, executable)) self.report('state="inferiorsetupfailed",msg="%s",exe="%s"' % (error, executable))
warn("STATE AFTER LAUNCH: %s" % stateNames[self.process.GetState()])
def runEngine(self, _): def runEngine(self, _):
error = lldb.SBError() s = threading.Thread(target=self.loop, args=[])
self.pid = self.process.GetProcessID() s.start()
self.report('pid="%s"' % self.pid)
self.consumeEvents()
error = self.process.Continue()
self.consumeEvents()
self.reportError(error)
def loop(self):
error = lldb.SBError()
listener = self.debugger.GetListener()
self.process = self.target.Launch(listener, None, None, None, None,
None, None, 0, False, error)
self.report('pid="%s"' % self.process.GetProcessID())
self.report('state="enginerunandinferiorrunok"') self.report('state="enginerunandinferiorrunok"')
if self.useLoop: event = lldb.SBEvent()
s = threading.Thread(target=self.loop, args=[]) while True:
s.start() if listener.WaitForEvent(10000000, event):
self.handleEvent(event)
else:
warn('TIMEOUT')
def describeError(self, error): def describeError(self, error):
desc = lldb.SBStream() desc = lldb.SBStream()
@@ -749,19 +751,25 @@ class Dumper:
self.report('location={file="%s",line="%s",addr="%s"}' % (file, line, frame.pc)) self.report('location={file="%s",line="%s",addr="%s"}' % (file, line, frame.pc))
def reportThreads(self): def reportThreads(self):
reasons = ['None', 'Trace', 'Breakpoint', 'Watchpoint', 'Signal', 'Exception',
'Exec', 'PlanComplete']
result = 'threads={threads=[' result = 'threads={threads=['
for i in xrange(0, self.process.GetNumThreads()): for i in xrange(0, self.process.GetNumThreads()):
thread = self.process.GetThreadAtIndex(i) thread = self.process.GetThreadAtIndex(i)
stopReason = thread.GetStopReason()
result += '{id="%d"' % thread.GetThreadID() result += '{id="%d"' % thread.GetThreadID()
result += ',index="%s"' % i result += ',index="%s"' % i
result += ',stop-reason="%s"' % thread.GetStopReason() result += ',details="%s"' % thread.GetQueueName()
result += ',stop-reason="%s"' % stopReason
if stopReason >= 0 and stopReason < len(reasons):
result += ',state="%s"' % reasons[stopReason]
result += ',name="%s"' % thread.GetName() result += ',name="%s"' % thread.GetName()
result += ',frame={' result += ',frame={'
frame = thread.GetFrameAtIndex(0) frame = thread.GetFrameAtIndex(0)
result += 'pc="0x%x"' % frame.pc result += 'pc="0x%x"' % frame.pc
result += ',addr="0x%x"' % frame.pc result += ',addr="0x%x"' % frame.pc
result += ',fp="0x%x"' % frame.fp result += ',fp="0x%x"' % frame.fp
result += ',func="%s"' % frame.function.name result += ',func="%s"' % frame.GetFunctionName()
result += ',line="%s"' % frame.line_entry.line result += ',line="%s"' % frame.line_entry.line
result += ',fullname="%s"' % fileName(frame.line_entry.file) result += ',fullname="%s"' % fileName(frame.line_entry.file)
result += ',file="%s"' % fileName(frame.line_entry.file) result += ',file="%s"' % fileName(frame.line_entry.file)
@@ -797,19 +805,12 @@ class Dumper:
result += '],hasmore="%s"},' % hasmore result += '],hasmore="%s"},' % hasmore
self.report(result) self.report(result)
# Convenience function.
def putItemCount(self, count, maximum = 1000000000):
# This needs to override the default value, so don't use 'put' directly.
if count > maximum:
self.putValue('<>%s items>' % maximum)
else:
self.putValue('<%s items>' % count)
def putType(self, type, priority = 0): def putType(self, type, priority = 0):
# Higher priority values override lower ones. # Higher priority values override lower ones.
if priority >= self.currentTypePriority: if priority >= self.currentTypePriority:
self.currentType = str(type) self.currentType = str(type)
self.currentTypePriority = priority self.currentTypePriority = priority
#warn("TYPE: %s PRIORITY: %s" % (type, priority))
def putBetterType(self, type): def putBetterType(self, type):
try: try:
@@ -817,6 +818,7 @@ class Dumper:
except: except:
self.currentType = str(type) self.currentType = str(type)
self.currentTypePriority = self.currentTypePriority + 1 self.currentTypePriority = self.currentTypePriority + 1
#warn("BETTER TYPE: %s PRIORITY: %s" % (type, self.currentTypePriority))
def readRawMemory(self, base, size): def readRawMemory(self, base, size):
if size == 0: if size == 0:
@@ -883,7 +885,7 @@ class Dumper:
formatter.update() formatter.update()
numchild = formatter.num_children() numchild = formatter.num_children()
self.put('iname="%s",' % self.currentIName) self.put('iname="%s",' % self.currentIName)
self.put('type="%s",' % typeName) self.putType(typeName)
self.put('numchild="%s",' % numchild) self.put('numchild="%s",' % numchild)
self.put('addr="0x%x",' % value.GetLoadAddress()) self.put('addr="0x%x",' % value.GetLoadAddress())
self.putItemCount(numchild) self.putItemCount(numchild)
@@ -902,32 +904,51 @@ class Dumper:
if value.GetType().IsReferenceType(): if value.GetType().IsReferenceType():
type = value.GetType().GetDereferencedType().GetPointerType() type = value.GetType().GetDereferencedType().GetPointerType()
# FIXME: Find something more direct. # FIXME: Find something more direct.
origType = value.GetTypeName();
value = value.CreateValueFromAddress(value.GetName(), value = value.CreateValueFromAddress(value.GetName(),
value.AddressOf().GetValueAsUnsigned(), type).Dereference() value.AddressOf().GetValueAsUnsigned(), type).Dereference()
#value = value.cast(value.dynamic_type) #value = value.cast(value.dynamic_type)
self.putItem(value) self.putItem(value)
self.putBetterType("%s &" % value.GetTypeName()) self.putBetterType(origType)
return return
# Pointers # Pointers
if value.GetType().IsPointerType() and self.autoDerefPointers: if value.GetType().IsPointerType() and self.autoDerefPointers:
self.putItem(value.Dereference())
if isNull(value):
self.putType(typeName)
self.putValue("0x0")
self.putNumChild(0)
return
origType = value.GetType()
innerType = value.GetType().GetPointeeType()
self.putType(innerType)
savedCurrentChildType = self.currentChildType
self.currentChildType = str(innerType)
self.putItem(value.dereference())
self.currentChildType = savedCurrentChildType
self.put('origaddr="%s",' % value.address)
return return
stripped = self.stripNamespaceFromType(typeName).replace("::", "__")
#warn("VALUE: %s" % value) #warn("VALUE: %s" % value)
if stripped in qqDumpers: #warn("FANCY: %s" % self.useFancy)
self.putType(typeName) if self.useFancy:
qqDumpers[stripped](self, value) stripped = self.stripNamespaceFromType(typeName).replace("::", "__")
return #warn("STRIPPED: %s" % stripped)
#warn("DUMPABLE: %s" % (stripped in qqDumpers))
if stripped in qqDumpers:
self.putType(typeName)
qqDumpers[stripped](self, value)
return
# Normal value # Normal value
v = value.GetValue() v = value.GetValue()
#numchild = 1 if value.MightHaveChildren() else 0 #numchild = 1 if value.MightHaveChildren() else 0
numchild = value.GetNumChildren() numchild = value.GetNumChildren()
self.put('iname="%s",' % self.currentIName) self.put('iname="%s",' % self.currentIName)
self.put('type="%s",' % typeName) self.putType(typeName)
self.putValue("" if v is None else v) self.putValue('' if v is None else v)
self.put('numchild="%s",' % numchild) self.put('numchild="%s",' % numchild)
self.put('addr="0x%x",' % value.GetLoadAddress()) self.put('addr="0x%x",' % value.GetLoadAddress())
if self.currentIName in self.expandedINames: if self.currentIName in self.expandedINames:
@@ -945,12 +966,37 @@ class Dumper:
def reportVariables(self, _ = None): def reportVariables(self, _ = None):
frame = self.currentThread().GetSelectedFrame() frame = self.currentThread().GetSelectedFrame()
self.currentIName = "local" self.currentIName = 'local'
self.put('data=[') self.put('data=[')
for value in frame.GetVariables(True, True, False, False): for value in frame.GetVariables(True, True, False, False):
if self.dummyValue is None:
self.dummyValue = value
with SubItem(self, value): with SubItem(self, value):
self.put('iname="%s",' % self.currentIName) self.put('iname="%s",' % self.currentIName)
self.putItem(value) self.putItem(value)
# 'watchers':[{'id':'watch.0','exp':'23'},...]
if not self.dummyValue is None:
for watcher in self.currentWatchers:
iname = watcher['iname']
index = iname[iname.find('.') + 1:]
exp = binascii.unhexlify(watcher['exp'])
warn("EXP: %s" % exp)
warn("INDEX: %s" % index)
if exp == "":
self.put('type="",value="",exp=""')
continue
value = self.dummyValue.CreateValueFromExpression(iname, exp)
#value = self.dummyValue
warn("VALUE: %s" % value)
self.currentIName = 'watch'
with SubItem(self, index):
self.put('exp="%s",' % exp)
self.put('wname="%s",' % binascii.hexlify(exp))
self.put('iname="%s",' % self.currentIName)
self.putItem(value)
self.put(']') self.put(']')
self.report('') self.report('')
@@ -967,6 +1013,7 @@ class Dumper:
self.reportVariables() self.reportVariables()
def reportRegisters(self, _ = None): def reportRegisters(self, _ = None):
return
if self.process is None: if self.process is None:
self.report('process="none"') self.report('process="none"')
else: else:
@@ -987,10 +1034,14 @@ class Dumper:
def interruptInferior(self, _ = None): def interruptInferior(self, _ = None):
if self.process is None: if self.process is None:
self.report('msg="No process"') self.report('msg="No process"')
else: return
#self.debugger.DispatchInputInterrupt() error = self.process.Stop()
error = self.process.Stop() self.reportError(error)
self.reportError(error) self.consumeEvents()
if error.GetType() == 1:
state = self.process.GetState()
if state != lldb.eStateStopped:
self.report('state="inferiorstopfailed"')
def detachInferior(self, _ = None): def detachInferior(self, _ = None):
if self.process is None: if self.process is None:
@@ -1044,12 +1095,9 @@ class Dumper:
pass pass
def processEvents(self): def processEvents(self):
if self.listener is None:
warn("NO LISTENER YET")
return
event = lldb.SBEvent() event = lldb.SBEvent()
while self.listener.PeekAtNextEvent(event): while self.debugger.GetListener().PeekAtNextEvent(event):
self.listener.GetNextEvent(event) self.debugger.GetListener().GetNextEvent(event)
self.handleEvent(event) self.handleEvent(event)
def describeBreakpoint(self, bp, modelId): def describeBreakpoint(self, bp, modelId):
@@ -1099,13 +1147,6 @@ class Dumper:
bpNew.SetOneShot(int(args["oneshot"])) bpNew.SetOneShot(int(args["oneshot"]))
except: except:
pass pass
#bpNew.SetCallback(breakpoint_function_wrapper, None)
#bpNew.SetCallback(breakpoint_function_wrapper, None)
#"breakpoint command add 1 -o \"import time; print time.asctime()\"
#cmd = "script print(11111111)"
#cmd = "continue"
#self.debugger.HandleCommand(
# "breakpoint command add -o 'script onBreak()' %s" % bpNew.GetID())
return bpNew return bpNew
def changeBreakpoint(self, args): def changeBreakpoint(self, args):
@@ -1246,14 +1287,27 @@ class Dumper:
def setOptions(self, args): def setOptions(self, args):
self.options = args self.options = args
def updateData(self, args): def setWatchers(self, args):
self.expandedINames = set(args['expanded'].split(',')) #self.currentWatchers = args['watchers']
self.autoDerefPointers = int(args['autoderef']) warn("WATCHERS %s" % self.currentWatchers)
self.useDynamicType = int(args['dyntype'])
# Keep always True for now.
#self.passExceptions = args['pe']
self.reportData() self.reportData()
def updateData(self, args):
warn("UPDATE 1")
if 'expanded' in args:
self.expandedINames = set(args['expanded'].split(','))
if 'autoderef' in args:
self.autoDerefPointers = int(args['autoderef'])
if 'dyntype' in args:
self.useDynamicType = int(args['dyntype'])
if 'fancy' in args:
self.useFancy = int(args['fancy'])
if 'passexceptions' in args:
self.passExceptions = int(args['passexceptions'])
self.passExceptions = True # FIXME
self.reportVariables(args)
warn("UPDATE 2")
def disassemble(self, args): def disassemble(self, args):
frame = self.currentFrame(); frame = self.currentFrame();
function = frame.GetFunction() function = frame.GetFunction()
@@ -1284,6 +1338,18 @@ class Dumper:
result += ',contents="%s"}' % binascii.hexlify(contents) result += ',contents="%s"}' % binascii.hexlify(contents)
self.report(result) self.report(result)
def assignValue(self, args):
exp = binascii.unhexlify(args['exp'])
value = binascii.unhexlify(args['value'])
warn("EXP: %s" % exp)
warn("VALUE: %s" % value)
lhs = self.dummyValue.CreateValueFromExpression("$$lhs", exp)
rhs = self.dummyValue.CreateValueFromExpression("$$rhs", value)
warn("LHS: %s" % lhs)
warn("RHS: %s" % rhs)
#lhs.SetData(rhs.GetData())
self.reportVariables()
def importDumpers(self, _ = None): def importDumpers(self, _ = None):
result = lldb.SBCommandReturnObject() result = lldb.SBCommandReturnObject()
interpreter = self.debugger.GetCommandInterpreter() interpreter = self.debugger.GetCommandInterpreter()
@@ -1292,16 +1358,6 @@ class Dumper:
for key in items: for key in items:
registerDumper(items[key]) registerDumper(items[key])
def loop(self):
event = lldb.SBEvent()
while True:
# Mac LLDB doesn't like sys.maxsize
# if self.listener.WaitForEvent(sys.maxsize, event):
if self.listener.WaitForEvent(10000000, event):
self.handleEvent(event)
else:
warn('TIMEOUT')
def execute(self, args): def execute(self, args):
getattr(self, args['cmd'])(args) getattr(self, args['cmd'])(args)
self.report('token="%s"' % args['token']) self.report('token="%s"' % args['token'])
@@ -1311,8 +1367,8 @@ class Dumper:
def consumeEvents(self): def consumeEvents(self):
event = lldb.SBEvent() event = lldb.SBEvent()
if self.listener and self.listener.PeekAtNextEvent(event): if self.debugger.GetListener().PeekAtNextEvent(event):
self.listener.GetNextEvent(event) self.debugger.GetListener().GetNextEvent(event)
self.handleEvent(event) self.handleEvent(event)
@@ -1320,27 +1376,9 @@ currentDir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentfram
execfile(os.path.join(currentDir, "qttypes.py")) execfile(os.path.join(currentDir, "qttypes.py"))
def doit1(): def doit():
db = Dumper() db = Dumper()
db.useLoop = False
db.report('state="enginesetupok"')
while True:
db.consumeEvents()
readable, _, _ = select.select([sys.stdin], [], [], 0.1)
if sys.stdin in readable:
line = raw_input()
if line.startswith("db "):
db.execute(eval(line[3:]))
db.consumeEvents()
def doit2():
db = Dumper()
db.useLoop = True
db.report('state="enginesetupok"') db.report('state="enginesetupok"')
while True: while True:
@@ -1348,49 +1386,64 @@ def doit2():
for reader in readable: for reader in readable:
if reader == sys.stdin: if reader == sys.stdin:
line = sys.stdin.readline() line = sys.stdin.readline()
#warn("READING LINE %s" % line) #warn("READING LINE '%s'" % line)
if line.startswith("db "): if line.startswith("db "):
db.execute(eval(line[3:])) db.execute(eval(line[3:]))
def testit(): def testit1():
db = Dumper() db = Dumper()
db.useLoop = False
error = lldb.SBError() db.setupInferior({'cmd':'setupInferior','executable':sys.argv[2],'token':1})
db.target = db.debugger.CreateTarget(sys.argv[2], None, None, True, error) db.handleBreakpoints({'cmd':'handleBreakpoints','bkpts':[{'operation':'add',
#db.importDumpers() 'modelid':'1','type':2,'ignorecount':0,'condition':'','function':'main',
'oneshot':0,'enabled':1,'file':'','line':0}]})
bpNew = db.target.BreakpointCreateByName('breakHere', 'doit') db.runEngine({'cmd':'runEngine','token':4})
db.listener = lldb.SBListener("event_Listener")
db.process = db.target.LaunchSimple(None, None, os.getcwd())
broadcaster = db.process.GetBroadcaster()
listener = lldb.SBListener("event_Listener 2")
rc = broadcaster.AddListener(listener, lldb.SBProcess.eBroadcastBitStateChanged)
event = lldb.SBEvent()
while True: while True:
event = lldb.SBEvent() readable, _, _ = select.select([sys.stdin], [], [])
if db.listener.WaitForEvent(1, event): for reader in readable:
out = lldb.SBStream() if reader == sys.stdin:
event.GetDescription(out) line = sys.stdin.readline().strip()
warn("EVENT: %s" % event) #warn("READING LINE '%s'" % line)
type = event.GetType() if line.startswith("db "):
msg = lldb.SBEvent.GetCStringFromEvent(event) db.execute(eval(line[3:]))
flavor = event.GetDataFlavor() else:
state = lldb.SBProcess.GetStateFromEvent(event) db.executeDebuggerCommand({'command':line})
db.report('event={type="%s",data="%s",msg="%s",flavor="%s",state="%s"}'
% (type, out.GetData(), msg, flavor, state))
db.report('state="%s"' % stateNames[state]) # Used in dumper auto test.
if type == lldb.SBProcess.eBroadcastBitStateChanged: # Usage: python lbridge.py /path/to/testbinary comma-separated-inames
#if state == lldb.eStateStopped: def testit():
#db.reportData()
pass db = Dumper()
else:
warn('TIMEOUT') # Disable intermediate reporting.
savedReport = db.report
db.report = lambda stuff: 0
db.debugger.SetAsync(False)
db.expandedINames = set(sys.argv[3].split(','))
db.setupInferior({'cmd':'setupInferior','executable':sys.argv[2],'token':1})
db.handleBreakpoints({'cmd':'handleBreakpoints','bkpts':[{'operation':'add',
'modelid':'1','type':2,'ignorecount':0,'condition':'','function':'breakHere',
'oneshot':0,'enabled':1,'file':'','line':0}]})
error = lldb.SBError()
listener = db.debugger.GetListener()
db.process = db.target.Launch(listener, None, None, None, None,
None, None, 0, False, error)
db.currentThread().SetSelectedFrame(1)
db.report = savedReport
db.reportVariables()
#db.report("DUMPER=%s" % qqDumpers)
if len(sys.argv) > 2: if len(sys.argv) > 2:
testit() testit()
else: else:
doit2() doit()

View File

@@ -433,8 +433,8 @@ def qdump__QFixed(d, value):
def qdump__QFiniteStack(d, value): def qdump__QFiniteStack(d, value):
alloc = value["_alloc"] alloc = int(value["_alloc"])
size = value["_size"] size = int(value["_size"])
check(0 <= size and size <= alloc and alloc <= 1000 * 1000 * 1000) check(0 <= size and size <= alloc and alloc <= 1000 * 1000 * 1000)
d.putItemCount(size) d.putItemCount(size)
d.putNumChild(size) d.putNumChild(size)
@@ -483,7 +483,7 @@ def qdump__QHash(d, value):
val = value.cast(hashDataType) val = value.cast(hashDataType)
bucket = val["buckets"] bucket = val["buckets"]
e = val.cast(hashNodeType) e = val.cast(hashNodeType)
for n in xrange(val["numBuckets"] - 1, -1, -1): for n in xrange(int(val["numBuckets"]) - 1, -1, -1):
n = n - 1 n = n - 1
if n < 0: if n < 0:
break break
@@ -497,8 +497,8 @@ def qdump__QHash(d, value):
if next["next"]: if next["next"]:
return next return next
d = node.cast(hashDataType.pointer()).dereference() d = node.cast(hashDataType.pointer()).dereference()
numBuckets = d["numBuckets"] numBuckets = int(d["numBuckets"])
start = (node["h"] % numBuckets) + 1 start = (int(node["h"]) % numBuckets) + 1
bucket = d["buckets"] + start bucket = d["buckets"] + start
for n in xrange(numBuckets - start): for n in xrange(numBuckets - start):
if bucket.dereference() != next: if bucket.dereference() != next:
@@ -511,7 +511,7 @@ def qdump__QHash(d, value):
d_ptr = value["d"] d_ptr = value["d"]
e_ptr = value["e"] e_ptr = value["e"]
size = d_ptr["size"] size = int(d_ptr["size"])
hashDataType = d_ptr.type hashDataType = d_ptr.type
hashNodeType = e_ptr.type hashNodeType = e_ptr.type
@@ -644,7 +644,7 @@ def qform__QImage():
def qdump__QImage(d, value): def qdump__QImage(d, value):
try: try:
painters = value["painters"] painters = int(value["painters"])
except: except:
d.putPlainChildren(value) d.putPlainChildren(value)
return return
@@ -696,7 +696,7 @@ def qdump__QImage(d, value):
def qdump__QLinkedList(d, value): def qdump__QLinkedList(d, value):
d_ptr = value["d"] d_ptr = value["d"]
e_ptr = value["e"] e_ptr = value["e"]
n = d_ptr["size"] n = int(d_ptr["size"])
check(0 <= n and n <= 100*1000*1000) check(0 <= n and n <= 100*1000*1000)
checkRef(d_ptr["ref"]) checkRef(d_ptr["ref"])
d.putItemCount(n) d.putItemCount(n)
@@ -762,7 +762,7 @@ def qdump__QMapNode(d, value):
def qdumpHelper__Qt4_QMap(d, value, forceLong): def qdumpHelper__Qt4_QMap(d, value, forceLong):
d_ptr = value["d"].dereference() d_ptr = value["d"].dereference()
e_ptr = value["e"].dereference() e_ptr = value["e"].dereference()
n = d_ptr["size"] n = int(d_ptr["size"])
check(0 <= n and n <= 100*1000*1000) check(0 <= n and n <= 100*1000*1000)
checkRef(d_ptr["ref"]) checkRef(d_ptr["ref"])
@@ -810,7 +810,7 @@ def qdumpHelper__Qt4_QMap(d, value, forceLong):
def qdumpHelper__Qt5_QMap(d, value, forceLong): def qdumpHelper__Qt5_QMap(d, value, forceLong):
d_ptr = value["d"].dereference() d_ptr = value["d"].dereference()
n = d_ptr["size"] n = int(d_ptr["size"])
check(0 <= n and n <= 100*1000*1000) check(0 <= n and n <= 100*1000*1000)
checkRef(d_ptr["ref"]) checkRef(d_ptr["ref"])
@@ -1325,7 +1325,7 @@ def qdump__QObject(d, value):
# } # }
def qdump__QPixmap(d, value): def qdump__QPixmap(d, value):
painters = value["painters"] painters = int(value["painters"])
check(0 <= painters and painters < 1000) check(0 <= painters and painters < 1000)
d_ptr = value["data"]["d"] d_ptr = value["data"]["d"]
if isNull(d_ptr): if isNull(d_ptr):
@@ -1337,11 +1337,8 @@ def qdump__QPixmap(d, value):
def qdump__QPoint(d, value): def qdump__QPoint(d, value):
x = value["xp"] x = int(value["xp"])
y = value["yp"] y = int(value["yp"])
# should not be needed, but sometimes yield myns::QVariant::Private::Data::qreal
x = x.cast(x.type.strip_typedefs())
y = y.cast(y.type.strip_typedefs())
d.putValue("(%s, %s)" % (x, y)) d.putValue("(%s, %s)" % (x, y))
d.putNumChild(2) d.putNumChild(2)
if d.isExpanded(): if d.isExpanded():
@@ -1350,7 +1347,13 @@ def qdump__QPoint(d, value):
def qdump__QPointF(d, value): def qdump__QPointF(d, value):
qdump__QPoint(d, value) x = float(value["xp"])
y = float(value["yp"])
d.putValue("(%s, %s)" % (x, y))
d.putNumChild(2)
if d.isExpanded():
with Children(d):
d.putFields(value)
def qdump__QRect(d, value): def qdump__QRect(d, value):
@@ -1463,7 +1466,7 @@ def qdump__QSet(d, value):
d_ptr = value["q_hash"]["d"] d_ptr = value["q_hash"]["d"]
e_ptr = value["q_hash"]["e"] e_ptr = value["q_hash"]["e"]
size = d_ptr["size"] size = int(d_ptr["size"])
hashDataType = d_ptr.type hashDataType = d_ptr.type
hashNodeType = e_ptr.type hashNodeType = e_ptr.type
@@ -1894,11 +1897,11 @@ def qdump__QWeakPointer(d, value):
d.putValue("<invalid>") d.putValue("<invalid>")
d.putNumChild(0) d.putNumChild(0)
return return
weakref = d_ptr["weakref"]["_q_value"] weakref = int(d_ptr["weakref"]["_q_value"])
strongref = d_ptr["strongref"]["_q_value"] strongref = int(d_ptr["strongref"]["_q_value"])
check(int(strongref) >= -1) check(strongref >= -1)
check(int(strongref) <= int(weakref)) check(strongref <= weakref)
check(int(weakref) <= 10*1000*1000) check(weakref <= 10*1000*1000)
if isSimpleType(val.dereference().type): if isSimpleType(val.dereference().type):
d.putNumChild(3) d.putNumChild(3)
@@ -2045,7 +2048,7 @@ def qform__std__map():
def qdump__std__map(d, value): def qdump__std__map(d, value):
impl = value["_M_t"]["_M_impl"] impl = value["_M_t"]["_M_impl"]
size = impl["_M_node_count"] size = int(impl["_M_node_count"])
check(0 <= size and size <= 100*1000*1000) check(0 <= size and size <= 100*1000*1000)
d.putItemCount(size) d.putItemCount(size)
d.putNumChild(size) d.putNumChild(size)
@@ -2149,7 +2152,7 @@ def qdump__std__set__const_iterator(d, value):
def qdump__std__set(d, value): def qdump__std__set(d, value):
impl = value["_M_t"]["_M_impl"] impl = value["_M_t"]["_M_impl"]
size = impl["_M_node_count"] size = int(impl["_M_node_count"])
check(0 <= size and size <= 100*1000*1000) check(0 <= size and size <= 100*1000*1000)
d.putItemCount(size) d.putItemCount(size)
d.putNumChild(size) d.putNumChild(size)
@@ -2217,6 +2220,13 @@ def qdump__std__string(d, value):
mem = d.readRawMemory(p, size * charType.sizeof) mem = d.readRawMemory(p, size * charType.sizeof)
d.putField("editvalue", mem) d.putField("editvalue", mem)
#def qdump__std__string(d, value):
# data = value["__r_"]
# d.putValue("SSSS")
# d.putType("std::string")
# d.putNumChild(1)
# d.putPlainChildren(value)
def qdump__std__shared_ptr(d, value): def qdump__std__shared_ptr(d, value):
i = value["_M_ptr"] i = value["_M_ptr"]
@@ -2328,7 +2338,7 @@ def qdump__wstring(d, value):
def qdump____gnu_cxx__hash_set(d, value): def qdump____gnu_cxx__hash_set(d, value):
ht = value["_M_ht"] ht = value["_M_ht"]
size = ht["_M_num_elements"] size = int(ht["_M_num_elements"])
check(0 <= size and size <= 1000 * 1000 * 1000) check(0 <= size and size <= 1000 * 1000 * 1000)
d.putItemCount(size) d.putItemCount(size)
d.putNumChild(size) d.putNumChild(size)
@@ -2398,11 +2408,11 @@ def qdump__boost__shared_ptr(d, value):
return return
countedbase = value["pn"]["pi_"].dereference() countedbase = value["pn"]["pi_"].dereference()
weakcount = countedbase["weak_count_"] weakcount = int(countedbase["weak_count_"])
usecount = countedbase["use_count_"] usecount = int(countedbase["use_count_"])
check(int(weakcount) >= 0) check(weakcount >= 0)
check(int(weakcount) <= int(usecount)) check(weakcount <= int(usecount))
check(int(usecount) <= 10*1000*1000) check(usecount <= 10*1000*1000)
val = value["px"].dereference() val = value["px"].dereference()
if isSimpleType(val.type): if isSimpleType(val.type):

View File

@@ -1,65 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE language SYSTEM "language.dtd">
<language name="Git Rebase" version="1.00" kateversion="2.4" section="Other" extensions="git-rebase-todo" license="LGPL" mimetype="text/vnd.git.rebase" author="Orgad Shaneh (orgads@gmail.com)">
<highlighting>
<list name="pick">
<item>p</item>
<item>pick</item>
</list>
<list name="reword">
<item>r</item>
<item>reword</item>
</list>
<list name="edit">
<item>e</item>
<item>edit</item>
</list>
<list name="squash">
<item>s</item>
<item>squash</item>
</list>
<list name="fixup">
<item>f</item>
<item>fixup</item>
</list>
<list name="exec">
<item>x</item>
<item>exec</item>
</list>
<contexts>
<context attribute="Normal Text" lineEndContext="#pop" name="Normal">
<DetectChar char="#" attribute="Comment" context="Comment" column="0"/>
<keyword attribute="Pick" context="Commit" String="pick" />
<keyword attribute="Reword" context="Commit" String="reword" />
<keyword attribute="Edit" context="Commit" String="edit" />
<keyword attribute="Squash" context="Commit" String="squash" />
<keyword attribute="Fixup" context="Commit" String="fixup" />
<keyword attribute="Exec" context="Commit" String="exec" />
</context>
<context attribute="Commit" lineEndContext="#pop" name="Commit">
<RegExpr attribute="Commit" context="Summary" String="[0-9a-f]{7,40}" />
</context>
<context attribute="Summary" lineEndContext="#pop" name="Summary" />
<context attribute="Comment" lineEndContext="#pop" name="Comment">
<RegExpr attribute="Commit" context="#stay" String="[0-9a-f]{7,40}" />
</context>
</contexts>
<itemDatas>
<itemData name="Normal Text" defStyleNum="dsNormal"/>
<itemData name="Pick" defStyleNum="dsKeyword"/>
<itemData name="Reword" defStyleNum="dsDecVal"/>
<itemData name="Edit" defStyleNum="dsDataType"/>
<itemData name="Squash" defStyleNum="dsChar"/>
<itemData name="Fixup" defStyleNum="dsBaseN"/>
<itemData name="Exec" defStyleNum="dsOthers"/>
<itemData name="Commit" defStyleNum="dsFunction"/>
<itemData name="Summary" defStyleNum="dsString"/>
<itemData name="Comment" defStyleNum="dsComment"/>
</itemDatas>
</highlighting>
<general>
<comments>
<comment name="singleLine" start="#"/>
</comments>
</general>
</language>

View File

@@ -55,7 +55,9 @@ enum InformationName
IsAnchoredBySibling, IsAnchoredBySibling,
HasContent, HasContent,
HasBindingForProperty, HasBindingForProperty,
ContentTransform ContentTransform,
ContentItemTransform,
ContentItemBoundingRect
}; };
} }

View File

@@ -143,8 +143,6 @@ QImage GraphicalNodeInstance::renderImage() const
QImage renderImage = designerSupport()->renderImageForItem(quickItem(), renderBoundingRect, renderBoundingRect.size().toSize()); QImage renderImage = designerSupport()->renderImageForItem(quickItem(), renderBoundingRect, renderBoundingRect.size().toSize());
renderImage = renderImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
return renderImage; return renderImage;
} }

View File

@@ -887,8 +887,10 @@ static QVector<InformationContainer> createInformationVector(const QList<ServerN
informationVector.append(InformationContainer(instance.instanceId(), SceneTransform, instance.sceneTransform())); informationVector.append(InformationContainer(instance.instanceId(), SceneTransform, instance.sceneTransform()));
informationVector.append(InformationContainer(instance.instanceId(), Size, instance.size())); informationVector.append(InformationContainer(instance.instanceId(), Size, instance.size()));
informationVector.append(InformationContainer(instance.instanceId(), BoundingRect, instance.boundingRect())); informationVector.append(InformationContainer(instance.instanceId(), BoundingRect, instance.boundingRect()));
informationVector.append(InformationContainer(instance.instanceId(), ContentItemBoundingRect, instance.contentItemBoundingRect()));
informationVector.append(InformationContainer(instance.instanceId(), Transform, instance.transform())); informationVector.append(InformationContainer(instance.instanceId(), Transform, instance.transform()));
informationVector.append(InformationContainer(instance.instanceId(), ContentTransform, instance.contentTransform())); informationVector.append(InformationContainer(instance.instanceId(), ContentTransform, instance.contentTransform()));
informationVector.append(InformationContainer(instance.instanceId(), ContentItemTransform, instance.contentItemTransform()));
informationVector.append(InformationContainer(instance.instanceId(), HasContent, instance.hasContent())); informationVector.append(InformationContainer(instance.instanceId(), HasContent, instance.hasContent()));
informationVector.append(InformationContainer(instance.instanceId(), IsMovable, instance.isMovable())); informationVector.append(InformationContainer(instance.instanceId(), IsMovable, instance.isMovable()));
informationVector.append(InformationContainer(instance.instanceId(), IsResizable, instance.isResizable())); informationVector.append(InformationContainer(instance.instanceId(), IsResizable, instance.isResizable()));

View File

@@ -35,6 +35,7 @@
#include <QDebug> #include <QDebug>
#include <QSharedPointer> #include <QSharedPointer>
#include <private/qqmlmetatype_p.h> #include <private/qqmlmetatype_p.h>
#include <QQmlProperty>
namespace QmlDesigner { namespace QmlDesigner {
namespace Internal { namespace Internal {
@@ -53,7 +54,7 @@ void NodeInstanceSignalSpy::setObjectNodeInstance(const ObjectNodeInstance::Poin
} }
void NodeInstanceSignalSpy::registerObject(QObject *spiedObject, const PropertyName &prefix) void NodeInstanceSignalSpy::registerObject(QObject *spiedObject)
{ {
if (m_registeredObjectList.contains(spiedObject)) // prevent cycles if (m_registeredObjectList.contains(spiedObject)) // prevent cycles
return; return;
@@ -62,49 +63,64 @@ void NodeInstanceSignalSpy::registerObject(QObject *spiedObject, const PropertyN
for (int index = QObject::staticMetaObject.propertyOffset(); for (int index = QObject::staticMetaObject.propertyOffset();
index < spiedObject->metaObject()->propertyCount(); index < spiedObject->metaObject()->propertyCount();
index++) { index++) {
QMetaProperty metaProperty = spiedObject->metaObject()->property(index); QMetaProperty metaProperty = spiedObject->metaObject()->property(index);
// handle dot properties and connect the signals to the object registerProperty(metaProperty, spiedObject);
if (metaProperty.isReadable() registerChildObject(metaProperty, spiedObject);
&& !metaProperty.isWritable() }
&& QQmlMetaType::isQObject(metaProperty.userType())) { }
QObject *propertyObject = QQmlMetaType::toQObject(metaProperty.read(spiedObject));
if (propertyObject)
registerObject(propertyObject, prefix + metaProperty.name() + '.');
} else if (metaProperty.hasNotifySignal()) {
QMetaMethod metaMethod = metaProperty.notifySignal();
bool isConnecting = QMetaObject::connect(spiedObject, metaMethod.methodIndex(), this, methodeOffset, Qt::DirectConnection);
Q_ASSERT(isConnecting);
Q_UNUSED(isConnecting);
m_indexPropertyHash.insert(methodeOffset, prefix + metaProperty.name());
methodeOffset++;
}
// search recursive in objects void NodeInstanceSignalSpy::registerProperty(const QMetaProperty &metaProperty, QObject *spiedObject, const PropertyName &propertyPrefix)
if (metaProperty.isReadable() {
&& metaProperty.isWritable() if (metaProperty.isReadable()
&& QQmlMetaType::isQObject(metaProperty.userType()) && metaProperty.isWritable()
&& QLatin1String(metaProperty.name()) != QLatin1String("parent")) { && !QQmlMetaType::isQObject(metaProperty.userType())
QObject *propertyObject = QQmlMetaType::toQObject(metaProperty.read(spiedObject)); && metaProperty.hasNotifySignal()) {
if (propertyObject) QMetaMethod metaMethod = metaProperty.notifySignal();
registerObject(propertyObject, prefix + metaProperty.name() + '/'); QMetaObject::connect(spiedObject, metaMethod.methodIndex(), this, methodeOffset, Qt::DirectConnection);
}
// search recursive in objects list m_indexPropertyHash.insert(methodeOffset, propertyPrefix + PropertyName(metaProperty.name()));
if (metaProperty.isReadable()
&& QQmlMetaType::isList(metaProperty.userType())) {
QQmlListReference list(spiedObject, metaProperty.name());
if (list.canCount() && list.canAt()) { registerValueType(metaProperty, spiedObject, propertyPrefix);
for (int i = 0; i < list.count(); i++) { methodeOffset++;
QObject *propertyObject = list.at(i); }
if (propertyObject) }
registerObject(propertyObject, prefix + metaProperty.name() + '/');
} void NodeInstanceSignalSpy::registerValueType(const QMetaProperty &metaProperty, QObject *spiedObject, const PropertyName &propertyPrefix)
} {
} if (QQmlValueTypeFactory::valueType(metaProperty.userType())) {
} QQmlValueType *valueType = QQmlValueTypeFactory::valueType(metaProperty.userType());
valueType->setValue(metaProperty.read(spiedObject));
for (int index = QObject::staticMetaObject.propertyOffset();
index < valueType->metaObject()->propertyCount();
index++) {
QMetaProperty valueTypeMetaProperty = valueType->metaObject()->property(index);
qDebug() << "spy value property: " << propertyPrefix + PropertyName(metaProperty.name()) + "." + valueTypeMetaProperty.name();
m_indexPropertyHash.insert(methodeOffset, propertyPrefix + PropertyName(metaProperty.name()) + "." + valueTypeMetaProperty.name());
}
}
}
void NodeInstanceSignalSpy::registerChildObject(const QMetaProperty &metaProperty, QObject *spiedObject)
{
if (metaProperty.isReadable()
&& !metaProperty.isWritable()
&& QQmlMetaType::isQObject(metaProperty.userType())
&& QLatin1String(metaProperty.name()) != "parent") {
QObject *childObject = QQmlMetaType::toQObject(metaProperty.read(spiedObject));
qDebug() << "spy child property: " << childObject << metaProperty.name();
if (childObject) {
for (int index = QObject::staticMetaObject.propertyOffset();
index < childObject->metaObject()->propertyCount();
index++) {
QMetaProperty childMetaProperty = childObject->metaObject()->property(index);
registerProperty(childMetaProperty, childObject, PropertyName(metaProperty.name()) + '.');
}
}
}
} }
int NodeInstanceSignalSpy::qt_metacall(QMetaObject::Call call, int methodId, void **a) int NodeInstanceSignalSpy::qt_metacall(QMetaObject::Call call, int methodId, void **a)
@@ -113,7 +129,8 @@ int NodeInstanceSignalSpy::qt_metacall(QMetaObject::Call call, int methodId, voi
ObjectNodeInstance::Pointer nodeInstance = m_objectNodeInstance.toStrongRef(); ObjectNodeInstance::Pointer nodeInstance = m_objectNodeInstance.toStrongRef();
if (nodeInstance && nodeInstance->nodeInstanceServer() && nodeInstance->isValid()) { if (nodeInstance && nodeInstance->nodeInstanceServer() && nodeInstance->isValid()) {
nodeInstance->nodeInstanceServer()->notifyPropertyChange(nodeInstance->instanceId(), m_indexPropertyHash.value(methodId)); foreach (const PropertyName &propertyName, m_indexPropertyHash.values(methodId))
nodeInstance->nodeInstanceServer()->notifyPropertyChange(nodeInstance->instanceId(), propertyName);
} }
} }

View File

@@ -54,11 +54,14 @@ public:
virtual int qt_metacall(QMetaObject::Call, int, void **); virtual int qt_metacall(QMetaObject::Call, int, void **);
protected: protected:
void registerObject(QObject *spiedObject, const PropertyName &prefix = PropertyName()); void registerObject(QObject *spiedObject);
void registerProperty(const QMetaProperty &metaProperty, QObject *spiedObject, const PropertyName &propertyPrefix = PropertyName());
void registerValueType(const QMetaProperty &metaProperty, QObject *spiedObject, const PropertyName &propertyPrefix);
void registerChildObject(const QMetaProperty &metaProperty, QObject *spiedObject);
private: private:
int methodeOffset; int methodeOffset;
QHash<int, PropertyName> m_indexPropertyHash; QMultiHash<int, PropertyName> m_indexPropertyHash;
QObjectList m_registeredObjectList; QObjectList m_registeredObjectList;
ObjectNodeInstanceWeakPointer m_objectNodeInstance; ObjectNodeInstanceWeakPointer m_objectNodeInstance;
}; };

View File

@@ -255,6 +255,11 @@ QTransform ObjectNodeInstance::customTransform() const
return QTransform(); return QTransform();
} }
QTransform ObjectNodeInstance::contentItemTransform() const
{
return QTransform();
}
QTransform ObjectNodeInstance::sceneTransform() const QTransform ObjectNodeInstance::sceneTransform() const
{ {
return QTransform(); return QTransform();
@@ -1064,6 +1069,11 @@ QObject *ObjectNodeInstance::object() const
return 0; return 0;
} }
QQuickItem *ObjectNodeInstance::contentItem() const
{
return 0;
}
bool ObjectNodeInstance::hasContent() const bool ObjectNodeInstance::hasContent() const
{ {
return false; return false;
@@ -1210,7 +1220,12 @@ ObjectNodeInstance::Pointer ObjectNodeInstance::parentInstance() const
QRectF ObjectNodeInstance::boundingRect() const QRectF ObjectNodeInstance::boundingRect() const
{ {
return QRect(); return QRectF();
}
QRectF ObjectNodeInstance::contentItemBoundingBox() const
{
return QRectF();
} }
QPointF ObjectNodeInstance::position() const QPointF ObjectNodeInstance::position() const

View File

@@ -44,6 +44,7 @@ class QQmlContext;
class QQmlEngine; class QQmlEngine;
class QQmlProperty; class QQmlProperty;
class QQmlAbstractBinding; class QQmlAbstractBinding;
class QQuickItem;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace QmlDesigner { namespace QmlDesigner {
@@ -104,12 +105,14 @@ public:
virtual bool equalGraphicsItem(QGraphicsItem *item) const; virtual bool equalGraphicsItem(QGraphicsItem *item) const;
virtual QRectF boundingRect() const; virtual QRectF boundingRect() const;
virtual QRectF contentItemBoundingBox() const;
virtual QPointF position() const; virtual QPointF position() const;
virtual QSizeF size() const; virtual QSizeF size() const;
virtual QTransform transform() const; virtual QTransform transform() const;
virtual QTransform contentTransform() const; virtual QTransform contentTransform() const;
virtual QTransform customTransform() const; virtual QTransform customTransform() const;
virtual QTransform contentItemTransform() const;
virtual QTransform sceneTransform() const; virtual QTransform sceneTransform() const;
virtual double opacity() const; virtual double opacity() const;
@@ -153,6 +156,7 @@ public:
void setResetValue(const PropertyName &propertyName, const QVariant &value); void setResetValue(const PropertyName &propertyName, const QVariant &value);
QObject *object() const; QObject *object() const;
virtual QQuickItem *contentItem() const;
virtual bool hasContent() const; virtual bool hasContent() const;
virtual bool isResizable() const; virtual bool isResizable() const;

View File

@@ -107,8 +107,6 @@ QImage Qt5PreviewNodeInstanceServer::renderPreviewImage()
QImage previewImage = rootNodeInstance().renderPreviewImage(previewImageSize); QImage previewImage = rootNodeInstance().renderPreviewImage(previewImageSize);
previewImage = previewImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
return previewImage; return previewImage;
} }

View File

@@ -56,11 +56,24 @@ QuickItemNodeInstance::~QuickItemNodeInstance()
{ {
} }
static bool isContentItem(QQuickItem *item, NodeInstanceServer *nodeInstanceServer)
{
return item->parentItem()
&& nodeInstanceServer->hasInstanceForObject(item->parentItem())
&& nodeInstanceServer->instanceForObject(item->parentItem()).internalInstance()->contentItem() == item;
}
static QTransform transformForItem(QQuickItem *item, NodeInstanceServer *nodeInstanceServer) static QTransform transformForItem(QQuickItem *item, NodeInstanceServer *nodeInstanceServer)
{ {
if (isContentItem(item, nodeInstanceServer))
return QTransform();
QTransform toParentTransform = DesignerSupport::parentTransform(item); QTransform toParentTransform = DesignerSupport::parentTransform(item);
if (item->parentItem() && !nodeInstanceServer->hasInstanceForObject(item->parentItem())) if (item->parentItem() && !nodeInstanceServer->hasInstanceForObject(item->parentItem())) {
return transformForItem(item->parentItem(), nodeInstanceServer) * toParentTransform; return transformForItem(item->parentItem(), nodeInstanceServer) * toParentTransform;
}
return toParentTransform; return toParentTransform;
} }
@@ -109,6 +122,35 @@ QuickItemNodeInstance::Pointer QuickItemNodeInstance::create(QObject *object)
return instance; return instance;
} }
QQuickItem *QuickItemNodeInstance::contentItem() const
{
return m_contentItem.data();
}
void QuickItemNodeInstance::doComponentComplete()
{
GraphicalNodeInstance::doComponentComplete();
QQmlProperty contentItemProperty(quickItem(), "contentItem", engine());
if (contentItemProperty.isValid())
m_contentItem = contentItemProperty.read().value<QQuickItem*>();
}
QRectF QuickItemNodeInstance::contentItemBoundingBox() const
{
if (contentItem()) {
QTransform contentItemTransform = DesignerSupport::parentTransform(contentItem());
return contentItemTransform.mapRect(contentItem()->boundingRect());
}
return QRectF();
}
QTransform QuickItemNodeInstance::contentItemTransform() const
{
return DesignerSupport::parentTransform(contentItem());
}
bool QuickItemNodeInstance::isQuickItem() const bool QuickItemNodeInstance::isQuickItem() const
{ {

View File

@@ -50,7 +50,12 @@ public:
static Pointer create(QObject *objectToBeWrapped); static Pointer create(QObject *objectToBeWrapped);
virtual QQuickItem *contentItem() const;
QRectF contentItemBoundingBox() const Q_DECL_OVERRIDE;
QTransform transform() const Q_DECL_OVERRIDE; QTransform transform() const Q_DECL_OVERRIDE;
QTransform contentItemTransform() const Q_DECL_OVERRIDE;
QObject *parent() const Q_DECL_OVERRIDE; QObject *parent() const Q_DECL_OVERRIDE;
@@ -61,6 +66,8 @@ public:
bool isMovable() const Q_DECL_OVERRIDE; bool isMovable() const Q_DECL_OVERRIDE;
bool isQuickItem() const Q_DECL_OVERRIDE; bool isQuickItem() const Q_DECL_OVERRIDE;
void doComponentComplete();
protected: protected:
QuickItemNodeInstance(QQuickItem*); QuickItemNodeInstance(QQuickItem*);
QQuickItem *quickItem() const; QQuickItem *quickItem() const;
@@ -68,6 +75,7 @@ protected:
void setResizable(bool resizable); void setResizable(bool resizable);
private: //variables private: //variables
QPointer<QQuickItem> m_contentItem;
bool m_isResizable; bool m_isResizable;
bool m_isMovable; bool m_isMovable;
}; };

View File

@@ -88,7 +88,6 @@ QuickWindowNodeInstance::Pointer QuickWindowNodeInstance::create(QObject *object
QQuickItemPrivate *privateItem = static_cast<QQuickItemPrivate*>(QObjectPrivate::get(quickWindow->contentItem())); QQuickItemPrivate *privateItem = static_cast<QQuickItemPrivate*>(QObjectPrivate::get(quickWindow->contentItem()));
if (privateItem->window) { if (privateItem->window) {
qDebug() << "removing from window";
if (!privateItem->parentItem) if (!privateItem->parentItem)
QQuickWindowPrivate::get(privateItem->window)->parentlessItems.remove(quickWindow->contentItem()); QQuickWindowPrivate::get(privateItem->window)->parentlessItems.remove(quickWindow->contentItem());
privateItem->derefWindow(); privateItem->derefWindow();

View File

@@ -315,6 +315,11 @@ QRectF ServerNodeInstance::boundingRect() const
return boundingRect; return boundingRect;
} }
QRectF ServerNodeInstance::contentItemBoundingRect() const
{
return m_nodeInstance->contentItemBoundingBox();
}
void ServerNodeInstance::setPropertyVariant(const PropertyName &name, const QVariant &value) void ServerNodeInstance::setPropertyVariant(const PropertyName &name, const QVariant &value)
{ {
m_nodeInstance->setPropertyVariant(name, value); m_nodeInstance->setPropertyVariant(name, value);
@@ -515,6 +520,11 @@ QTransform ServerNodeInstance::contentTransform() const
return m_nodeInstance->contentTransform(); return m_nodeInstance->contentTransform();
} }
QTransform ServerNodeInstance::contentItemTransform() const
{
return m_nodeInstance->contentItemTransform();
}
double ServerNodeInstance::rotation() const double ServerNodeInstance::rotation() const
{ {
return m_nodeInstance->rotation(); return m_nodeInstance->rotation();
@@ -631,11 +641,6 @@ qint32 ServerNodeInstance::instanceId() const
} }
} }
QObject* ServerNodeInstance::testHandle() const
{
return internalObject();
}
QList<ServerNodeInstance> ServerNodeInstance::stateInstances() const QList<ServerNodeInstance> ServerNodeInstance::stateInstances() const
{ {
return m_nodeInstance->stateInstances(); return m_nodeInstance->stateInstances();

View File

@@ -105,12 +105,14 @@ public:
bool equalGraphicsItem(QGraphicsItem *item) const; bool equalGraphicsItem(QGraphicsItem *item) const;
QRectF boundingRect() const; QRectF boundingRect() const;
QRectF contentItemBoundingRect() const;
QPointF position() const; QPointF position() const;
QSizeF size() const; QSizeF size() const;
QTransform transform() const; QTransform transform() const;
QTransform customTransform() const; QTransform customTransform() const;
QTransform sceneTransform() const; QTransform sceneTransform() const;
QTransform contentTransform() const; QTransform contentTransform() const;
QTransform contentItemTransform() const;
double rotation() const; double rotation() const;
double scale() const; double scale() const;
QList<QGraphicsTransform *> transformations() const; QList<QGraphicsTransform *> transformations() const;
@@ -156,7 +158,6 @@ public:
QString id() const; QString id() const;
qint32 instanceId() const; qint32 instanceId() const;
QObject* testHandle() const;
QSharedPointer<Internal::ObjectNodeInstance> internalInstance() const; QSharedPointer<Internal::ObjectNodeInstance> internalInstance() const;
QList<ServerNodeInstance> stateInstances() const; QList<ServerNodeInstance> stateInstances() const;

View File

@@ -23,7 +23,7 @@ QT_BREAKPAD_ROOT_PATH = $$(QT_BREAKPAD_ROOT_PATH)
include($$QT_BREAKPAD_ROOT_PATH/qtbreakpad.pri) include($$QT_BREAKPAD_ROOT_PATH/qtbreakpad.pri)
} }
SOURCES += $$PWD/main.cpp SOURCES += $$PWD/qml2puppetmain.cpp
RESOURCES += $$PWD/../qmlpuppet.qrc RESOURCES += $$PWD/../qmlpuppet.qrc
DEFINES -= QT_NO_CAST_FROM_ASCII DEFINES -= QT_NO_CAST_FROM_ASCII

View File

@@ -47,6 +47,10 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// Since we always render text into an FBO, we need to globally disable
// subpixel antialiasing and instead use gray.
qputenv("QSG_DISTANCEFIELD_ANTIALIASING", "gray");
QApplication application(argc, argv); QApplication application(argc, argv);
QCoreApplication::setOrganizationName("QtProject"); QCoreApplication::setOrganizationName("QtProject");
@@ -78,8 +82,10 @@ int main(int argc, char *argv[])
return 0; return 0;
} }
if (application.arguments().count() != 4) if (application.arguments().count() < 4) {
qDebug() << "Wrong argument count: " << application.arguments().count();
return -1; return -1;
}

View File

@@ -17,7 +17,7 @@ include (../commands/commands.pri)
include (../container/container.pri) include (../container/container.pri)
include (../interfaces/interfaces.pri) include (../interfaces/interfaces.pri)
SOURCES += $$PWD/main.cpp SOURCES += $$PWD/qmlpuppetmain.cpp
RESOURCES += $$PWD/../qmlpuppet.qrc RESOURCES += $$PWD/../qmlpuppet.qrc
DEFINES -= QT_NO_CAST_FROM_ASCII DEFINES -= QT_NO_CAST_FROM_ASCII

View File

@@ -64,7 +64,7 @@ int main(int argc, char *argv[])
return 0; return 0;
} }
if (application.arguments().count() != 4) if (application.arguments().count() < 4)
return -1; return -1;
#ifdef ENABLE_QT_BREAKPAD #ifdef ENABLE_QT_BREAKPAD

View File

@@ -0,0 +1,95 @@
/****************************************************************************
**
** Copyright (C) 2013 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.
**
****************************************************************************/
import QtQuick 1.0
import Bauhaus 1.0
import HelperWidgets 1.0
PropertyFrame {
id: frame;
x: 0
y: 0
ExpressionEditor {
id: expressionEdit
}
layout: QVBoxLayout {
topMargin: 0;
bottomMargin: 0;
leftMargin: 0;
rightMargin: 0;
spacing: 0;
Type {
}
HorizontalWhiteLine {
maximumHeight: 4;
styleSheet: "QLineEdit {border: 2px solid #707070; min-height: 0px; max-height: 0px;}";
}
HorizontalWhiteLine {
}
ScrollArea {
styleSheetFile: ":/qmldesigner/scrollbar.css";
widgetResizable: true;
finished: finishedNotify;
horizontalScrollBarPolicy: "Qt::ScrollBarAlwaysOff";
id: standardPane;
QFrame {
//minimumHeight: 1100
id: properyEditorStandard
layout: QVBoxLayout {
topMargin: 0;
bottomMargin: 0;
leftMargin: 0;
rightMargin: 0;
spacing: 0;
WidgetLoader {
id: specificsTwo;
baseUrl: globalBaseUrl;
qmlData: specificQmlData;
}
WidgetLoader {
id: specificsOne;
source: specificsUrl;
}
QScrollArea {
}
} // layout
} //QWidget
} //QScrollArea
}
}

View File

@@ -14434,12 +14434,12 @@ Preselects a desktop Qt for building the application if available.</source>
<message> <message>
<source>%1 Debug</source> <source>%1 Debug</source>
<extracomment>Name of a debug build configuration to created by a project wizard, %1 being the Qt version name. We recommend not translating it.</extracomment> <extracomment>Name of a debug build configuration to created by a project wizard, %1 being the Qt version name. We recommend not translating it.</extracomment>
<translation type="obsolete">%1 </translation> <translation>%1 Debug</translation>
</message> </message>
<message> <message>
<source>%1 Release</source> <source>%1 Release</source>
<extracomment>Name of a release build configuration to created by a project wizard, %1 being the Qt version name. We recommend not translating it.</extracomment> <extracomment>Name of a release build configuration to created by a project wizard, %1 being the Qt version name. We recommend not translating it.</extracomment>
<translation type="obsolete">%1 </translation> <translation>%1 Release</translation>
</message> </message>
<message> <message>
<source>&lt;No tool chain selected&gt;</source> <source>&lt;No tool chain selected&gt;</source>
@@ -22774,7 +22774,7 @@ S60 emulator run configuration default display name, %1 is base pro-File name</e
<message> <message>
<source>untitled</source> <source>untitled</source>
<extracomment>File path suggestion for a new project. If you choose to translate it, make sure it is a valid path name without blanks and using only ascii chars.</extracomment> <extracomment>File path suggestion for a new project. If you choose to translate it, make sure it is a valid path name without blanks and using only ascii chars.</extracomment>
<translation></translation> <translation>untitled</translation>
</message> </message>
</context> </context>
<context> <context>
@@ -27898,12 +27898,12 @@ Did you start Qemu?</source>
<message> <message>
<source>%1 Debug</source> <source>%1 Debug</source>
<extracomment>Debug build configuration. We recommend not translating it.</extracomment> <extracomment>Debug build configuration. We recommend not translating it.</extracomment>
<translation type="obsolete">%1 </translation> <translation>%1 Debug</translation>
</message> </message>
<message> <message>
<source>%1 Release</source> <source>%1 Release</source>
<extracomment>Release build configuration. We recommend not translating it.</extracomment> <extracomment>Release build configuration. We recommend not translating it.</extracomment>
<translation type="obsolete">%1 </translation> <translation>%1 Release</translation>
</message> </message>
</context> </context>
<context> <context>
@@ -40001,12 +40001,12 @@ Check if the phone is connected and App TRK is running.</source>
<message> <message>
<source>%1 Debug</source> <source>%1 Debug</source>
<extracomment>Name of a debug build configuration to created by a project wizard, %1 being the Qt version name. We recommend not translating it.</extracomment> <extracomment>Name of a debug build configuration to created by a project wizard, %1 being the Qt version name. We recommend not translating it.</extracomment>
<translation type="obsolete">%1 </translation> <translation>%1 Debug</translation>
</message> </message>
<message> <message>
<source>%1 Release</source> <source>%1 Release</source>
<extracomment>Name of a release build configuration to be created by a project wizard, %1 being the Qt version name. We recommend not translating it.</extracomment> <extracomment>Name of a release build configuration to be created by a project wizard, %1 being the Qt version name. We recommend not translating it.</extracomment>
<translation type="obsolete">%1 </translation> <translation>%1 Release</translation>
</message> </message>
</context> </context>
<context> <context>

File diff suppressed because it is too large Load Diff

View File

@@ -464,6 +464,57 @@ void Document::setGlobalNamespace(Namespace *globalNamespace)
_globalNamespace = globalNamespace; _globalNamespace = globalNamespace;
} }
/*!
* Extract the function name including scope at the given position.
*
* Note that a function (scope) starts at the name of that function, not at the return type. The
* implication is that this method will return an empty string when the line/column is on the
* return type.
*
* \param line the line number, starting with line 1
* \param column the column number, starting with column 1
*/
QString Document::functionAt(int line, int column) const
{
if (line < 1 || column < 1)
return QString();
CPlusPlus::Symbol *symbol = lastVisibleSymbolAt(line, column);
if (!symbol)
return QString();
// Find the enclosing function scope (which might be several levels up, or we might be standing
// on it)
Scope *scope;
if (symbol->isScope())
scope = symbol->asScope();
else
scope = symbol->enclosingScope();
while (scope && !scope->isFunction() )
scope = scope->enclosingScope();
if (!scope)
return QString();
// We found the function scope, extract its name.
const Overview o;
QString rc = o.prettyName(scope->name());
// Prepend namespace "Foo::Foo::foo()" up to empty root namespace
for (const Symbol *owner = scope->enclosingNamespace();
owner; owner = owner->enclosingNamespace()) {
const QString name = o.prettyName(owner->name());
if (name.isEmpty()) {
break;
} else {
rc.prepend(QLatin1String("::"));
rc.prepend(name);
}
}
return rc;
}
Scope *Document::scopeAt(unsigned line, unsigned column) Scope *Document::scopeAt(unsigned line, unsigned column)
{ {
FindScopeAt findScopeAt(_translationUnit, line, column); FindScopeAt findScopeAt(_translationUnit, line, column);

View File

@@ -99,6 +99,7 @@ public:
QList<Macro> definedMacros() const QList<Macro> definedMacros() const
{ return _definedMacros; } { return _definedMacros; }
QString functionAt(int line, int column) const;
Symbol *lastVisibleSymbolAt(unsigned line, unsigned column = 0) const; Symbol *lastVisibleSymbolAt(unsigned line, unsigned column = 0) const;
Scope *scopeAt(unsigned line, unsigned column = 0); Scope *scopeAt(unsigned line, unsigned column = 0);

View File

@@ -1332,19 +1332,6 @@ void Preprocessor::synchronizeOutputLines(const PPToken &tk, bool forceLine)
adjustForCommentOrStringNewlines(&m_env->currentLine, tk); adjustForCommentOrStringNewlines(&m_env->currentLine, tk);
} }
void Preprocessor::removeTrailingOutputLines()
{
QByteArray &buffer = currentOutputBuffer();
int i = buffer.size() - 1;
while (i >= 0 && buffer.at(i) == '\n')
--i;
const int mightChop = buffer.size() - i - 1;
if (mightChop > 1) {
// Keep one new line at end.
buffer.chop(mightChop - 1);
}
}
std::size_t Preprocessor::computeDistance(const Preprocessor::PPToken &tk, bool forceTillLine) std::size_t Preprocessor::computeDistance(const Preprocessor::PPToken &tk, bool forceTillLine)
{ {
// Find previous non-space character or line begin. // Find previous non-space character or line begin.
@@ -1450,8 +1437,6 @@ void Preprocessor::preprocess(const QString &fileName, const QByteArray &source,
} while (tk.isNot(T_EOF_SYMBOL)); } while (tk.isNot(T_EOF_SYMBOL));
removeTrailingOutputLines();
if (includeGuardMacroName) { if (includeGuardMacroName) {
if (m_state.m_includeGuardState == State::IncludeGuardState_AfterDefine if (m_state.m_includeGuardState == State::IncludeGuardState_AfterDefine
|| m_state.m_includeGuardState == State::IncludeGuardState_AfterEndif) || m_state.m_includeGuardState == State::IncludeGuardState_AfterEndif)
@@ -1915,8 +1900,6 @@ void Preprocessor::handleEndIfDirective(PPToken *tk, const PPToken &poundToken)
void Preprocessor::handleIfDefDirective(bool checkUndefined, PPToken *tk) void Preprocessor::handleIfDefDirective(bool checkUndefined, PPToken *tk)
{ {
static const QByteArray qCreatorRun("Q_CREATOR_RUN");
lex(tk); // consume "ifdef" token lex(tk); // consume "ifdef" token
if (tk->is(T_IDENTIFIER)) { if (tk->is(T_IDENTIFIER)) {
if (checkUndefined && m_state.m_ifLevel == 0) if (checkUndefined && m_state.m_ifLevel == 0)
@@ -1937,8 +1920,6 @@ void Preprocessor::handleIfDefDirective(bool checkUndefined, PPToken *tk)
} }
} else if (m_env->isBuiltinMacro(macroName)) { } else if (m_env->isBuiltinMacro(macroName)) {
value = true; value = true;
} else if (macroName == qCreatorRun) {
value = true;
} }
if (checkUndefined) if (checkUndefined)

View File

@@ -237,7 +237,6 @@ private:
void maybeStartOutputLine(); void maybeStartOutputLine();
void generateOutputLineMarker(unsigned lineno); void generateOutputLineMarker(unsigned lineno);
void synchronizeOutputLines(const PPToken &tk, bool forceLine = false); void synchronizeOutputLines(const PPToken &tk, bool forceLine = false);
void removeTrailingOutputLines();
void enforceSpacing(const PPToken &tk, bool forceSpacing = false); void enforceSpacing(const PPToken &tk, bool forceSpacing = false);
static std::size_t computeDistance(const PPToken &tk, bool forceTillLine = false); static std::size_t computeDistance(const PPToken &tk, bool forceTillLine = false);

View File

@@ -46,7 +46,6 @@
using namespace ExtensionSystem; using namespace ExtensionSystem;
/*! /*!
\fn PluginDetailsView::PluginDetailsView(QWidget *parent)
Constructs a new view with given \a parent widget. Constructs a new view with given \a parent widget.
*/ */
PluginDetailsView::PluginDetailsView(QWidget *parent) PluginDetailsView::PluginDetailsView(QWidget *parent)
@@ -57,7 +56,6 @@ PluginDetailsView::PluginDetailsView(QWidget *parent)
} }
/*! /*!
\fn PluginDetailsView::~PluginDetailsView()
\internal \internal
*/ */
PluginDetailsView::~PluginDetailsView() PluginDetailsView::~PluginDetailsView()
@@ -66,7 +64,6 @@ PluginDetailsView::~PluginDetailsView()
} }
/*! /*!
\fn void PluginDetailsView::update(PluginSpec *spec)
Reads the given \a spec and displays its values Reads the given \a spec and displays its values
in this PluginDetailsView. in this PluginDetailsView.
*/ */

View File

@@ -46,7 +46,6 @@
using namespace ExtensionSystem; using namespace ExtensionSystem;
/*! /*!
\fn PluginErrorView::PluginErrorView(QWidget *parent)
Constructs a new error view with given \a parent widget. Constructs a new error view with given \a parent widget.
*/ */
PluginErrorView::PluginErrorView(QWidget *parent) PluginErrorView::PluginErrorView(QWidget *parent)
@@ -57,7 +56,6 @@ PluginErrorView::PluginErrorView(QWidget *parent)
} }
/*! /*!
\fn PluginErrorView::~PluginErrorView()
\internal \internal
*/ */
PluginErrorView::~PluginErrorView() PluginErrorView::~PluginErrorView()
@@ -66,7 +64,6 @@ PluginErrorView::~PluginErrorView()
} }
/*! /*!
\fn void PluginErrorView::update(PluginSpec *spec)
Reads the given \a spec and displays its state and Reads the given \a spec and displays its state and
error information in this PluginErrorView. error information in this PluginErrorView.
*/ */

View File

@@ -454,6 +454,8 @@ QHash<QString, PluginCollection *> PluginManager::pluginCollections()
return m_instance->d->pluginCategories; return m_instance->d->pluginCategories;
} }
static const char argumentKeywordC[] = ":arguments";
/*! /*!
Serialize plugin options and arguments for sending in a single string Serialize plugin options and arguments for sending in a single string
via QtSingleApplication: via QtSingleApplication:
@@ -462,9 +464,6 @@ QHash<QString, PluginCollection *> PluginManager::pluginCollections()
\sa setPluginPaths() \sa setPluginPaths()
*/ */
static const char argumentKeywordC[] = ":arguments";
QString PluginManager::serializedArguments() QString PluginManager::serializedArguments()
{ {
const QChar separator = QLatin1Char('|'); const QChar separator = QLatin1Char('|');
@@ -639,7 +638,6 @@ void PluginManager::formatPluginOptions(QTextStream &str, int optionIndentation,
/*! /*!
Format the version of the plugin specs for command line help. Format the version of the plugin specs for command line help.
*/ */
void PluginManager::formatPluginVersions(QTextStream &str) void PluginManager::formatPluginVersions(QTextStream &str)
{ {
const PluginSpecSet::const_iterator cend = m_instance->d->pluginSpecs.constEnd(); const PluginSpecSet::const_iterator cend = m_instance->d->pluginSpecs.constEnd();

View File

@@ -145,7 +145,6 @@ using namespace ExtensionSystem;
using namespace ExtensionSystem::Internal; using namespace ExtensionSystem::Internal;
/*! /*!
\fn uint qHash(const ExtensionSystem::PluginDependency &value)
\internal \internal
*/ */
uint ExtensionSystem::qHash(const ExtensionSystem::PluginDependency &value) uint ExtensionSystem::qHash(const ExtensionSystem::PluginDependency &value)
@@ -154,7 +153,6 @@ uint ExtensionSystem::qHash(const ExtensionSystem::PluginDependency &value)
} }
/*! /*!
\fn bool PluginDependency::operator==(const PluginDependency &other) const
\internal \internal
*/ */
bool PluginDependency::operator==(const PluginDependency &other) const bool PluginDependency::operator==(const PluginDependency &other) const
@@ -163,7 +161,6 @@ bool PluginDependency::operator==(const PluginDependency &other) const
} }
/*! /*!
\fn PluginSpec::PluginSpec()
\internal \internal
*/ */
PluginSpec::PluginSpec() PluginSpec::PluginSpec()
@@ -172,7 +169,6 @@ PluginSpec::PluginSpec()
} }
/*! /*!
\fn PluginSpec::~PluginSpec()
\internal \internal
*/ */
PluginSpec::~PluginSpec() PluginSpec::~PluginSpec()
@@ -182,7 +178,6 @@ PluginSpec::~PluginSpec()
} }
/*! /*!
\fn QString PluginSpec::name() const
The plugin name. This is valid after the PluginSpec::Read state is reached. The plugin name. This is valid after the PluginSpec::Read state is reached.
*/ */
QString PluginSpec::name() const QString PluginSpec::name() const
@@ -191,7 +186,6 @@ QString PluginSpec::name() const
} }
/*! /*!
\fn QString PluginSpec::version() const
The plugin version. This is valid after the PluginSpec::Read state is reached. The plugin version. This is valid after the PluginSpec::Read state is reached.
*/ */
QString PluginSpec::version() const QString PluginSpec::version() const
@@ -200,7 +194,6 @@ QString PluginSpec::version() const
} }
/*! /*!
\fn QString PluginSpec::compatVersion() const
The plugin compatibility version. This is valid after the PluginSpec::Read state is reached. The plugin compatibility version. This is valid after the PluginSpec::Read state is reached.
*/ */
QString PluginSpec::compatVersion() const QString PluginSpec::compatVersion() const
@@ -209,7 +202,6 @@ QString PluginSpec::compatVersion() const
} }
/*! /*!
\fn QString PluginSpec::vendor() const
The plugin vendor. This is valid after the PluginSpec::Read state is reached. The plugin vendor. This is valid after the PluginSpec::Read state is reached.
*/ */
QString PluginSpec::vendor() const QString PluginSpec::vendor() const
@@ -218,7 +210,6 @@ QString PluginSpec::vendor() const
} }
/*! /*!
\fn QString PluginSpec::copyright() const
The plugin copyright. This is valid after the PluginSpec::Read state is reached. The plugin copyright. This is valid after the PluginSpec::Read state is reached.
*/ */
QString PluginSpec::copyright() const QString PluginSpec::copyright() const
@@ -227,7 +218,6 @@ QString PluginSpec::copyright() const
} }
/*! /*!
\fn QString PluginSpec::license() const
The plugin license. This is valid after the PluginSpec::Read state is reached. The plugin license. This is valid after the PluginSpec::Read state is reached.
*/ */
QString PluginSpec::license() const QString PluginSpec::license() const
@@ -236,7 +226,6 @@ QString PluginSpec::license() const
} }
/*! /*!
\fn QString PluginSpec::description() const
The plugin description. This is valid after the PluginSpec::Read state is reached. The plugin description. This is valid after the PluginSpec::Read state is reached.
*/ */
QString PluginSpec::description() const QString PluginSpec::description() const
@@ -245,7 +234,6 @@ QString PluginSpec::description() const
} }
/*! /*!
\fn QString PluginSpec::url() const
The plugin url where you can find more information about the plugin. This is valid after the PluginSpec::Read state is reached. The plugin url where you can find more information about the plugin. This is valid after the PluginSpec::Read state is reached.
*/ */
QString PluginSpec::url() const QString PluginSpec::url() const
@@ -254,7 +242,6 @@ QString PluginSpec::url() const
} }
/*! /*!
\fn QString PluginSpec::category() const
The category that the plugin belongs to. Categories are groups of plugins which allow for keeping them together in the UI. The category that the plugin belongs to. Categories are groups of plugins which allow for keeping them together in the UI.
Returns an empty string if the plugin does not belong to a category. Returns an empty string if the plugin does not belong to a category.
*/ */
@@ -264,7 +251,6 @@ QString PluginSpec::category() const
} }
/*! /*!
\fn bool PluginSpec::isExperimental() const
Returns if the plugin has its experimental flag set. Returns if the plugin has its experimental flag set.
*/ */
bool PluginSpec::isExperimental() const bool PluginSpec::isExperimental() const
@@ -283,7 +269,6 @@ bool PluginSpec::isDisabledByDefault() const
} }
/*! /*!
\fn bool PluginSpec::isEnabledInSettings() const
Returns if the plugin should be loaded at startup. True by default Returns if the plugin should be loaded at startup. True by default
The user can change it from the Plugin settings. The user can change it from the Plugin settings.
Note: That this function returns true even if a plugin is disabled because Note: That this function returns true even if a plugin is disabled because
@@ -295,7 +280,6 @@ bool PluginSpec::isEnabledInSettings() const
} }
/*! /*!
\fn bool PluginSpec::isEffectivelyEnabled() const
Returns if the plugin is loaded at startup. Returns if the plugin is loaded at startup.
\see PluginSpec::isEnabled \see PluginSpec::isEnabled
*/ */
@@ -307,7 +291,6 @@ bool PluginSpec::isEffectivelyEnabled() const
} }
/*! /*!
\fn bool PluginSpec::isDisabledIndirectly() const
Returns true if loading was not done due to user unselecting this plugin or its dependencies. Returns true if loading was not done due to user unselecting this plugin or its dependencies.
*/ */
bool PluginSpec::isDisabledIndirectly() const bool PluginSpec::isDisabledIndirectly() const
@@ -316,7 +299,6 @@ bool PluginSpec::isDisabledIndirectly() const
} }
/*! /*!
\fn bool PluginSpec::isForceEnabled() const
Returns if the plugin is enabled via the -load option on the command line. Returns if the plugin is enabled via the -load option on the command line.
*/ */
bool PluginSpec::isForceEnabled() const bool PluginSpec::isForceEnabled() const
@@ -325,7 +307,6 @@ bool PluginSpec::isForceEnabled() const
} }
/*! /*!
\fn bool PluginSpec::isForceDisabled() const
Returns if the plugin is disabled via the -noload option on the command line. Returns if the plugin is disabled via the -noload option on the command line.
*/ */
bool PluginSpec::isForceDisabled() const bool PluginSpec::isForceDisabled() const
@@ -334,7 +315,6 @@ bool PluginSpec::isForceDisabled() const
} }
/*! /*!
\fn QList<PluginDependency> PluginSpec::dependencies() const
The plugin dependencies. This is valid after the PluginSpec::Read state is reached. The plugin dependencies. This is valid after the PluginSpec::Read state is reached.
*/ */
QList<PluginDependency> PluginSpec::dependencies() const QList<PluginDependency> PluginSpec::dependencies() const
@@ -343,7 +323,6 @@ QList<PluginDependency> PluginSpec::dependencies() const
} }
/*! /*!
\fn PluginSpec::PluginArgumentDescriptions PluginSpec::argumentDescriptions() const
Returns a list of descriptions of command line arguments the plugin processes. Returns a list of descriptions of command line arguments the plugin processes.
*/ */
@@ -353,7 +332,6 @@ PluginSpec::PluginArgumentDescriptions PluginSpec::argumentDescriptions() const
} }
/*! /*!
\fn QString PluginSpec::location() const
The absolute path to the directory containing the plugin xml description file The absolute path to the directory containing the plugin xml description file
this PluginSpec corresponds to. this PluginSpec corresponds to.
*/ */
@@ -363,7 +341,6 @@ QString PluginSpec::location() const
} }
/*! /*!
\fn QString PluginSpec::filePath() const
The absolute path to the plugin xml description file (including the file name) The absolute path to the plugin xml description file (including the file name)
this PluginSpec corresponds to. this PluginSpec corresponds to.
*/ */
@@ -373,7 +350,6 @@ QString PluginSpec::filePath() const
} }
/*! /*!
\fn QStringList PluginSpec::arguments() const
Command line arguments specific to that plugin. Set at startup Command line arguments specific to that plugin. Set at startup
*/ */
@@ -383,7 +359,6 @@ QStringList PluginSpec::arguments() const
} }
/*! /*!
\fn void PluginSpec::setArguments(const QStringList &arguments)
Set the command line arguments specific to that plugin to \a arguments. Set the command line arguments specific to that plugin to \a arguments.
*/ */
@@ -393,7 +368,6 @@ void PluginSpec::setArguments(const QStringList &arguments)
} }
/*! /*!
\fn PluginSpec::addArgument(const QString &argument)
Adds \a argument to the command line arguments specific to that plugin. Adds \a argument to the command line arguments specific to that plugin.
*/ */
@@ -404,7 +378,6 @@ void PluginSpec::addArgument(const QString &argument)
/*! /*!
\fn PluginSpec::State PluginSpec::state() const
The state in which the plugin currently is. The state in which the plugin currently is.
See the description of the PluginSpec::State enum for details. See the description of the PluginSpec::State enum for details.
*/ */
@@ -414,7 +387,6 @@ PluginSpec::State PluginSpec::state() const
} }
/*! /*!
\fn bool PluginSpec::hasError() const
Returns whether an error occurred while reading/starting the plugin. Returns whether an error occurred while reading/starting the plugin.
*/ */
bool PluginSpec::hasError() const bool PluginSpec::hasError() const
@@ -423,7 +395,6 @@ bool PluginSpec::hasError() const
} }
/*! /*!
\fn QString PluginSpec::errorString() const
Detailed, possibly multi-line, error description in case of an error. Detailed, possibly multi-line, error description in case of an error.
*/ */
QString PluginSpec::errorString() const QString PluginSpec::errorString() const
@@ -432,7 +403,6 @@ QString PluginSpec::errorString() const
} }
/*! /*!
\fn bool PluginSpec::provides(const QString &pluginName, const QString &version) const
Returns if this plugin can be used to fill in a dependency of the given Returns if this plugin can be used to fill in a dependency of the given
\a pluginName and \a version. \a pluginName and \a version.
@@ -444,7 +414,6 @@ bool PluginSpec::provides(const QString &pluginName, const QString &version) con
} }
/*! /*!
\fn IPlugin *PluginSpec::plugin() const
The corresponding IPlugin instance, if the plugin library has already been successfully loaded, The corresponding IPlugin instance, if the plugin library has already been successfully loaded,
i.e. the PluginSpec::Loaded state is reached. i.e. the PluginSpec::Loaded state is reached.
*/ */
@@ -454,7 +423,6 @@ IPlugin *PluginSpec::plugin() const
} }
/*! /*!
\fn QList<PluginSpec *> PluginSpec::dependencySpecs() const
Returns the list of dependencies, already resolved to existing plugin specs. Returns the list of dependencies, already resolved to existing plugin specs.
Valid if PluginSpec::Resolved state is reached. Valid if PluginSpec::Resolved state is reached.
@@ -493,7 +461,6 @@ namespace {
const char ARGUMENT_PARAMETER[] = "parameter"; const char ARGUMENT_PARAMETER[] = "parameter";
} }
/*! /*!
\fn PluginSpecPrivate::PluginSpecPrivate(PluginSpec *spec)
\internal \internal
*/ */
PluginSpecPrivate::PluginSpecPrivate(PluginSpec *spec) PluginSpecPrivate::PluginSpecPrivate(PluginSpec *spec)
@@ -512,7 +479,6 @@ PluginSpecPrivate::PluginSpecPrivate(PluginSpec *spec)
} }
/*! /*!
\fn bool PluginSpecPrivate::read(const QString &fileName)
\internal \internal
*/ */
bool PluginSpecPrivate::read(const QString &fileName) bool PluginSpecPrivate::read(const QString &fileName)
@@ -590,7 +556,6 @@ void PluginSpec::setForceDisabled(bool value)
} }
/*! /*!
\fn bool PluginSpecPrivate::reportError(const QString &err)
\internal \internal
*/ */
bool PluginSpecPrivate::reportError(const QString &err) bool PluginSpecPrivate::reportError(const QString &err)
@@ -626,7 +591,6 @@ static inline QString msgUnexpectedToken()
} }
/*! /*!
\fn void PluginSpecPrivate::readPluginSpec(QXmlStreamReader &reader)
\internal \internal
*/ */
void PluginSpecPrivate::readPluginSpec(QXmlStreamReader &reader) void PluginSpecPrivate::readPluginSpec(QXmlStreamReader &reader)
@@ -702,10 +666,8 @@ void PluginSpecPrivate::readPluginSpec(QXmlStreamReader &reader)
} }
/*! /*!
\fn void PluginSpecPrivate::readArgumentDescriptions(QXmlStreamReader &reader)
\internal \internal
*/ */
void PluginSpecPrivate::readArgumentDescriptions(QXmlStreamReader &reader) void PluginSpecPrivate::readArgumentDescriptions(QXmlStreamReader &reader)
{ {
QString element; QString element;
@@ -736,7 +698,6 @@ void PluginSpecPrivate::readArgumentDescriptions(QXmlStreamReader &reader)
} }
/*! /*!
\fn void PluginSpecPrivate::readArgumentDescription(QXmlStreamReader &reader)
\internal \internal
*/ */
void PluginSpecPrivate::readArgumentDescription(QXmlStreamReader &reader) void PluginSpecPrivate::readArgumentDescription(QXmlStreamReader &reader)
@@ -766,7 +727,6 @@ bool PluginSpecPrivate::readBooleanValue(QXmlStreamReader &reader, const char *k
} }
/*! /*!
\fn void PluginSpecPrivate::readDependencies(QXmlStreamReader &reader)
\internal \internal
*/ */
void PluginSpecPrivate::readDependencies(QXmlStreamReader &reader) void PluginSpecPrivate::readDependencies(QXmlStreamReader &reader)
@@ -799,7 +759,6 @@ void PluginSpecPrivate::readDependencies(QXmlStreamReader &reader)
} }
/*! /*!
\fn void PluginSpecPrivate::readDependencyEntry(QXmlStreamReader &reader)
\internal \internal
*/ */
void PluginSpecPrivate::readDependencyEntry(QXmlStreamReader &reader) void PluginSpecPrivate::readDependencyEntry(QXmlStreamReader &reader)
@@ -834,7 +793,6 @@ void PluginSpecPrivate::readDependencyEntry(QXmlStreamReader &reader)
} }
/*! /*!
\fn bool PluginSpecPrivate::provides(const QString &pluginName, const QString &pluginVersion) const
\internal \internal
*/ */
bool PluginSpecPrivate::provides(const QString &pluginName, const QString &pluginVersion) const bool PluginSpecPrivate::provides(const QString &pluginName, const QString &pluginVersion) const
@@ -845,7 +803,6 @@ bool PluginSpecPrivate::provides(const QString &pluginName, const QString &plugi
} }
/*! /*!
\fn QRegExp &PluginSpecPrivate::versionRegExp()
\internal \internal
*/ */
QRegExp &PluginSpecPrivate::versionRegExp() QRegExp &PluginSpecPrivate::versionRegExp()
@@ -854,7 +811,6 @@ QRegExp &PluginSpecPrivate::versionRegExp()
return reg; return reg;
} }
/*! /*!
\fn bool PluginSpecPrivate::isValidVersion(const QString &version)
\internal \internal
*/ */
bool PluginSpecPrivate::isValidVersion(const QString &version) bool PluginSpecPrivate::isValidVersion(const QString &version)
@@ -863,7 +819,6 @@ bool PluginSpecPrivate::isValidVersion(const QString &version)
} }
/*! /*!
\fn int PluginSpecPrivate::versionCompare(const QString &version1, const QString &version2)
\internal \internal
*/ */
int PluginSpecPrivate::versionCompare(const QString &version1, const QString &version2) int PluginSpecPrivate::versionCompare(const QString &version1, const QString &version2)
@@ -888,7 +843,6 @@ int PluginSpecPrivate::versionCompare(const QString &version1, const QString &ve
} }
/*! /*!
\fn bool PluginSpecPrivate::resolveDependencies(const QList<PluginSpec *> &specs)
\internal \internal
*/ */
bool PluginSpecPrivate::resolveDependencies(const QList<PluginSpec *> &specs) bool PluginSpecPrivate::resolveDependencies(const QList<PluginSpec *> &specs)
@@ -956,7 +910,6 @@ void PluginSpecPrivate::disableIndirectlyIfDependencyDisabled()
} }
/*! /*!
\fn bool PluginSpecPrivate::loadLibrary()
\internal \internal
*/ */
bool PluginSpecPrivate::loadLibrary() bool PluginSpecPrivate::loadLibrary()
@@ -1013,7 +966,6 @@ bool PluginSpecPrivate::loadLibrary()
} }
/*! /*!
\fn bool PluginSpecPrivate::initializePlugin()
\internal \internal
*/ */
bool PluginSpecPrivate::initializePlugin() bool PluginSpecPrivate::initializePlugin()
@@ -1043,7 +995,6 @@ bool PluginSpecPrivate::initializePlugin()
} }
/*! /*!
\fn bool PluginSpecPrivate::initializeExtensions()
\internal \internal
*/ */
bool PluginSpecPrivate::initializeExtensions() bool PluginSpecPrivate::initializeExtensions()
@@ -1068,7 +1019,6 @@ bool PluginSpecPrivate::initializeExtensions()
} }
/*! /*!
\fn bool PluginSpecPrivate::delayedInitialize()
\internal \internal
*/ */
bool PluginSpecPrivate::delayedInitialize() bool PluginSpecPrivate::delayedInitialize()
@@ -1086,7 +1036,6 @@ bool PluginSpecPrivate::delayedInitialize()
} }
/*! /*!
\fn bool PluginSpecPrivate::stop()
\internal \internal
*/ */
IPlugin::ShutdownFlag PluginSpecPrivate::stop() IPlugin::ShutdownFlag PluginSpecPrivate::stop()
@@ -1098,7 +1047,6 @@ IPlugin::ShutdownFlag PluginSpecPrivate::stop()
} }
/*! /*!
\fn bool PluginSpecPrivate::kill()
\internal \internal
*/ */
void PluginSpecPrivate::kill() void PluginSpecPrivate::kill()

View File

@@ -265,8 +265,6 @@ QPacketAutoSend QPacketProtocol::send()
} }
/*! /*!
\fn void QPacketProtocol::send(const QPacket & packet)
Transmit the \a packet. Transmit the \a packet.
*/ */
void QPacketProtocol::send(const QPacket & p) void QPacketProtocol::send(const QPacket & p)

View File

@@ -237,7 +237,6 @@ QString QmlError::toString() const
/*! /*!
\relates QmlError \relates QmlError
\fn QDebug operator<<(QDebug debug, const QmlError &error)
Outputs a human readable version of \a error to \a debug. Outputs a human readable version of \a error to \a debug.
*/ */

View File

@@ -39,7 +39,8 @@ HEADERS += \
$$PWD/consoleitem.h \ $$PWD/consoleitem.h \
$$PWD/iscriptevaluator.h \ $$PWD/iscriptevaluator.h \
$$PWD/qmljssimplereader.h \ $$PWD/qmljssimplereader.h \
$$PWD/persistenttrie.h $$PWD/persistenttrie.h \
$$PWD/qmljsqrcparser.h
SOURCES += \ SOURCES += \
$$PWD/qmljsbind.cpp \ $$PWD/qmljsbind.cpp \
@@ -69,7 +70,8 @@ SOURCES += \
$$PWD/consolemanagerinterface.cpp \ $$PWD/consolemanagerinterface.cpp \
$$PWD/consoleitem.cpp \ $$PWD/consoleitem.cpp \
$$PWD/qmljssimplereader.cpp \ $$PWD/qmljssimplereader.cpp \
$$PWD/persistenttrie.cpp $$PWD/persistenttrie.cpp \
$$PWD/qmljsqrcparser.cpp
RESOURCES += \ RESOURCES += \
$$PWD/qmljs.qrc $$PWD/qmljs.qrc

View File

@@ -1,5 +1,5 @@
DEFINES += QMLJS_BUILD_DIR DEFINES += QMLJS_BUILD_DIR
QT +=script QT +=script xml
include(../../qtcreatorlibrary.pri) include(../../qtcreatorlibrary.pri)
include(qmljs-lib.pri) include(qmljs-lib.pri)

View File

@@ -12,7 +12,7 @@ QtcLibrary {
Depends { name: "Utils" } Depends { name: "Utils" }
Depends { name: "LanguageUtils" } Depends { name: "LanguageUtils" }
Depends { name: "Qt"; submodules: ["widgets", "script"] } Depends { name: "Qt"; submodules: ["widgets", "script", "xml"] }
files: [ files: [
"jsoncheck.cpp", "jsoncheck.cpp",
@@ -52,6 +52,8 @@ QtcLibrary {
"qmljsmodelmanagerinterface.h", "qmljsmodelmanagerinterface.h",
"qmljspropertyreader.cpp", "qmljspropertyreader.cpp",
"qmljspropertyreader.h", "qmljspropertyreader.h",
"qmljsqrcparser.cpp",
"qmljsqrcparser.h",
"qmljsreformatter.cpp", "qmljsreformatter.cpp",
"qmljsreformatter.h", "qmljsreformatter.h",
"qmljsrewriter.cpp", "qmljsrewriter.cpp",

View File

@@ -115,6 +115,22 @@ bool Document::isFullySupportedLanguage(Document::Language language)
return false; return false;
} }
bool Document::isQmlLikeOrJsLanguage(Document::Language language)
{
switch (language) {
case QmlLanguage:
case QmlQtQuick1Language:
case QmlQtQuick2Language:
case QmlQbsLanguage:
case QmlProjectLanguage:
case QmlTypeInfoLanguage:
case JavaScriptLanguage:
return true;
default:
return false;
}
}
Document::Document(const QString &fileName, Language language) Document::Document(const QString &fileName, Language language)
: _engine(0) : _engine(0)
, _ast(0) , _ast(0)

View File

@@ -65,6 +65,7 @@ public:
static bool isQmlLikeLanguage(Language languge); static bool isQmlLikeLanguage(Language languge);
static bool isFullySupportedLanguage(Language language); static bool isFullySupportedLanguage(Language language);
static bool isQmlLikeOrJsLanguage(Language language);
protected: protected:
Document(const QString &fileName, Language language); Document(const QString &fileName, Language language);

View File

@@ -35,6 +35,7 @@
#include "qmljstypedescriptionreader.h" #include "qmljstypedescriptionreader.h"
#include "qmljsvalueowner.h" #include "qmljsvalueowner.h"
#include "qmljscontext.h" #include "qmljscontext.h"
#include "qmljsmodelmanagerinterface.h"
#include "parser/qmljsast_p.h" #include "parser/qmljsast_p.h"
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
@@ -2107,13 +2108,19 @@ ImportInfo ImportInfo::pathImport(const QString &docPath, const QString &path,
importFileInfo = QFileInfo(docPath + QDir::separator() + path); importFileInfo = QFileInfo(docPath + QDir::separator() + path);
info._path = importFileInfo.absoluteFilePath(); info._path = importFileInfo.absoluteFilePath();
if (importFileInfo.isFile()) if (importFileInfo.isFile()) {
info._type = FileImport; info._type = FileImport;
else if (importFileInfo.isDir()) } else if (importFileInfo.isDir()) {
info._type = DirectoryImport; info._type = DirectoryImport;
else } else if (path.startsWith(QLatin1String("qrc:"))) {
info._path = path;
if (ModelManagerInterface::instance()->filesAtQrcPath(info.path()).isEmpty())
info._type = QrcDirectoryImport;
else
info._type = QrcFileImport;
} else {
info._type = UnknownFileImport; info._type = UnknownFileImport;
}
info._version = version; info._version = version;
info._as = as; info._as = as;
info._ast = ast; info._ast = ast;
@@ -2192,7 +2199,7 @@ const Value *TypeScope::lookupMember(const QString &name, const Context *context
const ImportInfo &info = i.info; const ImportInfo &info = i.info;
// JS import has no types // JS import has no types
if (info.type() == ImportInfo::FileImport) if (info.type() == ImportInfo::FileImport || info.type() == ImportInfo::QrcFileImport)
continue; continue;
if (!info.as().isEmpty()) { if (!info.as().isEmpty()) {
@@ -2222,7 +2229,7 @@ void TypeScope::processMembers(MemberProcessor *processor) const
const ImportInfo &info = i.info; const ImportInfo &info = i.info;
// JS import has no types // JS import has no types
if (info.type() == ImportInfo::FileImport) if (info.type() == ImportInfo::FileImport || info.type() == ImportInfo::QrcFileImport)
continue; continue;
if (!info.as().isEmpty()) if (!info.as().isEmpty())
@@ -2249,7 +2256,7 @@ const Value *JSImportScope::lookupMember(const QString &name, const Context *,
const ImportInfo &info = i.info; const ImportInfo &info = i.info;
// JS imports are always: import "somefile.js" as Foo // JS imports are always: import "somefile.js" as Foo
if (info.type() != ImportInfo::FileImport) if (info.type() != ImportInfo::FileImport && info.type() != ImportInfo::QrcFileImport)
continue; continue;
if (info.as() == name) { if (info.as() == name) {
@@ -2272,7 +2279,7 @@ void JSImportScope::processMembers(MemberProcessor *processor) const
const ObjectValue *import = i.object; const ObjectValue *import = i.object;
const ImportInfo &info = i.info; const ImportInfo &info = i.info;
if (info.type() == ImportInfo::FileImport) if (info.type() == ImportInfo::FileImport || info.type() == ImportInfo::QrcFileImport)
processor->processProperty(info.as(), import); processor->processProperty(info.as(), import);
} }
} }
@@ -2329,7 +2336,7 @@ ImportInfo Imports::info(const QString &name, const Context *context) const
continue; continue;
} }
if (info.type() == ImportInfo::FileImport) { if (info.type() == ImportInfo::FileImport || info.type() == ImportInfo::QrcFileImport) {
if (import->className() == firstId) if (import->className() == firstId)
return info; return info;
} else { } else {
@@ -2349,7 +2356,7 @@ QString Imports::nameForImportedObject(const ObjectValue *value, const Context *
const ObjectValue *import = i.object; const ObjectValue *import = i.object;
const ImportInfo &info = i.info; const ImportInfo &info = i.info;
if (info.type() == ImportInfo::FileImport) { if (info.type() == ImportInfo::FileImport || info.type() == ImportInfo::QrcFileImport) {
if (import == value) if (import == value)
return import->className(); return import->className();
} else { } else {

View File

@@ -872,6 +872,8 @@ public:
LibraryImport, LibraryImport,
FileImport, FileImport,
DirectoryImport, DirectoryImport,
QrcFileImport,
QrcDirectoryImport,
UnknownFileImport // refers a file/directory that wasn't found UnknownFileImport // refers a file/directory that wasn't found
}; };

View File

@@ -34,6 +34,7 @@
#include "qmljsbind.h" #include "qmljsbind.h"
#include "qmljsutils.h" #include "qmljsutils.h"
#include "qmljsmodelmanagerinterface.h" #include "qmljsmodelmanagerinterface.h"
#include <qmljs/qmljsqrcparser.h>
#include <QDir> #include <QDir>
#include <QDebug> #include <QDebug>
@@ -245,6 +246,8 @@ void LinkPrivate::populateImportedTypes(Imports *imports, Document::Ptr doc)
switch (info.type()) { switch (info.type()) {
case ImportInfo::FileImport: case ImportInfo::FileImport:
case ImportInfo::DirectoryImport: case ImportInfo::DirectoryImport:
case ImportInfo::QrcFileImport:
case ImportInfo::QrcDirectoryImport:
import = importFileOrDirectory(doc, info); import = importFileOrDirectory(doc, info);
break; break;
case ImportInfo::LibraryImport: case ImportInfo::LibraryImport:
@@ -285,7 +288,7 @@ Import LinkPrivate::importFileOrDirectory(Document::Ptr doc, const ImportInfo &i
import.object = 0; import.object = 0;
import.valid = true; import.valid = true;
const QString &path = importInfo.path(); QString path = importInfo.path();
if (importInfo.type() == ImportInfo::DirectoryImport if (importInfo.type() == ImportInfo::DirectoryImport
|| importInfo.type() == ImportInfo::ImplicitDirectoryImport) { || importInfo.type() == ImportInfo::ImplicitDirectoryImport) {
@@ -304,8 +307,36 @@ Import LinkPrivate::importFileOrDirectory(Document::Ptr doc, const ImportInfo &i
Document::Ptr importedDoc = snapshot.document(path); Document::Ptr importedDoc = snapshot.document(path);
if (importedDoc) if (importedDoc)
import.object = importedDoc->bind()->rootObjectValue(); import.object = importedDoc->bind()->rootObjectValue();
} } else if (importInfo.type() == ImportInfo::QrcFileImport) {
QLocale locale;
QStringList filePaths = ModelManagerInterface::instance()
->filesAtQrcPath(path, &locale, 0, ModelManagerInterface::ActiveQrcResources);
if (filePaths.isEmpty()) {
filePaths = ModelManagerInterface::instance()->filesAtQrcPath(path);
}
if (!filePaths.isEmpty()) {
Document::Ptr importedDoc = snapshot.document(filePaths.at(0));
if (importedDoc)
import.object = importedDoc->bind()->rootObjectValue();
}
} else if (importInfo.type() == ImportInfo::QrcDirectoryImport){
import.object = new ObjectValue(valueOwner);
importLibrary(doc, path, &import);
QMapIterator<QString,QStringList> iter(ModelManagerInterface::instance()
->filesInQrcPath(path));
while (iter.hasNext()) {
iter.next();
if (Document::isQmlLikeLanguage(Document::guessLanguageFromSuffix(iter.key()))) {
Document::Ptr importedDoc = snapshot.document(iter.value().at(0));
if (importedDoc && importedDoc->bind()->rootObjectValue()) {
const QString targetName = QFileInfo(iter.key()).baseName();
import.object->setMember(targetName, importedDoc->bind()->rootObjectValue());
}
}
}
}
return import; return import;
} }

View File

@@ -53,6 +53,11 @@ class QMLJS_EXPORT ModelManagerInterface: public QObject
Q_OBJECT Q_OBJECT
public: public:
enum QrcResourceSelector {
ActiveQrcResources,
AllQrcResources
};
class ProjectInfo class ProjectInfo
{ {
public: public:
@@ -80,6 +85,8 @@ public:
QPointer<ProjectExplorer::Project> project; QPointer<ProjectExplorer::Project> project;
QStringList sourceFiles; QStringList sourceFiles;
QStringList importPaths; QStringList importPaths;
QStringList activeResourceFiles;
QStringList allResourceFiles;
// whether trying to run qmldump makes sense // whether trying to run qmldump makes sense
bool tryQmlDump; bool tryQmlDump;
@@ -142,6 +149,14 @@ public:
bool emitDocumentOnDiskChanged) = 0; bool emitDocumentOnDiskChanged) = 0;
virtual void fileChangedOnDisk(const QString &path) = 0; virtual void fileChangedOnDisk(const QString &path) = 0;
virtual void removeFiles(const QStringList &files) = 0; virtual void removeFiles(const QStringList &files) = 0;
virtual QStringList filesAtQrcPath(const QString &path, const QLocale *locale = 0,
ProjectExplorer::Project *project = 0,
QrcResourceSelector resources = AllQrcResources) = 0;
virtual QMap<QString,QStringList> filesInQrcPath(const QString &path,
const QLocale *locale = 0,
ProjectExplorer::Project *project = 0,
bool addDirs = false,
QrcResourceSelector resources = AllQrcResources) = 0;
virtual QList<ProjectInfo> projectInfos() const = 0; virtual QList<ProjectInfo> projectInfos() const = 0;
virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const = 0; virtual ProjectInfo projectInfo(ProjectExplorer::Project *project) const = 0;

View File

@@ -0,0 +1,517 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "qmljsqrcparser.h"
#include <QFile>
#include <QDir>
#include <QFileInfo>
#include <QStringList>
#include <QDomDocument>
#include <QLocale>
#include <QMutex>
#include <QSet>
#include <QMutexLocker>
#include <QMultiHash>
#include <QCoreApplication>
#include <utils/qtcassert.h>
#include <QDebug>
namespace QmlJS {
namespace Internal {
/*!
* \class QrcParser
* \brief Parses one or more qrc files, and keeps their content cached
*
* A Qrc resource contains files read from the filesystem but organized in a possibly different way.
*
* To easily describe that with a simple structure we use a map from qrc paths to the paths in the
* filesystem.
* By using a map we can easily find all qrc paths that start with a given prefix, and thus loop
* on a qrc directory.
*
* Qrc files also support languages, those are mapped to a prefix of the qrc path.
* For example the french /image/bla.png (lang=fr) will have the path "fr/image/bla.png".
* The empty language represent the default resource.
* Languages are looked up using the locale uiLanguages() property
*
* For a single qrc a given path maps to a single file, but when one has multiple
* (platform specific exclusive) qrc files, then multiple files match, so QStringList are used.
*
* Especially the collect* methods are thought as low level interface.
*/
class QrcParserPrivate
{
Q_DECLARE_TR_FUNCTIONS(QmlJS::QrcParser)
public:
typedef QMap<QString,QStringList> SMap;
QrcParserPrivate(QrcParser *q);
bool parseFile(const QString &path);
QString firstFileAtPath(const QString &path, const QLocale &locale) const;
void collectFilesAtPath(const QString &path, QStringList *res, const QLocale *locale = 0) const;
bool hasDirAtPath(const QString &path, const QLocale *locale = 0) const;
void collectFilesInPath(const QString &path, QMap<QString,QStringList> *res, bool addDirs = false,
const QLocale *locale = 0) const;
QStringList errorMessages() const;
QStringList languages() const;
private:
static QString fixPrefix(const QString &prefix);
QStringList allUiLanguages(const QLocale *locale) const;
SMap m_resources;
QStringList m_languages;
QStringList m_errorMessages;
};
class QrcCachePrivate
{
Q_DECLARE_TR_FUNCTIONS(QmlJS::QrcCachePrivate)
public:
QrcCachePrivate(QrcCache *q);
QrcParser::Ptr addPath(const QString &path);
void removePath(const QString &path);
QrcParser::Ptr updatePath(const QString &path);
QrcParser::Ptr parsedPath(const QString &path);
void clear();
private:
QHash<QString, QPair<QrcParser::Ptr,int> > m_cache;
QMutex m_mutex;
};
} // namespace Internal
/*! \brief normalizes the path to a file in a qrc resource by dropping the "qrc:/" or ":" and
* any extra slashes at the beginning
*/
QString QrcParser::normalizedQrcFilePath(const QString &path) {
QString normPath = path;
int endPrefix = 0;
if (path.startsWith(QLatin1String("qrc:/"))) {
endPrefix = 4;
} else if (path.startsWith(QLatin1String(":/"))) {
endPrefix = 1;
}
if (endPrefix < path.size() && path.at(endPrefix) == QLatin1Char('/'))
while (endPrefix + 1 < path.size() && path.at(endPrefix+1) == QLatin1Char('/'))
++endPrefix;
normPath = path.right(path.size()-endPrefix);
if (!normPath.startsWith(QLatin1String("/")))
normPath.insert(0, QLatin1Char('/'));
return normPath;
}
/*! \brief normalizes the path to a directory in a qrc resource by dropping the "qrc:/" or ":" and
* any extra slashes at the beginning, and ensuring it ends with a slash
*/
QString QrcParser::normalizedQrcDirectoryPath(const QString &path) {
QString normPath = normalizedQrcFilePath(path);
if (!normPath.endsWith(QLatin1Char('/')))
normPath.append(QLatin1Char('/'));
return normPath;
}
QrcParser::QrcParser()
{
d = new Internal::QrcParserPrivate(this);
}
QrcParser::~QrcParser()
{
delete d;
}
bool QrcParser::parseFile(const QString &path)
{
return d->parseFile(path);
}
/*! \brief returns fs path of the first (active) file at the given qrc path
*/
QString QrcParser::firstFileAtPath(const QString &path, const QLocale &locale) const
{
return d->firstFileAtPath(path, locale);
}
/*! \brief adds al the fs paths for the given qrc path to *res
* If locale is null all possible files are added, otherwise just the first match
* using that locale.
*/
void QrcParser::collectFilesAtPath(const QString &path, QStringList *res, const QLocale *locale) const
{
d->collectFilesAtPath(path, res, locale);
}
/*! \brief returns true if the given path is a non empty directory
*/
bool QrcParser::hasDirAtPath(const QString &path, const QLocale *locale) const
{
return d->hasDirAtPath(path, locale);
}
/*! \brief adds the directory contents of the given qrc path to res
*
* adds the qrcFileName => fs paths associations contained in the given qrc path
* to res. If addDirs is true directories are also added.
* If locale is null all possible files are added, otherwise just the first match
* using that locale.
*/
void QrcParser::collectFilesInPath(const QString &path, QMap<QString,QStringList> *res, bool addDirs,
const QLocale *locale) const
{
d->collectFilesInPath(path, res, addDirs, locale);
}
/*! \brief returns the errors found while parsing
*/
QStringList QrcParser::errorMessages() const
{
return d->errorMessages();
}
/*! \brief returns all languages used in this qrc resource
*/
QStringList QrcParser::languages() const
{
return d->languages();
}
/*! \brief if the contents are valid
*/
bool QrcParser::isValid() const
{
return errorMessages().isEmpty();
}
QrcParser::Ptr QrcParser::parseQrcFile(const QString &path)
{
Ptr res(new QrcParser);
if (!path.isEmpty())
res->parseFile(path);
return res;
}
// ----------------
QrcCache::QrcCache()
{
d = new Internal::QrcCachePrivate(this);
}
QrcCache::~QrcCache()
{
delete d;
}
QrcParser::ConstPtr QrcCache::addPath(const QString &path)
{
return d->addPath(path);
}
void QrcCache::removePath(const QString &path)
{
d->removePath(path);
}
QrcParser::ConstPtr QrcCache::updatePath(const QString &path)
{
return d->updatePath(path);
}
QrcParser::ConstPtr QrcCache::parsedPath(const QString &path)
{
return d->parsedPath(path);
}
void QrcCache::clear()
{
d->clear();
}
// --------------------
namespace Internal {
QrcParserPrivate::QrcParserPrivate(QrcParser *)
{ }
bool QrcParserPrivate::parseFile(const QString &path)
{
QFile file(path);
if (!file.open(QIODevice::ReadOnly)) {
m_errorMessages.append(file.errorString());
return false;
}
QDomDocument doc;
QString error_msg;
int error_line, error_col;
if (!doc.setContent(&file, &error_msg, &error_line, &error_col)) {
m_errorMessages.append(tr("XML error on line %1, col %2: %3")
.arg(error_line).arg(error_col).arg(error_msg));
return false;
}
QDomElement root = doc.firstChildElement(QLatin1String("RCC"));
if (root.isNull()) {
m_errorMessages.append(tr("The <RCC> root element is missing."));
return false;
}
QDomElement relt = root.firstChildElement(QLatin1String("qresource"));
for (; !relt.isNull(); relt = relt.nextSiblingElement(QLatin1String("qresource"))) {
QString prefix = fixPrefix(relt.attribute(QLatin1String("prefix")));
const QString language = relt.attribute(QLatin1String("lang"));
if (!m_languages.contains(language))
m_languages.append(language);
QDomElement felt = relt.firstChildElement(QLatin1String("file"));
for (; !felt.isNull(); felt = felt.nextSiblingElement(QLatin1String("file"))) {
const QString fileName = felt.text();
QTC_CHECK(!QDir::isAbsolutePath(fileName));
const QString alias = felt.attribute(QLatin1String("alias"));
QString filePath = QFileInfo(path).path() + QLatin1Char('/') + fileName;
QString accessPath;
if (!alias.isEmpty())
accessPath = language + prefix + alias;
else
accessPath = language + prefix + fileName;
if (m_resources.contains(accessPath)) {
QStringList &val = m_resources[accessPath];
if (!val.contains(filePath))
val.append(filePath);
} else {
m_resources.insert(accessPath, QStringList(filePath));
}
}
}
return true;
}
// path is assumed to be a normalized absolute path
QString QrcParserPrivate::firstFileAtPath(const QString &path, const QLocale &locale) const
{
QTC_CHECK(path.startsWith(QLatin1Char('/')));
QStringList langs = allUiLanguages(&locale);
foreach (const QString &language, langs) {
if (m_languages.contains(language)) {
SMap::const_iterator res = m_resources.find(language + path);
if (res != m_resources.end())
return res.value().at(0);
}
}
return QString();
}
void QrcParserPrivate::collectFilesAtPath(const QString &path, QStringList *files,
const QLocale *locale) const
{
QTC_CHECK(path.startsWith(QLatin1Char('/')));
QStringList langs = allUiLanguages(locale);
foreach (const QString &language, langs) {
if (m_languages.contains(language)) {
SMap::const_iterator res = m_resources.find(language + path);
if (res != m_resources.end())
(*files) << res.value();
}
}
}
// path is expected to be normalized and start and end with a slash
bool QrcParserPrivate::hasDirAtPath(const QString &path, const QLocale *locale) const
{
QTC_CHECK(path.startsWith(QLatin1Char('/')));
QTC_CHECK(path.endsWith(QLatin1Char('/')));
QStringList langs = allUiLanguages(locale);
foreach (const QString &language, langs) {
if (m_languages.contains(language)) {
QString key = language + path;
SMap::const_iterator res = m_resources.lowerBound(key);
if (res != m_resources.end() && res.key().startsWith(key))
return true;
}
}
return false;
}
void QrcParserPrivate::collectFilesInPath(const QString &path, QMap<QString,QStringList> *contents,
bool addDirs, const QLocale *locale) const
{
QTC_CHECK(path.startsWith(QLatin1Char('/')));
QTC_CHECK(path.endsWith(QLatin1Char('/')));
SMap::const_iterator end = m_resources.end();
QStringList langs = allUiLanguages(locale);
foreach (const QString &language, langs) {
QString key = language + path;
SMap::const_iterator res = m_resources.lowerBound(key);
while (res != end && res.key().startsWith(key)) {
const QString &actualKey = res.key();
int endDir = actualKey.indexOf(QLatin1Char('/'), key.size());
if (endDir == -1) {
QString fileName = res.key().right(res.key().size()-key.size());
QStringList &els = (*contents)[fileName];
foreach (const QString &val, res.value())
if (!els.contains(val)){
els << val;
}
++res;
} else {
QString dirName = res.key().mid(key.size(), endDir - key.size() + 1);
if (addDirs)
contents->insert(dirName, QStringList());
QString key2 = key + dirName;
do {
++res;
} while (res != end && res.key().startsWith(key2));
}
}
}
}
QStringList QrcParserPrivate::errorMessages() const
{
return m_errorMessages;
}
QStringList QrcParserPrivate::languages() const
{
return m_languages;
}
QString QrcParserPrivate::fixPrefix(const QString &prefix)
{
const QChar slash = QLatin1Char('/');
QString result = QString(slash);
for (int i = 0; i < prefix.size(); ++i) {
const QChar c = prefix.at(i);
if (c == slash && result.at(result.size() - 1) == slash)
continue;
result.append(c);
}
if (!result.endsWith(slash))
result.append(slash);
return result;
}
QStringList QrcParserPrivate::allUiLanguages(const QLocale *locale) const
{
if (!locale)
return languages();
QStringList langs = locale->uiLanguages();
foreach (const QString &language, langs) { // qt4 support
if (language.contains(QLatin1Char('_')) || language.contains(QLatin1Char('-'))) {
QStringList splits = QString(language).replace(QLatin1Char('_'), QLatin1Char('-'))
.split(QLatin1Char('-'));
if (splits.size() > 1 && !langs.contains(splits.at(0)))
langs.append(splits.at(0));
}
}
if (!langs.contains(QString()))
langs.append(QString());
return langs;
}
// ----------------
QrcCachePrivate::QrcCachePrivate(QrcCache *)
{ }
QrcParser::Ptr QrcCachePrivate::addPath(const QString &path)
{
QPair<QrcParser::Ptr,int> currentValue;
{
QMutexLocker l(&m_mutex);
currentValue = m_cache.value(path, qMakePair(QrcParser::Ptr(0), 0));
currentValue.second += 1;
if (currentValue.second > 1) {
m_cache.insert(path, currentValue);
return currentValue.first;
}
}
QrcParser::Ptr newParser = QrcParser::parseQrcFile(path);
if (!newParser->isValid())
qDebug() << "adding invalid qrc " << path << " to the cache:" << newParser->errorMessages();
{
QMutexLocker l(&m_mutex);
QPair<QrcParser::Ptr,int> currentValue = m_cache.value(path, qMakePair(QrcParser::Ptr(0), 0));
if (currentValue.first.isNull())
currentValue.first = newParser;
currentValue.second += 1;
m_cache.insert(path, currentValue);
return currentValue.first;
}
}
void QrcCachePrivate::removePath(const QString &path)
{
QPair<QrcParser::Ptr,int> currentValue;
{
QMutexLocker l(&m_mutex);
currentValue = m_cache.value(path, qMakePair(QrcParser::Ptr(0), 0));
if (currentValue.second == 1) {
m_cache.remove(path);
} else if (currentValue.second > 1) {
currentValue.second -= 1;
m_cache.insert(path, currentValue);
} else {
QTC_CHECK(!m_cache.contains(path));
}
}
}
QrcParser::Ptr QrcCachePrivate::updatePath(const QString &path)
{
QrcParser::Ptr newParser = QrcParser::parseQrcFile(path);
{
QMutexLocker l(&m_mutex);
QPair<QrcParser::Ptr,int> currentValue = m_cache.value(path, qMakePair(QrcParser::Ptr(0), 0));
QTC_CHECK(currentValue.second > 0);
currentValue.first = newParser;
m_cache.insert(path, currentValue);
return currentValue.first;
}
}
QrcParser::Ptr QrcCachePrivate::parsedPath(const QString &path)
{
QMutexLocker l(&m_mutex);
QPair<QrcParser::Ptr,int> currentValue = m_cache.value(path, qMakePair(QrcParser::Ptr(0), 0));
return currentValue.first;
}
void QrcCachePrivate::clear()
{
QMutexLocker l(&m_mutex);
m_cache.clear();
}
} // namespace Internal
} // namespace QmlJS

View File

@@ -0,0 +1,87 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef QMLJSQRCPARSER_H
#define QMLJSQRCPARSER_H
#include "qmljs_global.h"
#include <QMap>
#include <QSharedPointer>
#include <QString>
#include <QStringList>
QT_FORWARD_DECLARE_CLASS(QLocale)
namespace QmlJS {
namespace Internal {
class QrcParserPrivate;
class QrcCachePrivate;
}
class QMLJS_EXPORT QrcParser
{
public:
typedef QSharedPointer<QrcParser> Ptr;
typedef QSharedPointer<const QrcParser> ConstPtr;
~QrcParser();
bool parseFile(const QString &path);
QString firstFileAtPath(const QString &path, const QLocale &locale) const;
void collectFilesAtPath(const QString &path, QStringList *res, const QLocale *locale = 0) const;
bool hasDirAtPath(const QString &path, const QLocale *locale = 0) const;
void collectFilesInPath(const QString &path, QMap<QString,QStringList> *res, bool addDirs = false,
const QLocale *locale = 0) const;
QStringList errorMessages() const;
QStringList languages() const;
bool isValid() const;
static Ptr parseQrcFile(const QString &path);
static QString normalizedQrcFilePath(const QString &path);
static QString normalizedQrcDirectoryPath(const QString &path);
private:
QrcParser();
QrcParser(const QrcParser &);
Internal::QrcParserPrivate *d;
};
class QMLJS_EXPORT QrcCache
{
public:
QrcCache();
~QrcCache();
QrcParser::ConstPtr addPath(const QString &path);
void removePath(const QString &path);
QrcParser::ConstPtr updatePath(const QString &path);
QrcParser::ConstPtr parsedPath(const QString &path);
void clear();
private:
Internal::QrcCachePrivate *d;
};
}
#endif // QMLJSQRCPARSER_H

View File

@@ -30,6 +30,7 @@
#include "qmljsscopechain.h" #include "qmljsscopechain.h"
#include "qmljsbind.h" #include "qmljsbind.h"
#include "qmljsevaluate.h" #include "qmljsevaluate.h"
#include "qmljsmodelmanagerinterface.h"
using namespace QmlJS; using namespace QmlJS;
@@ -310,7 +311,10 @@ void ScopeChain::initializeRootScope()
if (!m_document->bind()->isJsLibrary()) { if (!m_document->bind()->isJsLibrary()) {
foreach (Document::Ptr otherDoc, snapshot) { foreach (Document::Ptr otherDoc, snapshot) {
foreach (const ImportInfo &import, otherDoc->bind()->imports()) { foreach (const ImportInfo &import, otherDoc->bind()->imports()) {
if (import.type() == ImportInfo::FileImport && m_document->fileName() == import.path()) { if ((import.type() == ImportInfo::FileImport && m_document->fileName() == import.path())
|| (import.type() == ImportInfo::QrcFileImport
&& ModelManagerInterface::instance()->filesAtQrcPath(import.path())
.contains(m_document->fileName()))) {
QmlComponentChain *component = new QmlComponentChain(otherDoc); QmlComponentChain *component = new QmlComponentChain(otherDoc);
componentScopes.insert(otherDoc.data(), component); componentScopes.insert(otherDoc.data(), component);
chain->addInstantiatingComponent(component); chain->addInstantiatingComponent(component);

View File

@@ -373,10 +373,12 @@ bool FileSaver::finalize()
return FileSaverBase::finalize(); return FileSaverBase::finalize();
SaveFile *sf = static_cast<SaveFile *>(m_file); SaveFile *sf = static_cast<SaveFile *>(m_file);
if (m_hasError) if (m_hasError) {
sf->rollback(); if (sf->isOpen())
else sf->rollback();
} else {
setResult(sf->commit()); setResult(sf->commit());
}
delete sf; delete sf;
m_file = 0; m_file = 0;
return !m_hasError; return !m_hasError;

View File

@@ -191,8 +191,6 @@ QString SavedAction::toString() const
} }
/*! /*!
\fn QAction *SavedAction::updatedAction(const QString &text)
Adjust the \c text() of the underlying action. Adjust the \c text() of the underlying action.
This can be used to update the item shortly before e.g. a menu is shown. This can be used to update the item shortly before e.g. a menu is shown.

View File

@@ -289,13 +289,11 @@ bool TextFileFormat::writeFile(const QString &fileName, QString plainText, QStri
} }
Utils::FileSaver saver(fileName, fileMode); Utils::FileSaver saver(fileName, fileMode);
if (saver.hasError()) { if (!saver.hasError()) {
*errorString = saver.errorString(); if (hasUtf8Bom && codec->name() == "UTF-8")
return false; saver.write("\xef\xbb\xbf", 3);
saver.write(codec->fromUnicode(plainText));
} }
if (hasUtf8Bom && codec->name() == "UTF-8")
saver.write("\xef\xbb\xbf", 3);
saver.write(codec->fromUnicode(plainText));
const bool ok = saver.finalize(errorString); const bool ok = saver.finalize(errorString);
if (debug) if (debug)
qDebug().nospace() << Q_FUNC_INFO << fileName << ' ' << *this << ' ' << plainText.size() qDebug().nospace() << Q_FUNC_INFO << fileName << ' ' << *this << ' ' << plainText.size()

View File

@@ -289,8 +289,6 @@ Service::~Service()
} }
/*! /*!
\fn QString Service::networkInterface()
Returns the interface on which the service is reachable. Returns the interface on which the service is reachable.
*/ */
QNetworkInterface Service::networkInterface() const QNetworkInterface Service::networkInterface() const

View File

@@ -102,7 +102,6 @@ public:
setIcon(QIcon(QLatin1String(":/images/analyzer_mode.png"))); setIcon(QIcon(QLatin1String(":/images/analyzer_mode.png")));
setPriority(P_MODE_ANALYZE); setPriority(P_MODE_ANALYZE);
setId(MODE_ANALYZE); setId(MODE_ANALYZE);
setType(MODE_EDIT_TYPE);
} }
~AnalyzerMode() ~AnalyzerMode()

View File

@@ -84,6 +84,7 @@ public:
StartMode mode() const { return m_sp.startMode; } StartMode mode() const { return m_sp.startMode; }
virtual void notifyRemoteSetupDone(quint16) {} virtual void notifyRemoteSetupDone(quint16) {}
virtual void notifyRemoteFinished(bool) {}
public slots: public slots:
virtual void logApplicationMessage(const QString &, Utils::OutputFormat) {} virtual void logApplicationMessage(const QString &, Utils::OutputFormat) {}

View File

@@ -206,6 +206,9 @@ void AndroidConfig::save(QSettings &settings) const
settings.setValue(PartitionSizeKey, partitionSize); settings.setValue(PartitionSizeKey, partitionSize);
settings.setValue(AutomaticKitCreationKey, automaticKitCreation); settings.setValue(AutomaticKitCreationKey, automaticKitCreation);
settings.setValue(ToolchainHostKey, toolchainHost); settings.setValue(ToolchainHostKey, toolchainHost);
settings.setValue(MakeExtraSearchDirectory,
makeExtraSearchDirectories.isEmpty() ? QString()
: makeExtraSearchDirectories.at(0));
} }
void AndroidConfigurations::setConfig(const AndroidConfig &devConfigs) void AndroidConfigurations::setConfig(const AndroidConfig &devConfigs)

View File

@@ -572,19 +572,20 @@ void AndroidManager::updateTarget(ProjectExplorer::Target *target, const QString
bool modified = false; bool modified = false;
bool comment = false; bool comment = false;
for (int i = 0; i < lines.size(); i++) { for (int i = 0; i < lines.size(); i++) {
if (lines[i].contains("@ANDROID-")) { QByteArray trimmed = lines[i].trimmed();
commentLines = targetSDKNumber < lines[i].mid(lines[i].lastIndexOf('-') + 1).toInt(); if (trimmed.contains("@ANDROID-")) {
commentLines = targetSDKNumber < trimmed.mid(trimmed.lastIndexOf('-') + 1).toInt();
comment = !comment; comment = !comment;
continue; continue;
} }
if (!comment) if (!comment)
continue; continue;
if (commentLines) { if (commentLines) {
if (!lines[i].trimmed().startsWith("//QtCreator")) { if (!trimmed.startsWith("//QtCreator")) {
lines[i] = "//QtCreator " + lines[i]; lines[i] = "//QtCreator " + lines[i];
modified = true; modified = true;
} }
} else { if (lines[i].trimmed().startsWith("//QtCreator")) { } else { if (trimmed.startsWith("//QtCreator")) {
lines[i] = lines[i].mid(12); lines[i] = lines[i].mid(12);
modified = true; modified = true;
} }

View File

@@ -540,9 +540,7 @@ void BazaarPlugin::showCommitWidget(const QList<VcsBase::VcsBaseClient::StatusIt
return; return;
} }
Core::IEditor *editor = Core::EditorManager::openEditor(saver.fileName(), Core::IEditor *editor = Core::EditorManager::openEditor(saver.fileName(), Constants::COMMIT_ID);
Constants::COMMIT_ID,
Core::EditorManager::ModeSwitch);
if (!editor) { if (!editor) {
outputWindow->appendError(tr("Unable to create an editor for the commit.")); outputWindow->appendError(tr("Unable to create an editor for the commit."));
return; return;

View File

@@ -39,7 +39,7 @@
#include <coreplugin/actionmanager/command.h> #include <coreplugin/actionmanager/command.h>
#include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectexplorer.h>
#include <projectexplorer/session.h> #include <projectexplorer/session.h>
#include <texteditor/basetexteditor.h> #include <texteditor/itexteditor.h>
#include <utils/tooltip/tooltip.h> #include <utils/tooltip/tooltip.h>
#include <utils/tooltip/tipcontents.h> #include <utils/tooltip/tipcontents.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
@@ -237,9 +237,11 @@ void BookmarkView::contextMenuEvent(QContextMenuEvent *event)
QMenu menu; QMenu menu;
QAction *moveUp = menu.addAction(tr("Move Up")); QAction *moveUp = menu.addAction(tr("Move Up"));
QAction *moveDown = menu.addAction(tr("Move Down")); QAction *moveDown = menu.addAction(tr("Move Down"));
QAction *remove = menu.addAction(tr("&Remove"));
QAction *removeAll = menu.addAction(tr("Remove All"));
QAction *editNote = menu.addAction(tr("Edit Note")); QAction *editNote = menu.addAction(tr("Edit Note"));
menu.addSeparator();
QAction *remove = menu.addAction(tr("&Remove"));
menu.addSeparator();
QAction *removeAll = menu.addAction(tr("Remove All"));
m_contextMenuIndex = indexAt(event->pos()); m_contextMenuIndex = indexAt(event->pos());
if (!m_contextMenuIndex.isValid()) { if (!m_contextMenuIndex.isValid()) {
@@ -508,8 +510,8 @@ Bookmark *BookmarkManager::bookmarkForIndex(const QModelIndex &index)
bool BookmarkManager::gotoBookmark(Bookmark *bookmark) bool BookmarkManager::gotoBookmark(Bookmark *bookmark)
{ {
using namespace TextEditor; using namespace TextEditor;
if (ITextEditor *editor = qobject_cast<ITextEditor *>(BaseTextEditorWidget::openEditorAt(bookmark->filePath(), if (ITextEditor *editor = qobject_cast<ITextEditor *>(EditorManager::openEditorAt(bookmark->filePath(),
bookmark->lineNumber()))) { bookmark->lineNumber()))) {
return (editor->currentLine() == bookmark->lineNumber()); return (editor->currentLine() == bookmark->lineNumber());
} }
return false; return false;

View File

@@ -36,7 +36,6 @@
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectexplorer.h>
#include <projectexplorer/session.h> #include <projectexplorer/session.h>
#include <texteditor/basetexteditor.h>
#include <cpptools/cppmodelmanagerinterface.h> #include <cpptools/cppmodelmanagerinterface.h>
#include <cpptools/cpptoolsconstants.h> #include <cpptools/cpptoolsconstants.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
@@ -441,10 +440,7 @@ void Manager::onDocumentUpdated(CPlusPlus::Document::Ptr doc)
void Manager::gotoLocation(const QString &fileName, int line, int column) void Manager::gotoLocation(const QString &fileName, int line, int column)
{ {
bool newEditor = false; Core::EditorManager::openEditorAt(fileName, line, column);
TextEditor::BaseTextEditorWidget::openEditorAt(fileName, line, column, Core::Id(),
Core::EditorManager::IgnoreNavigationHistory,
&newEditor);
} }
/*! /*!

View File

@@ -687,9 +687,7 @@ QString ClearCasePlugin::ccGetFileActivity(const QString &workingDir, const QStr
ClearCaseSubmitEditor *ClearCasePlugin::openClearCaseSubmitEditor(const QString &fileName, bool isUcm) ClearCaseSubmitEditor *ClearCasePlugin::openClearCaseSubmitEditor(const QString &fileName, bool isUcm)
{ {
Core::IEditor *editor = Core::IEditor *editor =
Core::EditorManager::openEditor(fileName, Core::EditorManager::openEditor(fileName, Constants::CLEARCASECHECKINEDITOR_ID);
Constants::CLEARCASECHECKINEDITOR_ID,
Core::EditorManager::ModeSwitch);
ClearCaseSubmitEditor *submitEditor = qobject_cast<ClearCaseSubmitEditor*>(editor); ClearCaseSubmitEditor *submitEditor = qobject_cast<ClearCaseSubmitEditor*>(editor);
QTC_CHECK(submitEditor); QTC_CHECK(submitEditor);
submitEditor->registerActions(m_submitUndoAction, m_submitRedoAction, m_checkInSelectedAction, m_checkInDiffAction); submitEditor->registerActions(m_submitUndoAction, m_submitRedoAction, m_checkInSelectedAction, m_checkInDiffAction);
@@ -932,7 +930,7 @@ void ClearCasePlugin::ccDiffWithPred(const QString &workingDir, const QStringLis
// Show in the same editor if diff has been executed before // Show in the same editor if diff has been executed before
if (Core::IEditor *existingEditor = VcsBase::VcsBaseEditorWidget::locateEditorByTag(tag)) { if (Core::IEditor *existingEditor = VcsBase::VcsBaseEditorWidget::locateEditorByTag(tag)) {
existingEditor->createNew(result); existingEditor->createNew(result);
Core::EditorManager::activateEditor(existingEditor, Core::EditorManager::ModeSwitch); Core::EditorManager::activateEditor(existingEditor);
setDiffBaseDirectory(existingEditor, workingDir); setDiffBaseDirectory(existingEditor, workingDir);
return; return;
} }
@@ -1192,7 +1190,7 @@ void ClearCasePlugin::history(const QString &workingDir,
const QString tag = VcsBase::VcsBaseEditorWidget::editorTag(VcsBase::LogOutput, workingDir, files); const QString tag = VcsBase::VcsBaseEditorWidget::editorTag(VcsBase::LogOutput, workingDir, files);
if (Core::IEditor *editor = VcsBase::VcsBaseEditorWidget::locateEditorByTag(tag)) { if (Core::IEditor *editor = VcsBase::VcsBaseEditorWidget::locateEditorByTag(tag)) {
editor->createNew(response.stdOut); editor->createNew(response.stdOut);
Core::EditorManager::activateEditor(editor, Core::EditorManager::ModeSwitch); Core::EditorManager::activateEditor(editor);
} else { } else {
const QString title = QString::fromLatin1("cc history %1").arg(id); const QString title = QString::fromLatin1("cc history %1").arg(id);
const QString source = VcsBase::VcsBaseEditorWidget::getSource(workingDir, files); const QString source = VcsBase::VcsBaseEditorWidget::getSource(workingDir, files);
@@ -1305,7 +1303,7 @@ void ClearCasePlugin::vcsAnnotate(const QString &workingDir, const QString &file
if (Core::IEditor *editor = VcsBase::VcsBaseEditorWidget::locateEditorByTag(tag)) { if (Core::IEditor *editor = VcsBase::VcsBaseEditorWidget::locateEditorByTag(tag)) {
editor->createNew(res); editor->createNew(res);
VcsBase::VcsBaseEditorWidget::gotoLineOfEditor(editor, lineNumber); VcsBase::VcsBaseEditorWidget::gotoLineOfEditor(editor, lineNumber);
Core::EditorManager::activateEditor(editor, Core::EditorManager::ModeSwitch); Core::EditorManager::activateEditor(editor);
} else { } else {
const QString title = QString::fromLatin1("cc annotate %1").arg(id); const QString title = QString::fromLatin1("cc annotate %1").arg(id);
Core::IEditor *newEditor = showOutputInEditor(title, res, VcsBase::AnnotateOutput, source, codec); Core::IEditor *newEditor = showOutputInEditor(title, res, VcsBase::AnnotateOutput, source, codec);
@@ -1341,7 +1339,7 @@ void ClearCasePlugin::describe(const QString &source, const QString &changeNr)
const QString tag = VcsBase::VcsBaseEditorWidget::editorTag(VcsBase::DiffOutput, source, QStringList(), changeNr); const QString tag = VcsBase::VcsBaseEditorWidget::editorTag(VcsBase::DiffOutput, source, QStringList(), changeNr);
if (Core::IEditor *editor = VcsBase::VcsBaseEditorWidget::locateEditorByTag(tag)) { if (Core::IEditor *editor = VcsBase::VcsBaseEditorWidget::locateEditorByTag(tag)) {
editor->createNew(description); editor->createNew(description);
Core::EditorManager::activateEditor(editor, Core::EditorManager::ModeSwitch); Core::EditorManager::activateEditor(editor);
} else { } else {
const QString title = QString::fromLatin1("cc describe %1").arg(id); const QString title = QString::fromLatin1("cc describe %1").arg(id);
Core::IEditor *newEditor = showOutputInEditor(title, description, VcsBase::DiffOutput, source, codec); Core::IEditor *newEditor = showOutputInEditor(title, description, VcsBase::DiffOutput, source, codec);
@@ -1413,7 +1411,7 @@ Core::IEditor *ClearCasePlugin::showOutputInEditor(const QString& title, const Q
if (codec) if (codec)
e->setCodec(codec); e->setCodec(codec);
Core::IEditor *ie = e->editor(); Core::IEditor *ie = e->editor();
Core::EditorManager::activateEditor(ie, Core::EditorManager::ModeSwitch); Core::EditorManager::activateEditor(ie);
return ie; return ie;
} }

View File

@@ -649,7 +649,7 @@ bool BaseFileWizard::postGenerateOpenEditors(const GeneratedFiles &l, QString *e
{ {
foreach (const Core::GeneratedFile &file, l) { foreach (const Core::GeneratedFile &file, l) {
if (file.attributes() & Core::GeneratedFile::OpenEditorAttribute) { if (file.attributes() & Core::GeneratedFile::OpenEditorAttribute) {
if (!Core::EditorManager::openEditor(file.path(), file.editorId(), Core::EditorManager::ModeSwitch )) { if (!Core::EditorManager::openEditor(file.path(), file.editorId())) {
if (errorMessage) if (errorMessage)
*errorMessage = tr("Failed to open an editor for '%1'.").arg(QDir::toNativeSeparators(file.path())); *errorMessage = tr("Failed to open an editor for '%1'.").arg(QDir::toNativeSeparators(file.path()));
return false; return false;

View File

@@ -109,7 +109,7 @@ const char SPLIT_SIDE_BY_SIDE[] = "QtCreator.SplitSideBySide";
const char SPLIT_NEW_WINDOW[] = "QtCreator.SplitNewWindow"; const char SPLIT_NEW_WINDOW[] = "QtCreator.SplitNewWindow";
const char REMOVE_CURRENT_SPLIT[] = "QtCreator.RemoveCurrentSplit"; const char REMOVE_CURRENT_SPLIT[] = "QtCreator.RemoveCurrentSplit";
const char REMOVE_ALL_SPLITS[] = "QtCreator.RemoveAllSplits"; const char REMOVE_ALL_SPLITS[] = "QtCreator.RemoveAllSplits";
const char GOTO_OTHER_SPLIT[] = "QtCreator.GotoOtherSplit"; const char GOTO_NEXT_SPLIT[] = "QtCreator.GotoOtherSplit";
const char CLOSE[] = "QtCreator.Close"; const char CLOSE[] = "QtCreator.Close";
const char CLOSE_ALTERNATIVE[] = "QtCreator.Close_Alternative"; // temporary, see QTCREATORBUG-72 const char CLOSE_ALTERNATIVE[] = "QtCreator.Close_Alternative"; // temporary, see QTCREATORBUG-72
const char CLOSEALL[] = "QtCreator.CloseAll"; const char CLOSEALL[] = "QtCreator.CloseAll";

View File

@@ -120,7 +120,6 @@ DesignMode::DesignMode()
setIcon(QIcon(QLatin1String(":/fancyactionbar/images/mode_Design.png"))); setIcon(QIcon(QLatin1String(":/fancyactionbar/images/mode_Design.png")));
setPriority(Constants::P_MODE_DESIGN); setPriority(Constants::P_MODE_DESIGN);
setId(Constants::MODE_DESIGN); setId(Constants::MODE_DESIGN);
setType(Constants::MODE_DESIGN_TYPE);
ExtensionSystem::PluginManager::addObject(d->m_coreListener); ExtensionSystem::PluginManager::addObject(d->m_coreListener);

View File

@@ -1352,7 +1352,7 @@ void DocumentManager::executeOpenWithMenuAction(QAction *action)
return; return;
} }
EditorManager::openEditor(entry.fileName, entry.editorFactory->id(), EditorManager::ModeSwitch); EditorManager::openEditor(entry.fileName, entry.editorFactory->id());
return; return;
} }
if (entry.externalEditor) if (entry.externalEditor)

View File

@@ -55,7 +55,6 @@ EditMode::EditMode() :
setIcon(QIcon(QLatin1String(":/fancyactionbar/images/mode_Edit.png"))); setIcon(QIcon(QLatin1String(":/fancyactionbar/images/mode_Edit.png")));
setPriority(Constants::P_MODE_EDIT); setPriority(Constants::P_MODE_EDIT);
setId(Constants::MODE_EDIT); setId(Constants::MODE_EDIT);
setType(Constants::MODE_EDIT_TYPE);
m_rightSplitWidgetLayout->setSpacing(0); m_rightSplitWidgetLayout->setSpacing(0);
m_rightSplitWidgetLayout->setMargin(0); m_rightSplitWidgetLayout->setMargin(0);

View File

@@ -196,7 +196,7 @@ struct EditorManagerPrivate
QAction *m_splitNewWindowAction; QAction *m_splitNewWindowAction;
QAction *m_removeCurrentSplitAction; QAction *m_removeCurrentSplitAction;
QAction *m_removeAllSplitsAction; QAction *m_removeAllSplitsAction;
QAction *m_gotoOtherSplitAction; QAction *m_gotoNextSplitAction;
QAction *m_saveCurrentEditorContextAction; QAction *m_saveCurrentEditorContextAction;
QAction *m_saveAsCurrentEditorContextAction; QAction *m_saveAsCurrentEditorContextAction;
@@ -381,7 +381,7 @@ EditorManager::EditorManager(QWidget *parent) :
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
connect(d->m_splitSideBySideAction, SIGNAL(triggered()), this, SLOT(splitSideBySide())); connect(d->m_splitSideBySideAction, SIGNAL(triggered()), this, SLOT(splitSideBySide()));
d->m_splitNewWindowAction = new QAction(tr("Split New Window"), this); d->m_splitNewWindowAction = new QAction(tr("Open in New Window"), this);
cmd = ActionManager::registerAction(d->m_splitNewWindowAction, Constants::SPLIT_NEW_WINDOW, editManagerContext); cmd = ActionManager::registerAction(d->m_splitNewWindowAction, Constants::SPLIT_NEW_WINDOW, editManagerContext);
cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+E,4") : tr("Ctrl+E,4"))); cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+E,4") : tr("Ctrl+E,4")));
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
@@ -399,11 +399,11 @@ EditorManager::EditorManager(QWidget *parent) :
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
connect(d->m_removeAllSplitsAction, SIGNAL(triggered()), this, SLOT(removeAllSplits())); connect(d->m_removeAllSplitsAction, SIGNAL(triggered()), this, SLOT(removeAllSplits()));
d->m_gotoOtherSplitAction = new QAction(tr("Go to Next Split"), this); d->m_gotoNextSplitAction = new QAction(tr("Go to Next Split or Window"), this);
cmd = ActionManager::registerAction(d->m_gotoOtherSplitAction, Constants::GOTO_OTHER_SPLIT, editManagerContext); cmd = ActionManager::registerAction(d->m_gotoNextSplitAction, Constants::GOTO_NEXT_SPLIT, editManagerContext);
cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+E,o") : tr("Ctrl+E,o"))); cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+E,o") : tr("Ctrl+E,o")));
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
connect(d->m_gotoOtherSplitAction, SIGNAL(triggered()), this, SLOT(gotoOtherSplit())); connect(d->m_gotoNextSplitAction, SIGNAL(triggered()), this, SLOT(gotoNextSplit()));
ActionContainer *medit = ActionManager::actionContainer(Constants::M_EDIT); ActionContainer *medit = ActionManager::actionContainer(Constants::M_EDIT);
ActionContainer *advancedMenu = ActionManager::createMenu(Constants::M_EDIT_ADVANCED); ActionContainer *advancedMenu = ActionManager::createMenu(Constants::M_EDIT_ADVANCED);
@@ -604,13 +604,20 @@ EditorView *EditorManager::viewForEditor(IEditor *editor)
return 0; return 0;
} }
SplitterOrView *EditorManager::findRoot(EditorView *view) SplitterOrView *EditorManager::findRoot(const EditorView *view, int *rootIndex)
{ {
SplitterOrView *current = view->parentSplitterOrView(); SplitterOrView *current = view->parentSplitterOrView();
while (current && !m_instance->d->m_root.contains(current)) { while (current) {
int index = m_instance->d->m_root.indexOf(current);
if (index >= 0) {
if (rootIndex)
*rootIndex = index;
return current;
}
current = current->findParentSplitter(); current = current->findParentSplitter();
} }
return current; QTC_CHECK(false); // we should never have views without a root
return 0;
} }
QList<IEditor *> EditorManager::editorsForFileName(const QString &filename) const QList<IEditor *> EditorManager::editorsForFileName(const QString &filename) const
@@ -691,15 +698,15 @@ void EditorManager::splitNewWindow(Internal::EditorView *view)
context->setContext(Context(Constants::C_EDITORMANAGER)); context->setContext(Context(Constants::C_EDITORMANAGER));
context->setWidget(splitter); context->setWidget(splitter);
ICore::addContextObject(context); ICore::addContextObject(context);
m_instance->d->m_root.append(splitter);
m_instance->d->m_rootContext.append(context);
connect(splitter, SIGNAL(destroyed(QObject*)), m_instance, SLOT(rootDestroyed(QObject*)));
splitter->show(); splitter->show();
ICore::raiseWindow(splitter); ICore::raiseWindow(splitter);
if (newEditor) if (newEditor)
m_instance->activateEditor(splitter->view(), newEditor, IgnoreNavigationHistory); m_instance->activateEditor(splitter->view(), newEditor, IgnoreNavigationHistory);
else else
splitter->view()->setFocus(); splitter->view()->setFocus();
m_instance->d->m_root.append(splitter);
m_instance->d->m_rootContext.append(context);
connect(splitter, SIGNAL(destroyed(QObject*)), m_instance, SLOT(rootDestroyed(QObject*)));
m_instance->updateActions(); m_instance->updateActions();
} }
@@ -1042,15 +1049,15 @@ bool EditorManager::closeEditors(const QList<IEditor*> &editorsToClose, bool ask
if (!newCurrent) if (!newCurrent)
newCurrent = pickUnusedEditor(); newCurrent = pickUnusedEditor();
if (newCurrent) { if (newCurrent) {
activateEditor(view, newCurrent, NoActivate); activateEditor(view, newCurrent, DoNotChangeCurrentEditor);
} else { } else {
QModelIndex idx = d->m_editorModel->firstRestoredEditor(); QModelIndex idx = d->m_editorModel->firstRestoredEditor();
if (idx.isValid()) { if (idx.isValid()) {
activateEditorForIndex(view, idx, NoActivate); activateEditorForIndex(view, idx, DoNotChangeCurrentEditor);
} else { } else {
const QList<IEditor *> editors = d->m_editorModel->editors(); const QList<IEditor *> editors = d->m_editorModel->editors();
if (!editors.isEmpty()) if (!editors.isEmpty())
activateEditor(view, editors.last(), NoActivate); activateEditor(view, editors.last(), DoNotChangeCurrentEditor);
} }
} }
} }
@@ -1105,11 +1112,11 @@ void EditorManager::closeDuplicate(Core::IEditor *editor)
if (!newCurrent) if (!newCurrent)
newCurrent = pickUnusedEditor(); newCurrent = pickUnusedEditor();
if (newCurrent) { if (newCurrent) {
activateEditor(view, newCurrent, NoActivate); activateEditor(view, newCurrent, DoNotChangeCurrentEditor);
} else { } else {
QModelIndex idx = d->m_editorModel->firstRestoredEditor(); QModelIndex idx = d->m_editorModel->firstRestoredEditor();
if (idx.isValid()) if (idx.isValid())
activateEditorForIndex(view, idx, NoActivate); activateEditorForIndex(view, idx, DoNotChangeCurrentEditor);
} }
} }
@@ -1151,6 +1158,18 @@ void EditorManager::activateEditorForIndex(Internal::EditorView *view, const QMo
d->m_editorModel->removeEditor(index); d->m_editorModel->removeEditor(index);
} }
void EditorManager::activateView(EditorView *view)
{
QTC_ASSERT(view, return);
if (IEditor *editor = view->currentEditor()) {
setCurrentEditor(editor, true);
editor->widget()->setFocus();
ICore::raiseWindow(editor->widget());
} else {
setCurrentView(view);
}
}
Core::IEditor *EditorManager::placeEditor(Core::Internal::EditorView *view, Core::IEditor *editor) Core::IEditor *EditorManager::placeEditor(Core::Internal::EditorView *view, Core::IEditor *editor)
{ {
Q_ASSERT(view && editor); Q_ASSERT(view && editor);
@@ -1202,13 +1221,22 @@ Core::IEditor *EditorManager::activateEditor(Core::Internal::EditorView *view, C
editor = placeEditor(view, editor); editor = placeEditor(view, editor);
if (!(flags & NoActivate)) { if (!(flags & DoNotChangeCurrentEditor)) {
setCurrentEditor(editor, (flags & IgnoreNavigationHistory)); setCurrentEditor(editor, (flags & IgnoreNavigationHistory));
if (flags & ModeSwitch) if (!(flags & DoNotMakeVisible)) {
switchToPreferedMode(); // switch to design mode?
if (isVisible()) { if (editor->isDesignModePreferred()) {
editor->widget()->setFocus(); ModeManager::activateMode(Core::Constants::MODE_DESIGN);
ICore::raiseWindow(editor->widget()); ModeManager::setFocusToCurrentMode();
} else {
int rootIndex;
findRoot(view, &rootIndex);
if (rootIndex == 0) // main window --> we might need to switch mode
if (!editor->widget()->isVisible())
ModeManager::activateMode(Core::Constants::MODE_EDIT);
editor->widget()->setFocus();
ICore::raiseWindow(editor->widget());
}
} }
} }
return editor; return editor;
@@ -1394,18 +1422,23 @@ Core::Id EditorManager::getOpenWithEditorId(const QString &fileName,
IEditor *EditorManager::openEditor(const QString &fileName, const Id &editorId, IEditor *EditorManager::openEditor(const QString &fileName, const Id &editorId,
OpenEditorFlags flags, bool *newEditor) OpenEditorFlags flags, bool *newEditor)
{ {
if (flags & EditorManager::OpenInOtherSplit)
m_instance->gotoOtherSplit();
return m_instance->openEditor(m_instance->currentEditorView(), return m_instance->openEditor(m_instance->currentEditorView(),
fileName, editorId, flags, newEditor); fileName, editorId, flags, newEditor);
} }
IEditor *EditorManager::openEditorInNextSplit(const QString &fileName, const Id &editorId, OpenEditorFlags flags, bool *newEditor) IEditor *EditorManager::openEditorAt(const QString &fileName, int line, int column,
const Id &editorId, OpenEditorFlags flags, bool *newEditor)
{ {
if (!m_instance->hasSplitter()) m_instance->cutForwardNavigationHistory();
m_instance->splitSideBySide(); m_instance->addCurrentPositionToNavigationHistory();
OpenEditorFlags tempFlags = flags | IgnoreNavigationHistory;
m_instance->gotoOtherSplit(); Core::IEditor *editor = Core::EditorManager::openEditor(fileName, editorId,
return m_instance->openEditor(m_instance->currentEditorView(), tempFlags, newEditor);
fileName, editorId, flags, newEditor); if (editor && line != -1)
editor->gotoLine(line, column);
return editor;
} }
static int extractLineNumber(QString *fileName) static int extractLineNumber(QString *fileName)
@@ -1548,22 +1581,6 @@ QStringList EditorManager::getOpenFileNames() const
} }
/// Empty mode == figure out the correct mode from the editor
/// forcePrefered = true, switch to the mode even if the editor is visible in another mode
/// forcePrefered = false, only switch if it is not visible
void EditorManager::switchToPreferedMode()
{
Id preferedMode;
// Figure out preferred mode for editor
if (d->m_currentEditor)
preferedMode = d->m_currentEditor->preferredModeType();
if (!preferedMode.isValid())
preferedMode = Id(Constants::MODE_EDIT_TYPE);
ModeManager::activateModeType(preferedMode);
}
IEditor *EditorManager::openEditorWithContents(const Id &editorId, IEditor *EditorManager::openEditorWithContents(const Id &editorId,
QString *titlePattern, QString *titlePattern,
const QString &contents) const QString &contents)
@@ -1973,7 +1990,7 @@ void EditorManager::updateActions()
bool hasSplitter = parentSplitter && parentSplitter->isSplitter(); bool hasSplitter = parentSplitter && parentSplitter->isSplitter();
d->m_removeCurrentSplitAction->setEnabled(hasSplitter); d->m_removeCurrentSplitAction->setEnabled(hasSplitter);
d->m_removeAllSplitsAction->setEnabled(hasSplitter); d->m_removeAllSplitsAction->setEnabled(hasSplitter);
d->m_gotoOtherSplitAction->setEnabled(hasSplitter); d->m_gotoNextSplitAction->setEnabled(hasSplitter || d->m_root.size() > 1);
} }
void EditorManager::setCloseSplitEnabled(SplitterOrView *splitterOrView, bool enable) void EditorManager::setCloseSplitEnabled(SplitterOrView *splitterOrView, bool enable)
@@ -2010,7 +2027,8 @@ QList<IEditor*> EditorManager::visibleEditors() const
if (view->currentEditor()) if (view->currentEditor())
editors.append(view->currentEditor()); editors.append(view->currentEditor());
view = view->findNextView(); view = view->findNextView();
} while (view && view != firstView); QTC_ASSERT(view != firstView, break); // we start with firstView and shouldn't have cycles
} while (view);
} }
} else { } else {
if (root->editor()) if (root->editor())
@@ -2166,7 +2184,7 @@ bool EditorManager::restoreState(const QByteArray &state)
continue; continue;
QFileInfo rfi(autoSaveName(fileName)); QFileInfo rfi(autoSaveName(fileName));
if (rfi.exists() && fi.lastModified() < rfi.lastModified()) if (rfi.exists() && fi.lastModified() < rfi.lastModified())
openEditor(fileName, id); openEditor(fileName, id, DoNotMakeVisible);
else else
d->m_editorModel->addRestoredEditor(fileName, displayName, id); d->m_editorModel->addRestoredEditor(fileName, displayName, id);
} }
@@ -2375,26 +2393,77 @@ void EditorManager::removeAllSplits()
root->unsplitAll(); root->unsplitAll();
} }
/*!
* Moves focus to the next split, cycling through windows.
*/
void EditorManager::gotoNextSplit()
{
EditorView *view = currentEditorView();
if (!view)
return;
EditorView *nextView = view->findNextView();
if (!nextView) {
// we are in the "last" view in this root
int rootIndex = -1;
SplitterOrView *root = findRoot(view, &rootIndex);
QTC_ASSERT(root, return);
QTC_ASSERT(rootIndex >= 0 && rootIndex < d->m_root.size(), return);
// find next root. this might be the same root if there's only one.
int nextRootIndex = rootIndex + 1;
if (nextRootIndex >= d->m_root.size())
nextRootIndex = 0;
nextView = d->m_root.at(nextRootIndex)->findFirstView();
QTC_CHECK(nextView);
}
if (nextView)
activateView(nextView);
}
/*!
* Moves focus to "other" split, possibly creating a split if necessary.
* If there's no split and no other window, a side-by-side split is created.
* If the current window is split, focus is moved to the next split within this window, cycling.
* If the current window is not split, focus is moved to the next window.
*/
void EditorManager::gotoOtherSplit() void EditorManager::gotoOtherSplit()
{ {
EditorView *view = currentEditorView(); EditorView *view = currentEditorView();
if (!view) if (!view)
return; return;
SplitterOrView *root = findRoot(view); EditorView *nextView = view->findNextView();
QTC_ASSERT(root, return); if (!nextView) {
if (!root->isSplitter()) // we are in the "last" view in this root
splitSideBySide(); int rootIndex = -1;
SplitterOrView *root = findRoot(view, &rootIndex);
view = view->findNextView(); QTC_ASSERT(root, return);
if (view) { QTC_ASSERT(rootIndex >= 0 && rootIndex < d->m_root.size(), return);
if (IEditor *editor = view->currentEditor()) { // stay in same window if it is split
setCurrentEditor(editor, true); if (root->isSplitter()) {
editor->widget()->setFocus(); nextView = root->findFirstView();
ICore::raiseWindow(editor->widget()); QTC_CHECK(nextView != view);
} else { } else {
setCurrentView(view); // find next root. this might be the same root if there's only one.
int nextRootIndex = rootIndex + 1;
if (nextRootIndex >= d->m_root.size())
nextRootIndex = 0;
nextView = d->m_root.at(nextRootIndex)->findFirstView();
QTC_CHECK(nextView);
// if we had only one root with only one view, we end up at the startpoint
// in that case we need to split
if (nextView == view) {
QTC_CHECK(!root->isSplitter());
splitSideBySide(); // that deletes 'view'
view = root->findFirstView();
nextView = view->findNextView();
QTC_CHECK(nextView != view);
QTC_CHECK(nextView);
}
} }
} }
if (nextView)
activateView(nextView);
} }
qint64 EditorManager::maxTextFileSize() qint64 EditorManager::maxTextFileSize()

View File

@@ -107,18 +107,20 @@ public:
static EditorToolBar *createToolBar(QWidget *parent = 0); static EditorToolBar *createToolBar(QWidget *parent = 0);
enum OpenEditorFlag { enum OpenEditorFlag {
NoActivate = 1, DoNotChangeCurrentEditor = 1,
IgnoreNavigationHistory = 2, IgnoreNavigationHistory = 2,
ModeSwitch = 4, DoNotMakeVisible = 4,
CanContainLineNumber = 8 CanContainLineNumber = 8,
OpenInOtherSplit = 16
}; };
Q_DECLARE_FLAGS(OpenEditorFlags, OpenEditorFlag) Q_DECLARE_FLAGS(OpenEditorFlags, OpenEditorFlag)
static QString splitLineNumber(QString *fileName); static QString splitLineNumber(QString *fileName);
static IEditor *openEditor(const QString &fileName, const Id &editorId = Id(), static IEditor *openEditor(const QString &fileName, const Id &editorId = Id(),
OpenEditorFlags flags = 0, bool *newEditor = 0); OpenEditorFlags flags = 0, bool *newEditor = 0);
static IEditor *openEditorInNextSplit(const QString &fileName, const Id &editorId = Id(), static IEditor *openEditorAt(const QString &fileName, int line, int column = 0,
OpenEditorFlags flags = 0, bool *newEditor = 0); const Id &editorId = Id(), OpenEditorFlags flags = 0,
bool *newEditor = 0);
static IEditor *openEditorWithContents(const Id &editorId, static IEditor *openEditorWithContents(const Id &editorId,
QString *titlePattern = 0, const QString &contents = QString()); QString *titlePattern = 0, const QString &contents = QString());
@@ -234,6 +236,8 @@ private slots:
void rootDestroyed(QObject *root); void rootDestroyed(QObject *root);
void setCurrentEditorFromContextChange(); void setCurrentEditorFromContextChange();
void gotoNextSplit();
public slots: public slots:
void goBackInNavigationHistory(); void goBackInNavigationHistory();
void goForwardInNavigationHistory(); void goForwardInNavigationHistory();
@@ -257,6 +261,7 @@ private:
IEditor *duplicateEditor(IEditor *editor); IEditor *duplicateEditor(IEditor *editor);
IEditor *activateEditor(Internal::EditorView *view, IEditor *editor, OpenEditorFlags flags = 0); IEditor *activateEditor(Internal::EditorView *view, IEditor *editor, OpenEditorFlags flags = 0);
void activateEditorForIndex(Internal::EditorView *view, const QModelIndex &index, OpenEditorFlags = 0); void activateEditorForIndex(Internal::EditorView *view, const QModelIndex &index, OpenEditorFlags = 0);
void activateView(Internal::EditorView *view);
IEditor *openEditor(Internal::EditorView *view, const QString &fileName, IEditor *openEditor(Internal::EditorView *view, const QString &fileName,
const Id &id = Id(), OpenEditorFlags flags = 0, bool *newEditor = 0); const Id &id = Id(), OpenEditorFlags flags = 0, bool *newEditor = 0);
@@ -264,7 +269,7 @@ private:
void setCurrentView(Internal::EditorView *view); void setCurrentView(Internal::EditorView *view);
Internal::EditorView *currentEditorView() const; Internal::EditorView *currentEditorView() const;
static Internal::EditorView *viewForEditor(IEditor *editor); static Internal::EditorView *viewForEditor(IEditor *editor);
static Internal::SplitterOrView *findRoot(Internal::EditorView *view); static Internal::SplitterOrView *findRoot(const Internal::EditorView *view, int *rootIndex = 0);
void closeEditor(IEditor *editor); void closeEditor(IEditor *editor);
void closeDuplicate(IEditor *editor); void closeDuplicate(IEditor *editor);
@@ -273,7 +278,6 @@ private:
static void splitNewWindow(Internal::EditorView *view); static void splitNewWindow(Internal::EditorView *view);
IEditor *pickUnusedEditor() const; IEditor *pickUnusedEditor() const;
void addDocumentToRecentFiles(IDocument *document); void addDocumentToRecentFiles(IDocument *document);
void switchToPreferedMode();
void updateAutoSave(); void updateAutoSave();
void setCloseSplitEnabled(Internal::SplitterOrView *splitterOrView, bool enable); void setCloseSplitEnabled(Internal::SplitterOrView *splitterOrView, bool enable);
void updateMakeWritableWarning(); void updateMakeWritableWarning();

View File

@@ -144,8 +144,8 @@ EditorView *EditorView::findNextView()
current = parent; current = parent;
parent = current->findParentSplitter(); parent = current->findParentSplitter();
} }
// current has no parent, so just take the very first view // current has no parent, so we are at the top and there is no "next" view
return current->findFirstView(); return 0;
} }
void EditorView::closeView() void EditorView::closeView()
@@ -299,7 +299,7 @@ IEditor *EditorView::currentEditor() const
void EditorView::listSelectionActivated(int index) void EditorView::listSelectionActivated(int index)
{ {
QAbstractItemModel *model = EditorManager::instance()->openedEditorsModel(); QAbstractItemModel *model = EditorManager::instance()->openedEditorsModel();
EditorManager::instance()->activateEditorForIndex(this, model->index(index, 0), Core::EditorManager::ModeSwitch); EditorManager::instance()->activateEditorForIndex(this, model->index(index, 0));
} }
void EditorView::splitHorizontally() void EditorView::splitHorizontally()
@@ -465,11 +465,11 @@ void EditorView::goBackInNavigationHistory()
IEditor *editor = 0; IEditor *editor = 0;
if (location.document) { if (location.document) {
editor = em->activateEditorForDocument(this, location.document, editor = em->activateEditorForDocument(this, location.document,
EditorManager::IgnoreNavigationHistory | EditorManager::ModeSwitch); EditorManager::IgnoreNavigationHistory);
} }
if (!editor) { if (!editor) {
editor = em->openEditor(this, location.fileName, location.id, editor = em->openEditor(this, location.fileName, location.id,
EditorManager::IgnoreNavigationHistory | EditorManager::ModeSwitch); EditorManager::IgnoreNavigationHistory);
if (!editor) { if (!editor) {
m_navigationHistory.removeAt(m_currentNavigationHistoryPosition); m_navigationHistory.removeAt(m_currentNavigationHistoryPosition);
continue; continue;
@@ -492,7 +492,7 @@ void EditorView::goForwardInNavigationHistory()
IEditor *editor = 0; IEditor *editor = 0;
if (location.document) { if (location.document) {
editor = em->activateEditorForDocument(this, location.document, editor = em->activateEditorForDocument(this, location.document,
EditorManager::IgnoreNavigationHistory | EditorManager::ModeSwitch); EditorManager::IgnoreNavigationHistory);
} }
if (!editor) { if (!editor) {
editor = em->openEditor(this, location.fileName, location.id, EditorManager::IgnoreNavigationHistory); editor = em->openEditor(this, location.fileName, location.id, EditorManager::IgnoreNavigationHistory);
@@ -784,13 +784,13 @@ void SplitterOrView::restoreState(const QByteArray &state)
if (!QFile::exists(fileName)) if (!QFile::exists(fileName))
return; return;
IEditor *e = em->openEditor(view(), fileName, Id::fromString(id), Core::EditorManager::IgnoreNavigationHistory IEditor *e = em->openEditor(view(), fileName, Id::fromString(id), Core::EditorManager::IgnoreNavigationHistory
| Core::EditorManager::NoActivate); | Core::EditorManager::DoNotChangeCurrentEditor);
if (!e) { if (!e) {
QModelIndex idx = em->openedEditorsModel()->firstRestoredEditor(); QModelIndex idx = em->openedEditorsModel()->firstRestoredEditor();
if (idx.isValid()) if (idx.isValid())
em->activateEditorForIndex(view(), idx, Core::EditorManager::IgnoreNavigationHistory em->activateEditorForIndex(view(), idx, Core::EditorManager::IgnoreNavigationHistory
| Core::EditorManager::NoActivate); | Core::EditorManager::DoNotChangeCurrentEditor);
} }
if (e) { if (e) {

View File

@@ -68,7 +68,7 @@ public:
virtual QWidget *toolBar() = 0; virtual QWidget *toolBar() = 0;
virtual Id preferredModeType() const { return Id(); } virtual bool isDesignModePreferred() const { return false; }
signals: signals:
void changed(); void changed();

View File

@@ -29,11 +29,12 @@
#include "ieditorfactory.h" #include "ieditorfactory.h"
#include "ieditor.h" #include <utils/qtcassert.h>
#include "editormanager.h"
Core::IDocument *Core::IEditorFactory::open(const QString &fileName) Core::IDocument *Core::IEditorFactory::open(const QString &)
{ {
Core::IEditor *iface = Core::EditorManager::openEditor(fileName, id()); qWarning("This should never be called, use IEditorFactor::createEditor, "
return iface ? iface->document() : 0; "or EditorManager::openEditor instead!");
QTC_CHECK(false);
return 0;
} }

View File

@@ -44,7 +44,7 @@ public:
IEditorFactory(QObject *parent = 0) : IDocumentFactory(parent) {} IEditorFactory(QObject *parent = 0) : IDocumentFactory(parent) {}
virtual IEditor *createEditor(QWidget *parent) = 0; virtual IEditor *createEditor(QWidget *parent) = 0;
virtual IDocument *open(const QString &fileName); virtual IDocument *open(const QString &);
}; };
} // namespace Core } // namespace Core

View File

@@ -189,7 +189,7 @@ void OpenEditorsWidget::handleClicked(const QModelIndex &index)
void OpenEditorsWidget::activateEditor(const QModelIndex &index) void OpenEditorsWidget::activateEditor(const QModelIndex &index)
{ {
selectionModel()->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); selectionModel()->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
EditorManager::instance()->activateEditorForIndex(index, EditorManager::ModeSwitch); EditorManager::instance()->activateEditorForIndex(index);
} }
void OpenEditorsWidget::closeEditor(const QModelIndex &index) void OpenEditorsWidget::closeEditor(const QModelIndex &index)

View File

@@ -225,11 +225,10 @@ void OpenEditorsWindow::selectEditor(QTreeWidgetItem *item)
return; return;
if (IDocument *document = item->data(0, Qt::UserRole).value<IDocument*>()) { if (IDocument *document = item->data(0, Qt::UserRole).value<IDocument*>()) {
EditorView *view = item->data(0, Qt::UserRole+1).value<EditorView*>(); EditorView *view = item->data(0, Qt::UserRole+1).value<EditorView*>();
EditorManager::instance()->activateEditorForDocument(view, document, EditorManager::ModeSwitch); EditorManager::instance()->activateEditorForDocument(view, document);
} else { } else {
if (!EditorManager::openEditor( if (!EditorManager::openEditor(
item->toolTip(0), item->data(0, Qt::UserRole+2).value<Core::Id>(), item->toolTip(0), item->data(0, Qt::UserRole+2).value<Core::Id>())) {
Core::EditorManager::ModeSwitch)) {
EditorManager::instance()->openedEditorsModel()->removeEditor(item->toolTip(0)); EditorManager::instance()->openedEditorsModel()->removeEditor(item->toolTip(0));
delete item; delete item;
} }

View File

@@ -87,7 +87,7 @@ EditorToolBarPrivate::EditorToolBarPrivate(QWidget *parent, EditorToolBar *q) :
m_splitButton(new QToolButton), m_splitButton(new QToolButton),
m_horizontalSplitAction(new QAction(QIcon(QLatin1String(Constants::ICON_SPLIT_HORIZONTAL)), EditorManager::tr("Split"), parent)), m_horizontalSplitAction(new QAction(QIcon(QLatin1String(Constants::ICON_SPLIT_HORIZONTAL)), EditorManager::tr("Split"), parent)),
m_verticalSplitAction(new QAction(QIcon(QLatin1String(Constants::ICON_SPLIT_VERTICAL)), EditorManager::tr("Split Side by Side"), parent)), m_verticalSplitAction(new QAction(QIcon(QLatin1String(Constants::ICON_SPLIT_VERTICAL)), EditorManager::tr("Split Side by Side"), parent)),
m_splitNewWindowAction(new QAction(EditorManager::tr("Split New Window"), parent)), m_splitNewWindowAction(new QAction(EditorManager::tr("Open in New Window"), parent)),
m_closeSplitButton(new QToolButton), m_closeSplitButton(new QToolButton),
m_activeToolBar(0), m_activeToolBar(0),
m_toolBarPlaceholder(new QWidget), m_toolBarPlaceholder(new QWidget),
@@ -311,7 +311,7 @@ void EditorToolBar::changeActiveEditor(int row)
{ {
EditorManager *em = ICore::editorManager(); EditorManager *em = ICore::editorManager();
QAbstractItemModel *model = d->m_editorList->model(); QAbstractItemModel *model = d->m_editorList->model();
em->activateEditorForIndex(model->index(row, 0), EditorManager::ModeSwitch); em->activateEditorForIndex(model->index(row, 0));
} }
void EditorToolBar::listContextMenu(QPoint pos) void EditorToolBar::listContextMenu(QPoint pos)

View File

@@ -49,7 +49,6 @@ public:
QIcon icon() const { return m_icon; } QIcon icon() const { return m_icon; }
int priority() const { return m_priority; } int priority() const { return m_priority; }
Id id() const { return m_id; } Id id() const { return m_id; }
Id type() const { return m_type; }
bool isEnabled() const; bool isEnabled() const;
void setEnabled(bool enabled); void setEnabled(bool enabled);
@@ -57,7 +56,6 @@ public:
void setIcon(const QIcon &icon) { m_icon = icon; } void setIcon(const QIcon &icon) { m_icon = icon; }
void setPriority(int priority) { m_priority = priority; } void setPriority(int priority) { m_priority = priority; }
void setId(Id id) { m_id = id; } void setId(Id id) { m_id = id; }
void setType(Id type) { m_type = type; }
signals: signals:
void enabledStateChanged(bool enabled); void enabledStateChanged(bool enabled);
@@ -67,7 +65,6 @@ private:
QIcon m_icon; QIcon m_icon;
int m_priority; int m_priority;
Id m_id; Id m_id;
Id m_type;
bool m_isEnabled; bool m_isEnabled;
}; };

View File

@@ -861,8 +861,6 @@ IDocument *MainWindow::openFiles(const QStringList &fileNames, ICore::OpenFilesF
} }
} else { } else {
QFlags<EditorManager::OpenEditorFlag> emFlags; QFlags<EditorManager::OpenEditorFlag> emFlags;
if (flags & ICore::SwitchMode)
emFlags = EditorManager::ModeSwitch;
if (flags & ICore::CanContainLineNumbers) if (flags & ICore::CanContainLineNumbers)
emFlags |= EditorManager::CanContainLineNumber; emFlags |= EditorManager::CanContainLineNumber;
IEditor *editor = EditorManager::openEditor(absoluteFilePath, Id(), emFlags); IEditor *editor = EditorManager::openEditor(absoluteFilePath, Id(), emFlags);
@@ -1005,7 +1003,7 @@ void MainWindow::openFileWith()
if (isExternal) if (isExternal)
EditorManager::openExternalEditor(fileName, editorId); EditorManager::openExternalEditor(fileName, editorId);
else else
EditorManager::openEditor(fileName, editorId, Core::EditorManager::ModeSwitch); EditorManager::openEditor(fileName, editorId);
} }
} }
@@ -1289,7 +1287,7 @@ void MainWindow::openRecentFile()
{ {
if (const QAction *action = qobject_cast<const QAction*>(sender())) { if (const QAction *action = qobject_cast<const QAction*>(sender())) {
const DocumentManager::RecentFile file = action->data().value<DocumentManager::RecentFile>(); const DocumentManager::RecentFile file = action->data().value<DocumentManager::RecentFile>();
EditorManager::openEditor(file.first, file.second, EditorManager::ModeSwitch); EditorManager::openEditor(file.first, file.second);
} }
} }

View File

@@ -73,6 +73,7 @@ struct ModeManagerPrivate
Context m_addedContexts; Context m_addedContexts;
int m_oldCurrent; int m_oldCurrent;
bool m_saveSettingsOnModeChange; bool m_saveSettingsOnModeChange;
bool m_modeSelectorVisible;
}; };
static ModeManagerPrivate *d; static ModeManagerPrivate *d;
@@ -100,6 +101,8 @@ ModeManager::ModeManager(Internal::MainWindow *mainWindow,
d->m_actionBar = new Internal::FancyActionBar(modeStack); d->m_actionBar = new Internal::FancyActionBar(modeStack);
d->m_modeStack->addCornerWidget(d->m_actionBar); d->m_modeStack->addCornerWidget(d->m_actionBar);
d->m_saveSettingsOnModeChange = false; d->m_saveSettingsOnModeChange = false;
d->m_modeSelectorVisible = true;
d->m_modeStack->setSelectionWidgetVisible(d->m_modeSelectorVisible);
connect(d->m_modeStack, SIGNAL(currentAboutToShow(int)), SLOT(currentTabAboutToChange(int))); connect(d->m_modeStack, SIGNAL(currentAboutToShow(int)), SLOT(currentTabAboutToChange(int)));
connect(d->m_modeStack, SIGNAL(currentChanged(int)), SLOT(currentTabChanged(int))); connect(d->m_modeStack, SIGNAL(currentChanged(int)), SLOT(currentTabChanged(int)));
@@ -147,21 +150,6 @@ IMode *ModeManager::mode(Id id)
return 0; return 0;
} }
void ModeManager::activateModeType(Id type)
{
if (currentMode() && currentMode()->type() == type)
return;
int index = -1;
for (int i = 0; i < d->m_modes.count(); ++i) {
if (d->m_modes.at(i)->type() == type) {
index = i;
break;
}
}
if (index != -1)
d->m_modeStack->setCurrentIndex(index);
}
void ModeManager::slotActivateMode(int id) void ModeManager::slotActivateMode(int id)
{ {
m_instance->activateMode(Id::fromUniqueIdentifier(id)); m_instance->activateMode(Id::fromUniqueIdentifier(id));
@@ -330,21 +318,22 @@ void ModeManager::setFocusToCurrentMode()
QWidget *widget = mode->widget(); QWidget *widget = mode->widget();
if (widget) { if (widget) {
QWidget *focusWidget = widget->focusWidget(); QWidget *focusWidget = widget->focusWidget();
if (focusWidget) if (!focusWidget)
focusWidget->setFocus(); focusWidget = widget;
else focusWidget->setFocus();
widget->setFocus(); ICore::raiseWindow(focusWidget);
} }
} }
void ModeManager::setModeSelectorVisible(bool visible) void ModeManager::setModeSelectorVisible(bool visible)
{ {
d->m_modeSelectorVisible = visible;
d->m_modeStack->setSelectionWidgetVisible(visible); d->m_modeStack->setSelectionWidgetVisible(visible);
} }
bool ModeManager::isModeSelectorVisible() bool ModeManager::isModeSelectorVisible()
{ {
return d->m_modeStack->isSelectionWidgetVisible(); return d->m_modeSelectorVisible;
} }
ModeManager *ModeManager::instance() ModeManager *ModeManager::instance()

View File

@@ -65,7 +65,6 @@ public:
static void addProjectSelector(QAction *action); static void addProjectSelector(QAction *action);
static void addWidget(QWidget *widget); static void addWidget(QWidget *widget);
static void activateModeType(Id type);
static void activateMode(Id id); static void activateMode(Id id);
static void setFocusToCurrentMode(); static void setFocusToCurrentMode();
static bool isModeSelectorVisible(); static bool isModeSelectorVisible();

View File

@@ -145,7 +145,6 @@ FutureProgress::FutureProgress(QWidget *parent) :
} }
/*! /*!
\fn FutureProgress::~FutureProgress()
\internal \internal
*/ */
FutureProgress::~FutureProgress() FutureProgress::~FutureProgress()
@@ -155,7 +154,6 @@ FutureProgress::~FutureProgress()
} }
/*! /*!
\fn void FutureProgress::setWidget(QWidget *widget)
Sets the \a widget to show below the progress bar. Sets the \a widget to show below the progress bar.
This will be destroyed when the progress indicator is destroyed. This will be destroyed when the progress indicator is destroyed.
Default is to show no widget below the progress indicator. Default is to show no widget below the progress indicator.
@@ -172,7 +170,6 @@ void FutureProgress::setWidget(QWidget *widget)
} }
/*! /*!
\fn void FutureProgress::setTitle(const QString &title)
Changes the \a title of the progress indicator. Changes the \a title of the progress indicator.
*/ */
void FutureProgress::setTitle(const QString &title) void FutureProgress::setTitle(const QString &title)
@@ -181,7 +178,6 @@ void FutureProgress::setTitle(const QString &title)
} }
/*! /*!
\fn QString FutureProgress::title() const
Returns the title of the progress indicator. Returns the title of the progress indicator.
*/ */
QString FutureProgress::title() const QString FutureProgress::title() const
@@ -268,7 +264,6 @@ void FutureProgress::setProgressText(const QString &text)
} }
/*! /*!
\fn void FutureProgress::setFuture(const QFuture<void> &future)
\internal \internal
*/ */
void FutureProgress::setFuture(const QFuture<void> &future) void FutureProgress::setFuture(const QFuture<void> &future)
@@ -277,7 +272,6 @@ void FutureProgress::setFuture(const QFuture<void> &future)
} }
/*! /*!
\fn QFuture<void> FutureProgress::future() const
Returns a QFuture object that represents this running task. Returns a QFuture object that represents this running task.
*/ */
QFuture<void> FutureProgress::future() const QFuture<void> FutureProgress::future() const
@@ -286,7 +280,6 @@ QFuture<void> FutureProgress::future() const
} }
/*! /*!
\fn void FutureProgress::mousePressEvent(QMouseEvent *event)
\internal \internal
*/ */
void FutureProgress::mousePressEvent(QMouseEvent *event) void FutureProgress::mousePressEvent(QMouseEvent *event)
@@ -304,7 +297,6 @@ void FutureProgress::paintEvent(QPaintEvent *)
} }
/*! /*!
\fn bool FutureProgress::hasError() const
Returns the error state of this progress indicator. Returns the error state of this progress indicator.
*/ */
bool FutureProgress::hasError() const bool FutureProgress::hasError() const

View File

@@ -308,7 +308,7 @@ void VariableManager::registerFileVariables(const QByteArray &prefix, const QStr
{ {
registerVariable(prefix + kFilePathPostfix, tr("%1: Full path including file name.").arg(heading)); registerVariable(prefix + kFilePathPostfix, tr("%1: Full path including file name.").arg(heading));
registerVariable(prefix + kPathPostfix, tr("%1: Full path excluding file name.").arg(heading)); registerVariable(prefix + kPathPostfix, tr("%1: Full path excluding file name.").arg(heading));
registerVariable(prefix + kFileNamePostfix, tr("%1: File name without including path.").arg(heading)); registerVariable(prefix + kFileNamePostfix, tr("%1: File name without path.").arg(heading));
registerVariable(prefix + kFileBaseNamePostfix, tr("%1: File base name without path and suffix.").arg(heading)); registerVariable(prefix + kFileBaseNamePostfix, tr("%1: File base name without path and suffix.").arg(heading));
} }

View File

@@ -106,6 +106,11 @@ public:
return result; return result;
} }
void clearCache()
{
m_cachedMatches.clear();
}
void resetCache(const QString &dir) void resetCache(const QString &dir)
{ {
QTC_ASSERT(QDir(dir).isAbsolute(), return); QTC_ASSERT(QDir(dir).isAbsolute(), return);
@@ -226,8 +231,10 @@ IVersionControl* VcsManager::findVersionControlForDirectory(const QString &input
foreach (IVersionControl * versionControl, versionControls) { foreach (IVersionControl * versionControl, versionControls) {
QString topLevel; QString topLevel;
if (versionControl->managesDirectory(directory, &topLevel)) if (versionControl->isConfigured()
&& versionControl->managesDirectory(directory, &topLevel)) {
allThatCanManage.push_back(StringVersionControlPair(topLevel, versionControl)); allThatCanManage.push_back(StringVersionControlPair(topLevel, versionControl));
}
} }
// To properly find a nested repository (say, git checkout inside SVN), // To properly find a nested repository (say, git checkout inside SVN),
@@ -379,4 +386,12 @@ void VcsManager::promptToAdd(const QString &directory, const QStringList &fileNa
} }
} }
void VcsManager::clearVersionControlCache()
{
QStringList repoList = d->m_cachedMatches.keys();
d->clearCache();
foreach (const QString &repo, repoList)
emit repositoryChanged(repo);
}
} // namespace Core } // namespace Core

View File

@@ -95,6 +95,9 @@ public:
signals: signals:
void repositoryChanged(const QString &repository); void repositoryChanged(const QString &repository);
public slots:
void clearVersionControlCache();
private: private:
VcsManagerPrivate *d; VcsManagerPrivate *d;
}; };

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