forked from qt-creator/qt-creator
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:
7
dist/changes-2.8.0
vendored
7
dist/changes-2.8.0
vendored
@@ -90,17 +90,14 @@ C++ Support
|
||||
source (QTCREATORBUG-516)
|
||||
* Added refactoring action that assigns a function return value or new expression
|
||||
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 handling of non-arguments in function parameter scope (QTCREATORBUG-8316)
|
||||
* Fixed crash when adding include for undefined identifier in file that
|
||||
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
|
||||
* Improved support for anonymous classes
|
||||
(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 highlighting of types when there is 'using Namespace::TypeName' (QTCREATORBUG-7903)
|
||||
|
||||
@@ -116,7 +113,6 @@ Diff Viewer
|
||||
* Added file list combo box
|
||||
|
||||
Version Control Systems
|
||||
* Added "Select All" to clean dialog
|
||||
* Git
|
||||
* Added new side-by-side diff viewer
|
||||
* Added support for interactive rebase
|
||||
@@ -131,6 +127,7 @@ Version Control Systems
|
||||
* Added tags to branches dialog
|
||||
* Added ability to save repository location for Gerrit
|
||||
* Added graph toggle button for log viewer
|
||||
* Added "Select All" to clean dialog
|
||||
* ClearCase
|
||||
* Removed useless hijack button for dynamic view
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
\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 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
|
||||
\l{http://qt.gitorious.org/qt}.
|
||||
|
||||
BIN
doc/images/creator-toggle-progress-bar.png
Normal file
BIN
doc/images/creator-toggle-progress-bar.png
Normal file
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 |
@@ -231,7 +231,7 @@
|
||||
|
||||
\note The Mac OS X Snow Leopard (10.6) has a bug that might cause the
|
||||
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
|
||||
|
||||
|
||||
@@ -1322,7 +1322,7 @@
|
||||
existing process or use the \gui {Run in terminal} option in \QC.
|
||||
|
||||
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}.
|
||||
|
||||
However, the usefulness of this security measure seems dubious,
|
||||
|
||||
@@ -57,14 +57,27 @@
|
||||
select \gui {Sort Alphabetically} to arrange the symbols in alphabetic
|
||||
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
|
||||
|
||||
Split the editor view when you want to work on and view multiple files on
|
||||
the same screen.
|
||||
Split the editor view or open the editor in a new window when you want to
|
||||
work on and view multiple files on the same screen or on multiple screens.
|
||||
|
||||
\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
|
||||
|
||||
@@ -82,10 +95,17 @@
|
||||
Side by side split command creates views to the right of the
|
||||
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
|
||||
|
||||
To move between split views, select \gui Window > \gui{Go to Next Split} or
|
||||
press \key{Ctrl+E, O}.
|
||||
To move between split views and detached editor windows, select \gui Window
|
||||
> \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
|
||||
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
|
||||
Method Declaration/Definition}.
|
||||
|
||||
Links are opened in the same split by default. Every operation can also be opened in
|
||||
the next split by prebending \key {Ctrl+E} to the shortcut. For example \key {Ctrl+E,F2}
|
||||
to follow the symbol in the next split. If currently is just one editor open a split will be
|
||||
automatically opened. The default behavior could also be changed in
|
||||
\gui Tools > \gui{Options} > \gui{Text Editor} > \gui Display, by checking
|
||||
\gui{Always Open Links in Next Split}. Additional symbols and switching between definition
|
||||
and decleration is opened in another split. If you change the default behavior the shortcuts
|
||||
for open in next split are used to open the target in the current split.
|
||||
Links are opened in the same split by default. To open links in the next
|
||||
split, prepend \key {Ctrl+E} to the shortcut. For example, press \key {Ctrl+E,F2}
|
||||
to follow the symbol in the next split. If necessary, the view is
|
||||
automatically split. To change the default behavior, select \gui Tools >
|
||||
\gui{Options} > \gui{Text Editor} > \gui Display, and then select
|
||||
\gui{Always Open Links in Next Split}. Additional symbols are displayed and
|
||||
switching between definition and declaration is done in another 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
|
||||
|
||||
|
||||
@@ -2044,11 +2044,24 @@
|
||||
\title Searching with the Locator
|
||||
|
||||
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
|
||||
|
||||
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:
|
||||
|
||||
\list 1
|
||||
@@ -2108,7 +2121,8 @@
|
||||
|
||||
\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
|
||||
|
||||
@@ -2148,7 +2162,7 @@
|
||||
|
||||
\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).
|
||||
|
||||
|
||||
@@ -120,6 +120,24 @@
|
||||
Open the projects and files that were open when you last exited \QC.
|
||||
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
|
||||
|
||||
\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.
|
||||
|
||||
*/
|
||||
|
||||
@@ -66,6 +66,9 @@
|
||||
modes, click the icons, or use the \l{keyboard-shortcuts}
|
||||
{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)
|
||||
and \gui Design mode (2).
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
\row
|
||||
\li Subversion
|
||||
\li \l{http://subversion.apache.org/}
|
||||
\li Subversion version 1.6.17 and later
|
||||
\li
|
||||
\endtable
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
\b {Has a reported issue been addressed?}
|
||||
|
||||
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)
|
||||
\include widgets/creator-faq-qtdesigner.qdocinc
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
You can upload free applications as Debian packages to
|
||||
\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.
|
||||
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.
|
||||
|
||||
You can use the \gui {Publish for Fremantle Extras-devel Free Repository}
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
Only needed if you develop on Windows and if you use a USB connection
|
||||
to run applications on the device. The drivers are
|
||||
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
|
||||
PC_Connectivity_<version>.exe (at the time of writing,
|
||||
PC_Connectivity_0.9.4.exe).
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
bugs.
|
||||
|
||||
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}.
|
||||
|
||||
\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
|
||||
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
|
||||
some Linux distributions. It can cause Qt Designer to crash. For
|
||||
@@ -64,10 +64,10 @@
|
||||
|
||||
\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}
|
||||
|
||||
\li \l{https://bugreports.qt-project.org/browse/QTBUG-12025}
|
||||
\li \l{http://bugreports.qt-project.org/browse/QTBUG-12025}
|
||||
{QTBUG-12025}
|
||||
|
||||
\endlist
|
||||
|
||||
@@ -315,6 +315,11 @@
|
||||
|
||||
\endlist
|
||||
|
||||
\li Python
|
||||
|
||||
Python class and source files that you can use to create Python
|
||||
classes and scripts with UTF-8 encoding.
|
||||
|
||||
\endlist
|
||||
|
||||
\section2 Creating C++ Classes
|
||||
|
||||
@@ -79,5 +79,9 @@
|
||||
\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
|
||||
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"
|
||||
|
||||
*/
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
|
||||
To tailor your BAR packages, you will have to manually edit the application
|
||||
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}.
|
||||
|
||||
\section1 Deploying to QNX Neutrino Devices
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
\page creator-developing-bb10.html
|
||||
\nextpage creator-developing-generic-linux.html
|
||||
|
||||
|
||||
\title Connecting BlackBerry 10 Devices
|
||||
|
||||
\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:
|
||||
|
||||
\list
|
||||
\li \l {https://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 {https://www.blackberry.com/SignedKeys/} {BlackBerry signing code keys}
|
||||
\li \l {http://developer.blackberry.com/native/} {The BlackBerry 10 Native SDK}
|
||||
\li \l {http://developer.blackberry.com/native/} {The BlackBerry 10 Dev Alpha Simulator} if you do not have a BlackBerry DevAlpha device
|
||||
\li BlackBerry code signing keys (https://www.blackberry.com/SignedKeys/)
|
||||
\endlist
|
||||
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ def listOfLocals(varList):
|
||||
for symbol in block:
|
||||
name = symbol.print_name
|
||||
|
||||
if name == "__in_chrg":
|
||||
if name == "__in_chrg" or name == "__PRETTY_FUNCTION__":
|
||||
continue
|
||||
|
||||
# "NotImplementedError: Symbol type not yet supported in
|
||||
@@ -382,6 +382,9 @@ def registerDumper(function):
|
||||
|
||||
def bbsetup(args = ''):
|
||||
global qqDumpers, qqFormats, qqEditable, typeCache
|
||||
qqDumpers = {}
|
||||
qqFormats = {}
|
||||
qqEditable = {}
|
||||
typeCache = {}
|
||||
module = sys.modules[__name__]
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ def registerDumper(function):
|
||||
pass
|
||||
|
||||
def warn(message):
|
||||
print 'XXX="%s",' % message.encode("latin1").replace('"', "'")
|
||||
print '\nWARNING="%s",\n' % message.encode("latin1").replace('"', "'")
|
||||
|
||||
def showException(msg, exType, exValue, exTraceback):
|
||||
warn("**** CAUGHT EXCEPTION: %s ****" % msg)
|
||||
@@ -147,27 +147,9 @@ def showException(msg, exType, exValue, exTraceback):
|
||||
def registerCommand(name, func):
|
||||
pass
|
||||
|
||||
def currentFrame():
|
||||
currentThread = self.process.GetThreadAtIndex(0)
|
||||
return currentThread.GetFrameAtIndex(0)
|
||||
|
||||
def fileName(file):
|
||||
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
|
||||
ArrayCode = None
|
||||
@@ -334,7 +316,12 @@ def simpleEncoding(typeobj):
|
||||
# return Hex2EncodedInt1
|
||||
#if code == IntCode:
|
||||
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:
|
||||
return Hex2EncodedUInt1
|
||||
if size == 2:
|
||||
@@ -352,11 +339,6 @@ def simpleEncoding(typeobj):
|
||||
return Hex2EncodedInt4
|
||||
if size == 8:
|
||||
return Hex2EncodedInt8
|
||||
#if code == FloatCode:
|
||||
# if size == 4:
|
||||
# return Hex2EncodedFloat4
|
||||
# if size == 8:
|
||||
# return Hex2EncodedFloat8
|
||||
return None
|
||||
|
||||
class Children:
|
||||
@@ -495,9 +477,7 @@ class Dumper:
|
||||
self.debugger.HandleCommand("settings set auto-confirm on")
|
||||
self.process = None
|
||||
self.target = None
|
||||
self.pid = None
|
||||
self.eventState = lldb.eStateInvalid
|
||||
self.listener = None
|
||||
self.options = {}
|
||||
self.expandedINames = {}
|
||||
self.passExceptions = True
|
||||
@@ -505,7 +485,7 @@ class Dumper:
|
||||
self.ns = ""
|
||||
self.autoDerefPointers = True
|
||||
self.useDynamicType = True
|
||||
self.useLoop = True
|
||||
self.useFancy = True
|
||||
|
||||
self.currentIName = None
|
||||
self.currentValuePriority = -100
|
||||
@@ -518,6 +498,7 @@ class Dumper:
|
||||
self.currentPrintsAddress = None
|
||||
self.currentChildType = None
|
||||
self.currentChildNumChild = None
|
||||
self.currentWatchers = {}
|
||||
|
||||
self.executable_ = None
|
||||
self.charType_ = None
|
||||
@@ -526,11 +507,12 @@ class Dumper:
|
||||
self.charPtrType_ = None
|
||||
self.voidType_ = None
|
||||
self.isShuttingDown_ = False
|
||||
self.dummyValue = None
|
||||
|
||||
def extractTemplateArgument(self, typename, index):
|
||||
level = 0
|
||||
skipSpace = False
|
||||
inner = ""
|
||||
inner = ''
|
||||
for c in typename[typename.find('<') + 1 : -1]:
|
||||
if c == '<':
|
||||
inner += c
|
||||
@@ -543,7 +525,7 @@ class Dumper:
|
||||
if index == 0:
|
||||
return inner
|
||||
index -= 1
|
||||
inner = ""
|
||||
inner = ''
|
||||
else:
|
||||
inner += c
|
||||
skipSpace = True
|
||||
@@ -624,11 +606,29 @@ class Dumper:
|
||||
return True
|
||||
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):
|
||||
#warn("NUM CHILD: '%s' '%s'" % (numchild, self.currentChildNumChild))
|
||||
#if numchild != self.currentChildNumChild:
|
||||
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):
|
||||
# Higher priority values override lower ones.
|
||||
if priority >= self.currentValuePriority:
|
||||
@@ -681,6 +681,13 @@ class Dumper:
|
||||
return xrange(0, 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):
|
||||
#warn("LOOKUP: %s" % self.target.FindFirstType(name))
|
||||
return self.target.FindFirstType(name)
|
||||
@@ -690,15 +697,6 @@ class Dumper:
|
||||
self.executable_ = executable
|
||||
error = lldb.SBError()
|
||||
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()
|
||||
|
||||
if self.target.IsValid():
|
||||
@@ -706,23 +704,27 @@ class Dumper:
|
||||
else:
|
||||
self.report('state="inferiorsetupfailed",msg="%s",exe="%s"' % (error, executable))
|
||||
|
||||
warn("STATE AFTER LAUNCH: %s" % stateNames[self.process.GetState()])
|
||||
|
||||
def runEngine(self, _):
|
||||
error = lldb.SBError()
|
||||
self.pid = self.process.GetProcessID()
|
||||
self.report('pid="%s"' % self.pid)
|
||||
self.consumeEvents()
|
||||
error = self.process.Continue()
|
||||
self.consumeEvents()
|
||||
self.reportError(error)
|
||||
|
||||
self.report('state="enginerunandinferiorrunok"')
|
||||
|
||||
if self.useLoop:
|
||||
s = threading.Thread(target=self.loop, args=[])
|
||||
s.start()
|
||||
|
||||
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"')
|
||||
|
||||
event = lldb.SBEvent()
|
||||
while True:
|
||||
if listener.WaitForEvent(10000000, event):
|
||||
self.handleEvent(event)
|
||||
else:
|
||||
warn('TIMEOUT')
|
||||
|
||||
def describeError(self, error):
|
||||
desc = lldb.SBStream()
|
||||
error.GetDescription(desc)
|
||||
@@ -749,19 +751,25 @@ class Dumper:
|
||||
self.report('location={file="%s",line="%s",addr="%s"}' % (file, line, frame.pc))
|
||||
|
||||
def reportThreads(self):
|
||||
reasons = ['None', 'Trace', 'Breakpoint', 'Watchpoint', 'Signal', 'Exception',
|
||||
'Exec', 'PlanComplete']
|
||||
result = 'threads={threads=['
|
||||
for i in xrange(0, self.process.GetNumThreads()):
|
||||
thread = self.process.GetThreadAtIndex(i)
|
||||
stopReason = thread.GetStopReason()
|
||||
result += '{id="%d"' % thread.GetThreadID()
|
||||
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 += ',frame={'
|
||||
frame = thread.GetFrameAtIndex(0)
|
||||
result += 'pc="0x%x"' % frame.pc
|
||||
result += ',addr="0x%x"' % frame.pc
|
||||
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 += ',fullname="%s"' % fileName(frame.line_entry.file)
|
||||
result += ',file="%s"' % fileName(frame.line_entry.file)
|
||||
@@ -797,19 +805,12 @@ class Dumper:
|
||||
result += '],hasmore="%s"},' % hasmore
|
||||
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):
|
||||
# Higher priority values override lower ones.
|
||||
if priority >= self.currentTypePriority:
|
||||
self.currentType = str(type)
|
||||
self.currentTypePriority = priority
|
||||
#warn("TYPE: %s PRIORITY: %s" % (type, priority))
|
||||
|
||||
def putBetterType(self, type):
|
||||
try:
|
||||
@@ -817,6 +818,7 @@ class Dumper:
|
||||
except:
|
||||
self.currentType = str(type)
|
||||
self.currentTypePriority = self.currentTypePriority + 1
|
||||
#warn("BETTER TYPE: %s PRIORITY: %s" % (type, self.currentTypePriority))
|
||||
|
||||
def readRawMemory(self, base, size):
|
||||
if size == 0:
|
||||
@@ -883,7 +885,7 @@ class Dumper:
|
||||
formatter.update()
|
||||
numchild = formatter.num_children()
|
||||
self.put('iname="%s",' % self.currentIName)
|
||||
self.put('type="%s",' % typeName)
|
||||
self.putType(typeName)
|
||||
self.put('numchild="%s",' % numchild)
|
||||
self.put('addr="0x%x",' % value.GetLoadAddress())
|
||||
self.putItemCount(numchild)
|
||||
@@ -902,20 +904,39 @@ class Dumper:
|
||||
if value.GetType().IsReferenceType():
|
||||
type = value.GetType().GetDereferencedType().GetPointerType()
|
||||
# FIXME: Find something more direct.
|
||||
origType = value.GetTypeName();
|
||||
value = value.CreateValueFromAddress(value.GetName(),
|
||||
value.AddressOf().GetValueAsUnsigned(), type).Dereference()
|
||||
#value = value.cast(value.dynamic_type)
|
||||
self.putItem(value)
|
||||
self.putBetterType("%s &" % value.GetTypeName())
|
||||
self.putBetterType(origType)
|
||||
return
|
||||
|
||||
# Pointers
|
||||
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
|
||||
|
||||
stripped = self.stripNamespaceFromType(typeName).replace("::", "__")
|
||||
#warn("VALUE: %s" % value)
|
||||
#warn("FANCY: %s" % self.useFancy)
|
||||
if self.useFancy:
|
||||
stripped = self.stripNamespaceFromType(typeName).replace("::", "__")
|
||||
#warn("STRIPPED: %s" % stripped)
|
||||
#warn("DUMPABLE: %s" % (stripped in qqDumpers))
|
||||
if stripped in qqDumpers:
|
||||
self.putType(typeName)
|
||||
qqDumpers[stripped](self, value)
|
||||
@@ -926,8 +947,8 @@ class Dumper:
|
||||
#numchild = 1 if value.MightHaveChildren() else 0
|
||||
numchild = value.GetNumChildren()
|
||||
self.put('iname="%s",' % self.currentIName)
|
||||
self.put('type="%s",' % typeName)
|
||||
self.putValue("" if v is None else v)
|
||||
self.putType(typeName)
|
||||
self.putValue('' if v is None else v)
|
||||
self.put('numchild="%s",' % numchild)
|
||||
self.put('addr="0x%x",' % value.GetLoadAddress())
|
||||
if self.currentIName in self.expandedINames:
|
||||
@@ -945,12 +966,37 @@ class Dumper:
|
||||
|
||||
def reportVariables(self, _ = None):
|
||||
frame = self.currentThread().GetSelectedFrame()
|
||||
self.currentIName = "local"
|
||||
self.currentIName = 'local'
|
||||
self.put('data=[')
|
||||
for value in frame.GetVariables(True, True, False, False):
|
||||
if self.dummyValue is None:
|
||||
self.dummyValue = value
|
||||
with SubItem(self, value):
|
||||
self.put('iname="%s",' % self.currentIName)
|
||||
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.report('')
|
||||
|
||||
@@ -967,6 +1013,7 @@ class Dumper:
|
||||
self.reportVariables()
|
||||
|
||||
def reportRegisters(self, _ = None):
|
||||
return
|
||||
if self.process is None:
|
||||
self.report('process="none"')
|
||||
else:
|
||||
@@ -987,10 +1034,14 @@ class Dumper:
|
||||
def interruptInferior(self, _ = None):
|
||||
if self.process is None:
|
||||
self.report('msg="No process"')
|
||||
else:
|
||||
#self.debugger.DispatchInputInterrupt()
|
||||
return
|
||||
error = self.process.Stop()
|
||||
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):
|
||||
if self.process is None:
|
||||
@@ -1044,12 +1095,9 @@ class Dumper:
|
||||
pass
|
||||
|
||||
def processEvents(self):
|
||||
if self.listener is None:
|
||||
warn("NO LISTENER YET")
|
||||
return
|
||||
event = lldb.SBEvent()
|
||||
while self.listener.PeekAtNextEvent(event):
|
||||
self.listener.GetNextEvent(event)
|
||||
while self.debugger.GetListener().PeekAtNextEvent(event):
|
||||
self.debugger.GetListener().GetNextEvent(event)
|
||||
self.handleEvent(event)
|
||||
|
||||
def describeBreakpoint(self, bp, modelId):
|
||||
@@ -1099,13 +1147,6 @@ class Dumper:
|
||||
bpNew.SetOneShot(int(args["oneshot"]))
|
||||
except:
|
||||
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
|
||||
|
||||
def changeBreakpoint(self, args):
|
||||
@@ -1246,14 +1287,27 @@ class Dumper:
|
||||
def setOptions(self, args):
|
||||
self.options = args
|
||||
|
||||
def updateData(self, args):
|
||||
self.expandedINames = set(args['expanded'].split(','))
|
||||
self.autoDerefPointers = int(args['autoderef'])
|
||||
self.useDynamicType = int(args['dyntype'])
|
||||
# Keep always True for now.
|
||||
#self.passExceptions = args['pe']
|
||||
def setWatchers(self, args):
|
||||
#self.currentWatchers = args['watchers']
|
||||
warn("WATCHERS %s" % self.currentWatchers)
|
||||
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):
|
||||
frame = self.currentFrame();
|
||||
function = frame.GetFunction()
|
||||
@@ -1284,6 +1338,18 @@ class Dumper:
|
||||
result += ',contents="%s"}' % binascii.hexlify(contents)
|
||||
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):
|
||||
result = lldb.SBCommandReturnObject()
|
||||
interpreter = self.debugger.GetCommandInterpreter()
|
||||
@@ -1292,16 +1358,6 @@ class Dumper:
|
||||
for key in items:
|
||||
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):
|
||||
getattr(self, args['cmd'])(args)
|
||||
self.report('token="%s"' % args['token'])
|
||||
@@ -1311,8 +1367,8 @@ class Dumper:
|
||||
|
||||
def consumeEvents(self):
|
||||
event = lldb.SBEvent()
|
||||
if self.listener and self.listener.PeekAtNextEvent(event):
|
||||
self.listener.GetNextEvent(event)
|
||||
if self.debugger.GetListener().PeekAtNextEvent(event):
|
||||
self.debugger.GetListener().GetNextEvent(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"))
|
||||
|
||||
|
||||
def doit1():
|
||||
def doit():
|
||||
|
||||
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"')
|
||||
|
||||
while True:
|
||||
@@ -1348,49 +1386,64 @@ def doit2():
|
||||
for reader in readable:
|
||||
if reader == sys.stdin:
|
||||
line = sys.stdin.readline()
|
||||
#warn("READING LINE %s" % line)
|
||||
#warn("READING LINE '%s'" % line)
|
||||
if line.startswith("db "):
|
||||
db.execute(eval(line[3:]))
|
||||
|
||||
|
||||
def testit():
|
||||
def testit1():
|
||||
|
||||
db = Dumper()
|
||||
db.useLoop = False
|
||||
|
||||
error = lldb.SBError()
|
||||
db.target = db.debugger.CreateTarget(sys.argv[2], None, None, True, error)
|
||||
#db.importDumpers()
|
||||
|
||||
bpNew = db.target.BreakpointCreateByName('breakHere', 'doit')
|
||||
|
||||
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()
|
||||
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':'main',
|
||||
'oneshot':0,'enabled':1,'file':'','line':0}]})
|
||||
db.runEngine({'cmd':'runEngine','token':4})
|
||||
|
||||
while True:
|
||||
event = lldb.SBEvent()
|
||||
if db.listener.WaitForEvent(1, event):
|
||||
out = lldb.SBStream()
|
||||
event.GetDescription(out)
|
||||
warn("EVENT: %s" % event)
|
||||
type = event.GetType()
|
||||
msg = lldb.SBEvent.GetCStringFromEvent(event)
|
||||
flavor = event.GetDataFlavor()
|
||||
state = lldb.SBProcess.GetStateFromEvent(event)
|
||||
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])
|
||||
if type == lldb.SBProcess.eBroadcastBitStateChanged:
|
||||
#if state == lldb.eStateStopped:
|
||||
#db.reportData()
|
||||
pass
|
||||
readable, _, _ = select.select([sys.stdin], [], [])
|
||||
for reader in readable:
|
||||
if reader == sys.stdin:
|
||||
line = sys.stdin.readline().strip()
|
||||
#warn("READING LINE '%s'" % line)
|
||||
if line.startswith("db "):
|
||||
db.execute(eval(line[3:]))
|
||||
else:
|
||||
warn('TIMEOUT')
|
||||
db.executeDebuggerCommand({'command':line})
|
||||
|
||||
|
||||
# Used in dumper auto test.
|
||||
# Usage: python lbridge.py /path/to/testbinary comma-separated-inames
|
||||
def testit():
|
||||
|
||||
db = Dumper()
|
||||
|
||||
# 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:
|
||||
testit()
|
||||
else:
|
||||
doit2()
|
||||
doit()
|
||||
|
||||
@@ -433,8 +433,8 @@ def qdump__QFixed(d, value):
|
||||
|
||||
|
||||
def qdump__QFiniteStack(d, value):
|
||||
alloc = value["_alloc"]
|
||||
size = value["_size"]
|
||||
alloc = int(value["_alloc"])
|
||||
size = int(value["_size"])
|
||||
check(0 <= size and size <= alloc and alloc <= 1000 * 1000 * 1000)
|
||||
d.putItemCount(size)
|
||||
d.putNumChild(size)
|
||||
@@ -483,7 +483,7 @@ def qdump__QHash(d, value):
|
||||
val = value.cast(hashDataType)
|
||||
bucket = val["buckets"]
|
||||
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
|
||||
if n < 0:
|
||||
break
|
||||
@@ -497,8 +497,8 @@ def qdump__QHash(d, value):
|
||||
if next["next"]:
|
||||
return next
|
||||
d = node.cast(hashDataType.pointer()).dereference()
|
||||
numBuckets = d["numBuckets"]
|
||||
start = (node["h"] % numBuckets) + 1
|
||||
numBuckets = int(d["numBuckets"])
|
||||
start = (int(node["h"]) % numBuckets) + 1
|
||||
bucket = d["buckets"] + start
|
||||
for n in xrange(numBuckets - start):
|
||||
if bucket.dereference() != next:
|
||||
@@ -511,7 +511,7 @@ def qdump__QHash(d, value):
|
||||
|
||||
d_ptr = value["d"]
|
||||
e_ptr = value["e"]
|
||||
size = d_ptr["size"]
|
||||
size = int(d_ptr["size"])
|
||||
|
||||
hashDataType = d_ptr.type
|
||||
hashNodeType = e_ptr.type
|
||||
@@ -644,7 +644,7 @@ def qform__QImage():
|
||||
|
||||
def qdump__QImage(d, value):
|
||||
try:
|
||||
painters = value["painters"]
|
||||
painters = int(value["painters"])
|
||||
except:
|
||||
d.putPlainChildren(value)
|
||||
return
|
||||
@@ -696,7 +696,7 @@ def qdump__QImage(d, value):
|
||||
def qdump__QLinkedList(d, value):
|
||||
d_ptr = value["d"]
|
||||
e_ptr = value["e"]
|
||||
n = d_ptr["size"]
|
||||
n = int(d_ptr["size"])
|
||||
check(0 <= n and n <= 100*1000*1000)
|
||||
checkRef(d_ptr["ref"])
|
||||
d.putItemCount(n)
|
||||
@@ -762,7 +762,7 @@ def qdump__QMapNode(d, value):
|
||||
def qdumpHelper__Qt4_QMap(d, value, forceLong):
|
||||
d_ptr = value["d"].dereference()
|
||||
e_ptr = value["e"].dereference()
|
||||
n = d_ptr["size"]
|
||||
n = int(d_ptr["size"])
|
||||
check(0 <= n and n <= 100*1000*1000)
|
||||
checkRef(d_ptr["ref"])
|
||||
|
||||
@@ -810,7 +810,7 @@ def qdumpHelper__Qt4_QMap(d, value, forceLong):
|
||||
|
||||
def qdumpHelper__Qt5_QMap(d, value, forceLong):
|
||||
d_ptr = value["d"].dereference()
|
||||
n = d_ptr["size"]
|
||||
n = int(d_ptr["size"])
|
||||
check(0 <= n and n <= 100*1000*1000)
|
||||
checkRef(d_ptr["ref"])
|
||||
|
||||
@@ -1325,7 +1325,7 @@ def qdump__QObject(d, value):
|
||||
# }
|
||||
|
||||
def qdump__QPixmap(d, value):
|
||||
painters = value["painters"]
|
||||
painters = int(value["painters"])
|
||||
check(0 <= painters and painters < 1000)
|
||||
d_ptr = value["data"]["d"]
|
||||
if isNull(d_ptr):
|
||||
@@ -1337,11 +1337,8 @@ def qdump__QPixmap(d, value):
|
||||
|
||||
|
||||
def qdump__QPoint(d, value):
|
||||
x = value["xp"]
|
||||
y = 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())
|
||||
x = int(value["xp"])
|
||||
y = int(value["yp"])
|
||||
d.putValue("(%s, %s)" % (x, y))
|
||||
d.putNumChild(2)
|
||||
if d.isExpanded():
|
||||
@@ -1350,7 +1347,13 @@ def qdump__QPoint(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):
|
||||
@@ -1463,7 +1466,7 @@ def qdump__QSet(d, value):
|
||||
|
||||
d_ptr = value["q_hash"]["d"]
|
||||
e_ptr = value["q_hash"]["e"]
|
||||
size = d_ptr["size"]
|
||||
size = int(d_ptr["size"])
|
||||
|
||||
hashDataType = d_ptr.type
|
||||
hashNodeType = e_ptr.type
|
||||
@@ -1894,11 +1897,11 @@ def qdump__QWeakPointer(d, value):
|
||||
d.putValue("<invalid>")
|
||||
d.putNumChild(0)
|
||||
return
|
||||
weakref = d_ptr["weakref"]["_q_value"]
|
||||
strongref = d_ptr["strongref"]["_q_value"]
|
||||
check(int(strongref) >= -1)
|
||||
check(int(strongref) <= int(weakref))
|
||||
check(int(weakref) <= 10*1000*1000)
|
||||
weakref = int(d_ptr["weakref"]["_q_value"])
|
||||
strongref = int(d_ptr["strongref"]["_q_value"])
|
||||
check(strongref >= -1)
|
||||
check(strongref <= weakref)
|
||||
check(weakref <= 10*1000*1000)
|
||||
|
||||
if isSimpleType(val.dereference().type):
|
||||
d.putNumChild(3)
|
||||
@@ -2045,7 +2048,7 @@ def qform__std__map():
|
||||
|
||||
def qdump__std__map(d, value):
|
||||
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)
|
||||
d.putItemCount(size)
|
||||
d.putNumChild(size)
|
||||
@@ -2149,7 +2152,7 @@ def qdump__std__set__const_iterator(d, value):
|
||||
|
||||
def qdump__std__set(d, value):
|
||||
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)
|
||||
d.putItemCount(size)
|
||||
d.putNumChild(size)
|
||||
@@ -2217,6 +2220,13 @@ def qdump__std__string(d, value):
|
||||
mem = d.readRawMemory(p, size * charType.sizeof)
|
||||
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):
|
||||
i = value["_M_ptr"]
|
||||
@@ -2328,7 +2338,7 @@ def qdump__wstring(d, value):
|
||||
|
||||
def qdump____gnu_cxx__hash_set(d, value):
|
||||
ht = value["_M_ht"]
|
||||
size = ht["_M_num_elements"]
|
||||
size = int(ht["_M_num_elements"])
|
||||
check(0 <= size and size <= 1000 * 1000 * 1000)
|
||||
d.putItemCount(size)
|
||||
d.putNumChild(size)
|
||||
@@ -2398,11 +2408,11 @@ def qdump__boost__shared_ptr(d, value):
|
||||
return
|
||||
|
||||
countedbase = value["pn"]["pi_"].dereference()
|
||||
weakcount = countedbase["weak_count_"]
|
||||
usecount = countedbase["use_count_"]
|
||||
check(int(weakcount) >= 0)
|
||||
check(int(weakcount) <= int(usecount))
|
||||
check(int(usecount) <= 10*1000*1000)
|
||||
weakcount = int(countedbase["weak_count_"])
|
||||
usecount = int(countedbase["use_count_"])
|
||||
check(weakcount >= 0)
|
||||
check(weakcount <= int(usecount))
|
||||
check(usecount <= 10*1000*1000)
|
||||
|
||||
val = value["px"].dereference()
|
||||
if isSimpleType(val.type):
|
||||
|
||||
@@ -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>
|
||||
@@ -55,7 +55,9 @@ enum InformationName
|
||||
IsAnchoredBySibling,
|
||||
HasContent,
|
||||
HasBindingForProperty,
|
||||
ContentTransform
|
||||
ContentTransform,
|
||||
ContentItemTransform,
|
||||
ContentItemBoundingRect
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -143,8 +143,6 @@ QImage GraphicalNodeInstance::renderImage() const
|
||||
|
||||
QImage renderImage = designerSupport()->renderImageForItem(quickItem(), renderBoundingRect, renderBoundingRect.size().toSize());
|
||||
|
||||
renderImage = renderImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
||||
|
||||
return renderImage;
|
||||
}
|
||||
|
||||
|
||||
@@ -887,8 +887,10 @@ static QVector<InformationContainer> createInformationVector(const QList<ServerN
|
||||
informationVector.append(InformationContainer(instance.instanceId(), SceneTransform, instance.sceneTransform()));
|
||||
informationVector.append(InformationContainer(instance.instanceId(), Size, instance.size()));
|
||||
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(), ContentTransform, instance.contentTransform()));
|
||||
informationVector.append(InformationContainer(instance.instanceId(), ContentItemTransform, instance.contentItemTransform()));
|
||||
informationVector.append(InformationContainer(instance.instanceId(), HasContent, instance.hasContent()));
|
||||
informationVector.append(InformationContainer(instance.instanceId(), IsMovable, instance.isMovable()));
|
||||
informationVector.append(InformationContainer(instance.instanceId(), IsResizable, instance.isResizable()));
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <QDebug>
|
||||
#include <QSharedPointer>
|
||||
#include <private/qqmlmetatype_p.h>
|
||||
#include <QQmlProperty>
|
||||
|
||||
namespace QmlDesigner {
|
||||
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
|
||||
return;
|
||||
@@ -64,44 +65,59 @@ void NodeInstanceSignalSpy::registerObject(QObject *spiedObject, const PropertyN
|
||||
index++) {
|
||||
QMetaProperty metaProperty = spiedObject->metaObject()->property(index);
|
||||
|
||||
// handle dot properties and connect the signals to the object
|
||||
if (metaProperty.isReadable()
|
||||
&& !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++;
|
||||
registerProperty(metaProperty, spiedObject);
|
||||
registerChildObject(metaProperty, spiedObject);
|
||||
}
|
||||
}
|
||||
|
||||
// search recursive in objects
|
||||
void NodeInstanceSignalSpy::registerProperty(const QMetaProperty &metaProperty, QObject *spiedObject, const PropertyName &propertyPrefix)
|
||||
{
|
||||
if (metaProperty.isReadable()
|
||||
&& metaProperty.isWritable()
|
||||
&& QQmlMetaType::isQObject(metaProperty.userType())
|
||||
&& QLatin1String(metaProperty.name()) != QLatin1String("parent")) {
|
||||
QObject *propertyObject = QQmlMetaType::toQObject(metaProperty.read(spiedObject));
|
||||
if (propertyObject)
|
||||
registerObject(propertyObject, prefix + metaProperty.name() + '/');
|
||||
}
|
||||
&& !QQmlMetaType::isQObject(metaProperty.userType())
|
||||
&& metaProperty.hasNotifySignal()) {
|
||||
QMetaMethod metaMethod = metaProperty.notifySignal();
|
||||
QMetaObject::connect(spiedObject, metaMethod.methodIndex(), this, methodeOffset, Qt::DirectConnection);
|
||||
|
||||
// search recursive in objects list
|
||||
m_indexPropertyHash.insert(methodeOffset, propertyPrefix + PropertyName(metaProperty.name()));
|
||||
|
||||
registerValueType(metaProperty, spiedObject, propertyPrefix);
|
||||
|
||||
methodeOffset++;
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
&& QQmlMetaType::isList(metaProperty.userType())) {
|
||||
QQmlListReference list(spiedObject, metaProperty.name());
|
||||
&& !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 (list.canCount() && list.canAt()) {
|
||||
|
||||
for (int i = 0; i < list.count(); i++) {
|
||||
QObject *propertyObject = list.at(i);
|
||||
if (propertyObject)
|
||||
registerObject(propertyObject, prefix + 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()) + '.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,7 +129,8 @@ int NodeInstanceSignalSpy::qt_metacall(QMetaObject::Call call, int methodId, voi
|
||||
ObjectNodeInstance::Pointer nodeInstance = m_objectNodeInstance.toStrongRef();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -54,11 +54,14 @@ public:
|
||||
virtual int qt_metacall(QMetaObject::Call, int, void **);
|
||||
|
||||
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:
|
||||
int methodeOffset;
|
||||
QHash<int, PropertyName> m_indexPropertyHash;
|
||||
QMultiHash<int, PropertyName> m_indexPropertyHash;
|
||||
QObjectList m_registeredObjectList;
|
||||
ObjectNodeInstanceWeakPointer m_objectNodeInstance;
|
||||
};
|
||||
|
||||
@@ -255,6 +255,11 @@ QTransform ObjectNodeInstance::customTransform() const
|
||||
return QTransform();
|
||||
}
|
||||
|
||||
QTransform ObjectNodeInstance::contentItemTransform() const
|
||||
{
|
||||
return QTransform();
|
||||
}
|
||||
|
||||
QTransform ObjectNodeInstance::sceneTransform() const
|
||||
{
|
||||
return QTransform();
|
||||
@@ -1064,6 +1069,11 @@ QObject *ObjectNodeInstance::object() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
QQuickItem *ObjectNodeInstance::contentItem() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ObjectNodeInstance::hasContent() const
|
||||
{
|
||||
return false;
|
||||
@@ -1210,7 +1220,12 @@ ObjectNodeInstance::Pointer ObjectNodeInstance::parentInstance() const
|
||||
|
||||
QRectF ObjectNodeInstance::boundingRect() const
|
||||
{
|
||||
return QRect();
|
||||
return QRectF();
|
||||
}
|
||||
|
||||
QRectF ObjectNodeInstance::contentItemBoundingBox() const
|
||||
{
|
||||
return QRectF();
|
||||
}
|
||||
|
||||
QPointF ObjectNodeInstance::position() const
|
||||
|
||||
@@ -44,6 +44,7 @@ class QQmlContext;
|
||||
class QQmlEngine;
|
||||
class QQmlProperty;
|
||||
class QQmlAbstractBinding;
|
||||
class QQuickItem;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace QmlDesigner {
|
||||
@@ -104,12 +105,14 @@ public:
|
||||
virtual bool equalGraphicsItem(QGraphicsItem *item) const;
|
||||
|
||||
virtual QRectF boundingRect() const;
|
||||
virtual QRectF contentItemBoundingBox() const;
|
||||
|
||||
virtual QPointF position() const;
|
||||
virtual QSizeF size() const;
|
||||
virtual QTransform transform() const;
|
||||
virtual QTransform contentTransform() const;
|
||||
virtual QTransform customTransform() const;
|
||||
virtual QTransform contentItemTransform() const;
|
||||
virtual QTransform sceneTransform() const;
|
||||
virtual double opacity() const;
|
||||
|
||||
@@ -153,6 +156,7 @@ public:
|
||||
void setResetValue(const PropertyName &propertyName, const QVariant &value);
|
||||
|
||||
QObject *object() const;
|
||||
virtual QQuickItem *contentItem() const;
|
||||
|
||||
virtual bool hasContent() const;
|
||||
virtual bool isResizable() const;
|
||||
|
||||
@@ -107,8 +107,6 @@ QImage Qt5PreviewNodeInstanceServer::renderPreviewImage()
|
||||
|
||||
QImage previewImage = rootNodeInstance().renderPreviewImage(previewImageSize);
|
||||
|
||||
previewImage = previewImage.convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
||||
|
||||
return previewImage;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
if (isContentItem(item, nodeInstanceServer))
|
||||
return QTransform();
|
||||
|
||||
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 toParentTransform;
|
||||
}
|
||||
@@ -109,6 +122,35 @@ QuickItemNodeInstance::Pointer QuickItemNodeInstance::create(QObject *object)
|
||||
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
|
||||
{
|
||||
|
||||
@@ -50,7 +50,12 @@ public:
|
||||
|
||||
static Pointer create(QObject *objectToBeWrapped);
|
||||
|
||||
virtual QQuickItem *contentItem() const;
|
||||
|
||||
QRectF contentItemBoundingBox() const Q_DECL_OVERRIDE;
|
||||
|
||||
QTransform transform() const Q_DECL_OVERRIDE;
|
||||
QTransform contentItemTransform() const Q_DECL_OVERRIDE;
|
||||
|
||||
QObject *parent() const Q_DECL_OVERRIDE;
|
||||
|
||||
@@ -61,6 +66,8 @@ public:
|
||||
bool isMovable() const Q_DECL_OVERRIDE;
|
||||
bool isQuickItem() const Q_DECL_OVERRIDE;
|
||||
|
||||
void doComponentComplete();
|
||||
|
||||
protected:
|
||||
QuickItemNodeInstance(QQuickItem*);
|
||||
QQuickItem *quickItem() const;
|
||||
@@ -68,6 +75,7 @@ protected:
|
||||
void setResizable(bool resizable);
|
||||
|
||||
private: //variables
|
||||
QPointer<QQuickItem> m_contentItem;
|
||||
bool m_isResizable;
|
||||
bool m_isMovable;
|
||||
};
|
||||
|
||||
@@ -88,7 +88,6 @@ QuickWindowNodeInstance::Pointer QuickWindowNodeInstance::create(QObject *object
|
||||
QQuickItemPrivate *privateItem = static_cast<QQuickItemPrivate*>(QObjectPrivate::get(quickWindow->contentItem()));
|
||||
|
||||
if (privateItem->window) {
|
||||
qDebug() << "removing from window";
|
||||
if (!privateItem->parentItem)
|
||||
QQuickWindowPrivate::get(privateItem->window)->parentlessItems.remove(quickWindow->contentItem());
|
||||
privateItem->derefWindow();
|
||||
|
||||
@@ -315,6 +315,11 @@ QRectF ServerNodeInstance::boundingRect() const
|
||||
return boundingRect;
|
||||
}
|
||||
|
||||
QRectF ServerNodeInstance::contentItemBoundingRect() const
|
||||
{
|
||||
return m_nodeInstance->contentItemBoundingBox();
|
||||
}
|
||||
|
||||
void ServerNodeInstance::setPropertyVariant(const PropertyName &name, const QVariant &value)
|
||||
{
|
||||
m_nodeInstance->setPropertyVariant(name, value);
|
||||
@@ -515,6 +520,11 @@ QTransform ServerNodeInstance::contentTransform() const
|
||||
return m_nodeInstance->contentTransform();
|
||||
}
|
||||
|
||||
QTransform ServerNodeInstance::contentItemTransform() const
|
||||
{
|
||||
return m_nodeInstance->contentItemTransform();
|
||||
}
|
||||
|
||||
double ServerNodeInstance::rotation() const
|
||||
{
|
||||
return m_nodeInstance->rotation();
|
||||
@@ -631,11 +641,6 @@ qint32 ServerNodeInstance::instanceId() const
|
||||
}
|
||||
}
|
||||
|
||||
QObject* ServerNodeInstance::testHandle() const
|
||||
{
|
||||
return internalObject();
|
||||
}
|
||||
|
||||
QList<ServerNodeInstance> ServerNodeInstance::stateInstances() const
|
||||
{
|
||||
return m_nodeInstance->stateInstances();
|
||||
|
||||
@@ -105,12 +105,14 @@ public:
|
||||
bool equalGraphicsItem(QGraphicsItem *item) const;
|
||||
|
||||
QRectF boundingRect() const;
|
||||
QRectF contentItemBoundingRect() const;
|
||||
QPointF position() const;
|
||||
QSizeF size() const;
|
||||
QTransform transform() const;
|
||||
QTransform customTransform() const;
|
||||
QTransform sceneTransform() const;
|
||||
QTransform contentTransform() const;
|
||||
QTransform contentItemTransform() const;
|
||||
double rotation() const;
|
||||
double scale() const;
|
||||
QList<QGraphicsTransform *> transformations() const;
|
||||
@@ -156,7 +158,6 @@ public:
|
||||
QString id() const;
|
||||
qint32 instanceId() const;
|
||||
|
||||
QObject* testHandle() const;
|
||||
QSharedPointer<Internal::ObjectNodeInstance> internalInstance() const;
|
||||
|
||||
QList<ServerNodeInstance> stateInstances() const;
|
||||
|
||||
@@ -23,7 +23,7 @@ QT_BREAKPAD_ROOT_PATH = $$(QT_BREAKPAD_ROOT_PATH)
|
||||
include($$QT_BREAKPAD_ROOT_PATH/qtbreakpad.pri)
|
||||
}
|
||||
|
||||
SOURCES += $$PWD/main.cpp
|
||||
SOURCES += $$PWD/qml2puppetmain.cpp
|
||||
RESOURCES += $$PWD/../qmlpuppet.qrc
|
||||
DEFINES -= QT_NO_CAST_FROM_ASCII
|
||||
|
||||
|
||||
@@ -47,6 +47,10 @@
|
||||
|
||||
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);
|
||||
|
||||
QCoreApplication::setOrganizationName("QtProject");
|
||||
@@ -78,8 +82,10 @@ int main(int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (application.arguments().count() != 4)
|
||||
if (application.arguments().count() < 4) {
|
||||
qDebug() << "Wrong argument count: " << application.arguments().count();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ include (../commands/commands.pri)
|
||||
include (../container/container.pri)
|
||||
include (../interfaces/interfaces.pri)
|
||||
|
||||
SOURCES += $$PWD/main.cpp
|
||||
SOURCES += $$PWD/qmlpuppetmain.cpp
|
||||
RESOURCES += $$PWD/../qmlpuppet.qrc
|
||||
DEFINES -= QT_NO_CAST_FROM_ASCII
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ int main(int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (application.arguments().count() != 4)
|
||||
if (application.arguments().count() < 4)
|
||||
return -1;
|
||||
|
||||
#ifdef ENABLE_QT_BREAKPAD
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -14434,12 +14434,12 @@ Preselects a desktop Qt for building the application if available.</source>
|
||||
<message>
|
||||
<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>
|
||||
<translation type="obsolete">%1 调试</translation>
|
||||
<translation>%1 Debug</translation>
|
||||
</message>
|
||||
<message>
|
||||
<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>
|
||||
<translation type="obsolete">%1 发布</translation>
|
||||
<translation>%1 Release</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><No tool chain selected></source>
|
||||
@@ -22774,7 +22774,7 @@ S60 emulator run configuration default display name, %1 is base pro-File name</e
|
||||
<message>
|
||||
<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>
|
||||
<translation>未命名</translation>
|
||||
<translation>untitled</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -27898,12 +27898,12 @@ Did you start Qemu?</source>
|
||||
<message>
|
||||
<source>%1 Debug</source>
|
||||
<extracomment>Debug build configuration. We recommend not translating it.</extracomment>
|
||||
<translation type="obsolete">%1 调试</translation>
|
||||
<translation>%1 Debug</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>%1 Release</source>
|
||||
<extracomment>Release build configuration. We recommend not translating it.</extracomment>
|
||||
<translation type="obsolete">%1 发布</translation>
|
||||
<translation>%1 Release</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -40001,12 +40001,12 @@ Check if the phone is connected and App TRK is running.</source>
|
||||
<message>
|
||||
<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>
|
||||
<translation type="obsolete">%1 调试</translation>
|
||||
<translation>%1 Debug</translation>
|
||||
</message>
|
||||
<message>
|
||||
<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>
|
||||
<translation type="obsolete">%1 发布</translation>
|
||||
<translation>%1 Release</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -464,6 +464,57 @@ void Document::setGlobalNamespace(Namespace *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)
|
||||
{
|
||||
FindScopeAt findScopeAt(_translationUnit, line, column);
|
||||
|
||||
@@ -99,6 +99,7 @@ public:
|
||||
QList<Macro> definedMacros() const
|
||||
{ return _definedMacros; }
|
||||
|
||||
QString functionAt(int line, int column) const;
|
||||
Symbol *lastVisibleSymbolAt(unsigned line, unsigned column = 0) const;
|
||||
Scope *scopeAt(unsigned line, unsigned column = 0);
|
||||
|
||||
|
||||
@@ -1332,19 +1332,6 @@ void Preprocessor::synchronizeOutputLines(const PPToken &tk, bool forceLine)
|
||||
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)
|
||||
{
|
||||
// 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));
|
||||
|
||||
removeTrailingOutputLines();
|
||||
|
||||
if (includeGuardMacroName) {
|
||||
if (m_state.m_includeGuardState == State::IncludeGuardState_AfterDefine
|
||||
|| m_state.m_includeGuardState == State::IncludeGuardState_AfterEndif)
|
||||
@@ -1915,8 +1900,6 @@ void Preprocessor::handleEndIfDirective(PPToken *tk, const PPToken £Token)
|
||||
|
||||
void Preprocessor::handleIfDefDirective(bool checkUndefined, PPToken *tk)
|
||||
{
|
||||
static const QByteArray qCreatorRun("Q_CREATOR_RUN");
|
||||
|
||||
lex(tk); // consume "ifdef" token
|
||||
if (tk->is(T_IDENTIFIER)) {
|
||||
if (checkUndefined && m_state.m_ifLevel == 0)
|
||||
@@ -1937,8 +1920,6 @@ void Preprocessor::handleIfDefDirective(bool checkUndefined, PPToken *tk)
|
||||
}
|
||||
} else if (m_env->isBuiltinMacro(macroName)) {
|
||||
value = true;
|
||||
} else if (macroName == qCreatorRun) {
|
||||
value = true;
|
||||
}
|
||||
|
||||
if (checkUndefined)
|
||||
|
||||
@@ -237,7 +237,6 @@ private:
|
||||
void maybeStartOutputLine();
|
||||
void generateOutputLineMarker(unsigned lineno);
|
||||
void synchronizeOutputLines(const PPToken &tk, bool forceLine = false);
|
||||
void removeTrailingOutputLines();
|
||||
|
||||
void enforceSpacing(const PPToken &tk, bool forceSpacing = false);
|
||||
static std::size_t computeDistance(const PPToken &tk, bool forceTillLine = false);
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
using namespace ExtensionSystem;
|
||||
|
||||
/*!
|
||||
\fn PluginDetailsView::PluginDetailsView(QWidget *parent)
|
||||
Constructs a new view with given \a parent widget.
|
||||
*/
|
||||
PluginDetailsView::PluginDetailsView(QWidget *parent)
|
||||
@@ -57,7 +56,6 @@ PluginDetailsView::PluginDetailsView(QWidget *parent)
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn PluginDetailsView::~PluginDetailsView()
|
||||
\internal
|
||||
*/
|
||||
PluginDetailsView::~PluginDetailsView()
|
||||
@@ -66,7 +64,6 @@ PluginDetailsView::~PluginDetailsView()
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void PluginDetailsView::update(PluginSpec *spec)
|
||||
Reads the given \a spec and displays its values
|
||||
in this PluginDetailsView.
|
||||
*/
|
||||
|
||||
@@ -46,7 +46,6 @@
|
||||
using namespace ExtensionSystem;
|
||||
|
||||
/*!
|
||||
\fn PluginErrorView::PluginErrorView(QWidget *parent)
|
||||
Constructs a new error view with given \a parent widget.
|
||||
*/
|
||||
PluginErrorView::PluginErrorView(QWidget *parent)
|
||||
@@ -57,7 +56,6 @@ PluginErrorView::PluginErrorView(QWidget *parent)
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn PluginErrorView::~PluginErrorView()
|
||||
\internal
|
||||
*/
|
||||
PluginErrorView::~PluginErrorView()
|
||||
@@ -66,7 +64,6 @@ PluginErrorView::~PluginErrorView()
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void PluginErrorView::update(PluginSpec *spec)
|
||||
Reads the given \a spec and displays its state and
|
||||
error information in this PluginErrorView.
|
||||
*/
|
||||
|
||||
@@ -454,6 +454,8 @@ QHash<QString, PluginCollection *> PluginManager::pluginCollections()
|
||||
return m_instance->d->pluginCategories;
|
||||
}
|
||||
|
||||
static const char argumentKeywordC[] = ":arguments";
|
||||
|
||||
/*!
|
||||
Serialize plugin options and arguments for sending in a single string
|
||||
via QtSingleApplication:
|
||||
@@ -462,9 +464,6 @@ QHash<QString, PluginCollection *> PluginManager::pluginCollections()
|
||||
|
||||
\sa setPluginPaths()
|
||||
*/
|
||||
|
||||
static const char argumentKeywordC[] = ":arguments";
|
||||
|
||||
QString PluginManager::serializedArguments()
|
||||
{
|
||||
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.
|
||||
*/
|
||||
|
||||
void PluginManager::formatPluginVersions(QTextStream &str)
|
||||
{
|
||||
const PluginSpecSet::const_iterator cend = m_instance->d->pluginSpecs.constEnd();
|
||||
|
||||
@@ -145,7 +145,6 @@ using namespace ExtensionSystem;
|
||||
using namespace ExtensionSystem::Internal;
|
||||
|
||||
/*!
|
||||
\fn uint qHash(const ExtensionSystem::PluginDependency &value)
|
||||
\internal
|
||||
*/
|
||||
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
|
||||
*/
|
||||
bool PluginDependency::operator==(const PluginDependency &other) const
|
||||
@@ -163,7 +161,6 @@ bool PluginDependency::operator==(const PluginDependency &other) const
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn PluginSpec::PluginSpec()
|
||||
\internal
|
||||
*/
|
||||
PluginSpec::PluginSpec()
|
||||
@@ -172,7 +169,6 @@ PluginSpec::PluginSpec()
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn PluginSpec::~PluginSpec()
|
||||
\internal
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
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.
|
||||
*/
|
||||
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
|
||||
The user can change it from the Plugin settings.
|
||||
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.
|
||||
\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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
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)
|
||||
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
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -404,7 +378,6 @@ void PluginSpec::addArgument(const QString &argument)
|
||||
|
||||
|
||||
/*!
|
||||
\fn PluginSpec::State PluginSpec::state() const
|
||||
The state in which the plugin currently is.
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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
|
||||
\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,
|
||||
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.
|
||||
Valid if PluginSpec::Resolved state is reached.
|
||||
|
||||
@@ -493,7 +461,6 @@ namespace {
|
||||
const char ARGUMENT_PARAMETER[] = "parameter";
|
||||
}
|
||||
/*!
|
||||
\fn PluginSpecPrivate::PluginSpecPrivate(PluginSpec *spec)
|
||||
\internal
|
||||
*/
|
||||
PluginSpecPrivate::PluginSpecPrivate(PluginSpec *spec)
|
||||
@@ -512,7 +479,6 @@ PluginSpecPrivate::PluginSpecPrivate(PluginSpec *spec)
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool PluginSpecPrivate::read(const QString &fileName)
|
||||
\internal
|
||||
*/
|
||||
bool PluginSpecPrivate::read(const QString &fileName)
|
||||
@@ -590,7 +556,6 @@ void PluginSpec::setForceDisabled(bool value)
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool PluginSpecPrivate::reportError(const QString &err)
|
||||
\internal
|
||||
*/
|
||||
bool PluginSpecPrivate::reportError(const QString &err)
|
||||
@@ -626,7 +591,6 @@ static inline QString msgUnexpectedToken()
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void PluginSpecPrivate::readPluginSpec(QXmlStreamReader &reader)
|
||||
\internal
|
||||
*/
|
||||
void PluginSpecPrivate::readPluginSpec(QXmlStreamReader &reader)
|
||||
@@ -702,10 +666,8 @@ void PluginSpecPrivate::readPluginSpec(QXmlStreamReader &reader)
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void PluginSpecPrivate::readArgumentDescriptions(QXmlStreamReader &reader)
|
||||
\internal
|
||||
*/
|
||||
|
||||
void PluginSpecPrivate::readArgumentDescriptions(QXmlStreamReader &reader)
|
||||
{
|
||||
QString element;
|
||||
@@ -736,7 +698,6 @@ void PluginSpecPrivate::readArgumentDescriptions(QXmlStreamReader &reader)
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void PluginSpecPrivate::readArgumentDescription(QXmlStreamReader &reader)
|
||||
\internal
|
||||
*/
|
||||
void PluginSpecPrivate::readArgumentDescription(QXmlStreamReader &reader)
|
||||
@@ -766,7 +727,6 @@ bool PluginSpecPrivate::readBooleanValue(QXmlStreamReader &reader, const char *k
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void PluginSpecPrivate::readDependencies(QXmlStreamReader &reader)
|
||||
\internal
|
||||
*/
|
||||
void PluginSpecPrivate::readDependencies(QXmlStreamReader &reader)
|
||||
@@ -799,7 +759,6 @@ void PluginSpecPrivate::readDependencies(QXmlStreamReader &reader)
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void PluginSpecPrivate::readDependencyEntry(QXmlStreamReader &reader)
|
||||
\internal
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
QRegExp &PluginSpecPrivate::versionRegExp()
|
||||
@@ -854,7 +811,6 @@ QRegExp &PluginSpecPrivate::versionRegExp()
|
||||
return reg;
|
||||
}
|
||||
/*!
|
||||
\fn bool PluginSpecPrivate::isValidVersion(const QString &version)
|
||||
\internal
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
bool PluginSpecPrivate::resolveDependencies(const QList<PluginSpec *> &specs)
|
||||
@@ -956,7 +910,6 @@ void PluginSpecPrivate::disableIndirectlyIfDependencyDisabled()
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool PluginSpecPrivate::loadLibrary()
|
||||
\internal
|
||||
*/
|
||||
bool PluginSpecPrivate::loadLibrary()
|
||||
@@ -1013,7 +966,6 @@ bool PluginSpecPrivate::loadLibrary()
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool PluginSpecPrivate::initializePlugin()
|
||||
\internal
|
||||
*/
|
||||
bool PluginSpecPrivate::initializePlugin()
|
||||
@@ -1043,7 +995,6 @@ bool PluginSpecPrivate::initializePlugin()
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool PluginSpecPrivate::initializeExtensions()
|
||||
\internal
|
||||
*/
|
||||
bool PluginSpecPrivate::initializeExtensions()
|
||||
@@ -1068,7 +1019,6 @@ bool PluginSpecPrivate::initializeExtensions()
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool PluginSpecPrivate::delayedInitialize()
|
||||
\internal
|
||||
*/
|
||||
bool PluginSpecPrivate::delayedInitialize()
|
||||
@@ -1086,7 +1036,6 @@ bool PluginSpecPrivate::delayedInitialize()
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool PluginSpecPrivate::stop()
|
||||
\internal
|
||||
*/
|
||||
IPlugin::ShutdownFlag PluginSpecPrivate::stop()
|
||||
@@ -1098,7 +1047,6 @@ IPlugin::ShutdownFlag PluginSpecPrivate::stop()
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool PluginSpecPrivate::kill()
|
||||
\internal
|
||||
*/
|
||||
void PluginSpecPrivate::kill()
|
||||
|
||||
@@ -265,8 +265,6 @@ QPacketAutoSend QPacketProtocol::send()
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void QPacketProtocol::send(const QPacket & packet)
|
||||
|
||||
Transmit the \a packet.
|
||||
*/
|
||||
void QPacketProtocol::send(const QPacket & p)
|
||||
|
||||
@@ -237,7 +237,6 @@ QString QmlError::toString() const
|
||||
|
||||
/*!
|
||||
\relates QmlError
|
||||
\fn QDebug operator<<(QDebug debug, const QmlError &error)
|
||||
|
||||
Outputs a human readable version of \a error to \a debug.
|
||||
*/
|
||||
|
||||
@@ -39,7 +39,8 @@ HEADERS += \
|
||||
$$PWD/consoleitem.h \
|
||||
$$PWD/iscriptevaluator.h \
|
||||
$$PWD/qmljssimplereader.h \
|
||||
$$PWD/persistenttrie.h
|
||||
$$PWD/persistenttrie.h \
|
||||
$$PWD/qmljsqrcparser.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/qmljsbind.cpp \
|
||||
@@ -69,7 +70,8 @@ SOURCES += \
|
||||
$$PWD/consolemanagerinterface.cpp \
|
||||
$$PWD/consoleitem.cpp \
|
||||
$$PWD/qmljssimplereader.cpp \
|
||||
$$PWD/persistenttrie.cpp
|
||||
$$PWD/persistenttrie.cpp \
|
||||
$$PWD/qmljsqrcparser.cpp
|
||||
|
||||
RESOURCES += \
|
||||
$$PWD/qmljs.qrc
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
DEFINES += QMLJS_BUILD_DIR
|
||||
|
||||
QT +=script
|
||||
QT +=script xml
|
||||
include(../../qtcreatorlibrary.pri)
|
||||
include(qmljs-lib.pri)
|
||||
|
||||
@@ -12,7 +12,7 @@ QtcLibrary {
|
||||
|
||||
Depends { name: "Utils" }
|
||||
Depends { name: "LanguageUtils" }
|
||||
Depends { name: "Qt"; submodules: ["widgets", "script"] }
|
||||
Depends { name: "Qt"; submodules: ["widgets", "script", "xml"] }
|
||||
|
||||
files: [
|
||||
"jsoncheck.cpp",
|
||||
@@ -52,6 +52,8 @@ QtcLibrary {
|
||||
"qmljsmodelmanagerinterface.h",
|
||||
"qmljspropertyreader.cpp",
|
||||
"qmljspropertyreader.h",
|
||||
"qmljsqrcparser.cpp",
|
||||
"qmljsqrcparser.h",
|
||||
"qmljsreformatter.cpp",
|
||||
"qmljsreformatter.h",
|
||||
"qmljsrewriter.cpp",
|
||||
|
||||
@@ -115,6 +115,22 @@ bool Document::isFullySupportedLanguage(Document::Language language)
|
||||
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)
|
||||
: _engine(0)
|
||||
, _ast(0)
|
||||
|
||||
@@ -65,6 +65,7 @@ public:
|
||||
|
||||
static bool isQmlLikeLanguage(Language languge);
|
||||
static bool isFullySupportedLanguage(Language language);
|
||||
static bool isQmlLikeOrJsLanguage(Language language);
|
||||
protected:
|
||||
Document(const QString &fileName, Language language);
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "qmljstypedescriptionreader.h"
|
||||
#include "qmljsvalueowner.h"
|
||||
#include "qmljscontext.h"
|
||||
#include "qmljsmodelmanagerinterface.h"
|
||||
#include "parser/qmljsast_p.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
@@ -2107,13 +2108,19 @@ ImportInfo ImportInfo::pathImport(const QString &docPath, const QString &path,
|
||||
importFileInfo = QFileInfo(docPath + QDir::separator() + path);
|
||||
info._path = importFileInfo.absoluteFilePath();
|
||||
|
||||
if (importFileInfo.isFile())
|
||||
if (importFileInfo.isFile()) {
|
||||
info._type = FileImport;
|
||||
else if (importFileInfo.isDir())
|
||||
} else if (importFileInfo.isDir()) {
|
||||
info._type = DirectoryImport;
|
||||
} 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._version = version;
|
||||
info._as = as;
|
||||
info._ast = ast;
|
||||
@@ -2192,7 +2199,7 @@ const Value *TypeScope::lookupMember(const QString &name, const Context *context
|
||||
const ImportInfo &info = i.info;
|
||||
|
||||
// JS import has no types
|
||||
if (info.type() == ImportInfo::FileImport)
|
||||
if (info.type() == ImportInfo::FileImport || info.type() == ImportInfo::QrcFileImport)
|
||||
continue;
|
||||
|
||||
if (!info.as().isEmpty()) {
|
||||
@@ -2222,7 +2229,7 @@ void TypeScope::processMembers(MemberProcessor *processor) const
|
||||
const ImportInfo &info = i.info;
|
||||
|
||||
// JS import has no types
|
||||
if (info.type() == ImportInfo::FileImport)
|
||||
if (info.type() == ImportInfo::FileImport || info.type() == ImportInfo::QrcFileImport)
|
||||
continue;
|
||||
|
||||
if (!info.as().isEmpty())
|
||||
@@ -2249,7 +2256,7 @@ const Value *JSImportScope::lookupMember(const QString &name, const Context *,
|
||||
const ImportInfo &info = i.info;
|
||||
|
||||
// JS imports are always: import "somefile.js" as Foo
|
||||
if (info.type() != ImportInfo::FileImport)
|
||||
if (info.type() != ImportInfo::FileImport && info.type() != ImportInfo::QrcFileImport)
|
||||
continue;
|
||||
|
||||
if (info.as() == name) {
|
||||
@@ -2272,7 +2279,7 @@ void JSImportScope::processMembers(MemberProcessor *processor) const
|
||||
const ObjectValue *import = i.object;
|
||||
const ImportInfo &info = i.info;
|
||||
|
||||
if (info.type() == ImportInfo::FileImport)
|
||||
if (info.type() == ImportInfo::FileImport || info.type() == ImportInfo::QrcFileImport)
|
||||
processor->processProperty(info.as(), import);
|
||||
}
|
||||
}
|
||||
@@ -2329,7 +2336,7 @@ ImportInfo Imports::info(const QString &name, const Context *context) const
|
||||
continue;
|
||||
}
|
||||
|
||||
if (info.type() == ImportInfo::FileImport) {
|
||||
if (info.type() == ImportInfo::FileImport || info.type() == ImportInfo::QrcFileImport) {
|
||||
if (import->className() == firstId)
|
||||
return info;
|
||||
} else {
|
||||
@@ -2349,7 +2356,7 @@ QString Imports::nameForImportedObject(const ObjectValue *value, const Context *
|
||||
const ObjectValue *import = i.object;
|
||||
const ImportInfo &info = i.info;
|
||||
|
||||
if (info.type() == ImportInfo::FileImport) {
|
||||
if (info.type() == ImportInfo::FileImport || info.type() == ImportInfo::QrcFileImport) {
|
||||
if (import == value)
|
||||
return import->className();
|
||||
} else {
|
||||
|
||||
@@ -872,6 +872,8 @@ public:
|
||||
LibraryImport,
|
||||
FileImport,
|
||||
DirectoryImport,
|
||||
QrcFileImport,
|
||||
QrcDirectoryImport,
|
||||
UnknownFileImport // refers a file/directory that wasn't found
|
||||
};
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "qmljsbind.h"
|
||||
#include "qmljsutils.h"
|
||||
#include "qmljsmodelmanagerinterface.h"
|
||||
#include <qmljs/qmljsqrcparser.h>
|
||||
|
||||
#include <QDir>
|
||||
#include <QDebug>
|
||||
@@ -245,6 +246,8 @@ void LinkPrivate::populateImportedTypes(Imports *imports, Document::Ptr doc)
|
||||
switch (info.type()) {
|
||||
case ImportInfo::FileImport:
|
||||
case ImportInfo::DirectoryImport:
|
||||
case ImportInfo::QrcFileImport:
|
||||
case ImportInfo::QrcDirectoryImport:
|
||||
import = importFileOrDirectory(doc, info);
|
||||
break;
|
||||
case ImportInfo::LibraryImport:
|
||||
@@ -285,7 +288,7 @@ Import LinkPrivate::importFileOrDirectory(Document::Ptr doc, const ImportInfo &i
|
||||
import.object = 0;
|
||||
import.valid = true;
|
||||
|
||||
const QString &path = importInfo.path();
|
||||
QString path = importInfo.path();
|
||||
|
||||
if (importInfo.type() == ImportInfo::DirectoryImport
|
||||
|| importInfo.type() == ImportInfo::ImplicitDirectoryImport) {
|
||||
@@ -304,8 +307,36 @@ Import LinkPrivate::importFileOrDirectory(Document::Ptr doc, const ImportInfo &i
|
||||
Document::Ptr importedDoc = snapshot.document(path);
|
||||
if (importedDoc)
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,11 @@ class QMLJS_EXPORT ModelManagerInterface: public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum QrcResourceSelector {
|
||||
ActiveQrcResources,
|
||||
AllQrcResources
|
||||
};
|
||||
|
||||
class ProjectInfo
|
||||
{
|
||||
public:
|
||||
@@ -80,6 +85,8 @@ public:
|
||||
QPointer<ProjectExplorer::Project> project;
|
||||
QStringList sourceFiles;
|
||||
QStringList importPaths;
|
||||
QStringList activeResourceFiles;
|
||||
QStringList allResourceFiles;
|
||||
|
||||
// whether trying to run qmldump makes sense
|
||||
bool tryQmlDump;
|
||||
@@ -142,6 +149,14 @@ public:
|
||||
bool emitDocumentOnDiskChanged) = 0;
|
||||
virtual void fileChangedOnDisk(const QString &path) = 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 ProjectInfo projectInfo(ProjectExplorer::Project *project) const = 0;
|
||||
|
||||
517
src/libs/qmljs/qmljsqrcparser.cpp
Normal file
517
src/libs/qmljs/qmljsqrcparser.cpp
Normal 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
|
||||
87
src/libs/qmljs/qmljsqrcparser.h
Normal file
87
src/libs/qmljs/qmljsqrcparser.h
Normal 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
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "qmljsscopechain.h"
|
||||
#include "qmljsbind.h"
|
||||
#include "qmljsevaluate.h"
|
||||
#include "qmljsmodelmanagerinterface.h"
|
||||
|
||||
using namespace QmlJS;
|
||||
|
||||
@@ -310,7 +311,10 @@ void ScopeChain::initializeRootScope()
|
||||
if (!m_document->bind()->isJsLibrary()) {
|
||||
foreach (Document::Ptr otherDoc, snapshot) {
|
||||
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);
|
||||
componentScopes.insert(otherDoc.data(), component);
|
||||
chain->addInstantiatingComponent(component);
|
||||
|
||||
@@ -373,10 +373,12 @@ bool FileSaver::finalize()
|
||||
return FileSaverBase::finalize();
|
||||
|
||||
SaveFile *sf = static_cast<SaveFile *>(m_file);
|
||||
if (m_hasError)
|
||||
if (m_hasError) {
|
||||
if (sf->isOpen())
|
||||
sf->rollback();
|
||||
else
|
||||
} else {
|
||||
setResult(sf->commit());
|
||||
}
|
||||
delete sf;
|
||||
m_file = 0;
|
||||
return !m_hasError;
|
||||
|
||||
@@ -191,8 +191,6 @@ QString SavedAction::toString() const
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QAction *SavedAction::updatedAction(const QString &text)
|
||||
|
||||
Adjust the \c text() of the underlying action.
|
||||
|
||||
This can be used to update the item shortly before e.g. a menu is shown.
|
||||
|
||||
@@ -289,13 +289,11 @@ bool TextFileFormat::writeFile(const QString &fileName, QString plainText, QStri
|
||||
}
|
||||
|
||||
Utils::FileSaver saver(fileName, fileMode);
|
||||
if (saver.hasError()) {
|
||||
*errorString = saver.errorString();
|
||||
return false;
|
||||
}
|
||||
if (!saver.hasError()) {
|
||||
if (hasUtf8Bom && codec->name() == "UTF-8")
|
||||
saver.write("\xef\xbb\xbf", 3);
|
||||
saver.write(codec->fromUnicode(plainText));
|
||||
}
|
||||
const bool ok = saver.finalize(errorString);
|
||||
if (debug)
|
||||
qDebug().nospace() << Q_FUNC_INFO << fileName << ' ' << *this << ' ' << plainText.size()
|
||||
|
||||
@@ -289,8 +289,6 @@ Service::~Service()
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QString Service::networkInterface()
|
||||
|
||||
Returns the interface on which the service is reachable.
|
||||
*/
|
||||
QNetworkInterface Service::networkInterface() const
|
||||
|
||||
@@ -102,7 +102,6 @@ public:
|
||||
setIcon(QIcon(QLatin1String(":/images/analyzer_mode.png")));
|
||||
setPriority(P_MODE_ANALYZE);
|
||||
setId(MODE_ANALYZE);
|
||||
setType(MODE_EDIT_TYPE);
|
||||
}
|
||||
|
||||
~AnalyzerMode()
|
||||
|
||||
@@ -84,6 +84,7 @@ public:
|
||||
StartMode mode() const { return m_sp.startMode; }
|
||||
|
||||
virtual void notifyRemoteSetupDone(quint16) {}
|
||||
virtual void notifyRemoteFinished(bool) {}
|
||||
|
||||
public slots:
|
||||
virtual void logApplicationMessage(const QString &, Utils::OutputFormat) {}
|
||||
|
||||
@@ -206,6 +206,9 @@ void AndroidConfig::save(QSettings &settings) const
|
||||
settings.setValue(PartitionSizeKey, partitionSize);
|
||||
settings.setValue(AutomaticKitCreationKey, automaticKitCreation);
|
||||
settings.setValue(ToolchainHostKey, toolchainHost);
|
||||
settings.setValue(MakeExtraSearchDirectory,
|
||||
makeExtraSearchDirectories.isEmpty() ? QString()
|
||||
: makeExtraSearchDirectories.at(0));
|
||||
}
|
||||
|
||||
void AndroidConfigurations::setConfig(const AndroidConfig &devConfigs)
|
||||
|
||||
@@ -572,19 +572,20 @@ void AndroidManager::updateTarget(ProjectExplorer::Target *target, const QString
|
||||
bool modified = false;
|
||||
bool comment = false;
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
if (lines[i].contains("@ANDROID-")) {
|
||||
commentLines = targetSDKNumber < lines[i].mid(lines[i].lastIndexOf('-') + 1).toInt();
|
||||
QByteArray trimmed = lines[i].trimmed();
|
||||
if (trimmed.contains("@ANDROID-")) {
|
||||
commentLines = targetSDKNumber < trimmed.mid(trimmed.lastIndexOf('-') + 1).toInt();
|
||||
comment = !comment;
|
||||
continue;
|
||||
}
|
||||
if (!comment)
|
||||
continue;
|
||||
if (commentLines) {
|
||||
if (!lines[i].trimmed().startsWith("//QtCreator")) {
|
||||
if (!trimmed.startsWith("//QtCreator")) {
|
||||
lines[i] = "//QtCreator " + lines[i];
|
||||
modified = true;
|
||||
}
|
||||
} else { if (lines[i].trimmed().startsWith("//QtCreator")) {
|
||||
} else { if (trimmed.startsWith("//QtCreator")) {
|
||||
lines[i] = lines[i].mid(12);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
@@ -540,9 +540,7 @@ void BazaarPlugin::showCommitWidget(const QList<VcsBase::VcsBaseClient::StatusIt
|
||||
return;
|
||||
}
|
||||
|
||||
Core::IEditor *editor = Core::EditorManager::openEditor(saver.fileName(),
|
||||
Constants::COMMIT_ID,
|
||||
Core::EditorManager::ModeSwitch);
|
||||
Core::IEditor *editor = Core::EditorManager::openEditor(saver.fileName(), Constants::COMMIT_ID);
|
||||
if (!editor) {
|
||||
outputWindow->appendError(tr("Unable to create an editor for the commit."));
|
||||
return;
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#include <coreplugin/actionmanager/command.h>
|
||||
#include <projectexplorer/projectexplorer.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <texteditor/basetexteditor.h>
|
||||
#include <texteditor/itexteditor.h>
|
||||
#include <utils/tooltip/tooltip.h>
|
||||
#include <utils/tooltip/tipcontents.h>
|
||||
#include <utils/qtcassert.h>
|
||||
@@ -237,9 +237,11 @@ void BookmarkView::contextMenuEvent(QContextMenuEvent *event)
|
||||
QMenu menu;
|
||||
QAction *moveUp = menu.addAction(tr("Move Up"));
|
||||
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"));
|
||||
menu.addSeparator();
|
||||
QAction *remove = menu.addAction(tr("&Remove"));
|
||||
menu.addSeparator();
|
||||
QAction *removeAll = menu.addAction(tr("Remove All"));
|
||||
|
||||
m_contextMenuIndex = indexAt(event->pos());
|
||||
if (!m_contextMenuIndex.isValid()) {
|
||||
@@ -508,7 +510,7 @@ Bookmark *BookmarkManager::bookmarkForIndex(const QModelIndex &index)
|
||||
bool BookmarkManager::gotoBookmark(Bookmark *bookmark)
|
||||
{
|
||||
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()))) {
|
||||
return (editor->currentLine() == bookmark->lineNumber());
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include <utils/qtcassert.h>
|
||||
#include <projectexplorer/projectexplorer.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <texteditor/basetexteditor.h>
|
||||
#include <cpptools/cppmodelmanagerinterface.h>
|
||||
#include <cpptools/cpptoolsconstants.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)
|
||||
{
|
||||
bool newEditor = false;
|
||||
TextEditor::BaseTextEditorWidget::openEditorAt(fileName, line, column, Core::Id(),
|
||||
Core::EditorManager::IgnoreNavigationHistory,
|
||||
&newEditor);
|
||||
Core::EditorManager::openEditorAt(fileName, line, column);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -687,9 +687,7 @@ QString ClearCasePlugin::ccGetFileActivity(const QString &workingDir, const QStr
|
||||
ClearCaseSubmitEditor *ClearCasePlugin::openClearCaseSubmitEditor(const QString &fileName, bool isUcm)
|
||||
{
|
||||
Core::IEditor *editor =
|
||||
Core::EditorManager::openEditor(fileName,
|
||||
Constants::CLEARCASECHECKINEDITOR_ID,
|
||||
Core::EditorManager::ModeSwitch);
|
||||
Core::EditorManager::openEditor(fileName, Constants::CLEARCASECHECKINEDITOR_ID);
|
||||
ClearCaseSubmitEditor *submitEditor = qobject_cast<ClearCaseSubmitEditor*>(editor);
|
||||
QTC_CHECK(submitEditor);
|
||||
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
|
||||
if (Core::IEditor *existingEditor = VcsBase::VcsBaseEditorWidget::locateEditorByTag(tag)) {
|
||||
existingEditor->createNew(result);
|
||||
Core::EditorManager::activateEditor(existingEditor, Core::EditorManager::ModeSwitch);
|
||||
Core::EditorManager::activateEditor(existingEditor);
|
||||
setDiffBaseDirectory(existingEditor, workingDir);
|
||||
return;
|
||||
}
|
||||
@@ -1192,7 +1190,7 @@ void ClearCasePlugin::history(const QString &workingDir,
|
||||
const QString tag = VcsBase::VcsBaseEditorWidget::editorTag(VcsBase::LogOutput, workingDir, files);
|
||||
if (Core::IEditor *editor = VcsBase::VcsBaseEditorWidget::locateEditorByTag(tag)) {
|
||||
editor->createNew(response.stdOut);
|
||||
Core::EditorManager::activateEditor(editor, Core::EditorManager::ModeSwitch);
|
||||
Core::EditorManager::activateEditor(editor);
|
||||
} else {
|
||||
const QString title = QString::fromLatin1("cc history %1").arg(id);
|
||||
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)) {
|
||||
editor->createNew(res);
|
||||
VcsBase::VcsBaseEditorWidget::gotoLineOfEditor(editor, lineNumber);
|
||||
Core::EditorManager::activateEditor(editor, Core::EditorManager::ModeSwitch);
|
||||
Core::EditorManager::activateEditor(editor);
|
||||
} else {
|
||||
const QString title = QString::fromLatin1("cc annotate %1").arg(id);
|
||||
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);
|
||||
if (Core::IEditor *editor = VcsBase::VcsBaseEditorWidget::locateEditorByTag(tag)) {
|
||||
editor->createNew(description);
|
||||
Core::EditorManager::activateEditor(editor, Core::EditorManager::ModeSwitch);
|
||||
Core::EditorManager::activateEditor(editor);
|
||||
} else {
|
||||
const QString title = QString::fromLatin1("cc describe %1").arg(id);
|
||||
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)
|
||||
e->setCodec(codec);
|
||||
Core::IEditor *ie = e->editor();
|
||||
Core::EditorManager::activateEditor(ie, Core::EditorManager::ModeSwitch);
|
||||
Core::EditorManager::activateEditor(ie);
|
||||
return ie;
|
||||
}
|
||||
|
||||
|
||||
@@ -649,7 +649,7 @@ bool BaseFileWizard::postGenerateOpenEditors(const GeneratedFiles &l, QString *e
|
||||
{
|
||||
foreach (const Core::GeneratedFile &file, l) {
|
||||
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)
|
||||
*errorMessage = tr("Failed to open an editor for '%1'.").arg(QDir::toNativeSeparators(file.path()));
|
||||
return false;
|
||||
|
||||
@@ -109,7 +109,7 @@ const char SPLIT_SIDE_BY_SIDE[] = "QtCreator.SplitSideBySide";
|
||||
const char SPLIT_NEW_WINDOW[] = "QtCreator.SplitNewWindow";
|
||||
const char REMOVE_CURRENT_SPLIT[] = "QtCreator.RemoveCurrentSplit";
|
||||
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_ALTERNATIVE[] = "QtCreator.Close_Alternative"; // temporary, see QTCREATORBUG-72
|
||||
const char CLOSEALL[] = "QtCreator.CloseAll";
|
||||
|
||||
@@ -120,7 +120,6 @@ DesignMode::DesignMode()
|
||||
setIcon(QIcon(QLatin1String(":/fancyactionbar/images/mode_Design.png")));
|
||||
setPriority(Constants::P_MODE_DESIGN);
|
||||
setId(Constants::MODE_DESIGN);
|
||||
setType(Constants::MODE_DESIGN_TYPE);
|
||||
|
||||
ExtensionSystem::PluginManager::addObject(d->m_coreListener);
|
||||
|
||||
|
||||
@@ -1352,7 +1352,7 @@ void DocumentManager::executeOpenWithMenuAction(QAction *action)
|
||||
return;
|
||||
}
|
||||
|
||||
EditorManager::openEditor(entry.fileName, entry.editorFactory->id(), EditorManager::ModeSwitch);
|
||||
EditorManager::openEditor(entry.fileName, entry.editorFactory->id());
|
||||
return;
|
||||
}
|
||||
if (entry.externalEditor)
|
||||
|
||||
@@ -55,7 +55,6 @@ EditMode::EditMode() :
|
||||
setIcon(QIcon(QLatin1String(":/fancyactionbar/images/mode_Edit.png")));
|
||||
setPriority(Constants::P_MODE_EDIT);
|
||||
setId(Constants::MODE_EDIT);
|
||||
setType(Constants::MODE_EDIT_TYPE);
|
||||
|
||||
m_rightSplitWidgetLayout->setSpacing(0);
|
||||
m_rightSplitWidgetLayout->setMargin(0);
|
||||
|
||||
@@ -196,7 +196,7 @@ struct EditorManagerPrivate
|
||||
QAction *m_splitNewWindowAction;
|
||||
QAction *m_removeCurrentSplitAction;
|
||||
QAction *m_removeAllSplitsAction;
|
||||
QAction *m_gotoOtherSplitAction;
|
||||
QAction *m_gotoNextSplitAction;
|
||||
|
||||
QAction *m_saveCurrentEditorContextAction;
|
||||
QAction *m_saveAsCurrentEditorContextAction;
|
||||
@@ -381,7 +381,7 @@ EditorManager::EditorManager(QWidget *parent) :
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
|
||||
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->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+E,4") : tr("Ctrl+E,4")));
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
|
||||
@@ -399,11 +399,11 @@ EditorManager::EditorManager(QWidget *parent) :
|
||||
mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT);
|
||||
connect(d->m_removeAllSplitsAction, SIGNAL(triggered()), this, SLOT(removeAllSplits()));
|
||||
|
||||
d->m_gotoOtherSplitAction = new QAction(tr("Go to Next Split"), this);
|
||||
cmd = ActionManager::registerAction(d->m_gotoOtherSplitAction, Constants::GOTO_OTHER_SPLIT, editManagerContext);
|
||||
d->m_gotoNextSplitAction = new QAction(tr("Go to Next Split or Window"), this);
|
||||
cmd = ActionManager::registerAction(d->m_gotoNextSplitAction, Constants::GOTO_NEXT_SPLIT, editManagerContext);
|
||||
cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("Meta+E,o") : tr("Ctrl+E,o")));
|
||||
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 *advancedMenu = ActionManager::createMenu(Constants::M_EDIT_ADVANCED);
|
||||
@@ -604,13 +604,20 @@ EditorView *EditorManager::viewForEditor(IEditor *editor)
|
||||
return 0;
|
||||
}
|
||||
|
||||
SplitterOrView *EditorManager::findRoot(EditorView *view)
|
||||
SplitterOrView *EditorManager::findRoot(const EditorView *view, int *rootIndex)
|
||||
{
|
||||
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();
|
||||
}
|
||||
return current;
|
||||
QTC_CHECK(false); // we should never have views without a root
|
||||
return 0;
|
||||
}
|
||||
|
||||
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->setWidget(splitter);
|
||||
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();
|
||||
ICore::raiseWindow(splitter);
|
||||
if (newEditor)
|
||||
m_instance->activateEditor(splitter->view(), newEditor, IgnoreNavigationHistory);
|
||||
else
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -1042,15 +1049,15 @@ bool EditorManager::closeEditors(const QList<IEditor*> &editorsToClose, bool ask
|
||||
if (!newCurrent)
|
||||
newCurrent = pickUnusedEditor();
|
||||
if (newCurrent) {
|
||||
activateEditor(view, newCurrent, NoActivate);
|
||||
activateEditor(view, newCurrent, DoNotChangeCurrentEditor);
|
||||
} else {
|
||||
QModelIndex idx = d->m_editorModel->firstRestoredEditor();
|
||||
if (idx.isValid()) {
|
||||
activateEditorForIndex(view, idx, NoActivate);
|
||||
activateEditorForIndex(view, idx, DoNotChangeCurrentEditor);
|
||||
} else {
|
||||
const QList<IEditor *> editors = d->m_editorModel->editors();
|
||||
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)
|
||||
newCurrent = pickUnusedEditor();
|
||||
if (newCurrent) {
|
||||
activateEditor(view, newCurrent, NoActivate);
|
||||
activateEditor(view, newCurrent, DoNotChangeCurrentEditor);
|
||||
} else {
|
||||
QModelIndex idx = d->m_editorModel->firstRestoredEditor();
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
Q_ASSERT(view && editor);
|
||||
@@ -1202,15 +1221,24 @@ Core::IEditor *EditorManager::activateEditor(Core::Internal::EditorView *view, C
|
||||
|
||||
editor = placeEditor(view, editor);
|
||||
|
||||
if (!(flags & NoActivate)) {
|
||||
if (!(flags & DoNotChangeCurrentEditor)) {
|
||||
setCurrentEditor(editor, (flags & IgnoreNavigationHistory));
|
||||
if (flags & ModeSwitch)
|
||||
switchToPreferedMode();
|
||||
if (isVisible()) {
|
||||
if (!(flags & DoNotMakeVisible)) {
|
||||
// switch to design mode?
|
||||
if (editor->isDesignModePreferred()) {
|
||||
ModeManager::activateMode(Core::Constants::MODE_DESIGN);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1394,18 +1422,23 @@ Core::Id EditorManager::getOpenWithEditorId(const QString &fileName,
|
||||
IEditor *EditorManager::openEditor(const QString &fileName, const Id &editorId,
|
||||
OpenEditorFlags flags, bool *newEditor)
|
||||
{
|
||||
if (flags & EditorManager::OpenInOtherSplit)
|
||||
m_instance->gotoOtherSplit();
|
||||
return m_instance->openEditor(m_instance->currentEditorView(),
|
||||
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->splitSideBySide();
|
||||
|
||||
m_instance->gotoOtherSplit();
|
||||
return m_instance->openEditor(m_instance->currentEditorView(),
|
||||
fileName, editorId, flags, newEditor);
|
||||
m_instance->cutForwardNavigationHistory();
|
||||
m_instance->addCurrentPositionToNavigationHistory();
|
||||
OpenEditorFlags tempFlags = flags | IgnoreNavigationHistory;
|
||||
Core::IEditor *editor = Core::EditorManager::openEditor(fileName, editorId,
|
||||
tempFlags, newEditor);
|
||||
if (editor && line != -1)
|
||||
editor->gotoLine(line, column);
|
||||
return editor;
|
||||
}
|
||||
|
||||
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,
|
||||
QString *titlePattern,
|
||||
const QString &contents)
|
||||
@@ -1973,7 +1990,7 @@ void EditorManager::updateActions()
|
||||
bool hasSplitter = parentSplitter && parentSplitter->isSplitter();
|
||||
d->m_removeCurrentSplitAction->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)
|
||||
@@ -2010,7 +2027,8 @@ QList<IEditor*> EditorManager::visibleEditors() const
|
||||
if (view->currentEditor())
|
||||
editors.append(view->currentEditor());
|
||||
view = view->findNextView();
|
||||
} while (view && view != firstView);
|
||||
QTC_ASSERT(view != firstView, break); // we start with firstView and shouldn't have cycles
|
||||
} while (view);
|
||||
}
|
||||
} else {
|
||||
if (root->editor())
|
||||
@@ -2166,7 +2184,7 @@ bool EditorManager::restoreState(const QByteArray &state)
|
||||
continue;
|
||||
QFileInfo rfi(autoSaveName(fileName));
|
||||
if (rfi.exists() && fi.lastModified() < rfi.lastModified())
|
||||
openEditor(fileName, id);
|
||||
openEditor(fileName, id, DoNotMakeVisible);
|
||||
else
|
||||
d->m_editorModel->addRestoredEditor(fileName, displayName, id);
|
||||
}
|
||||
@@ -2375,26 +2393,77 @@ void EditorManager::removeAllSplits()
|
||||
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()
|
||||
{
|
||||
EditorView *view = currentEditorView();
|
||||
if (!view)
|
||||
return;
|
||||
SplitterOrView *root = findRoot(view);
|
||||
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);
|
||||
if (!root->isSplitter())
|
||||
splitSideBySide();
|
||||
|
||||
view = view->findNextView();
|
||||
if (view) {
|
||||
if (IEditor *editor = view->currentEditor()) {
|
||||
setCurrentEditor(editor, true);
|
||||
editor->widget()->setFocus();
|
||||
ICore::raiseWindow(editor->widget());
|
||||
QTC_ASSERT(rootIndex >= 0 && rootIndex < d->m_root.size(), return);
|
||||
// stay in same window if it is split
|
||||
if (root->isSplitter()) {
|
||||
nextView = root->findFirstView();
|
||||
QTC_CHECK(nextView != view);
|
||||
} 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()
|
||||
|
||||
@@ -107,18 +107,20 @@ public:
|
||||
static EditorToolBar *createToolBar(QWidget *parent = 0);
|
||||
|
||||
enum OpenEditorFlag {
|
||||
NoActivate = 1,
|
||||
DoNotChangeCurrentEditor = 1,
|
||||
IgnoreNavigationHistory = 2,
|
||||
ModeSwitch = 4,
|
||||
CanContainLineNumber = 8
|
||||
DoNotMakeVisible = 4,
|
||||
CanContainLineNumber = 8,
|
||||
OpenInOtherSplit = 16
|
||||
};
|
||||
Q_DECLARE_FLAGS(OpenEditorFlags, OpenEditorFlag)
|
||||
|
||||
static QString splitLineNumber(QString *fileName);
|
||||
static IEditor *openEditor(const QString &fileName, const Id &editorId = Id(),
|
||||
OpenEditorFlags flags = 0, bool *newEditor = 0);
|
||||
static IEditor *openEditorInNextSplit(const QString &fileName, const Id &editorId = Id(),
|
||||
OpenEditorFlags flags = 0, bool *newEditor = 0);
|
||||
static IEditor *openEditorAt(const QString &fileName, int line, int column = 0,
|
||||
const Id &editorId = Id(), OpenEditorFlags flags = 0,
|
||||
bool *newEditor = 0);
|
||||
static IEditor *openEditorWithContents(const Id &editorId,
|
||||
QString *titlePattern = 0, const QString &contents = QString());
|
||||
|
||||
@@ -234,6 +236,8 @@ private slots:
|
||||
void rootDestroyed(QObject *root);
|
||||
void setCurrentEditorFromContextChange();
|
||||
|
||||
void gotoNextSplit();
|
||||
|
||||
public slots:
|
||||
void goBackInNavigationHistory();
|
||||
void goForwardInNavigationHistory();
|
||||
@@ -257,6 +261,7 @@ private:
|
||||
IEditor *duplicateEditor(IEditor *editor);
|
||||
IEditor *activateEditor(Internal::EditorView *view, IEditor *editor, OpenEditorFlags flags = 0);
|
||||
void activateEditorForIndex(Internal::EditorView *view, const QModelIndex &index, OpenEditorFlags = 0);
|
||||
void activateView(Internal::EditorView *view);
|
||||
IEditor *openEditor(Internal::EditorView *view, const QString &fileName,
|
||||
const Id &id = Id(), OpenEditorFlags flags = 0, bool *newEditor = 0);
|
||||
|
||||
@@ -264,7 +269,7 @@ private:
|
||||
void setCurrentView(Internal::EditorView *view);
|
||||
Internal::EditorView *currentEditorView() const;
|
||||
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 closeDuplicate(IEditor *editor);
|
||||
@@ -273,7 +278,6 @@ private:
|
||||
static void splitNewWindow(Internal::EditorView *view);
|
||||
IEditor *pickUnusedEditor() const;
|
||||
void addDocumentToRecentFiles(IDocument *document);
|
||||
void switchToPreferedMode();
|
||||
void updateAutoSave();
|
||||
void setCloseSplitEnabled(Internal::SplitterOrView *splitterOrView, bool enable);
|
||||
void updateMakeWritableWarning();
|
||||
|
||||
@@ -144,8 +144,8 @@ EditorView *EditorView::findNextView()
|
||||
current = parent;
|
||||
parent = current->findParentSplitter();
|
||||
}
|
||||
// current has no parent, so just take the very first view
|
||||
return current->findFirstView();
|
||||
// current has no parent, so we are at the top and there is no "next" view
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EditorView::closeView()
|
||||
@@ -299,7 +299,7 @@ IEditor *EditorView::currentEditor() const
|
||||
void EditorView::listSelectionActivated(int index)
|
||||
{
|
||||
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()
|
||||
@@ -465,11 +465,11 @@ void EditorView::goBackInNavigationHistory()
|
||||
IEditor *editor = 0;
|
||||
if (location.document) {
|
||||
editor = em->activateEditorForDocument(this, location.document,
|
||||
EditorManager::IgnoreNavigationHistory | EditorManager::ModeSwitch);
|
||||
EditorManager::IgnoreNavigationHistory);
|
||||
}
|
||||
if (!editor) {
|
||||
editor = em->openEditor(this, location.fileName, location.id,
|
||||
EditorManager::IgnoreNavigationHistory | EditorManager::ModeSwitch);
|
||||
EditorManager::IgnoreNavigationHistory);
|
||||
if (!editor) {
|
||||
m_navigationHistory.removeAt(m_currentNavigationHistoryPosition);
|
||||
continue;
|
||||
@@ -492,7 +492,7 @@ void EditorView::goForwardInNavigationHistory()
|
||||
IEditor *editor = 0;
|
||||
if (location.document) {
|
||||
editor = em->activateEditorForDocument(this, location.document,
|
||||
EditorManager::IgnoreNavigationHistory | EditorManager::ModeSwitch);
|
||||
EditorManager::IgnoreNavigationHistory);
|
||||
}
|
||||
if (!editor) {
|
||||
editor = em->openEditor(this, location.fileName, location.id, EditorManager::IgnoreNavigationHistory);
|
||||
@@ -784,13 +784,13 @@ void SplitterOrView::restoreState(const QByteArray &state)
|
||||
if (!QFile::exists(fileName))
|
||||
return;
|
||||
IEditor *e = em->openEditor(view(), fileName, Id::fromString(id), Core::EditorManager::IgnoreNavigationHistory
|
||||
| Core::EditorManager::NoActivate);
|
||||
| Core::EditorManager::DoNotChangeCurrentEditor);
|
||||
|
||||
if (!e) {
|
||||
QModelIndex idx = em->openedEditorsModel()->firstRestoredEditor();
|
||||
if (idx.isValid())
|
||||
em->activateEditorForIndex(view(), idx, Core::EditorManager::IgnoreNavigationHistory
|
||||
| Core::EditorManager::NoActivate);
|
||||
| Core::EditorManager::DoNotChangeCurrentEditor);
|
||||
}
|
||||
|
||||
if (e) {
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
|
||||
virtual QWidget *toolBar() = 0;
|
||||
|
||||
virtual Id preferredModeType() const { return Id(); }
|
||||
virtual bool isDesignModePreferred() const { return false; }
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
|
||||
@@ -29,11 +29,12 @@
|
||||
|
||||
#include "ieditorfactory.h"
|
||||
|
||||
#include "ieditor.h"
|
||||
#include "editormanager.h"
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
Core::IDocument *Core::IEditorFactory::open(const QString &fileName)
|
||||
Core::IDocument *Core::IEditorFactory::open(const QString &)
|
||||
{
|
||||
Core::IEditor *iface = Core::EditorManager::openEditor(fileName, id());
|
||||
return iface ? iface->document() : 0;
|
||||
qWarning("This should never be called, use IEditorFactor::createEditor, "
|
||||
"or EditorManager::openEditor instead!");
|
||||
QTC_CHECK(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
IEditorFactory(QObject *parent = 0) : IDocumentFactory(parent) {}
|
||||
|
||||
virtual IEditor *createEditor(QWidget *parent) = 0;
|
||||
virtual IDocument *open(const QString &fileName);
|
||||
virtual IDocument *open(const QString &);
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
||||
@@ -189,7 +189,7 @@ void OpenEditorsWidget::handleClicked(const QModelIndex &index)
|
||||
void OpenEditorsWidget::activateEditor(const QModelIndex &index)
|
||||
{
|
||||
selectionModel()->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
|
||||
EditorManager::instance()->activateEditorForIndex(index, EditorManager::ModeSwitch);
|
||||
EditorManager::instance()->activateEditorForIndex(index);
|
||||
}
|
||||
|
||||
void OpenEditorsWidget::closeEditor(const QModelIndex &index)
|
||||
|
||||
@@ -225,11 +225,10 @@ void OpenEditorsWindow::selectEditor(QTreeWidgetItem *item)
|
||||
return;
|
||||
if (IDocument *document = item->data(0, Qt::UserRole).value<IDocument*>()) {
|
||||
EditorView *view = item->data(0, Qt::UserRole+1).value<EditorView*>();
|
||||
EditorManager::instance()->activateEditorForDocument(view, document, EditorManager::ModeSwitch);
|
||||
EditorManager::instance()->activateEditorForDocument(view, document);
|
||||
} else {
|
||||
if (!EditorManager::openEditor(
|
||||
item->toolTip(0), item->data(0, Qt::UserRole+2).value<Core::Id>(),
|
||||
Core::EditorManager::ModeSwitch)) {
|
||||
item->toolTip(0), item->data(0, Qt::UserRole+2).value<Core::Id>())) {
|
||||
EditorManager::instance()->openedEditorsModel()->removeEditor(item->toolTip(0));
|
||||
delete item;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ EditorToolBarPrivate::EditorToolBarPrivate(QWidget *parent, EditorToolBar *q) :
|
||||
m_splitButton(new QToolButton),
|
||||
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_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_activeToolBar(0),
|
||||
m_toolBarPlaceholder(new QWidget),
|
||||
@@ -311,7 +311,7 @@ void EditorToolBar::changeActiveEditor(int row)
|
||||
{
|
||||
EditorManager *em = ICore::editorManager();
|
||||
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)
|
||||
|
||||
@@ -49,7 +49,6 @@ public:
|
||||
QIcon icon() const { return m_icon; }
|
||||
int priority() const { return m_priority; }
|
||||
Id id() const { return m_id; }
|
||||
Id type() const { return m_type; }
|
||||
bool isEnabled() const;
|
||||
|
||||
void setEnabled(bool enabled);
|
||||
@@ -57,7 +56,6 @@ public:
|
||||
void setIcon(const QIcon &icon) { m_icon = icon; }
|
||||
void setPriority(int priority) { m_priority = priority; }
|
||||
void setId(Id id) { m_id = id; }
|
||||
void setType(Id type) { m_type = type; }
|
||||
|
||||
signals:
|
||||
void enabledStateChanged(bool enabled);
|
||||
@@ -67,7 +65,6 @@ private:
|
||||
QIcon m_icon;
|
||||
int m_priority;
|
||||
Id m_id;
|
||||
Id m_type;
|
||||
bool m_isEnabled;
|
||||
};
|
||||
|
||||
|
||||
@@ -861,8 +861,6 @@ IDocument *MainWindow::openFiles(const QStringList &fileNames, ICore::OpenFilesF
|
||||
}
|
||||
} else {
|
||||
QFlags<EditorManager::OpenEditorFlag> emFlags;
|
||||
if (flags & ICore::SwitchMode)
|
||||
emFlags = EditorManager::ModeSwitch;
|
||||
if (flags & ICore::CanContainLineNumbers)
|
||||
emFlags |= EditorManager::CanContainLineNumber;
|
||||
IEditor *editor = EditorManager::openEditor(absoluteFilePath, Id(), emFlags);
|
||||
@@ -1005,7 +1003,7 @@ void MainWindow::openFileWith()
|
||||
if (isExternal)
|
||||
EditorManager::openExternalEditor(fileName, editorId);
|
||||
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())) {
|
||||
const DocumentManager::RecentFile file = action->data().value<DocumentManager::RecentFile>();
|
||||
EditorManager::openEditor(file.first, file.second, EditorManager::ModeSwitch);
|
||||
EditorManager::openEditor(file.first, file.second);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@ struct ModeManagerPrivate
|
||||
Context m_addedContexts;
|
||||
int m_oldCurrent;
|
||||
bool m_saveSettingsOnModeChange;
|
||||
bool m_modeSelectorVisible;
|
||||
};
|
||||
|
||||
static ModeManagerPrivate *d;
|
||||
@@ -100,6 +101,8 @@ ModeManager::ModeManager(Internal::MainWindow *mainWindow,
|
||||
d->m_actionBar = new Internal::FancyActionBar(modeStack);
|
||||
d->m_modeStack->addCornerWidget(d->m_actionBar);
|
||||
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(currentChanged(int)), SLOT(currentTabChanged(int)));
|
||||
@@ -147,21 +150,6 @@ IMode *ModeManager::mode(Id id)
|
||||
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)
|
||||
{
|
||||
m_instance->activateMode(Id::fromUniqueIdentifier(id));
|
||||
@@ -330,21 +318,22 @@ void ModeManager::setFocusToCurrentMode()
|
||||
QWidget *widget = mode->widget();
|
||||
if (widget) {
|
||||
QWidget *focusWidget = widget->focusWidget();
|
||||
if (focusWidget)
|
||||
if (!focusWidget)
|
||||
focusWidget = widget;
|
||||
focusWidget->setFocus();
|
||||
else
|
||||
widget->setFocus();
|
||||
ICore::raiseWindow(focusWidget);
|
||||
}
|
||||
}
|
||||
|
||||
void ModeManager::setModeSelectorVisible(bool visible)
|
||||
{
|
||||
d->m_modeSelectorVisible = visible;
|
||||
d->m_modeStack->setSelectionWidgetVisible(visible);
|
||||
}
|
||||
|
||||
bool ModeManager::isModeSelectorVisible()
|
||||
{
|
||||
return d->m_modeStack->isSelectionWidgetVisible();
|
||||
return d->m_modeSelectorVisible;
|
||||
}
|
||||
|
||||
ModeManager *ModeManager::instance()
|
||||
|
||||
@@ -65,7 +65,6 @@ public:
|
||||
static void addProjectSelector(QAction *action);
|
||||
static void addWidget(QWidget *widget);
|
||||
|
||||
static void activateModeType(Id type);
|
||||
static void activateMode(Id id);
|
||||
static void setFocusToCurrentMode();
|
||||
static bool isModeSelectorVisible();
|
||||
|
||||
@@ -145,7 +145,6 @@ FutureProgress::FutureProgress(QWidget *parent) :
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn FutureProgress::~FutureProgress()
|
||||
\internal
|
||||
*/
|
||||
FutureProgress::~FutureProgress()
|
||||
@@ -155,7 +154,6 @@ FutureProgress::~FutureProgress()
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void FutureProgress::setWidget(QWidget *widget)
|
||||
Sets the \a widget to show below the progress bar.
|
||||
This will be destroyed when the progress indicator is destroyed.
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
QString FutureProgress::title() const
|
||||
@@ -268,7 +264,6 @@ void FutureProgress::setProgressText(const QString &text)
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void FutureProgress::setFuture(const QFuture<void> &future)
|
||||
\internal
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
QFuture<void> FutureProgress::future() const
|
||||
@@ -286,7 +280,6 @@ QFuture<void> FutureProgress::future() const
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void FutureProgress::mousePressEvent(QMouseEvent *event)
|
||||
\internal
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
bool FutureProgress::hasError() const
|
||||
|
||||
@@ -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 + 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));
|
||||
}
|
||||
|
||||
|
||||
@@ -106,6 +106,11 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
void clearCache()
|
||||
{
|
||||
m_cachedMatches.clear();
|
||||
}
|
||||
|
||||
void resetCache(const QString &dir)
|
||||
{
|
||||
QTC_ASSERT(QDir(dir).isAbsolute(), return);
|
||||
@@ -226,9 +231,11 @@ IVersionControl* VcsManager::findVersionControlForDirectory(const QString &input
|
||||
|
||||
foreach (IVersionControl * versionControl, versionControls) {
|
||||
QString topLevel;
|
||||
if (versionControl->managesDirectory(directory, &topLevel))
|
||||
if (versionControl->isConfigured()
|
||||
&& versionControl->managesDirectory(directory, &topLevel)) {
|
||||
allThatCanManage.push_back(StringVersionControlPair(topLevel, versionControl));
|
||||
}
|
||||
}
|
||||
|
||||
// To properly find a nested repository (say, git checkout inside SVN),
|
||||
// we need to select the version control with the longest toplevel pathname.
|
||||
@@ -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
|
||||
|
||||
@@ -95,6 +95,9 @@ public:
|
||||
signals:
|
||||
void repositoryChanged(const QString &repository);
|
||||
|
||||
public slots:
|
||||
void clearVersionControlCache();
|
||||
|
||||
private:
|
||||
VcsManagerPrivate *d;
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user