forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/3.3'
Change-Id: I0ab4982e229d475b8e3575414b4bebbfea07498d
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 33 KiB |
BIN
doc/images/qtcreator-variables-button.png
Normal file
BIN
doc/images/qtcreator-variables-button.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
@@ -457,7 +457,7 @@
|
|||||||
|
|
||||||
\li To continue running the program, press \key{F5}.
|
\li To continue running the program, press \key{F5}.
|
||||||
|
|
||||||
\li To run to the line containing the cursor, press \ke{yCtrl+F10}
|
\li To run to the line containing the cursor, press \key{Ctrl+F10}
|
||||||
(\key{Shift+F8} on OS X).
|
(\key{Shift+F8} on OS X).
|
||||||
|
|
||||||
\li To run to the selected function when you are stepping into a nested
|
\li To run to the selected function when you are stepping into a nested
|
||||||
|
|||||||
@@ -94,11 +94,6 @@
|
|||||||
You can change the configuration of preconfigured tools and configure
|
You can change the configuration of preconfigured tools and configure
|
||||||
additional tools in \QC \gui Options.
|
additional tools in \QC \gui Options.
|
||||||
|
|
||||||
You can use \QC variables in the fields that you can select from
|
|
||||||
lists of available \QC variables (1).
|
|
||||||
|
|
||||||
\image qtcreator-external-tools.png "External Tools options"
|
|
||||||
|
|
||||||
To configure external tools:
|
To configure external tools:
|
||||||
|
|
||||||
\list 1
|
\list 1
|
||||||
|
|||||||
@@ -612,7 +612,7 @@
|
|||||||
\li Alt+Z, Alt+C
|
\li Alt+Z, Alt+C
|
||||||
\li Alt+C, Alt+C
|
\li Alt+C, Alt+C
|
||||||
\li Alt+G, Alt+C
|
\li Alt+G, Alt+C
|
||||||
\li Alt+H, Alt+C
|
\li Alt+G, Alt+C
|
||||||
\li Alt+P, Alt+S
|
\li Alt+P, Alt+S
|
||||||
\li Alt+S, Alt+C
|
\li Alt+S, Alt+C
|
||||||
\row
|
\row
|
||||||
@@ -620,7 +620,7 @@
|
|||||||
\li Alt+Z, Alt+D
|
\li Alt+Z, Alt+D
|
||||||
\li Alt+C, Alt+D
|
\li Alt+C, Alt+D
|
||||||
\li Alt+G, Alt+D
|
\li Alt+G, Alt+D
|
||||||
\li Alt+H, Alt+D
|
\li Alt+G, Alt+D
|
||||||
\li
|
\li
|
||||||
\li Alt+S, Alt+D
|
\li Alt+S, Alt+D
|
||||||
\row
|
\row
|
||||||
@@ -644,7 +644,7 @@
|
|||||||
\li Alt+Z, Alt+L
|
\li Alt+Z, Alt+L
|
||||||
\li
|
\li
|
||||||
\li Alt+G, Alt+L
|
\li Alt+G, Alt+L
|
||||||
\li Alt+H, Alt+L
|
\li Alt+G, Alt+L
|
||||||
\li Alt+P, Alt+F
|
\li Alt+P, Alt+F
|
||||||
\li
|
\li
|
||||||
\row
|
\row
|
||||||
@@ -660,7 +660,7 @@
|
|||||||
\li Alt+Z, Alt+S
|
\li Alt+Z, Alt+S
|
||||||
\li
|
\li
|
||||||
\li
|
\li
|
||||||
\li Alt+H, Alt+S
|
\li Alt+G, Alt+S
|
||||||
\li
|
\li
|
||||||
\li
|
\li
|
||||||
\row
|
\row
|
||||||
|
|||||||
@@ -96,17 +96,10 @@
|
|||||||
|
|
||||||
You can use \QC variables in arguments, executable paths, and working
|
You can use \QC variables in arguments, executable paths, and working
|
||||||
directories. The variables take care of quoting their expansions, so you do
|
directories. The variables take care of quoting their expansions, so you do
|
||||||
not need to put them in quotes.
|
not need to put them in quotes. Select the
|
||||||
|
\inlineimage qtcreator-variables-button.png
|
||||||
The following \QC variables are available:
|
(\gui {Variables}) button in a field to select from a list of variables that
|
||||||
|
are available in a particular context.
|
||||||
\list
|
|
||||||
|
|
||||||
\li %{buildDir}
|
|
||||||
|
|
||||||
\li %{sourceDir}
|
|
||||||
|
|
||||||
\endlist
|
|
||||||
|
|
||||||
\section1 Build Steps
|
\section1 Build Steps
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
\title Qt Quick UI Forms
|
\title Qt Quick UI Forms
|
||||||
|
|
||||||
You can use \QC wizards to create UI forms tha have the filename extension
|
You can use \QC wizards to create UI forms that have the filename extension
|
||||||
\e .ui.qml. The UI forms contain a purely declarative subset of the QML
|
\e .ui.qml. The UI forms contain a purely declarative subset of the QML
|
||||||
language. It is recommended that you edit the forms in the \gui Design mode.
|
language. It is recommended that you edit the forms in the \gui Design mode.
|
||||||
\QC enforces the use of the supported QML features by displaying error
|
\QC enforces the use of the supported QML features by displaying error
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import qbs
|
import qbs
|
||||||
import qbs.FileInfo
|
import qbs.FileInfo
|
||||||
import QtcProduct
|
|
||||||
|
|
||||||
QtcProduct {
|
QtcProduct {
|
||||||
type: "application"
|
type: "application"
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
import QtcFunctions
|
import QtcFunctions
|
||||||
import QtcProduct
|
|
||||||
|
|
||||||
QtcProduct {
|
QtcProduct {
|
||||||
type: "dynamiclibrary"
|
type: "dynamiclibrary"
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
import qbs.FileInfo
|
import qbs.FileInfo
|
||||||
import QtcFunctions
|
import QtcFunctions
|
||||||
import QtcProduct
|
|
||||||
|
|
||||||
QtcProduct {
|
QtcProduct {
|
||||||
type: ["dynamiclibrary", "pluginSpec"]
|
type: ["dynamiclibrary", "pluginSpec"]
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
import QtcProduct
|
|
||||||
|
|
||||||
QtcProduct {
|
QtcProduct {
|
||||||
type: "application" // no Mac app bundle
|
type: "application" // no Mac app bundle
|
||||||
|
|||||||
@@ -1582,14 +1582,20 @@ def qdump__QRegion(d, value):
|
|||||||
ns = d.qtNamespace()
|
ns = d.qtNamespace()
|
||||||
rectType = d.lookupType(ns + "QRect")
|
rectType = d.lookupType(ns + "QRect")
|
||||||
d.putIntItem("numRects", n)
|
d.putIntItem("numRects", n)
|
||||||
d.putSubItem("extents", d.createValue(pp + 2 * v, rectType))
|
if d.qtVersion() >= 0x050400:
|
||||||
d.putSubItem("innerRect", d.createValue(pp + 2 * v + rectType.sizeof, rectType))
|
# Changed in ee324e4ed
|
||||||
d.putIntItem("innerArea", d.extractInt(pp + 2 * v + 2 * rectType.sizeof))
|
d.putSubItem("extents", d.createValue(pp + 8 + v, rectType))
|
||||||
|
d.putSubItem("innerRect", d.createValue(pp + 8 + v + rectType.sizeof, rectType))
|
||||||
|
d.putIntItem("innerArea", d.extractInt(pp + 4))
|
||||||
|
else:
|
||||||
|
d.putSubItem("extents", d.createValue(pp + 2 * v, rectType))
|
||||||
|
d.putSubItem("innerRect", d.createValue(pp + 2 * v + rectType.sizeof, rectType))
|
||||||
|
d.putIntItem("innerArea", d.extractInt(pp + 2 * v + 2 * rectType.sizeof))
|
||||||
# FIXME
|
# FIXME
|
||||||
try:
|
try:
|
||||||
# Can fail if QVector<QRect> debuginfo is missing.
|
# Can fail if QVector<QRect> debuginfo is missing.
|
||||||
vectType = d.lookupType("%sQVector<%sQRect>" % (ns, ns))
|
vectType = d.lookupType("%sQVector<%sQRect>" % (ns, ns))
|
||||||
d.putSubItem("rects", d.createValue(pp + v, vectType))
|
d.putSubItem("rects", d.createValue(pp + 8, vectType))
|
||||||
except:
|
except:
|
||||||
with SubItem(d, "rects"):
|
with SubItem(d, "rects"):
|
||||||
d.putItemCount(n)
|
d.putItemCount(n)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Label {
|
Label {
|
||||||
text: "%1"
|
text: "%1"
|
||||||
toolTip: "%1"
|
tooltip: "%1"
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckBox {
|
CheckBox {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Label {
|
Label {
|
||||||
text: "%1"
|
text: "%1"
|
||||||
toolTip: "%1"
|
tooltip: "%1"
|
||||||
}
|
}
|
||||||
SpinBox {
|
SpinBox {
|
||||||
maximumValue: 9999999
|
maximumValue: 9999999
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Label {
|
Label {
|
||||||
text: "%1"
|
text: "%1"
|
||||||
toolTip: "%1"
|
tooltip: "%1"
|
||||||
}
|
}
|
||||||
SpinBox {
|
SpinBox {
|
||||||
maximumValue: 9999999
|
maximumValue: 9999999
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Label {
|
Label {
|
||||||
text: "%1"
|
text: "%1"
|
||||||
toolTip: "%1"
|
tooltip: "%1"
|
||||||
}
|
}
|
||||||
LineEdit {
|
LineEdit {
|
||||||
backendValue: backendValues.%2
|
backendValue: backendValues.%2
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Label {
|
Label {
|
||||||
text: "%1"
|
text: "%1"
|
||||||
toolTip: "%1"
|
tooltip: "%1"
|
||||||
}
|
}
|
||||||
LineEdit {
|
LineEdit {
|
||||||
backendValue: backendValues.%2
|
backendValue: backendValues.%2
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ Column {
|
|||||||
ComboBox {
|
ComboBox {
|
||||||
model: ["LeftToRight", "TopToBottom"]
|
model: ["LeftToRight", "TopToBottom"]
|
||||||
backendValue: backendValues.flow
|
backendValue: backendValues.flow
|
||||||
scope: "Qt"
|
scope: "Flow"
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpandingSpacer {
|
ExpandingSpacer {
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ Column {
|
|||||||
model: ["LeftToRight", "TopToBottom"]
|
model: ["LeftToRight", "TopToBottom"]
|
||||||
backendValue: backendValues.flow
|
backendValue: backendValues.flow
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
scope: "Qt"
|
scope: "Grid"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,11 @@
|
|||||||
"source": "file.pro",
|
"source": "file.pro",
|
||||||
"target": "%{ProFileName}",
|
"target": "%{ProFileName}",
|
||||||
"openAsProject": true
|
"openAsProject": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "../git.ignore",
|
||||||
|
"target": "%{ProjectDirectory}/.gitignore",
|
||||||
|
"condition": "%{JS: ('%{VersionControl}%{IsSubproject}' === 'G.Git') ? 'yes' : ''}"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
72
share/qtcreator/templates/wizards/projects/qmake/git.ignore
Normal file
72
share/qtcreator/templates/wizards/projects/qmake/git.ignore
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
# This file is used to ignore files which are generated
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
*~
|
||||||
|
*.autosave
|
||||||
|
*.a
|
||||||
|
*.core
|
||||||
|
*.moc
|
||||||
|
*.o
|
||||||
|
*.obj
|
||||||
|
*.orig
|
||||||
|
*.rej
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*_pch.h.cpp
|
||||||
|
*_resource.rc
|
||||||
|
*.qm
|
||||||
|
.#*
|
||||||
|
*.*#
|
||||||
|
core
|
||||||
|
!core/
|
||||||
|
tags
|
||||||
|
.DS_Store
|
||||||
|
*.debug
|
||||||
|
Makefile*
|
||||||
|
*.prl
|
||||||
|
*.app
|
||||||
|
moc_*.cpp
|
||||||
|
ui_*.h
|
||||||
|
qrc_*.cpp
|
||||||
|
Thumbs.db
|
||||||
|
*.res
|
||||||
|
*.rc
|
||||||
|
/.qmake.cache
|
||||||
|
/.qmake.stash
|
||||||
|
|
||||||
|
# qtcreator generated files
|
||||||
|
*.pro.user*
|
||||||
|
|
||||||
|
# xemacs temporary files
|
||||||
|
*.flc
|
||||||
|
|
||||||
|
# Vim temporary files
|
||||||
|
.*.swp
|
||||||
|
|
||||||
|
# Visual Studio generated files
|
||||||
|
*.ib_pdb_index
|
||||||
|
*.idb
|
||||||
|
*.ilk
|
||||||
|
*.pdb
|
||||||
|
*.sln
|
||||||
|
*.suo
|
||||||
|
*.vcproj
|
||||||
|
*vcproj.*.*.user
|
||||||
|
*.ncb
|
||||||
|
*.sdf
|
||||||
|
*.opensdf
|
||||||
|
*.vcxproj
|
||||||
|
*vcxproj.*
|
||||||
|
|
||||||
|
# MinGW generated files
|
||||||
|
*.Debug
|
||||||
|
*.Release
|
||||||
|
|
||||||
|
# Python byte code
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Binaries
|
||||||
|
# --------
|
||||||
|
*.dll
|
||||||
|
*.exe
|
||||||
|
|
||||||
@@ -73,8 +73,8 @@ ProgressBarColorFinished=ff5aaa3c
|
|||||||
ProgressBarColorNormal=hoverBackground
|
ProgressBarColorNormal=hoverBackground
|
||||||
ProgressBarTitleColor=text
|
ProgressBarTitleColor=text
|
||||||
QtOutputFormatter_LinkTextColor=ff0000ff
|
QtOutputFormatter_LinkTextColor=ff0000ff
|
||||||
SearchResultWidgetBackgroundColor=shadowBackground
|
InfoBarBackground=shadowBackground
|
||||||
SearchResultWidgetTextColor=text
|
InfoBarText=text
|
||||||
TextColorDisabled=textDisabled
|
TextColorDisabled=textDisabled
|
||||||
TextColorHighlight=ffff0000
|
TextColorHighlight=ffff0000
|
||||||
TextColorNormal=text
|
TextColorNormal=text
|
||||||
@@ -84,7 +84,8 @@ ToolBarBackgroundColor=shadowBackground
|
|||||||
TreeViewArrowColorNormal=hoverBackground
|
TreeViewArrowColorNormal=hoverBackground
|
||||||
TreeViewArrowColorSelected=text
|
TreeViewArrowColorSelected=text
|
||||||
Welcome_BackgroundColorNormal=normalBackground
|
Welcome_BackgroundColorNormal=normalBackground
|
||||||
Welcome_Button_BorderColor=0
|
Welcome_Button_BorderColorNormal=0
|
||||||
|
Welcome_Button_BorderColorPressed=0
|
||||||
Welcome_Button_TextColorNormal=ffe7e7e7
|
Welcome_Button_TextColorNormal=ffe7e7e7
|
||||||
Welcome_Button_TextColorPressed=ffffffff
|
Welcome_Button_TextColorPressed=ffffffff
|
||||||
Welcome_Caption_TextColorNormal=ff4acb47
|
Welcome_Caption_TextColorNormal=ff4acb47
|
||||||
|
|||||||
@@ -67,8 +67,8 @@ ProgressBarColorFinished=ff5aaa3c
|
|||||||
ProgressBarColorNormal=b4ffffff
|
ProgressBarColorNormal=b4ffffff
|
||||||
ProgressBarTitleColor=ffffffff
|
ProgressBarTitleColor=ffffffff
|
||||||
QtOutputFormatter_LinkTextColor=ff0000aa
|
QtOutputFormatter_LinkTextColor=ff0000aa
|
||||||
SearchResultWidgetBackgroundColor=ffffffff
|
InfoBarBackground=ffffffe1
|
||||||
SearchResultWidgetTextColor=ff000000
|
InfoBarText=ff000000
|
||||||
TextColorDisabled=ff000000
|
TextColorDisabled=ff000000
|
||||||
TextColorHighlight=ffa0a0a4
|
TextColorHighlight=ffa0a0a4
|
||||||
TextColorNormal=ff000000
|
TextColorNormal=ff000000
|
||||||
@@ -78,7 +78,8 @@ ToolBarBackgroundColor=ffff0000
|
|||||||
TreeViewArrowColorNormal=ffff0000
|
TreeViewArrowColorNormal=ffff0000
|
||||||
TreeViewArrowColorSelected=ffff0000
|
TreeViewArrowColorSelected=ffff0000
|
||||||
Welcome_BackgroundColorNormal=ffffffff
|
Welcome_BackgroundColorNormal=ffffffff
|
||||||
Welcome_Button_BorderColor=ff737373
|
Welcome_Button_BorderColorNormal=ff737373
|
||||||
|
Welcome_Button_BorderColorPressed=ff333333
|
||||||
Welcome_Button_TextColorNormal=ff000000
|
Welcome_Button_TextColorNormal=ff000000
|
||||||
Welcome_Button_TextColorPressed=ffc0c0c0
|
Welcome_Button_TextColorPressed=ffc0c0c0
|
||||||
Welcome_Caption_TextColorNormal=ff328930
|
Welcome_Caption_TextColorNormal=ff328930
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ Controls.ScrollView {
|
|||||||
Item {
|
Item {
|
||||||
id: canvas
|
id: canvas
|
||||||
|
|
||||||
implicitWidth: childrenRect.width + 200
|
implicitWidth: childrenRect.width
|
||||||
implicitHeight: childrenRect.height
|
implicitHeight: childrenRect.height
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
@@ -97,8 +97,6 @@ Controls.ScrollView {
|
|||||||
|
|
||||||
anchors.top: recentProjectsTitle.bottom
|
anchors.top: recentProjectsTitle.bottom
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: 60
|
|
||||||
|
|
||||||
model: projectList
|
model: projectList
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ Button {
|
|||||||
color: (creatorTheme.WidgetStyle === 'StyleFlat') ? "#232323" : "#eeeeee"
|
color: (creatorTheme.WidgetStyle === 'StyleFlat') ? "#232323" : "#eeeeee"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
border.color: creatorTheme.Welcome_Button_BorderColor
|
border.color: creatorTheme.Welcome_Button_BorderColorNormal
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -114,7 +114,7 @@ Button {
|
|||||||
color: (creatorTheme.WidgetStyle === 'StyleFlat') ? "#151515" : "#424242"
|
color: (creatorTheme.WidgetStyle === 'StyleFlat') ? "#151515" : "#424242"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
border.color: creatorTheme.Welcome_Button_BorderColor
|
border.color: creatorTheme.Welcome_Button_BorderColorPressed
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import QtQuick.Controls 1.0
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
id: projectList
|
id: projectList
|
||||||
height: column.height + 200
|
height: column.height + 200
|
||||||
|
width: column.width
|
||||||
color: creatorTheme.Welcome_BackgroundColorNormal
|
color: creatorTheme.Welcome_BackgroundColorNormal
|
||||||
|
|
||||||
property alias model: repeater.model
|
property alias model: repeater.model
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
import QtcLibrary
|
|
||||||
|
|
||||||
QtcLibrary {
|
QtcLibrary {
|
||||||
name: "Aggregation"
|
name: "Aggregation"
|
||||||
|
|||||||
@@ -493,8 +493,12 @@ void Document::setGlobalNamespace(Namespace *globalNamespace)
|
|||||||
*
|
*
|
||||||
* \param line the line number, starting with line 1
|
* \param line the line number, starting with line 1
|
||||||
* \param column the column number, starting with column 1
|
* \param column the column number, starting with column 1
|
||||||
|
* \param lineOpeningDeclaratorParenthesis optional output parameter, the line of the opening
|
||||||
|
parenthesis of the declarator starting with 1
|
||||||
|
* \param lineClosingBrace optional output parameter, the line of the closing brace starting with 1
|
||||||
*/
|
*/
|
||||||
QString Document::functionAt(int line, int column) const
|
QString Document::functionAt(int line, int column, int *lineOpeningDeclaratorParenthesis,
|
||||||
|
int *lineClosingBrace) const
|
||||||
{
|
{
|
||||||
if (line < 1 || column < 1)
|
if (line < 1 || column < 1)
|
||||||
return QString();
|
return QString();
|
||||||
@@ -505,10 +509,8 @@ QString Document::functionAt(int line, int column) const
|
|||||||
|
|
||||||
// Find the enclosing function scope (which might be several levels up, or we might be standing
|
// Find the enclosing function scope (which might be several levels up, or we might be standing
|
||||||
// on it)
|
// on it)
|
||||||
Scope *scope;
|
Scope *scope = symbol->asScope();
|
||||||
if (symbol->isScope())
|
if (!scope)
|
||||||
scope = symbol->asScope();
|
|
||||||
else
|
|
||||||
scope = symbol->enclosingScope();
|
scope = symbol->enclosingScope();
|
||||||
|
|
||||||
while (scope && !scope->isFunction() )
|
while (scope && !scope->isFunction() )
|
||||||
@@ -517,22 +519,21 @@ QString Document::functionAt(int line, int column) const
|
|||||||
if (!scope)
|
if (!scope)
|
||||||
return QString();
|
return QString();
|
||||||
|
|
||||||
// We found the function scope, extract its name.
|
// We found the function scope
|
||||||
const Overview o;
|
if (lineOpeningDeclaratorParenthesis) {
|
||||||
QString rc = o.prettyName(scope->name());
|
unsigned line;
|
||||||
|
translationUnit()->getPosition(scope->startOffset(), &line);
|
||||||
// Prepend namespace "Foo::Foo::foo()" up to empty root namespace
|
*lineOpeningDeclaratorParenthesis = static_cast<int>(line);
|
||||||
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;
|
|
||||||
|
if (lineClosingBrace) {
|
||||||
|
unsigned line;
|
||||||
|
translationUnit()->getPosition(scope->endOffset(), &line);
|
||||||
|
*lineClosingBrace = static_cast<int>(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QList<const Name *> fullyQualifiedName = LookupContext::fullyQualifiedName(scope);
|
||||||
|
return Overview().prettyName(fullyQualifiedName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Scope *Document::scopeAt(unsigned line, unsigned column)
|
Scope *Document::scopeAt(unsigned line, unsigned column)
|
||||||
|
|||||||
@@ -101,7 +101,8 @@ public:
|
|||||||
QList<Macro> definedMacros() const
|
QList<Macro> definedMacros() const
|
||||||
{ return _definedMacros; }
|
{ return _definedMacros; }
|
||||||
|
|
||||||
QString functionAt(int line, int column) const;
|
QString functionAt(int line, int column, int *lineOpeningDeclaratorParenthesis = 0,
|
||||||
|
int *lineClosingBrace = 0) const;
|
||||||
Symbol *lastVisibleSymbolAt(unsigned line, unsigned column = 0) const;
|
Symbol *lastVisibleSymbolAt(unsigned line, unsigned column = 0) const;
|
||||||
Scope *scopeAt(unsigned line, unsigned column = 0);
|
Scope *scopeAt(unsigned line, unsigned column = 0);
|
||||||
|
|
||||||
|
|||||||
@@ -200,6 +200,36 @@ private:
|
|||||||
ClassOrNamespace *_binding;
|
ClassOrNamespace *_binding;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int evaluateFunctionArgument(const FullySpecifiedType &actualTy,
|
||||||
|
const FullySpecifiedType &formalTy)
|
||||||
|
{
|
||||||
|
int score = 0;
|
||||||
|
if (actualTy.type()->match(formalTy.type())) {
|
||||||
|
++score;
|
||||||
|
if (actualTy.isConst() == formalTy.isConst())
|
||||||
|
++score;
|
||||||
|
} else if (actualTy.simplified().type()->match(formalTy.simplified().type())) {
|
||||||
|
++score;
|
||||||
|
if (actualTy.simplified().isConst() == formalTy.simplified().isConst())
|
||||||
|
++score;
|
||||||
|
} else {
|
||||||
|
PointerType *actualAsPointer = actualTy.type()->asPointerType();
|
||||||
|
PointerType *formalAsPointer = formalTy.type()->asPointerType();
|
||||||
|
|
||||||
|
if (actualAsPointer && formalAsPointer) {
|
||||||
|
FullySpecifiedType actualElementType = actualAsPointer->elementType();
|
||||||
|
FullySpecifiedType formalElementType = formalAsPointer->elementType();
|
||||||
|
if (actualElementType.type()->match(formalElementType.type())) {
|
||||||
|
++score;
|
||||||
|
if (actualElementType.isConst() == formalElementType.isConst())
|
||||||
|
++score;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
} // end of anonymous namespace
|
} // end of anonymous namespace
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
@@ -771,15 +801,6 @@ bool ResolveExpression::maybeValidPrototype(Function *funTy, unsigned actualArgu
|
|||||||
return funTy->maybeValidPrototype(actualArgumentCount);
|
return funTy->maybeValidPrototype(actualArgumentCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResolveExpression::implicitConversion(const FullySpecifiedType &sourceTy, const FullySpecifiedType &targetTy) const
|
|
||||||
{
|
|
||||||
if (sourceTy.match(targetTy))
|
|
||||||
return true;
|
|
||||||
else if (sourceTy.simplified().match(targetTy.simplified()))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ResolveExpression::visit(CallAST *ast)
|
bool ResolveExpression::visit(CallAST *ast)
|
||||||
{
|
{
|
||||||
const QList<LookupItem> baseResults = resolve(ast->base_expression, _scope);
|
const QList<LookupItem> baseResults = resolve(ast->base_expression, _scope);
|
||||||
@@ -820,11 +841,13 @@ bool ResolveExpression::visit(CallAST *ast)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
actualTy = actual.first().type();
|
actualTy = actual.first().type();
|
||||||
} else
|
} else {
|
||||||
actualTy = formalTy;
|
actualTy = formalTy;
|
||||||
|
score += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (implicitConversion(actualTy, formalTy))
|
score += evaluateFunctionArgument(actualTy, formalTy);
|
||||||
++score;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sortedResults.insert(LookupMap::value_type(-score, base));
|
sortedResults.insert(LookupMap::value_type(-score, base));
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ protected:
|
|||||||
void addResults(const QList<LookupItem> &items);
|
void addResults(const QList<LookupItem> &items);
|
||||||
|
|
||||||
static bool maybeValidPrototype(Function *funTy, unsigned actualArgumentCount);
|
static bool maybeValidPrototype(Function *funTy, unsigned actualArgumentCount);
|
||||||
bool implicitConversion(const FullySpecifiedType &sourceTy, const FullySpecifiedType &targetTy) const;
|
|
||||||
|
|
||||||
using ASTVisitor::visit;
|
using ASTVisitor::visit;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
import QtcLibrary
|
|
||||||
|
|
||||||
QtcLibrary {
|
QtcLibrary {
|
||||||
name: "CPlusPlus"
|
name: "CPlusPlus"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
import QtcLibrary
|
|
||||||
|
|
||||||
QtcLibrary {
|
QtcLibrary {
|
||||||
name: "ExtensionSystem"
|
name: "ExtensionSystem"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
import QtcLibrary
|
|
||||||
|
|
||||||
QtcLibrary {
|
QtcLibrary {
|
||||||
name: "GLSL"
|
name: "GLSL"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
import QtcLibrary
|
|
||||||
|
|
||||||
QtcLibrary {
|
QtcLibrary {
|
||||||
name: "LanguageUtils"
|
name: "LanguageUtils"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
import QtcLibrary
|
|
||||||
|
|
||||||
QtcLibrary {
|
QtcLibrary {
|
||||||
name: "QmlDebug"
|
name: "QmlDebug"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
import QtcLibrary
|
|
||||||
|
|
||||||
QtcLibrary {
|
QtcLibrary {
|
||||||
name: "QmlEditorWidgets"
|
name: "QmlEditorWidgets"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
import QtcLibrary
|
|
||||||
|
|
||||||
QtcLibrary {
|
QtcLibrary {
|
||||||
name: "QmlJS"
|
name: "QmlJS"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
import QtcLibrary
|
|
||||||
|
|
||||||
QtcLibrary {
|
QtcLibrary {
|
||||||
name: "QtcSsh"
|
name: "QtcSsh"
|
||||||
|
|||||||
@@ -200,95 +200,137 @@ struct RemoveCvAndReference
|
|||||||
typedef typename std::remove_cv<typename std::remove_reference<T>::type>::type type;
|
typedef typename std::remove_cv<typename std::remove_reference<T>::type>::type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename F, typename T>
|
// abstraction to treat Container<T> and QStringList similarly
|
||||||
struct ResultOfFunctionWithoutCvAndReference
|
template<typename T>
|
||||||
|
struct ContainerType
|
||||||
{
|
{
|
||||||
typedef typename RemoveCvAndReference<decltype(declval<F>()(declval<T>()))>::type type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// actual implementation of transform
|
// specialization for qt container T_Container<T_Type>
|
||||||
template<template<typename> class C, // result container type
|
template<template<typename> class T_Container, typename T_Type>
|
||||||
template<typename> class SC, // input container type
|
struct ContainerType<T_Container<T_Type>> {
|
||||||
typename T, // element type of input container
|
typedef T_Type ElementType;
|
||||||
typename F> // function type
|
|
||||||
Q_REQUIRED_RESULT
|
template<class NewElementType>
|
||||||
auto transform_impl(const SC<T> &container, F function)
|
struct WithElementType
|
||||||
-> C<typename ResultOfFunctionWithoutCvAndReference<F, T>::type>
|
{
|
||||||
|
typedef T_Container<NewElementType> type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// specialization for QStringList
|
||||||
|
template<>
|
||||||
|
struct ContainerType<QStringList>
|
||||||
{
|
{
|
||||||
C<typename ResultOfFunctionWithoutCvAndReference<F, T>::type> result;
|
typedef QString ElementType;
|
||||||
result.reserve(container.size());
|
|
||||||
std::transform(container.begin(), container.end(),
|
template<class NewElementType>
|
||||||
inserter(result),
|
struct WithElementType
|
||||||
function);
|
{
|
||||||
return result;
|
typedef QList<NewElementType> type;
|
||||||
}
|
};
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// transform taking a member function pointer
|
// actual implementation of transform
|
||||||
template<template<typename> class C,
|
template<typename C, // result container type
|
||||||
typename T,
|
typename SC> // input container type
|
||||||
|
struct TransformImpl {
|
||||||
|
template <typename F>
|
||||||
|
Q_REQUIRED_RESULT
|
||||||
|
static C call(const SC &container, F function)
|
||||||
|
{
|
||||||
|
C result;
|
||||||
|
result.reserve(container.size());
|
||||||
|
std::transform(container.begin(), container.end(),
|
||||||
|
inserter(result),
|
||||||
|
function);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename R, typename S>
|
||||||
|
Q_REQUIRED_RESULT
|
||||||
|
static C call(const SC &container, R (S::*p)() const)
|
||||||
|
{
|
||||||
|
return call(container, std::mem_fn(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// same container type for input and output, e.g. transforming a QList<QString> into QList<int>
|
||||||
|
// or QStringList -> QList<>
|
||||||
|
template<typename C, // container
|
||||||
|
typename F>
|
||||||
|
Q_REQUIRED_RESULT
|
||||||
|
auto transform(const C &container, F function)
|
||||||
|
-> typename ContainerType<C>::template WithElementType< // the type C<stripped return type of F>
|
||||||
|
typename RemoveCvAndReference< // the return type of F stripped
|
||||||
|
decltype(declval<F>()(declval<typename ContainerType<C>::ElementType>())) // the return type of F
|
||||||
|
>::type
|
||||||
|
>::type
|
||||||
|
{
|
||||||
|
return TransformImpl<
|
||||||
|
typename ContainerType<C>::template WithElementType< // the type C<stripped return type>
|
||||||
|
typename RemoveCvAndReference< // the return type stripped
|
||||||
|
decltype(declval<F>()(declval<typename ContainerType<C>::ElementType>())) // the return type of F
|
||||||
|
>::type
|
||||||
|
>::type,
|
||||||
|
C
|
||||||
|
>::call(container, function);
|
||||||
|
}
|
||||||
|
|
||||||
|
// same container type for member function pointer
|
||||||
|
template<typename C,
|
||||||
typename R,
|
typename R,
|
||||||
typename S>
|
typename S>
|
||||||
Q_REQUIRED_RESULT
|
Q_REQUIRED_RESULT
|
||||||
auto transform(const C<T> &container, R (S::*p)() const)
|
auto transform(const C &container, R (S::*p)() const)
|
||||||
-> C<typename RemoveCvAndReference<R>::type>
|
->typename ContainerType<C>::template WithElementType<typename RemoveCvAndReference<R>::type>::type
|
||||||
{
|
{
|
||||||
C<typename RemoveCvAndReference<R>::type> result;
|
return TransformImpl<
|
||||||
result.reserve(container.size());
|
typename ContainerType<C>::template WithElementType< // the type C<stripped R>
|
||||||
std::transform(container.begin(), container.end(),
|
typename RemoveCvAndReference<R>::type // stripped R
|
||||||
std::back_inserter(result),
|
>::type,
|
||||||
std::mem_fn(p));
|
C
|
||||||
return result;
|
>::call(container, p);
|
||||||
}
|
|
||||||
|
|
||||||
// same container type for input and output, e.g. transforming a QList<QString> into QList<int>
|
|
||||||
template<template<typename> class C, // container
|
|
||||||
typename T, // element type
|
|
||||||
typename F> // function type
|
|
||||||
Q_REQUIRED_RESULT
|
|
||||||
auto transform(const C<T> &container, F function)
|
|
||||||
-> C<typename RemoveCvAndReference<decltype(declval<F>()(declval<T>()))>::type>
|
|
||||||
{
|
|
||||||
return transform_impl<QList>(container, function);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// different container types for input and output, e.g. transforming a QList into a QSet
|
// different container types for input and output, e.g. transforming a QList into a QSet
|
||||||
template<template<typename> class C, // result container type
|
template<template<typename> class C, // result container type
|
||||||
template<typename> class SC, // input container type
|
typename SC, // input container type
|
||||||
typename T, // element type of input container
|
|
||||||
typename F> // function type
|
typename F> // function type
|
||||||
Q_REQUIRED_RESULT
|
Q_REQUIRED_RESULT
|
||||||
auto transform(const SC<T> &container, F function)
|
auto transform(const SC &container, F function)
|
||||||
-> C<typename RemoveCvAndReference<decltype(declval<F>()(declval<T>()))>::type>
|
-> C< // container C<stripped return type of F>
|
||||||
|
typename RemoveCvAndReference< // stripped return type of F
|
||||||
|
decltype(declval<F>()(declval<typename ContainerType<SC>::ElementType>())) // return type of F
|
||||||
|
>::type>
|
||||||
{
|
{
|
||||||
return transform_impl(container, function);
|
return TransformImpl<
|
||||||
|
C< // result container type
|
||||||
|
typename RemoveCvAndReference< // stripped
|
||||||
|
decltype(declval<F>()(declval<typename ContainerType<SC>::ElementType>())) // return type of F
|
||||||
|
>::type>,
|
||||||
|
SC
|
||||||
|
>::call(container, function);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// different container types for input and output, e.g. transforming a QList into a QSet
|
||||||
//////////
|
// for member function pointers
|
||||||
// transform for QStringList, because that isn't a specialization but a separate type
|
|
||||||
// and g++ doesn't want to use the above templates for that
|
|
||||||
// clang and msvc do find the base class QList<QString>
|
|
||||||
//////////
|
|
||||||
|
|
||||||
// QStringList -> QList<>
|
|
||||||
template<typename F> // function type
|
|
||||||
Q_REQUIRED_RESULT
|
|
||||||
auto transform(const QStringList &container, F function)
|
|
||||||
-> QList<typename RemoveCvAndReference<decltype(declval<F>()(declval<QString>()))>::type>
|
|
||||||
{
|
|
||||||
return transform_impl<QList>(QList<QString>(container), function);
|
|
||||||
}
|
|
||||||
|
|
||||||
// QStringList -> any container type
|
|
||||||
template<template<typename> class C, // result container type
|
template<template<typename> class C, // result container type
|
||||||
typename F> // function type
|
typename SC, // input container type
|
||||||
|
typename R,
|
||||||
|
typename S>
|
||||||
Q_REQUIRED_RESULT
|
Q_REQUIRED_RESULT
|
||||||
auto transform(const QStringList &container, F function)
|
auto transform(const SC &container, R (S::*p)())
|
||||||
-> C<typename RemoveCvAndReference<decltype(declval<F>()(declval<QString>()))>::type>
|
-> C<typename RemoveCvAndReference<R>::type>
|
||||||
{
|
{
|
||||||
return transform_impl<C>(QList<QString>(container), function);
|
return TransformImpl<
|
||||||
|
C<typename RemoveCvAndReference<R>::type>,
|
||||||
|
SC
|
||||||
|
>::call(container, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
|
|||||||
@@ -701,6 +701,8 @@ FileName FileName::relativeChildPath(const FileName &parent) const
|
|||||||
/// Appends \a s, ensuring a / between the parts
|
/// Appends \a s, ensuring a / between the parts
|
||||||
FileName &FileName::appendPath(const QString &s)
|
FileName &FileName::appendPath(const QString &s)
|
||||||
{
|
{
|
||||||
|
if (s.isEmpty())
|
||||||
|
return *this;
|
||||||
if (!isEmpty() && !QString::endsWith(QLatin1Char('/')))
|
if (!isEmpty() && !QString::endsWith(QLatin1Char('/')))
|
||||||
appendString(QLatin1Char('/'));
|
appendString(QLatin1Char('/'));
|
||||||
appendString(s);
|
appendString(s);
|
||||||
|
|||||||
@@ -358,23 +358,27 @@ void MacroExpander::registerIntVariable(const QByteArray &variable,
|
|||||||
* \sa registerVariable(), registerIntVariable(), registerPrefix()
|
* \sa registerVariable(), registerIntVariable(), registerPrefix()
|
||||||
*/
|
*/
|
||||||
void MacroExpander::registerFileVariables(const QByteArray &prefix,
|
void MacroExpander::registerFileVariables(const QByteArray &prefix,
|
||||||
const QString &heading, const StringFunction &base)
|
const QString &heading, const StringFunction &base, bool visibleInChooser)
|
||||||
{
|
{
|
||||||
registerVariable(prefix + kFilePathPostfix,
|
registerVariable(prefix + kFilePathPostfix,
|
||||||
tr("%1: Full path including file name.").arg(heading),
|
tr("%1: Full path including file name.").arg(heading),
|
||||||
[base]() -> QString { QString tmp = base(); return tmp.isEmpty() ? QString() : QFileInfo(tmp).filePath(); });
|
[base]() -> QString { QString tmp = base(); return tmp.isEmpty() ? QString() : QFileInfo(tmp).filePath(); },
|
||||||
|
visibleInChooser);
|
||||||
|
|
||||||
registerVariable(prefix + kPathPostfix,
|
registerVariable(prefix + kPathPostfix,
|
||||||
tr("%1: Full path excluding file name.").arg(heading),
|
tr("%1: Full path excluding file name.").arg(heading),
|
||||||
[base]() -> QString { QString tmp = base(); return tmp.isEmpty() ? QString() : QFileInfo(tmp).path(); });
|
[base]() -> QString { QString tmp = base(); return tmp.isEmpty() ? QString() : QFileInfo(tmp).path(); },
|
||||||
|
visibleInChooser);
|
||||||
|
|
||||||
registerVariable(prefix + kFileNamePostfix,
|
registerVariable(prefix + kFileNamePostfix,
|
||||||
tr("%1: File name without path.").arg(heading),
|
tr("%1: File name without path.").arg(heading),
|
||||||
[base]() -> QString { QString tmp = base(); return tmp.isEmpty() ? QString() : QFileInfo(tmp).fileName(); });
|
[base]() -> QString { QString tmp = base(); return tmp.isEmpty() ? QString() : QFileInfo(tmp).fileName(); },
|
||||||
|
visibleInChooser);
|
||||||
|
|
||||||
registerVariable(prefix + kFileBaseNamePostfix,
|
registerVariable(prefix + kFileBaseNamePostfix,
|
||||||
tr("%1: File base name without path and suffix.").arg(heading),
|
tr("%1: File base name without path and suffix.").arg(heading),
|
||||||
[base]() -> QString { QString tmp = base(); return tmp.isEmpty() ? QString() : QFileInfo(tmp).baseName(); });
|
[base]() -> QString { QString tmp = base(); return tmp.isEmpty() ? QString() : QFileInfo(tmp).baseName(); },
|
||||||
|
visibleInChooser);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroExpander::registerExtraResolver(const MacroExpander::ResolverFunction &value)
|
void MacroExpander::registerExtraResolver(const MacroExpander::ResolverFunction &value)
|
||||||
|
|||||||
@@ -81,7 +81,8 @@ public:
|
|||||||
const QString &description, const IntFunction &value);
|
const QString &description, const IntFunction &value);
|
||||||
|
|
||||||
void registerFileVariables(const QByteArray &prefix,
|
void registerFileVariables(const QByteArray &prefix,
|
||||||
const QString &heading, const StringFunction &value);
|
const QString &heading, const StringFunction &value,
|
||||||
|
bool visibleInChooser = true);
|
||||||
|
|
||||||
void registerExtraResolver(const ResolverFunction &value);
|
void registerExtraResolver(const ResolverFunction &value);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
import QtcTool
|
|
||||||
|
|
||||||
QtcTool {
|
QtcTool {
|
||||||
name: "qtcreator_ctrlc_stub"
|
name: "qtcreator_ctrlc_stub"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
import QtcTool
|
|
||||||
|
|
||||||
QtcTool {
|
QtcTool {
|
||||||
name: "qtcreator_process_stub"
|
name: "qtcreator_process_stub"
|
||||||
|
|||||||
@@ -174,6 +174,8 @@ void ProxyAction::updateToolTipWithKeySequence()
|
|||||||
|
|
||||||
QString ProxyAction::stringWithAppendedShortcut(const QString &str, const QKeySequence &shortcut)
|
QString ProxyAction::stringWithAppendedShortcut(const QString &str, const QKeySequence &shortcut)
|
||||||
{
|
{
|
||||||
|
QString s = str;
|
||||||
|
s.replace(QLatin1String("&&"), QLatin1String("&"));
|
||||||
return QString::fromLatin1("%1 <span style=\"color: gray; font-size: small\">%2</span>").
|
return QString::fromLatin1("%1 <span style=\"color: gray; font-size: small\">%2</span>").
|
||||||
arg(str, shortcut.toString(QKeySequence::NativeText));
|
arg(s, shortcut.toString(QKeySequence::NativeText));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,8 +111,8 @@ public:
|
|||||||
ProgressBarColorError,
|
ProgressBarColorError,
|
||||||
ProgressBarColorFinished,
|
ProgressBarColorFinished,
|
||||||
ProgressBarColorNormal,
|
ProgressBarColorNormal,
|
||||||
SearchResultWidgetBackgroundColor,
|
InfoBarBackground,
|
||||||
SearchResultWidgetTextColor,
|
InfoBarText,
|
||||||
TextColorDisabled,
|
TextColorDisabled,
|
||||||
TextColorHighlight,
|
TextColorHighlight,
|
||||||
TextColorNormal,
|
TextColorNormal,
|
||||||
@@ -136,7 +136,8 @@ public:
|
|||||||
Welcome_TextColorHeading, // #535353 // Sessions, Recent Projects
|
Welcome_TextColorHeading, // #535353 // Sessions, Recent Projects
|
||||||
Welcome_BackgroundColorNormal, // #ffffff
|
Welcome_BackgroundColorNormal, // #ffffff
|
||||||
Welcome_DividerColor, // #737373
|
Welcome_DividerColor, // #737373
|
||||||
Welcome_Button_BorderColor,
|
Welcome_Button_BorderColorNormal,
|
||||||
|
Welcome_Button_BorderColorPressed,
|
||||||
Welcome_Button_TextColorNormal,
|
Welcome_Button_TextColorNormal,
|
||||||
Welcome_Button_TextColorPressed,
|
Welcome_Button_TextColorPressed,
|
||||||
Welcome_Link_TextColorNormal,
|
Welcome_Link_TextColorNormal,
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
import QtcLibrary
|
|
||||||
|
|
||||||
QtcLibrary {
|
QtcLibrary {
|
||||||
name: "Utils"
|
name: "Utils"
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
|
|
||||||
import QtcPlugin
|
|
||||||
|
|
||||||
QtcPlugin {
|
QtcPlugin {
|
||||||
name: "AnalyzerBase"
|
name: "AnalyzerBase"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
|
|
||||||
import QtcPlugin
|
|
||||||
|
|
||||||
QtcPlugin {
|
QtcPlugin {
|
||||||
name: "Android"
|
name: "Android"
|
||||||
|
|
||||||
|
|||||||
@@ -131,6 +131,33 @@ namespace {
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is32BitUserSpace()
|
||||||
|
{
|
||||||
|
// Do the exact same check as android's emulator is doing:
|
||||||
|
if (Utils::HostOsInfo::isLinuxHost()) {
|
||||||
|
if (QSysInfo::WordSize == 32 ) {
|
||||||
|
Utils::Environment env = Utils::Environment::systemEnvironment();
|
||||||
|
QString executable = env.searchInPath(QLatin1String("file")).toString();
|
||||||
|
QString shell = env.value(QLatin1String("SHELL"));
|
||||||
|
if (executable.isEmpty() || shell.isEmpty())
|
||||||
|
return true; // we can't detect, but creator is 32bit so assume 32bit
|
||||||
|
|
||||||
|
QProcess proc;
|
||||||
|
proc.setProcessChannelMode(QProcess::MergedChannels);
|
||||||
|
proc.start(executable, QStringList() << shell);
|
||||||
|
if (!proc.waitForFinished(2000)) {
|
||||||
|
proc.kill();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (proc.readAll().contains("x86-64"))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
@@ -660,9 +687,13 @@ bool AndroidConfig::startAVDAsync(const QString &avdName) const
|
|||||||
avdProcess->connect(avdProcess, SIGNAL(finished(int)), avdProcess, SLOT(deleteLater()));
|
avdProcess->connect(avdProcess, SIGNAL(finished(int)), avdProcess, SLOT(deleteLater()));
|
||||||
|
|
||||||
// start the emulator
|
// start the emulator
|
||||||
avdProcess->start(emulatorToolPath().toString(),
|
QStringList arguments;
|
||||||
QStringList() << QLatin1String("-partition-size") << QString::number(partitionSize())
|
if (AndroidConfigurations::force32bitEmulator())
|
||||||
<< QLatin1String("-avd") << avdName);
|
arguments << QLatin1String("-force-32bit");
|
||||||
|
|
||||||
|
arguments << QLatin1String("-partition-size") << QString::number(partitionSize())
|
||||||
|
<< QLatin1String("-avd") << avdName;
|
||||||
|
avdProcess->start(emulatorToolPath().toString(), arguments);
|
||||||
if (!avdProcess->waitForStarted(-1)) {
|
if (!avdProcess->waitForStarted(-1)) {
|
||||||
delete avdProcess;
|
delete avdProcess;
|
||||||
return false;
|
return false;
|
||||||
@@ -1166,6 +1197,11 @@ void AndroidConfigurations::updateAutomaticKitList()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AndroidConfigurations::force32bitEmulator()
|
||||||
|
{
|
||||||
|
return m_instance->m_force32bit;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Workaround for '????????????' serial numbers
|
* Workaround for '????????????' serial numbers
|
||||||
* @return ("-d") for buggy devices, ("-s", <serial no>) for normal
|
* @return ("-d") for buggy devices, ("-s", <serial no>) for normal
|
||||||
@@ -1203,6 +1239,8 @@ AndroidConfigurations::AndroidConfigurations(QObject *parent)
|
|||||||
connect(ProjectExplorer::SessionManager::instance(), SIGNAL(projectRemoved(ProjectExplorer::Project*)),
|
connect(ProjectExplorer::SessionManager::instance(), SIGNAL(projectRemoved(ProjectExplorer::Project*)),
|
||||||
this, SLOT(clearDefaultDevices(ProjectExplorer::Project*)));
|
this, SLOT(clearDefaultDevices(ProjectExplorer::Project*)));
|
||||||
|
|
||||||
|
m_force32bit = is32BitUserSpace();
|
||||||
|
|
||||||
m_instance = this;
|
m_instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -215,6 +215,7 @@ public slots:
|
|||||||
static void clearDefaultDevices(ProjectExplorer::Project *project);
|
static void clearDefaultDevices(ProjectExplorer::Project *project);
|
||||||
static void updateToolChainList();
|
static void updateToolChainList();
|
||||||
static void updateAutomaticKitList();
|
static void updateAutomaticKitList();
|
||||||
|
static bool force32bitEmulator();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void updated();
|
void updated();
|
||||||
@@ -228,6 +229,7 @@ private:
|
|||||||
AndroidConfig m_config;
|
AndroidConfig m_config;
|
||||||
|
|
||||||
QMap<ProjectExplorer::Project *, QMap<QString, QString> > m_defaultDeviceForAbi;
|
QMap<ProjectExplorer::Project *, QMap<QString, QString> > m_defaultDeviceForAbi;
|
||||||
|
bool m_force32bit;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Android
|
} // namespace Android
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
|
|
||||||
import QtcPlugin
|
|
||||||
|
|
||||||
QtcPlugin {
|
QtcPlugin {
|
||||||
name: "AutotoolsProjectManager"
|
name: "AutotoolsProjectManager"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import qbs
|
import qbs
|
||||||
|
|
||||||
import QtcPlugin
|
|
||||||
|
|
||||||
QtcPlugin {
|
QtcPlugin {
|
||||||
name: "BareMetal"
|
name: "BareMetal"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
|
|
||||||
import QtcPlugin
|
|
||||||
|
|
||||||
QtcPlugin {
|
QtcPlugin {
|
||||||
name: "Bazaar"
|
name: "Bazaar"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
|
|
||||||
import QtcPlugin
|
|
||||||
|
|
||||||
QtcPlugin {
|
QtcPlugin {
|
||||||
name: "Beautifier"
|
name: "Beautifier"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
|
|
||||||
import QtcPlugin
|
|
||||||
|
|
||||||
QtcPlugin {
|
QtcPlugin {
|
||||||
name: "BinEditor"
|
name: "BinEditor"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
|
|
||||||
import QtcPlugin
|
|
||||||
|
|
||||||
QtcPlugin {
|
QtcPlugin {
|
||||||
name: "Bookmarks"
|
name: "Bookmarks"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
|
|
||||||
import QtcPlugin
|
|
||||||
|
|
||||||
QtcPlugin {
|
QtcPlugin {
|
||||||
name: "ClassView"
|
name: "ClassView"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
|
|
||||||
import QtcPlugin
|
|
||||||
|
|
||||||
QtcPlugin {
|
QtcPlugin {
|
||||||
name: "ClearCase"
|
name: "ClearCase"
|
||||||
|
|
||||||
|
|||||||
@@ -869,6 +869,20 @@ void CMakeCbpParser::sortFiles()
|
|||||||
CMakeBuildTarget *last = 0;
|
CMakeBuildTarget *last = 0;
|
||||||
Utils::FileName parentDirectory;
|
Utils::FileName parentDirectory;
|
||||||
|
|
||||||
|
// find a good build target to fall back
|
||||||
|
int fallbackIndex = 0;
|
||||||
|
{
|
||||||
|
int bestIncludeCount = -1;
|
||||||
|
for (int i = 0; i < m_buildTargets.size(); ++i) {
|
||||||
|
const CMakeBuildTarget &target = m_buildTargets.at(i);
|
||||||
|
if (target.sourceDirectory == m_sourceDirectory
|
||||||
|
&& target.includeFiles.count() > bestIncludeCount) {
|
||||||
|
bestIncludeCount = target.includeFiles.count();
|
||||||
|
fallbackIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach (const Utils::FileName &fileName, fileNames) {
|
foreach (const Utils::FileName &fileName, fileNames) {
|
||||||
if (fileName.parentDir() == parentDirectory && last) {
|
if (fileName.parentDir() == parentDirectory && last) {
|
||||||
// easy case, same parent directory as last file
|
// easy case, same parent directory as last file
|
||||||
@@ -891,7 +905,7 @@ void CMakeCbpParser::sortFiles()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bestIndex == -1 && !m_buildTargets.isEmpty())
|
if (bestIndex == -1 && !m_buildTargets.isEmpty())
|
||||||
bestIndex = 0;
|
bestIndex = fallbackIndex;
|
||||||
|
|
||||||
if (bestIndex != -1) {
|
if (bestIndex != -1) {
|
||||||
m_buildTargets[bestIndex].files.append(fileName.toString());
|
m_buildTargets[bestIndex].files.append(fileName.toString());
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
|
|
||||||
import QtcPlugin
|
|
||||||
|
|
||||||
QtcPlugin {
|
QtcPlugin {
|
||||||
name: "CMakeProjectManager"
|
name: "CMakeProjectManager"
|
||||||
|
|
||||||
|
|||||||
@@ -307,6 +307,18 @@ Command *ActionContainerPrivate::addSeparator(const Context &context, Id group,
|
|||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ActionContainerPrivate::setEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
foreach (const Group &group, m_groups) {
|
||||||
|
foreach (QObject *item, group.items) {
|
||||||
|
if (Command *command = qobject_cast<Command *>(item))
|
||||||
|
command->action()->setEnabled(enabled);
|
||||||
|
else if (ActionContainer *container = qobject_cast<ActionContainer *>(item))
|
||||||
|
container->setEnabled(enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ActionContainerPrivate::clear()
|
void ActionContainerPrivate::clear()
|
||||||
{
|
{
|
||||||
QMutableListIterator<Group> it(m_groups);
|
QMutableListIterator<Group> it(m_groups);
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ public:
|
|||||||
virtual void addMenu(ActionContainer *menu, Id group = Id()) = 0;
|
virtual void addMenu(ActionContainer *menu, Id group = Id()) = 0;
|
||||||
virtual void addMenu(ActionContainer *before, ActionContainer *menu, Id group = Id()) = 0;
|
virtual void addMenu(ActionContainer *before, ActionContainer *menu, Id group = Id()) = 0;
|
||||||
virtual Command *addSeparator(const Context &context, Id group = Id(), QAction **outSeparator = 0) = 0;
|
virtual Command *addSeparator(const Context &context, Id group = Id(), QAction **outSeparator = 0) = 0;
|
||||||
|
virtual void setEnabled(bool enabled) = 0;
|
||||||
|
|
||||||
// This clears this menu and submenus from all actions and submenus.
|
// This clears this menu and submenus from all actions and submenus.
|
||||||
// It does not destroy the submenus and commands, just removes them from their parents.
|
// It does not destroy the submenus and commands, just removes them from their parents.
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ public:
|
|||||||
void addMenu(ActionContainer *menu, Id group = Id());
|
void addMenu(ActionContainer *menu, Id group = Id());
|
||||||
void addMenu(ActionContainer *before, ActionContainer *menu, Id group = Id());
|
void addMenu(ActionContainer *before, ActionContainer *menu, Id group = Id());
|
||||||
Command *addSeparator(const Context &context, Id group = Id(), QAction **outSeparator = 0);
|
Command *addSeparator(const Context &context, Id group = Id(), QAction **outSeparator = 0);
|
||||||
|
void setEnabled(bool enabled);
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
|
||||||
Id id() const;
|
Id id() const;
|
||||||
|
|||||||
@@ -313,6 +313,10 @@ void Action::addOverrideAction(QAction *action, const Core::Context &context, bo
|
|||||||
{
|
{
|
||||||
if (Utils::HostOsInfo::isMacHost())
|
if (Utils::HostOsInfo::isMacHost())
|
||||||
action->setIconVisibleInMenu(false);
|
action->setIconVisibleInMenu(false);
|
||||||
|
// disallow TextHeuristic menu role, because it doesn't work with translations,
|
||||||
|
// e.g. QTCREATORBUG-13101
|
||||||
|
if (action->menuRole() == QAction::TextHeuristicRole)
|
||||||
|
action->setMenuRole(QAction::NoRole);
|
||||||
if (isEmpty())
|
if (isEmpty())
|
||||||
m_action->initialize(action);
|
m_action->initialize(action);
|
||||||
if (context.isEmpty()) {
|
if (context.isEmpty()) {
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ void CorePlugin::parseArguments(const QStringList &arguments)
|
|||||||
QString themeName = QLatin1String("default");
|
QString themeName = QLatin1String("default");
|
||||||
QColor overrideColor;
|
QColor overrideColor;
|
||||||
bool overrideTheme = false;
|
bool overrideTheme = false;
|
||||||
|
bool presentationMode = false;
|
||||||
|
|
||||||
for (int i = 0; i < arguments.size(); ++i) {
|
for (int i = 0; i < arguments.size(); ++i) {
|
||||||
if (arguments.at(i) == QLatin1String("-color")) {
|
if (arguments.at(i) == QLatin1String("-color")) {
|
||||||
@@ -103,7 +104,7 @@ void CorePlugin::parseArguments(const QStringList &arguments)
|
|||||||
i++; // skip the argument
|
i++; // skip the argument
|
||||||
}
|
}
|
||||||
if (arguments.at(i) == QLatin1String("-presentationMode"))
|
if (arguments.at(i) == QLatin1String("-presentationMode"))
|
||||||
ActionManager::setPresentationModeEnabled(true);
|
presentationMode = true;
|
||||||
if (arguments.at(i) == QLatin1String("-theme")) {
|
if (arguments.at(i) == QLatin1String("-theme")) {
|
||||||
overrideTheme = true;
|
overrideTheme = true;
|
||||||
themeName = arguments.at(i + 1);
|
themeName = arguments.at(i + 1);
|
||||||
@@ -137,6 +138,7 @@ void CorePlugin::parseArguments(const QStringList &arguments)
|
|||||||
// defer creation of these widgets until here,
|
// defer creation of these widgets until here,
|
||||||
// because they need a valid theme set
|
// because they need a valid theme set
|
||||||
m_mainWindow = new MainWindow;
|
m_mainWindow = new MainWindow;
|
||||||
|
ActionManager::setPresentationModeEnabled(presentationMode);
|
||||||
m_findPlugin = new FindPlugin;
|
m_findPlugin = new FindPlugin;
|
||||||
m_locator = new Locator;
|
m_locator = new Locator;
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ SOURCES += corejsextensions.cpp \
|
|||||||
fancytabwidget.cpp \
|
fancytabwidget.cpp \
|
||||||
generalsettings.cpp \
|
generalsettings.cpp \
|
||||||
themesettings.cpp \
|
themesettings.cpp \
|
||||||
|
themesettingswidget.cpp \
|
||||||
id.cpp \
|
id.cpp \
|
||||||
icontext.cpp \
|
icontext.cpp \
|
||||||
jsexpander.cpp \
|
jsexpander.cpp \
|
||||||
@@ -121,6 +122,7 @@ HEADERS += corejsextensions.h \
|
|||||||
fancytabwidget.h \
|
fancytabwidget.h \
|
||||||
generalsettings.h \
|
generalsettings.h \
|
||||||
themesettings.h \
|
themesettings.h \
|
||||||
|
themesettingswidget.h \
|
||||||
id.h \
|
id.h \
|
||||||
jsexpander.h \
|
jsexpander.h \
|
||||||
messagemanager.h \
|
messagemanager.h \
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
import qbs.FileInfo
|
import qbs.FileInfo
|
||||||
import QtcPlugin
|
|
||||||
|
|
||||||
QtcPlugin {
|
QtcPlugin {
|
||||||
name: "Core"
|
name: "Core"
|
||||||
@@ -98,9 +97,8 @@ QtcPlugin {
|
|||||||
"styleanimator.cpp", "styleanimator.h",
|
"styleanimator.cpp", "styleanimator.h",
|
||||||
"tabpositionindicator.cpp", "tabpositionindicator.h",
|
"tabpositionindicator.cpp", "tabpositionindicator.h",
|
||||||
"textdocument.cpp", "textdocument.h",
|
"textdocument.cpp", "textdocument.h",
|
||||||
"themesettings.cpp",
|
"themesettings.cpp", "themesettings.h", "themesettings.ui",
|
||||||
"themesettings.h",
|
"themesettingswidget.cpp", "themesettingswidget.h",
|
||||||
"themesettings.ui",
|
|
||||||
"toolsettings.cpp", "toolsettings.h",
|
"toolsettings.cpp", "toolsettings.h",
|
||||||
"variablechooser.cpp", "variablechooser.h",
|
"variablechooser.cpp", "variablechooser.h",
|
||||||
"vcsmanager.cpp", "vcsmanager.h",
|
"vcsmanager.cpp", "vcsmanager.h",
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ DocumentManagerPrivate::DocumentManagerPrivate() :
|
|||||||
m_linkWatcher(0),
|
m_linkWatcher(0),
|
||||||
m_blockActivated(false),
|
m_blockActivated(false),
|
||||||
m_lastVisitedDirectory(QDir::currentPath()),
|
m_lastVisitedDirectory(QDir::currentPath()),
|
||||||
m_useProjectsDirectory(Utils::HostOsInfo::isMacHost()), // Creator is in bizarre places when launched via finder.
|
m_useProjectsDirectory(true),
|
||||||
m_blockedIDocument(0)
|
m_blockedIDocument(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -225,12 +225,12 @@ FindToolBar::FindToolBar(FindPlugin *plugin, CurrentDocumentFind *currentDocumen
|
|||||||
m_ui.replaceButton->setDefaultAction(m_localReplaceAction);
|
m_ui.replaceButton->setDefaultAction(m_localReplaceAction);
|
||||||
|
|
||||||
m_replaceNextAction = new QAction(tr("Replace && Find"), this);
|
m_replaceNextAction = new QAction(tr("Replace && Find"), this);
|
||||||
m_replaceNextAction->setIconText(tr("Replace && Find")); // work around bug in Qt that kills ampersands in tool button
|
|
||||||
cmd = Core::ActionManager::registerAction(m_replaceNextAction, Constants::REPLACE_NEXT, globalcontext);
|
cmd = Core::ActionManager::registerAction(m_replaceNextAction, Constants::REPLACE_NEXT, globalcontext);
|
||||||
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+=")));
|
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+=")));
|
||||||
mfind->addAction(cmd, Constants::G_FIND_ACTIONS);
|
mfind->addAction(cmd, Constants::G_FIND_ACTIONS);
|
||||||
connect(m_replaceNextAction, SIGNAL(triggered()), this, SLOT(invokeGlobalReplaceNext()));
|
connect(m_replaceNextAction, SIGNAL(triggered()), this, SLOT(invokeGlobalReplaceNext()));
|
||||||
m_localReplaceNextAction = new QAction(m_replaceNextAction->text(), this);
|
m_localReplaceNextAction = new QAction(m_replaceNextAction->text(), this);
|
||||||
|
m_localReplaceNextAction->setIconText(m_replaceNextAction->text()); // Workaround QTBUG-23396
|
||||||
cmd = ActionManager::registerAction(m_localReplaceNextAction, Constants::REPLACE_NEXT, findcontext);
|
cmd = ActionManager::registerAction(m_localReplaceNextAction, Constants::REPLACE_NEXT, findcontext);
|
||||||
cmd->augmentActionWithShortcutToolTip(m_localReplaceNextAction);
|
cmd->augmentActionWithShortcutToolTip(m_localReplaceNextAction);
|
||||||
connect(m_localReplaceNextAction, &QAction::triggered, this, &FindToolBar::invokeReplaceNext);
|
connect(m_localReplaceNextAction, &QAction::triggered, this, &FindToolBar::invokeReplaceNext);
|
||||||
|
|||||||
@@ -96,8 +96,8 @@ SearchResultWidget::SearchResultWidget(QWidget *parent) :
|
|||||||
|
|
||||||
QFrame *topWidget = new QFrame;
|
QFrame *topWidget = new QFrame;
|
||||||
QPalette pal;
|
QPalette pal;
|
||||||
pal.setColor(QPalette::Window, creatorTheme()->color(Theme::SearchResultWidgetBackgroundColor));
|
pal.setColor(QPalette::Window, creatorTheme()->color(Theme::InfoBarBackground));
|
||||||
pal.setColor(QPalette::WindowText, creatorTheme()->color(Theme::SearchResultWidgetTextColor));
|
pal.setColor(QPalette::WindowText, creatorTheme()->color(Theme::InfoBarText));
|
||||||
topWidget->setPalette(pal);
|
topWidget->setPalette(pal);
|
||||||
if (creatorTheme()->flag(Theme::DrawSearchResultWidgetFrame)) {
|
if (creatorTheme()->flag(Theme::DrawSearchResultWidgetFrame)) {
|
||||||
topWidget->setFrameStyle(QFrame::Panel | QFrame::Raised);
|
topWidget->setFrameStyle(QFrame::Panel | QFrame::Raised);
|
||||||
|
|||||||
@@ -73,6 +73,16 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="themeLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Theme:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="Core::Internal::ThemeSettingsWidget" name="themeWidget" native="true"/>
|
||||||
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="languageLabel">
|
<widget class="QLabel" name="languageLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -334,6 +344,12 @@
|
|||||||
<signal>browsingFinished()</signal>
|
<signal>browsingFinished()</signal>
|
||||||
</slots>
|
</slots>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>Core::Internal::ThemeSettingsWidget</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header location="global">coreplugin/themesettingswidget.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="core.qrc"/>
|
<include location="core.qrc"/>
|
||||||
|
|||||||
@@ -33,6 +33,8 @@
|
|||||||
#include "coreconstants.h"
|
#include "coreconstants.h"
|
||||||
#include "icore.h"
|
#include "icore.h"
|
||||||
|
|
||||||
|
#include <utils/theme/theme.h>
|
||||||
|
|
||||||
#include <QFrame>
|
#include <QFrame>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
@@ -40,6 +42,8 @@
|
|||||||
|
|
||||||
static const char C_SUPPRESSED_WARNINGS[] = "SuppressedWarnings";
|
static const char C_SUPPRESSED_WARNINGS[] = "SuppressedWarnings";
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
QSet<Id> InfoBar::globallySuppressed;
|
QSet<Id> InfoBar::globallySuppressed;
|
||||||
@@ -202,8 +206,8 @@ void InfoBarDisplay::update()
|
|||||||
QFrame *infoWidget = new QFrame;
|
QFrame *infoWidget = new QFrame;
|
||||||
|
|
||||||
QPalette pal;
|
QPalette pal;
|
||||||
pal.setColor(QPalette::Window, QColor(255, 255, 225));
|
pal.setColor(QPalette::Window, creatorTheme()->color(Theme::InfoBarBackground));
|
||||||
pal.setColor(QPalette::WindowText, Qt::black);
|
pal.setColor(QPalette::WindowText, Theme::InfoBarText);
|
||||||
|
|
||||||
infoWidget->setPalette(pal);
|
infoWidget->setPalette(pal);
|
||||||
infoWidget->setFrameStyle(QFrame::Panel | QFrame::Raised);
|
infoWidget->setFrameStyle(QFrame::Panel | QFrame::Raised);
|
||||||
|
|||||||
@@ -132,7 +132,6 @@ MainWindow::MainWindow() :
|
|||||||
m_rightPaneWidget(0),
|
m_rightPaneWidget(0),
|
||||||
m_versionDialog(0),
|
m_versionDialog(0),
|
||||||
m_generalSettings(new GeneralSettings),
|
m_generalSettings(new GeneralSettings),
|
||||||
m_themeSettings(new ThemeSettings),
|
|
||||||
m_shortcutSettings(new ShortcutSettings),
|
m_shortcutSettings(new ShortcutSettings),
|
||||||
m_toolSettings(new ToolSettings),
|
m_toolSettings(new ToolSettings),
|
||||||
m_mimeTypeSettings(new MimeTypeSettings),
|
m_mimeTypeSettings(new MimeTypeSettings),
|
||||||
@@ -256,7 +255,6 @@ MainWindow::~MainWindow()
|
|||||||
|
|
||||||
ExtensionSystem::PluginManager::removeObject(m_shortcutSettings);
|
ExtensionSystem::PluginManager::removeObject(m_shortcutSettings);
|
||||||
ExtensionSystem::PluginManager::removeObject(m_generalSettings);
|
ExtensionSystem::PluginManager::removeObject(m_generalSettings);
|
||||||
ExtensionSystem::PluginManager::removeObject(m_themeSettings);
|
|
||||||
ExtensionSystem::PluginManager::removeObject(m_toolSettings);
|
ExtensionSystem::PluginManager::removeObject(m_toolSettings);
|
||||||
ExtensionSystem::PluginManager::removeObject(m_mimeTypeSettings);
|
ExtensionSystem::PluginManager::removeObject(m_mimeTypeSettings);
|
||||||
ExtensionSystem::PluginManager::removeObject(m_systemEditor);
|
ExtensionSystem::PluginManager::removeObject(m_systemEditor);
|
||||||
@@ -268,8 +266,6 @@ MainWindow::~MainWindow()
|
|||||||
m_shortcutSettings = 0;
|
m_shortcutSettings = 0;
|
||||||
delete m_generalSettings;
|
delete m_generalSettings;
|
||||||
m_generalSettings = 0;
|
m_generalSettings = 0;
|
||||||
delete m_themeSettings;
|
|
||||||
m_themeSettings = 0;
|
|
||||||
delete m_toolSettings;
|
delete m_toolSettings;
|
||||||
m_toolSettings = 0;
|
m_toolSettings = 0;
|
||||||
delete m_mimeTypeSettings;
|
delete m_mimeTypeSettings;
|
||||||
@@ -327,7 +323,6 @@ bool MainWindow::init(QString *errorMessage)
|
|||||||
m_progressManager->init(); // needs the status bar manager
|
m_progressManager->init(); // needs the status bar manager
|
||||||
|
|
||||||
ExtensionSystem::PluginManager::addObject(m_generalSettings);
|
ExtensionSystem::PluginManager::addObject(m_generalSettings);
|
||||||
ExtensionSystem::PluginManager::addObject(m_themeSettings);
|
|
||||||
ExtensionSystem::PluginManager::addObject(m_shortcutSettings);
|
ExtensionSystem::PluginManager::addObject(m_shortcutSettings);
|
||||||
ExtensionSystem::PluginManager::addObject(m_toolSettings);
|
ExtensionSystem::PluginManager::addObject(m_toolSettings);
|
||||||
ExtensionSystem::PluginManager::addObject(m_mimeTypeSettings);
|
ExtensionSystem::PluginManager::addObject(m_mimeTypeSettings);
|
||||||
@@ -567,9 +562,9 @@ void MainWindow::registerDefaultActions()
|
|||||||
// Exit Action
|
// Exit Action
|
||||||
icon = QIcon::fromTheme(QLatin1String("application-exit"));
|
icon = QIcon::fromTheme(QLatin1String("application-exit"));
|
||||||
m_exitAction = new QAction(icon, tr("E&xit"), this);
|
m_exitAction = new QAction(icon, tr("E&xit"), this);
|
||||||
|
m_exitAction->setMenuRole(QAction::QuitRole);
|
||||||
cmd = ActionManager::registerAction(m_exitAction, Constants::EXIT, globalContext);
|
cmd = ActionManager::registerAction(m_exitAction, Constants::EXIT, globalContext);
|
||||||
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Q")));
|
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Q")));
|
||||||
cmd->action()->setMenuRole(QAction::QuitRole);
|
|
||||||
mfile->addAction(cmd, Constants::G_FILE_OTHER);
|
mfile->addAction(cmd, Constants::G_FILE_OTHER);
|
||||||
connect(m_exitAction, SIGNAL(triggered()), this, SLOT(exit()));
|
connect(m_exitAction, SIGNAL(triggered()), this, SLOT(exit()));
|
||||||
|
|
||||||
@@ -638,11 +633,9 @@ void MainWindow::registerDefaultActions()
|
|||||||
mtools->addSeparator(globalContext, Constants::G_TOOLS_OPTIONS);
|
mtools->addSeparator(globalContext, Constants::G_TOOLS_OPTIONS);
|
||||||
|
|
||||||
m_optionsAction = new QAction(tr("&Options..."), this);
|
m_optionsAction = new QAction(tr("&Options..."), this);
|
||||||
|
m_optionsAction->setMenuRole(QAction::PreferencesRole);
|
||||||
cmd = ActionManager::registerAction(m_optionsAction, Constants::OPTIONS, globalContext);
|
cmd = ActionManager::registerAction(m_optionsAction, Constants::OPTIONS, globalContext);
|
||||||
if (UseMacShortcuts) {
|
cmd->setDefaultKeySequence(QKeySequence::Preferences);
|
||||||
cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+,")));
|
|
||||||
cmd->action()->setMenuRole(QAction::PreferencesRole);
|
|
||||||
}
|
|
||||||
mtools->addAction(cmd, Constants::G_TOOLS_OPTIONS);
|
mtools->addAction(cmd, Constants::G_TOOLS_OPTIONS);
|
||||||
connect(m_optionsAction, SIGNAL(triggered()), this, SLOT(showOptionsDialog()));
|
connect(m_optionsAction, SIGNAL(triggered()), this, SLOT(showOptionsDialog()));
|
||||||
|
|
||||||
@@ -665,7 +658,6 @@ void MainWindow::registerDefaultActions()
|
|||||||
|
|
||||||
// Full Screen Action
|
// Full Screen Action
|
||||||
QAction *toggleFullScreenAction = new QAction(tr("Full Screen"), this);
|
QAction *toggleFullScreenAction = new QAction(tr("Full Screen"), this);
|
||||||
toggleFullScreenAction->setMenuRole(QAction::NoRole);
|
|
||||||
toggleFullScreenAction->setCheckable(!Utils::HostOsInfo::isMacHost());
|
toggleFullScreenAction->setCheckable(!Utils::HostOsInfo::isMacHost());
|
||||||
toggleFullScreenAction->setEnabled(false); // actual implementation in WindowSupport
|
toggleFullScreenAction->setEnabled(false); // actual implementation in WindowSupport
|
||||||
cmd = ActionManager::registerAction(toggleFullScreenAction, Constants::TOGGLE_FULLSCREEN, globalContext);
|
cmd = ActionManager::registerAction(toggleFullScreenAction, Constants::TOGGLE_FULLSCREEN, globalContext);
|
||||||
@@ -721,18 +713,16 @@ void MainWindow::registerDefaultActions()
|
|||||||
tmpaction = new QAction(icon, tr("About &Qt Creator"), this); // it's convention not to add dots to the about menu
|
tmpaction = new QAction(icon, tr("About &Qt Creator"), this); // it's convention not to add dots to the about menu
|
||||||
else
|
else
|
||||||
tmpaction = new QAction(icon, tr("About &Qt Creator..."), this);
|
tmpaction = new QAction(icon, tr("About &Qt Creator..."), this);
|
||||||
|
tmpaction->setMenuRole(QAction::AboutRole);
|
||||||
cmd = ActionManager::registerAction(tmpaction, Constants::ABOUT_QTCREATOR, globalContext);
|
cmd = ActionManager::registerAction(tmpaction, Constants::ABOUT_QTCREATOR, globalContext);
|
||||||
if (Utils::HostOsInfo::isMacHost())
|
|
||||||
cmd->action()->setMenuRole(QAction::ApplicationSpecificRole);
|
|
||||||
mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
|
mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
|
||||||
tmpaction->setEnabled(true);
|
tmpaction->setEnabled(true);
|
||||||
connect(tmpaction, SIGNAL(triggered()), this, SLOT(aboutQtCreator()));
|
connect(tmpaction, SIGNAL(triggered()), this, SLOT(aboutQtCreator()));
|
||||||
|
|
||||||
//About Plugins Action
|
//About Plugins Action
|
||||||
tmpaction = new QAction(tr("About &Plugins..."), this);
|
tmpaction = new QAction(tr("About &Plugins..."), this);
|
||||||
|
tmpaction->setMenuRole(QAction::ApplicationSpecificRole);
|
||||||
cmd = ActionManager::registerAction(tmpaction, Constants::ABOUT_PLUGINS, globalContext);
|
cmd = ActionManager::registerAction(tmpaction, Constants::ABOUT_PLUGINS, globalContext);
|
||||||
if (Utils::HostOsInfo::isMacHost())
|
|
||||||
cmd->action()->setMenuRole(QAction::ApplicationSpecificRole);
|
|
||||||
mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
|
mhelp->addAction(cmd, Constants::G_HELP_ABOUT);
|
||||||
tmpaction->setEnabled(true);
|
tmpaction->setEnabled(true);
|
||||||
connect(tmpaction, SIGNAL(triggered()), this, SLOT(aboutPlugins()));
|
connect(tmpaction, SIGNAL(triggered()), this, SLOT(aboutPlugins()));
|
||||||
|
|||||||
@@ -72,7 +72,6 @@ namespace Internal {
|
|||||||
class ActionManagerPrivate;
|
class ActionManagerPrivate;
|
||||||
class FancyTabWidget;
|
class FancyTabWidget;
|
||||||
class GeneralSettings;
|
class GeneralSettings;
|
||||||
class ThemeSettings;
|
|
||||||
class ProgressManagerPrivate;
|
class ProgressManagerPrivate;
|
||||||
class ShortcutSettings;
|
class ShortcutSettings;
|
||||||
class ToolSettings;
|
class ToolSettings;
|
||||||
@@ -192,7 +191,6 @@ private:
|
|||||||
QMap<QWidget *, IContext *> m_contextWidgets;
|
QMap<QWidget *, IContext *> m_contextWidgets;
|
||||||
|
|
||||||
GeneralSettings *m_generalSettings;
|
GeneralSettings *m_generalSettings;
|
||||||
ThemeSettings *m_themeSettings;
|
|
||||||
ShortcutSettings *m_shortcutSettings;
|
ShortcutSettings *m_shortcutSettings;
|
||||||
ToolSettings *m_toolSettings;
|
ToolSettings *m_toolSettings;
|
||||||
MimeTypeSettings *m_mimeTypeSettings;
|
MimeTypeSettings *m_mimeTypeSettings;
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ ThemeColorsTableView::ThemeColorsTableView(QWidget *parent)
|
|||||||
|
|
||||||
void ThemeColorsTableView::mousePressEvent(QMouseEvent *event)
|
void ThemeColorsTableView::mousePressEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
if (event->button() == Qt::LeftButton) {
|
if ((editTriggers() & NoEditTriggers) && (event->button() == Qt::LeftButton)) {
|
||||||
QModelIndex index = indexAt(event->pos());
|
QModelIndex index = indexAt(event->pos());
|
||||||
if (model()->flags(index) & Qt::ItemIsEditable && index.column() == 1) {
|
if (model()->flags(index) & Qt::ItemIsEditable && index.column() == 1) {
|
||||||
setCurrentIndex(index);
|
setCurrentIndex(index);
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ ThemeEditorWidget::~ThemeEditorWidget()
|
|||||||
|
|
||||||
void ThemeEditorWidget::changeColor(const QModelIndex &index)
|
void ThemeEditorWidget::changeColor(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
|
if (!(m_ui->tableView->editTriggers() & QAbstractItemView::DoubleClicked))
|
||||||
|
return;
|
||||||
if (m_model->inSectionBody(index.row()) != ThemeSettingsTableModel::SectionColors)
|
if (m_model->inSectionBody(index.row()) != ThemeSettingsTableModel::SectionColors)
|
||||||
return;
|
return;
|
||||||
if (index.column() == 1)
|
if (index.column() == 1)
|
||||||
@@ -114,7 +116,9 @@ void ThemeEditorWidget::changeColor(const QModelIndex &index)
|
|||||||
void ThemeEditorWidget::setReadOnly(bool readOnly)
|
void ThemeEditorWidget::setReadOnly(bool readOnly)
|
||||||
{
|
{
|
||||||
m_readOnly = readOnly;
|
m_readOnly = readOnly;
|
||||||
m_ui->tableView->setEnabled(!readOnly);
|
m_ui->tableView->setEditTriggers(
|
||||||
|
readOnly ? QAbstractItemView::NoEditTriggers
|
||||||
|
: QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed);
|
||||||
m_ui->filter->setEnabled(!readOnly);
|
m_ui->filter->setEnabled(!readOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,436 +29,46 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "themesettings.h"
|
#include "themesettings.h"
|
||||||
|
#include "themesettingswidget.h"
|
||||||
#include "coreconstants.h"
|
#include "coreconstants.h"
|
||||||
#include "icore.h"
|
|
||||||
#include "editormanager/editormanager_p.h"
|
|
||||||
#include "themeeditor/themesettingstablemodel.h"
|
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <QCoreApplication>
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QInputDialog>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QSettings>
|
|
||||||
|
|
||||||
#include "ui_themesettings.h"
|
|
||||||
|
|
||||||
using namespace Utils;
|
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
const char themeNameKey[] = "ThemeName";
|
ThemeSettings::ThemeSettings() :
|
||||||
|
m_widget(0)
|
||||||
static QString customThemesPath()
|
|
||||||
{
|
|
||||||
QString path = Core::ICore::userResourcePath();
|
|
||||||
path.append(QLatin1String("/themes/"));
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QString createThemeFileName(const QString &pattern)
|
|
||||||
{
|
|
||||||
const QString stylesPath = customThemesPath();
|
|
||||||
QString baseFileName = stylesPath;
|
|
||||||
baseFileName += pattern;
|
|
||||||
|
|
||||||
// Find an available file name
|
|
||||||
int i = 1;
|
|
||||||
QString fileName;
|
|
||||||
do {
|
|
||||||
fileName = baseFileName.arg((i == 1) ? QString() : QString::number(i));
|
|
||||||
++i;
|
|
||||||
} while (QFile::exists(fileName));
|
|
||||||
|
|
||||||
// Create the base directory when it doesn't exist
|
|
||||||
if (!QFile::exists(stylesPath) && !QDir().mkpath(stylesPath)) {
|
|
||||||
qWarning() << "Failed to create theme directory:" << stylesPath;
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
return fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct ThemeEntry
|
|
||||||
{
|
|
||||||
ThemeEntry() {}
|
|
||||||
ThemeEntry(const QString &fileName, bool readOnly):
|
|
||||||
m_fileName(fileName),
|
|
||||||
m_readOnly(readOnly)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
QString fileName() const { return m_fileName; }
|
|
||||||
QString name() const;
|
|
||||||
bool readOnly() const { return m_readOnly; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString m_fileName;
|
|
||||||
bool m_readOnly;
|
|
||||||
};
|
|
||||||
|
|
||||||
QString ThemeEntry::name() const
|
|
||||||
{
|
|
||||||
QSettings settings(m_fileName, QSettings::IniFormat);
|
|
||||||
QString n = settings.value(QLatin1String(themeNameKey), QCoreApplication::tr("unnamed")).toString();
|
|
||||||
return m_readOnly ? QCoreApplication::tr("%1 (built-in)").arg(n) : n;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class ThemeListModel : public QAbstractListModel
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ThemeListModel(QObject *parent = 0):
|
|
||||||
QAbstractListModel(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int rowCount(const QModelIndex &parent) const
|
|
||||||
{
|
|
||||||
return parent.isValid() ? 0 : m_themes.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant data(const QModelIndex &index, int role) const
|
|
||||||
{
|
|
||||||
if (role == Qt::DisplayRole)
|
|
||||||
return m_themes.at(index.row()).name();
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeTheme(int index)
|
|
||||||
{
|
|
||||||
beginRemoveRows(QModelIndex(), index, index);
|
|
||||||
m_themes.removeAt(index);
|
|
||||||
endRemoveRows();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setThemes(const QList<ThemeEntry> &themes)
|
|
||||||
{
|
|
||||||
beginResetModel();
|
|
||||||
m_themes = themes;
|
|
||||||
endResetModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
const ThemeEntry &themeAt(int index) const
|
|
||||||
{
|
|
||||||
return m_themes.at(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
QList<ThemeEntry> m_themes;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ThemeSettingsPrivate
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ThemeSettingsPrivate();
|
|
||||||
~ThemeSettingsPrivate();
|
|
||||||
|
|
||||||
public:
|
|
||||||
ThemeListModel *m_themeListModel;
|
|
||||||
bool m_refreshingThemeList;
|
|
||||||
Ui::ThemeSettings *m_ui;
|
|
||||||
QPointer<QWidget> m_widget;
|
|
||||||
ThemeEntry m_currentTheme;
|
|
||||||
};
|
|
||||||
|
|
||||||
ThemeSettingsPrivate::ThemeSettingsPrivate()
|
|
||||||
: m_themeListModel(new ThemeListModel)
|
|
||||||
, m_refreshingThemeList(false)
|
|
||||||
, m_ui(0)
|
|
||||||
{
|
|
||||||
m_currentTheme = ThemeEntry(creatorTheme()->fileName(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
ThemeSettingsPrivate::~ThemeSettingsPrivate()
|
|
||||||
{
|
|
||||||
delete m_themeListModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
ThemeSettings::ThemeSettings()
|
|
||||||
{
|
{
|
||||||
setId(Core::Constants::SETTINGS_ID_ENVIRONMENT);
|
setId(Core::Constants::SETTINGS_ID_ENVIRONMENT);
|
||||||
setDisplayName(tr("Theme"));
|
setDisplayName(tr("Theme"));
|
||||||
setCategory(Core::Constants::SETTINGS_CATEGORY_CORE);
|
setCategory(Core::Constants::SETTINGS_CATEGORY_CORE);
|
||||||
setDisplayCategory(QCoreApplication::translate("Core", Core::Constants::SETTINGS_TR_CATEGORY_CORE));
|
setDisplayCategory(QCoreApplication::translate("Core", Core::Constants::SETTINGS_TR_CATEGORY_CORE));
|
||||||
setCategoryIcon(QLatin1String(Core::Constants::SETTINGS_CATEGORY_CORE_ICON));
|
setCategoryIcon(QLatin1String(Core::Constants::SETTINGS_CATEGORY_CORE_ICON));
|
||||||
|
|
||||||
d = new ThemeSettingsPrivate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ThemeSettings::~ThemeSettings()
|
ThemeSettings::~ThemeSettings()
|
||||||
{
|
{
|
||||||
delete d;
|
delete m_widget;
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeSettings::refreshThemeList()
|
|
||||||
{
|
|
||||||
QList<ThemeEntry> themes;
|
|
||||||
|
|
||||||
QString resourcePath = Core::ICore::resourcePath();
|
|
||||||
QDir themeDir(resourcePath + QLatin1String("/themes"));
|
|
||||||
themeDir.setNameFilters(QStringList() << QLatin1String("*.creatortheme"));
|
|
||||||
themeDir.setFilter(QDir::Files);
|
|
||||||
|
|
||||||
int selected = 0;
|
|
||||||
|
|
||||||
QStringList themeList = themeDir.entryList();
|
|
||||||
QString defaultTheme = QFileInfo(defaultThemeFileName()).fileName();
|
|
||||||
if (themeList.removeAll(defaultTheme))
|
|
||||||
themeList.prepend(defaultTheme);
|
|
||||||
foreach (const QString &file, themeList) {
|
|
||||||
const QString fileName = themeDir.absoluteFilePath(file);
|
|
||||||
if (d->m_currentTheme.fileName() == fileName)
|
|
||||||
selected = themes.size();
|
|
||||||
themes.append(ThemeEntry(fileName, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (themes.isEmpty())
|
|
||||||
qWarning() << "Warning: no themes found in path:" << themeDir.path();
|
|
||||||
|
|
||||||
themeDir.setPath(customThemesPath());
|
|
||||||
foreach (const QString &file, themeDir.entryList()) {
|
|
||||||
const QString fileName = themeDir.absoluteFilePath(file);
|
|
||||||
if (d->m_currentTheme.fileName() == fileName)
|
|
||||||
selected = themes.size();
|
|
||||||
themes.append(ThemeEntry(fileName, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
d->m_currentTheme = themes[selected];
|
|
||||||
|
|
||||||
d->m_refreshingThemeList = true;
|
|
||||||
d->m_themeListModel->setThemes(themes);
|
|
||||||
d->m_ui->themeComboBox->setCurrentIndex(selected);
|
|
||||||
d->m_refreshingThemeList = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ThemeSettings::defaultThemeFileName(const QString &fileName)
|
|
||||||
{
|
|
||||||
QString defaultScheme = Core::ICore::resourcePath();
|
|
||||||
defaultScheme += QLatin1String("/themes/");
|
|
||||||
|
|
||||||
if (!fileName.isEmpty() && QFile::exists(defaultScheme + fileName))
|
|
||||||
defaultScheme += fileName;
|
|
||||||
else
|
|
||||||
defaultScheme += QLatin1String("default.creatortheme");
|
|
||||||
|
|
||||||
return defaultScheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeSettings::themeSelected(int index)
|
|
||||||
{
|
|
||||||
bool readOnly = true;
|
|
||||||
if (index != -1) {
|
|
||||||
// Check whether we're switching away from a changed theme
|
|
||||||
if (!d->m_refreshingThemeList)
|
|
||||||
maybeSaveTheme();
|
|
||||||
|
|
||||||
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
|
|
||||||
readOnly = entry.readOnly();
|
|
||||||
d->m_currentTheme = entry;
|
|
||||||
|
|
||||||
QSettings settings(entry.fileName(), QSettings::IniFormat);
|
|
||||||
Theme theme;
|
|
||||||
theme.readSettings(settings);
|
|
||||||
d->m_ui->editor->initFrom(&theme);
|
|
||||||
}
|
|
||||||
d->m_ui->copyButton->setEnabled(index != -1);
|
|
||||||
d->m_ui->deleteButton->setEnabled(!readOnly);
|
|
||||||
d->m_ui->renameButton->setEnabled(!readOnly);
|
|
||||||
d->m_ui->editor->setReadOnly(readOnly);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *ThemeSettings::widget()
|
QWidget *ThemeSettings::widget()
|
||||||
{
|
{
|
||||||
if (!d->m_widget) {
|
if (!m_widget)
|
||||||
d->m_widget = new QWidget;
|
m_widget = new ThemeSettingsWidget;
|
||||||
d->m_ui = new Ui::ThemeSettings();
|
return m_widget;
|
||||||
d->m_ui->setupUi(d->m_widget);
|
|
||||||
d->m_ui->themeComboBox->setModel(d->m_themeListModel);
|
|
||||||
|
|
||||||
connect(d->m_ui->themeComboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
|
||||||
this, &ThemeSettings::themeSelected);
|
|
||||||
connect(d->m_ui->copyButton, &QAbstractButton::clicked, this, &ThemeSettings::copyTheme);
|
|
||||||
connect(d->m_ui->renameButton, &QAbstractButton::clicked, this, &ThemeSettings::renameTheme);
|
|
||||||
connect(d->m_ui->deleteButton, &QAbstractButton::clicked, this, &ThemeSettings::confirmDeleteTheme);
|
|
||||||
|
|
||||||
refreshThemeList();
|
|
||||||
}
|
|
||||||
return d->m_widget;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeSettings::confirmDeleteTheme()
|
|
||||||
{
|
|
||||||
const int index = d->m_ui->themeComboBox->currentIndex();
|
|
||||||
if (index == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
|
|
||||||
if (entry.readOnly())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QMessageBox *messageBox = new QMessageBox(QMessageBox::Warning,
|
|
||||||
tr("Delete Theme"),
|
|
||||||
tr("Are you sure you want to delete the theme '%1' permanently?").arg(entry.name()),
|
|
||||||
QMessageBox::Discard | QMessageBox::Cancel,
|
|
||||||
d->m_ui->deleteButton->window());
|
|
||||||
|
|
||||||
// Change the text and role of the discard button
|
|
||||||
QPushButton *deleteButton = static_cast<QPushButton*>(messageBox->button(QMessageBox::Discard));
|
|
||||||
deleteButton->setText(tr("Delete"));
|
|
||||||
messageBox->addButton(deleteButton, QMessageBox::AcceptRole);
|
|
||||||
messageBox->setDefaultButton(deleteButton);
|
|
||||||
|
|
||||||
connect(deleteButton, &QAbstractButton::clicked, messageBox, &QDialog::accept);
|
|
||||||
connect(messageBox, &QDialog::accepted, this, &ThemeSettings::deleteTheme);
|
|
||||||
messageBox->setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
messageBox->open();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeSettings::deleteTheme()
|
|
||||||
{
|
|
||||||
const int index = d->m_ui->themeComboBox->currentIndex();
|
|
||||||
QTC_ASSERT(index != -1, return);
|
|
||||||
|
|
||||||
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
|
|
||||||
QTC_ASSERT(!entry.readOnly(), return);
|
|
||||||
|
|
||||||
if (QFile::remove(entry.fileName()))
|
|
||||||
d->m_themeListModel->removeTheme(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeSettings::copyTheme()
|
|
||||||
{
|
|
||||||
QInputDialog *dialog = new QInputDialog(d->m_ui->copyButton->window());
|
|
||||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
dialog->setInputMode(QInputDialog::TextInput);
|
|
||||||
dialog->setWindowTitle(tr("Copy Theme"));
|
|
||||||
dialog->setLabelText(tr("Theme name:"));
|
|
||||||
|
|
||||||
//TODO
|
|
||||||
//dialog->setTextValue(tr("%1 (copy)").arg(d_ptr->m_value.colorScheme().displayName()));
|
|
||||||
|
|
||||||
connect(dialog, &QInputDialog::textValueSelected, this, &ThemeSettings::copyThemeByName);
|
|
||||||
dialog->open();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeSettings::maybeSaveTheme()
|
|
||||||
{
|
|
||||||
if (!d->m_ui->editor->model()->hasChanges())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QMessageBox *messageBox = new QMessageBox(QMessageBox::Warning,
|
|
||||||
tr("Theme Changed"),
|
|
||||||
tr("The theme \"%1\" was modified, do you want to save the changes?")
|
|
||||||
.arg(d->m_currentTheme.name()),
|
|
||||||
QMessageBox::Discard | QMessageBox::Save,
|
|
||||||
d->m_ui->themeComboBox->window());
|
|
||||||
|
|
||||||
// Change the text of the discard button
|
|
||||||
QPushButton *discardButton = static_cast<QPushButton*>(messageBox->button(QMessageBox::Discard));
|
|
||||||
discardButton->setText(tr("Discard"));
|
|
||||||
messageBox->addButton(discardButton, QMessageBox::DestructiveRole);
|
|
||||||
messageBox->setDefaultButton(QMessageBox::Save);
|
|
||||||
|
|
||||||
if (messageBox->exec() == QMessageBox::Save) {
|
|
||||||
Theme newTheme;
|
|
||||||
d->m_ui->editor->model()->toTheme(&newTheme);
|
|
||||||
newTheme.writeSettings(d->m_currentTheme.fileName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeSettings::renameTheme()
|
|
||||||
{
|
|
||||||
int index = d->m_ui->themeComboBox->currentIndex();
|
|
||||||
if (index == -1)
|
|
||||||
return;
|
|
||||||
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
|
|
||||||
|
|
||||||
maybeSaveTheme();
|
|
||||||
|
|
||||||
QInputDialog *dialog = new QInputDialog(d->m_ui->renameButton->window());
|
|
||||||
dialog->setInputMode(QInputDialog::TextInput);
|
|
||||||
dialog->setWindowTitle(tr("Rename Theme"));
|
|
||||||
dialog->setLabelText(tr("Theme name:"));
|
|
||||||
dialog->setTextValue(d->m_ui->editor->model()->m_name);
|
|
||||||
int ret = dialog->exec();
|
|
||||||
QString newName = dialog->textValue();
|
|
||||||
delete dialog;
|
|
||||||
|
|
||||||
if (ret != QDialog::Accepted || newName.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// overwrite file with new name
|
|
||||||
Theme newTheme;
|
|
||||||
d->m_ui->editor->model()->toTheme(&newTheme);
|
|
||||||
newTheme.setName(newName);
|
|
||||||
newTheme.writeSettings(entry.fileName());
|
|
||||||
|
|
||||||
refreshThemeList();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeSettings::copyThemeByName(const QString &name)
|
|
||||||
{
|
|
||||||
int index = d->m_ui->themeComboBox->currentIndex();
|
|
||||||
if (index == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
|
|
||||||
|
|
||||||
QString baseFileName = QFileInfo(entry.fileName()).completeBaseName();
|
|
||||||
baseFileName += QLatin1String("_copy%1.creatortheme");
|
|
||||||
QString fileName = createThemeFileName(baseFileName);
|
|
||||||
|
|
||||||
if (fileName.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Ask about saving any existing modifactions
|
|
||||||
maybeSaveTheme();
|
|
||||||
|
|
||||||
Theme newTheme;
|
|
||||||
d->m_ui->editor->model()->toTheme(&newTheme);
|
|
||||||
newTheme.setName(name);
|
|
||||||
newTheme.writeSettings(fileName);
|
|
||||||
|
|
||||||
d->m_currentTheme = ThemeEntry(fileName, true);
|
|
||||||
|
|
||||||
refreshThemeList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThemeSettings::apply()
|
void ThemeSettings::apply()
|
||||||
{
|
{
|
||||||
if (!d->m_ui) // wasn't shown, can't be changed
|
if (m_widget)
|
||||||
return;
|
m_widget->apply();
|
||||||
|
|
||||||
{
|
|
||||||
d->m_ui->editor->model()->toTheme(creatorTheme());
|
|
||||||
if (creatorTheme()->flag(Theme::ApplyThemePaletteGlobally))
|
|
||||||
QApplication::setPalette(creatorTheme()->palette(QApplication::palette()));
|
|
||||||
foreach (QWidget *w, QApplication::topLevelWidgets())
|
|
||||||
w->update();
|
|
||||||
}
|
|
||||||
|
|
||||||
// save definition of theme
|
|
||||||
if (!d->m_currentTheme.readOnly()) {
|
|
||||||
Theme newTheme;
|
|
||||||
d->m_ui->editor->model()->toTheme(&newTheme);
|
|
||||||
newTheme.writeSettings(d->m_currentTheme.fileName());
|
|
||||||
}
|
|
||||||
|
|
||||||
// save filename of selected theme in global config
|
|
||||||
QSettings *settings = Core::ICore::settings();
|
|
||||||
settings->setValue(QLatin1String(Core::Constants::SETTINGS_THEME), d->m_currentTheme.fileName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThemeSettings::finish()
|
void ThemeSettings::finish()
|
||||||
{
|
{
|
||||||
delete d->m_widget;
|
delete m_widget;
|
||||||
if (!d->m_ui) // page was never shown
|
m_widget = 0;
|
||||||
return
|
|
||||||
delete d->m_ui;
|
|
||||||
d->m_ui = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
namespace Core {
|
namespace Core {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class ThemeSettingsPrivate;
|
class ThemeSettingsWidget;
|
||||||
|
|
||||||
class ThemeSettings : public IOptionsPage
|
class ThemeSettings : public IOptionsPage
|
||||||
{
|
{
|
||||||
@@ -50,20 +50,7 @@ public:
|
|||||||
void apply();
|
void apply();
|
||||||
void finish();
|
void finish();
|
||||||
|
|
||||||
static QString defaultThemeFileName(const QString &fileName = QString());
|
ThemeSettingsWidget *m_widget;
|
||||||
|
|
||||||
private slots:
|
|
||||||
void themeSelected(int index);
|
|
||||||
void copyTheme();
|
|
||||||
void renameTheme();
|
|
||||||
void copyThemeByName(const QString &);
|
|
||||||
void confirmDeleteTheme();
|
|
||||||
void deleteTheme();
|
|
||||||
void maybeSaveTheme();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void refreshThemeList();
|
|
||||||
ThemeSettingsPrivate *d;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -2,15 +2,19 @@
|
|||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>Core::Internal::ThemeSettings</class>
|
<class>Core::Internal::ThemeSettings</class>
|
||||||
<widget class="QWidget" name="Core::Internal::ThemeSettings">
|
<widget class="QWidget" name="Core::Internal::ThemeSettings">
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>527</width>
|
|
||||||
<height>359</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
@@ -66,8 +70,6 @@
|
|||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources/>
|
||||||
<include location="core.qrc"/>
|
|
||||||
</resources>
|
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
|||||||
440
src/plugins/coreplugin/themesettingswidget.cpp
Normal file
440
src/plugins/coreplugin/themesettingswidget.cpp
Normal file
@@ -0,0 +1,440 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Thorben Kroeger <thorbenkroeger@gmail.com>.
|
||||||
|
** 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://www.qt.io/licensing. For further information
|
||||||
|
** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
|
||||||
|
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||||
|
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||||
|
** following information to ensure the GNU Lesser General Public License
|
||||||
|
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||||
|
** 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 "themesettingswidget.h"
|
||||||
|
#include "coreconstants.h"
|
||||||
|
#include "icore.h"
|
||||||
|
#include "themeeditor/themesettingstablemodel.h"
|
||||||
|
|
||||||
|
#include <utils/theme/theme.h>
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QInputDialog>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
|
#include "ui_themesettings.h"
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
const char themeNameKey[] = "ThemeName";
|
||||||
|
|
||||||
|
static QString customThemesPath()
|
||||||
|
{
|
||||||
|
QString path = Core::ICore::userResourcePath();
|
||||||
|
path.append(QLatin1String("/themes/"));
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString createThemeFileName(const QString &pattern)
|
||||||
|
{
|
||||||
|
const QString stylesPath = customThemesPath();
|
||||||
|
QString baseFileName = stylesPath;
|
||||||
|
baseFileName += pattern;
|
||||||
|
|
||||||
|
// Find an available file name
|
||||||
|
int i = 1;
|
||||||
|
QString fileName;
|
||||||
|
do {
|
||||||
|
fileName = baseFileName.arg((i == 1) ? QString() : QString::number(i));
|
||||||
|
++i;
|
||||||
|
} while (QFile::exists(fileName));
|
||||||
|
|
||||||
|
// Create the base directory when it doesn't exist
|
||||||
|
if (!QFile::exists(stylesPath) && !QDir().mkpath(stylesPath)) {
|
||||||
|
qWarning() << "Failed to create theme directory:" << stylesPath;
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct ThemeEntry
|
||||||
|
{
|
||||||
|
ThemeEntry() {}
|
||||||
|
ThemeEntry(const QString &fileName, bool readOnly):
|
||||||
|
m_fileName(fileName),
|
||||||
|
m_readOnly(readOnly)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
QString fileName() const { return m_fileName; }
|
||||||
|
QString name() const;
|
||||||
|
bool readOnly() const { return m_readOnly; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_fileName;
|
||||||
|
bool m_readOnly;
|
||||||
|
};
|
||||||
|
|
||||||
|
QString ThemeEntry::name() const
|
||||||
|
{
|
||||||
|
QSettings settings(m_fileName, QSettings::IniFormat);
|
||||||
|
QString n = settings.value(QLatin1String(themeNameKey), QCoreApplication::tr("unnamed")).toString();
|
||||||
|
return m_readOnly ? QCoreApplication::tr("%1 (built-in)").arg(n) : n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ThemeListModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ThemeListModel(QObject *parent = 0):
|
||||||
|
QAbstractListModel(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
return parent.isValid() ? 0 : m_themes.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (role == Qt::DisplayRole)
|
||||||
|
return m_themes.at(index.row()).name();
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeTheme(int index)
|
||||||
|
{
|
||||||
|
beginRemoveRows(QModelIndex(), index, index);
|
||||||
|
m_themes.removeAt(index);
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setThemes(const QList<ThemeEntry> &themes)
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
m_themes = themes;
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
const ThemeEntry &themeAt(int index) const
|
||||||
|
{
|
||||||
|
return m_themes.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<ThemeEntry> m_themes;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ThemeSettingsPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ThemeSettingsPrivate(QWidget *widget);
|
||||||
|
~ThemeSettingsPrivate();
|
||||||
|
|
||||||
|
public:
|
||||||
|
ThemeListModel *m_themeListModel;
|
||||||
|
bool m_refreshingThemeList;
|
||||||
|
Ui::ThemeSettings *m_ui;
|
||||||
|
ThemeEntry m_currentTheme;
|
||||||
|
};
|
||||||
|
|
||||||
|
ThemeSettingsPrivate::ThemeSettingsPrivate(QWidget *widget)
|
||||||
|
: m_themeListModel(new ThemeListModel)
|
||||||
|
, m_refreshingThemeList(false)
|
||||||
|
, m_ui(new Ui::ThemeSettings)
|
||||||
|
{
|
||||||
|
m_currentTheme = ThemeEntry(creatorTheme()->fileName(), true);
|
||||||
|
m_ui->setupUi(widget);
|
||||||
|
m_ui->editor->hide(); // TODO: Restore after improving the editor
|
||||||
|
m_ui->themeComboBox->setModel(m_themeListModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
ThemeSettingsPrivate::~ThemeSettingsPrivate()
|
||||||
|
{
|
||||||
|
delete m_themeListModel;
|
||||||
|
delete m_ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThemeSettingsWidget::ThemeSettingsWidget(QWidget *parent) :
|
||||||
|
QWidget(parent)
|
||||||
|
{
|
||||||
|
d = new ThemeSettingsPrivate(this);
|
||||||
|
|
||||||
|
connect(d->m_ui->themeComboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||||
|
this, &ThemeSettingsWidget::themeSelected);
|
||||||
|
connect(d->m_ui->copyButton, &QAbstractButton::clicked, this, &ThemeSettingsWidget::copyTheme);
|
||||||
|
connect(d->m_ui->renameButton, &QAbstractButton::clicked, this, &ThemeSettingsWidget::renameTheme);
|
||||||
|
connect(d->m_ui->deleteButton, &QAbstractButton::clicked, this, &ThemeSettingsWidget::confirmDeleteTheme);
|
||||||
|
|
||||||
|
refreshThemeList();
|
||||||
|
}
|
||||||
|
|
||||||
|
ThemeSettingsWidget::~ThemeSettingsWidget()
|
||||||
|
{
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeSettingsWidget::refreshThemeList()
|
||||||
|
{
|
||||||
|
QList<ThemeEntry> themes;
|
||||||
|
|
||||||
|
QString resourcePath = Core::ICore::resourcePath();
|
||||||
|
QDir themeDir(resourcePath + QLatin1String("/themes"));
|
||||||
|
themeDir.setNameFilters(QStringList() << QLatin1String("*.creatortheme"));
|
||||||
|
themeDir.setFilter(QDir::Files);
|
||||||
|
|
||||||
|
int selected = 0;
|
||||||
|
|
||||||
|
QStringList themeList = themeDir.entryList();
|
||||||
|
QString defaultTheme = QFileInfo(defaultThemeFileName()).fileName();
|
||||||
|
if (themeList.removeAll(defaultTheme))
|
||||||
|
themeList.prepend(defaultTheme);
|
||||||
|
foreach (const QString &file, themeList) {
|
||||||
|
const QString fileName = themeDir.absoluteFilePath(file);
|
||||||
|
if (d->m_currentTheme.fileName() == fileName)
|
||||||
|
selected = themes.size();
|
||||||
|
themes.append(ThemeEntry(fileName, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (themes.isEmpty())
|
||||||
|
qWarning() << "Warning: no themes found in path:" << themeDir.path();
|
||||||
|
|
||||||
|
themeDir.setPath(customThemesPath());
|
||||||
|
foreach (const QString &file, themeDir.entryList()) {
|
||||||
|
const QString fileName = themeDir.absoluteFilePath(file);
|
||||||
|
if (d->m_currentTheme.fileName() == fileName)
|
||||||
|
selected = themes.size();
|
||||||
|
themes.append(ThemeEntry(fileName, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
d->m_currentTheme = themes[selected];
|
||||||
|
|
||||||
|
d->m_refreshingThemeList = true;
|
||||||
|
d->m_themeListModel->setThemes(themes);
|
||||||
|
d->m_ui->themeComboBox->setCurrentIndex(selected);
|
||||||
|
d->m_refreshingThemeList = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ThemeSettingsWidget::defaultThemeFileName(const QString &fileName)
|
||||||
|
{
|
||||||
|
QString defaultScheme = Core::ICore::resourcePath();
|
||||||
|
defaultScheme += QLatin1String("/themes/");
|
||||||
|
|
||||||
|
if (!fileName.isEmpty() && QFile::exists(defaultScheme + fileName))
|
||||||
|
defaultScheme += fileName;
|
||||||
|
else
|
||||||
|
defaultScheme += QLatin1String("default.creatortheme");
|
||||||
|
|
||||||
|
return defaultScheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeSettingsWidget::themeSelected(int index)
|
||||||
|
{
|
||||||
|
bool readOnly = true;
|
||||||
|
if (index != -1) {
|
||||||
|
// Check whether we're switching away from a changed theme
|
||||||
|
if (!d->m_refreshingThemeList)
|
||||||
|
maybeSaveTheme();
|
||||||
|
|
||||||
|
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
|
||||||
|
readOnly = entry.readOnly();
|
||||||
|
d->m_currentTheme = entry;
|
||||||
|
|
||||||
|
QSettings settings(entry.fileName(), QSettings::IniFormat);
|
||||||
|
Theme theme;
|
||||||
|
theme.readSettings(settings);
|
||||||
|
d->m_ui->editor->initFrom(&theme);
|
||||||
|
}
|
||||||
|
d->m_ui->copyButton->setEnabled(index != -1);
|
||||||
|
d->m_ui->deleteButton->setEnabled(!readOnly);
|
||||||
|
d->m_ui->renameButton->setEnabled(!readOnly);
|
||||||
|
d->m_ui->editor->setReadOnly(readOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeSettingsWidget::confirmDeleteTheme()
|
||||||
|
{
|
||||||
|
const int index = d->m_ui->themeComboBox->currentIndex();
|
||||||
|
if (index == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
|
||||||
|
if (entry.readOnly())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QMessageBox *messageBox = new QMessageBox(QMessageBox::Warning,
|
||||||
|
tr("Delete Theme"),
|
||||||
|
tr("Are you sure you want to delete the theme '%1' permanently?").arg(entry.name()),
|
||||||
|
QMessageBox::Discard | QMessageBox::Cancel,
|
||||||
|
d->m_ui->deleteButton->window());
|
||||||
|
|
||||||
|
// Change the text and role of the discard button
|
||||||
|
QPushButton *deleteButton = static_cast<QPushButton*>(messageBox->button(QMessageBox::Discard));
|
||||||
|
deleteButton->setText(tr("Delete"));
|
||||||
|
messageBox->addButton(deleteButton, QMessageBox::AcceptRole);
|
||||||
|
messageBox->setDefaultButton(deleteButton);
|
||||||
|
|
||||||
|
connect(deleteButton, &QAbstractButton::clicked, messageBox, &QDialog::accept);
|
||||||
|
connect(messageBox, &QDialog::accepted, this, &ThemeSettingsWidget::deleteTheme);
|
||||||
|
messageBox->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
messageBox->open();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeSettingsWidget::deleteTheme()
|
||||||
|
{
|
||||||
|
const int index = d->m_ui->themeComboBox->currentIndex();
|
||||||
|
QTC_ASSERT(index != -1, return);
|
||||||
|
|
||||||
|
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
|
||||||
|
QTC_ASSERT(!entry.readOnly(), return);
|
||||||
|
|
||||||
|
if (QFile::remove(entry.fileName()))
|
||||||
|
d->m_themeListModel->removeTheme(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeSettingsWidget::copyTheme()
|
||||||
|
{
|
||||||
|
QInputDialog *dialog = new QInputDialog(d->m_ui->copyButton->window());
|
||||||
|
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
dialog->setInputMode(QInputDialog::TextInput);
|
||||||
|
dialog->setWindowTitle(tr("Copy Theme"));
|
||||||
|
dialog->setLabelText(tr("Theme name:"));
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
//dialog->setTextValue(tr("%1 (copy)").arg(d_ptr->m_value.colorScheme().displayName()));
|
||||||
|
|
||||||
|
connect(dialog, &QInputDialog::textValueSelected, this, &ThemeSettingsWidget::copyThemeByName);
|
||||||
|
dialog->open();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeSettingsWidget::maybeSaveTheme()
|
||||||
|
{
|
||||||
|
if (!d->m_ui->editor->model()->hasChanges())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QMessageBox *messageBox = new QMessageBox(QMessageBox::Warning,
|
||||||
|
tr("Theme Changed"),
|
||||||
|
tr("The theme \"%1\" was modified, do you want to save the changes?")
|
||||||
|
.arg(d->m_currentTheme.name()),
|
||||||
|
QMessageBox::Discard | QMessageBox::Save,
|
||||||
|
d->m_ui->themeComboBox->window());
|
||||||
|
|
||||||
|
// Change the text of the discard button
|
||||||
|
QPushButton *discardButton = static_cast<QPushButton*>(messageBox->button(QMessageBox::Discard));
|
||||||
|
discardButton->setText(tr("Discard"));
|
||||||
|
messageBox->addButton(discardButton, QMessageBox::DestructiveRole);
|
||||||
|
messageBox->setDefaultButton(QMessageBox::Save);
|
||||||
|
|
||||||
|
if (messageBox->exec() == QMessageBox::Save) {
|
||||||
|
Theme newTheme;
|
||||||
|
d->m_ui->editor->model()->toTheme(&newTheme);
|
||||||
|
newTheme.writeSettings(d->m_currentTheme.fileName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeSettingsWidget::renameTheme()
|
||||||
|
{
|
||||||
|
int index = d->m_ui->themeComboBox->currentIndex();
|
||||||
|
if (index == -1)
|
||||||
|
return;
|
||||||
|
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
|
||||||
|
|
||||||
|
maybeSaveTheme();
|
||||||
|
|
||||||
|
QInputDialog *dialog = new QInputDialog(d->m_ui->renameButton->window());
|
||||||
|
dialog->setInputMode(QInputDialog::TextInput);
|
||||||
|
dialog->setWindowTitle(tr("Rename Theme"));
|
||||||
|
dialog->setLabelText(tr("Theme name:"));
|
||||||
|
dialog->setTextValue(d->m_ui->editor->model()->m_name);
|
||||||
|
int ret = dialog->exec();
|
||||||
|
QString newName = dialog->textValue();
|
||||||
|
delete dialog;
|
||||||
|
|
||||||
|
if (ret != QDialog::Accepted || newName.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// overwrite file with new name
|
||||||
|
Theme newTheme;
|
||||||
|
d->m_ui->editor->model()->toTheme(&newTheme);
|
||||||
|
newTheme.setName(newName);
|
||||||
|
newTheme.writeSettings(entry.fileName());
|
||||||
|
|
||||||
|
refreshThemeList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeSettingsWidget::copyThemeByName(const QString &name)
|
||||||
|
{
|
||||||
|
int index = d->m_ui->themeComboBox->currentIndex();
|
||||||
|
if (index == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
|
||||||
|
|
||||||
|
QString baseFileName = QFileInfo(entry.fileName()).completeBaseName();
|
||||||
|
baseFileName += QLatin1String("_copy%1.creatortheme");
|
||||||
|
QString fileName = createThemeFileName(baseFileName);
|
||||||
|
|
||||||
|
if (fileName.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Ask about saving any existing modifactions
|
||||||
|
maybeSaveTheme();
|
||||||
|
|
||||||
|
Theme newTheme;
|
||||||
|
d->m_ui->editor->model()->toTheme(&newTheme);
|
||||||
|
newTheme.setName(name);
|
||||||
|
newTheme.writeSettings(fileName);
|
||||||
|
|
||||||
|
d->m_currentTheme = ThemeEntry(fileName, true);
|
||||||
|
|
||||||
|
refreshThemeList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeSettingsWidget::apply()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
d->m_ui->editor->model()->toTheme(creatorTheme());
|
||||||
|
if (creatorTheme()->flag(Theme::ApplyThemePaletteGlobally))
|
||||||
|
QApplication::setPalette(creatorTheme()->palette(QApplication::palette()));
|
||||||
|
foreach (QWidget *w, QApplication::topLevelWidgets())
|
||||||
|
w->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
// save definition of theme
|
||||||
|
if (!d->m_currentTheme.readOnly()) {
|
||||||
|
Theme newTheme;
|
||||||
|
d->m_ui->editor->model()->toTheme(&newTheme);
|
||||||
|
newTheme.writeSettings(d->m_currentTheme.fileName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// save filename of selected theme in global config
|
||||||
|
QSettings *settings = Core::ICore::settings();
|
||||||
|
settings->setValue(QLatin1String(Core::Constants::SETTINGS_THEME), d->m_currentTheme.fileName());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace Core
|
||||||
70
src/plugins/coreplugin/themesettingswidget.h
Normal file
70
src/plugins/coreplugin/themesettingswidget.h
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Thorben Kroeger <thorbenkroeger@gmail.com>.
|
||||||
|
** 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://www.qt.io/licensing. For further information
|
||||||
|
** use the contact form at http://www.qt.io/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 or version 3 as published by the Free
|
||||||
|
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||||
|
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||||
|
** following information to ensure the GNU Lesser General Public License
|
||||||
|
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||||
|
** 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 THEMESETTINGSWIDGET_H
|
||||||
|
#define THEMESETTINGSWIDGET_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class ThemeSettingsPrivate;
|
||||||
|
|
||||||
|
class ThemeSettingsWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ThemeSettingsWidget(QWidget *parent = 0);
|
||||||
|
~ThemeSettingsWidget();
|
||||||
|
|
||||||
|
static QString defaultThemeFileName(const QString &fileName = QString());
|
||||||
|
|
||||||
|
void apply();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void themeSelected(int index);
|
||||||
|
void copyTheme();
|
||||||
|
void renameTheme();
|
||||||
|
void copyThemeByName(const QString &);
|
||||||
|
void confirmDeleteTheme();
|
||||||
|
void deleteTheme();
|
||||||
|
void maybeSaveTheme();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void refreshThemeList();
|
||||||
|
ThemeSettingsPrivate *d;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace Core
|
||||||
|
|
||||||
|
#endif // THEMESETTINGSWIDGET_H
|
||||||
@@ -567,6 +567,8 @@ bool VariableChooser::eventFilter(QObject *obj, QEvent *event)
|
|||||||
return handleEscapePressed(ke, this);
|
return handleEscapePressed(ke, this);
|
||||||
} else if (event->type() == QEvent::Resize) {
|
} else if (event->type() == QEvent::Resize) {
|
||||||
d->updateButtonGeometry();
|
d->updateButtonGeometry();
|
||||||
|
} else if (event->type() == QEvent::Hide) {
|
||||||
|
close();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
|
|
||||||
import QtcPlugin
|
|
||||||
|
|
||||||
QtcPlugin {
|
QtcPlugin {
|
||||||
name: "CodePaster"
|
name: "CodePaster"
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
import QtcTool
|
|
||||||
|
|
||||||
QtcTool {
|
QtcTool {
|
||||||
name: "cpaster"
|
name: "cpaster"
|
||||||
|
|||||||
@@ -1365,9 +1365,8 @@ void CppCodeModelInspectorDialog::refresh()
|
|||||||
if (editor) {
|
if (editor) {
|
||||||
const QString editorFilePath = editor->document()->filePath();
|
const QString editorFilePath = editor->document()->filePath();
|
||||||
editorDocument = cmmi->editorDocument(editorFilePath);
|
editorDocument = cmmi->editorDocument(editorFilePath);
|
||||||
if (editorDocument) {
|
if (auto *builtinDocumentParser = BuiltinEditorDocumentParser::get(editorFilePath)) {
|
||||||
const CPlusPlus::Snapshot editorSnapshot
|
const CPlusPlus::Snapshot editorSnapshot = builtinDocumentParser->snapshot();
|
||||||
= BuiltinEditorDocumentParser::get(editorFilePath)->snapshot();
|
|
||||||
m_snapshotInfos->append(SnapshotInfo(editorSnapshot, SnapshotInfo::EditorSnapshot));
|
m_snapshotInfos->append(SnapshotInfo(editorSnapshot, SnapshotInfo::EditorSnapshot));
|
||||||
const QString editorSnapshotTitle
|
const QString editorSnapshotTitle
|
||||||
= QString::fromLatin1("Current Editor's Snapshot (%1 Documents)")
|
= QString::fromLatin1("Current Editor's Snapshot (%1 Documents)")
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
import qbs.FileInfo
|
import qbs.FileInfo
|
||||||
|
|
||||||
import QtcPlugin
|
|
||||||
|
|
||||||
QtcPlugin {
|
QtcPlugin {
|
||||||
name: "CppEditor"
|
name: "CppEditor"
|
||||||
|
|
||||||
|
|||||||
@@ -100,6 +100,9 @@ private slots:
|
|||||||
void test_FollowSymbolUnderCursor_data();
|
void test_FollowSymbolUnderCursor_data();
|
||||||
void test_FollowSymbolUnderCursor();
|
void test_FollowSymbolUnderCursor();
|
||||||
|
|
||||||
|
void test_FollowSymbolUnderCursor_followCall_data();
|
||||||
|
void test_FollowSymbolUnderCursor_followCall();
|
||||||
|
|
||||||
void test_FollowSymbolUnderCursor_QObject_connect_data();
|
void test_FollowSymbolUnderCursor_QObject_connect_data();
|
||||||
void test_FollowSymbolUnderCursor_QObject_connect();
|
void test_FollowSymbolUnderCursor_QObject_connect();
|
||||||
|
|
||||||
|
|||||||
@@ -931,45 +931,6 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_data()
|
|||||||
"};\n"
|
"};\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
QTest::newRow("matchFunctionSignature_FollowCall_1") << _(
|
|
||||||
"class Bar {};\n"
|
|
||||||
"void $foo(int) {}\n"
|
|
||||||
"void foo(const char *) {}\n"
|
|
||||||
"void foo(const Bar &) {}\n"
|
|
||||||
"void foo(char) {}\n"
|
|
||||||
"\n"
|
|
||||||
"void t()\n"
|
|
||||||
"{\n"
|
|
||||||
" @foo(5);\n"
|
|
||||||
"}\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
QTest::newRow("matchFunctionSignature_FollowCall_2") << _(
|
|
||||||
"class Bar {};\n"
|
|
||||||
"void foo(int) {}\n"
|
|
||||||
"void $foo(const char *) {}\n"
|
|
||||||
"void foo(const Bar &) {}\n"
|
|
||||||
"void foo(char) {}\n"
|
|
||||||
"\n"
|
|
||||||
"void t()\n"
|
|
||||||
"{\n"
|
|
||||||
" @foo(\"hoo\");\n"
|
|
||||||
"}\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
QTest::newRow("matchFunctionSignature_FollowCall_3") << _(
|
|
||||||
"class Bar {};\n"
|
|
||||||
"void foo(int) {}\n"
|
|
||||||
"void foo(const char *) {}\n"
|
|
||||||
"void foo(const Bar &) {}\n"
|
|
||||||
"void $foo(char) {}\n"
|
|
||||||
"\n"
|
|
||||||
"void t()\n"
|
|
||||||
"{\n"
|
|
||||||
" @foo('a');\n"
|
|
||||||
"}\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
QTest::newRow("infiniteLoopLocalTypedef_QTCREATORBUG-11999") << _(
|
QTest::newRow("infiniteLoopLocalTypedef_QTCREATORBUG-11999") << _(
|
||||||
"template<class MyTree>\n"
|
"template<class MyTree>\n"
|
||||||
"class TreeConstIterator\n"
|
"class TreeConstIterator\n"
|
||||||
@@ -993,6 +954,73 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor()
|
|||||||
F2TestCase(F2TestCase::FollowSymbolUnderCursorAction, singleDocument(source));
|
F2TestCase(F2TestCase::FollowSymbolUnderCursorAction, singleDocument(source));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CppEditorPlugin::test_FollowSymbolUnderCursor_followCall_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QByteArray>("variableDeclaration"); // without semicolon, can be ""
|
||||||
|
QTest::addColumn<QByteArray>("callArgument");
|
||||||
|
QTest::addColumn<QByteArray>("expectedSignature"); // you might need to add a function
|
||||||
|
// declaration with such a signature
|
||||||
|
|
||||||
|
QTest::newRow("intLiteral-to-int")
|
||||||
|
<< _("")
|
||||||
|
<< _("5")
|
||||||
|
<< _("int");
|
||||||
|
QTest::newRow("charLiteral-to-const-char-ptr")
|
||||||
|
<< _("")
|
||||||
|
<< _("\"hoo\"")
|
||||||
|
<< _("const char *");
|
||||||
|
QTest::newRow("charLiteral-to-int")
|
||||||
|
<< _("")
|
||||||
|
<< _("'a'")
|
||||||
|
<< _("char");
|
||||||
|
|
||||||
|
QTest::newRow("charPtr-to-constCharPtr")
|
||||||
|
<< _("char *var = \"var\"")
|
||||||
|
<< _("var")
|
||||||
|
<< _("const char *");
|
||||||
|
QTest::newRow("charPtr-to-constCharPtr")
|
||||||
|
<< _("char *var = \"var\"")
|
||||||
|
<< _("var")
|
||||||
|
<< _("const char *");
|
||||||
|
QTest::newRow("constCharPtr-to-constCharPtr")
|
||||||
|
<< _("const char *var = \"var\"")
|
||||||
|
<< _("var")
|
||||||
|
<< _("const char *");
|
||||||
|
|
||||||
|
QTest::newRow("Bar-to-constBarRef")
|
||||||
|
<< _("Bar var")
|
||||||
|
<< _("var")
|
||||||
|
<< _("const Bar &");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CppEditorPlugin::test_FollowSymbolUnderCursor_followCall()
|
||||||
|
{
|
||||||
|
QFETCH(QByteArray, variableDeclaration);
|
||||||
|
QFETCH(QByteArray, callArgument);
|
||||||
|
QFETCH(QByteArray, expectedSignature);
|
||||||
|
|
||||||
|
const QByteArray templateSource =
|
||||||
|
"class Bar {};\n"
|
||||||
|
"void fun(int);\n"
|
||||||
|
"void fun(const char *);\n"
|
||||||
|
"void fun(const Bar &);\n"
|
||||||
|
"void fun(char);\n"
|
||||||
|
"void fun(double);\n"
|
||||||
|
"\n"
|
||||||
|
"void t()\n"
|
||||||
|
"{\n"
|
||||||
|
" " + variableDeclaration + ";\n"
|
||||||
|
" @fun(" + callArgument + ");\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
const QByteArray matchText = " fun(" + expectedSignature + ")";
|
||||||
|
const QByteArray replaceText = " $fun(" + expectedSignature + ")";
|
||||||
|
QByteArray source = templateSource;
|
||||||
|
source.replace(matchText, replaceText);
|
||||||
|
QVERIFY(source != templateSource);
|
||||||
|
F2TestCase(F2TestCase::FollowSymbolUnderCursorAction, singleDocument(source));
|
||||||
|
}
|
||||||
|
|
||||||
void CppEditorPlugin::test_FollowSymbolUnderCursor_multipleDocuments_data()
|
void CppEditorPlugin::test_FollowSymbolUnderCursor_multipleDocuments_data()
|
||||||
{
|
{
|
||||||
QTest::addColumn<QList<TestDocumentPtr> >("documents");
|
QTest::addColumn<QList<TestDocumentPtr> >("documents");
|
||||||
|
|||||||
@@ -629,21 +629,9 @@ public:
|
|||||||
, m_newSourceFiles(newProjectInfo.sourceFiles())
|
, m_newSourceFiles(newProjectInfo.sourceFiles())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool definesChanged() const
|
bool definesChanged() const { return m_new.definesChanged(m_old); }
|
||||||
{
|
bool configurationChanged() const { return m_new.configurationChanged(m_old); }
|
||||||
return m_new.defines() != m_old.defines();
|
bool configurationOrFilesChanged() const { return m_new.configurationOrFilesChanged(m_old); }
|
||||||
}
|
|
||||||
|
|
||||||
bool configurationChanged() const
|
|
||||||
{
|
|
||||||
return definesChanged()
|
|
||||||
|| m_new.headerPaths() != m_old.headerPaths();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nothingChanged() const
|
|
||||||
{
|
|
||||||
return !configurationChanged() && m_new.sourceFiles() == m_old.sourceFiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
QSet<QString> addedFiles() const
|
QSet<QString> addedFiles() const
|
||||||
{
|
{
|
||||||
@@ -735,8 +723,12 @@ QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &newProjectIn
|
|||||||
ProjectInfo oldProjectInfo = d->m_projectToProjectsInfo.value(project);
|
ProjectInfo oldProjectInfo = d->m_projectToProjectsInfo.value(project);
|
||||||
if (oldProjectInfo.isValid()) {
|
if (oldProjectInfo.isValid()) {
|
||||||
ProjectInfoComparer comparer(oldProjectInfo, newProjectInfo);
|
ProjectInfoComparer comparer(oldProjectInfo, newProjectInfo);
|
||||||
if (comparer.nothingChanged())
|
|
||||||
|
if (!comparer.configurationOrFilesChanged()) {
|
||||||
|
// Some other attached data might have changed
|
||||||
|
d->m_projectToProjectsInfo.insert(project, newProjectInfo);
|
||||||
return QFuture<void>();
|
return QFuture<void>();
|
||||||
|
}
|
||||||
|
|
||||||
// If the project configuration changed, do a full reindexing
|
// If the project configuration changed, do a full reindexing
|
||||||
if (comparer.configurationChanged()) {
|
if (comparer.configurationChanged()) {
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ ProjectPart::ProjectPart()
|
|||||||
, languageExtensions(NoExtensions)
|
, languageExtensions(NoExtensions)
|
||||||
, qtVersion(UnknownQt)
|
, qtVersion(UnknownQt)
|
||||||
, warningFlags(ProjectExplorer::ToolChain::WarningsDefault)
|
, warningFlags(ProjectExplorer::ToolChain::WarningsDefault)
|
||||||
|
, selectedForBuilding(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,6 +138,36 @@ ProjectInfo::ProjectInfo(QPointer<ProjectExplorer::Project> project)
|
|||||||
: m_project(project)
|
: m_project(project)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
bool ProjectInfo::operator ==(const ProjectInfo &other) const
|
||||||
|
{
|
||||||
|
return m_project == other.m_project
|
||||||
|
&& m_projectParts == other.m_projectParts
|
||||||
|
&& m_compilerCallData == other.m_compilerCallData
|
||||||
|
&& m_headerPaths == other.m_headerPaths
|
||||||
|
&& m_sourceFiles == other.m_sourceFiles
|
||||||
|
&& m_defines == other.m_defines;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProjectInfo::operator !=(const ProjectInfo &other) const
|
||||||
|
{
|
||||||
|
return !operator ==(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProjectInfo::definesChanged(const ProjectInfo &other) const
|
||||||
|
{
|
||||||
|
return m_defines != other.m_defines;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProjectInfo::configurationChanged(const ProjectInfo &other) const
|
||||||
|
{
|
||||||
|
return definesChanged(other) || m_headerPaths != other.m_headerPaths;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProjectInfo::configurationOrFilesChanged(const ProjectInfo &other) const
|
||||||
|
{
|
||||||
|
return configurationChanged(other) || m_sourceFiles != other.m_sourceFiles;
|
||||||
|
}
|
||||||
|
|
||||||
bool ProjectInfo::isValid() const
|
bool ProjectInfo::isValid() const
|
||||||
{
|
{
|
||||||
return !m_project.isNull();
|
return !m_project.isNull();
|
||||||
@@ -193,6 +224,7 @@ void ProjectInfo::clearProjectParts()
|
|||||||
m_headerPaths.clear();
|
m_headerPaths.clear();
|
||||||
m_sourceFiles.clear();
|
m_sourceFiles.clear();
|
||||||
m_defines.clear();
|
m_defines.clear();
|
||||||
|
m_compilerCallData.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProjectPart::HeaderPaths ProjectInfo::headerPaths() const
|
const ProjectPart::HeaderPaths ProjectInfo::headerPaths() const
|
||||||
@@ -210,6 +242,16 @@ const QByteArray ProjectInfo::defines() const
|
|||||||
return m_defines;
|
return m_defines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProjectInfo::setCompilerCallData(const CompilerCallData &data)
|
||||||
|
{
|
||||||
|
m_compilerCallData = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProjectInfo::CompilerCallData ProjectInfo::compilerCallData() const
|
||||||
|
{
|
||||||
|
return m_compilerCallData;
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class ProjectFileCategorizer
|
class ProjectFileCategorizer
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ public: // fields
|
|||||||
LanguageExtensions languageExtensions;
|
LanguageExtensions languageExtensions;
|
||||||
QtVersion qtVersion;
|
QtVersion qtVersion;
|
||||||
ProjectExplorer::ToolChain::WarningFlags warningFlags;
|
ProjectExplorer::ToolChain::WarningFlags warningFlags;
|
||||||
|
bool selectedForBuilding;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline uint qHash(const ProjectPart::HeaderPath &key, uint seed = 0)
|
inline uint qHash(const ProjectPart::HeaderPath &key, uint seed = 0)
|
||||||
@@ -142,6 +143,12 @@ public:
|
|||||||
|
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
|
|
||||||
|
bool operator ==(const ProjectInfo &other) const;
|
||||||
|
bool operator !=(const ProjectInfo &other) const;
|
||||||
|
bool definesChanged(const ProjectInfo &other) const;
|
||||||
|
bool configurationChanged(const ProjectInfo &other) const;
|
||||||
|
bool configurationOrFilesChanged(const ProjectInfo &other) const;
|
||||||
|
|
||||||
QPointer<ProjectExplorer::Project> project() const;
|
QPointer<ProjectExplorer::Project> project() const;
|
||||||
const QList<ProjectPart::Ptr> projectParts() const;
|
const QList<ProjectPart::Ptr> projectParts() const;
|
||||||
|
|
||||||
@@ -153,10 +160,16 @@ public:
|
|||||||
const QSet<QString> sourceFiles() const;
|
const QSet<QString> sourceFiles() const;
|
||||||
const QByteArray defines() const;
|
const QByteArray defines() const;
|
||||||
|
|
||||||
|
// Source file --> List of compiler calls
|
||||||
|
typedef QHash<QString, QList<QStringList>> CompilerCallData;
|
||||||
|
void setCompilerCallData(const CompilerCallData &data);
|
||||||
|
CompilerCallData compilerCallData() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPointer<ProjectExplorer::Project> m_project;
|
QPointer<ProjectExplorer::Project> m_project;
|
||||||
QList<ProjectPart::Ptr> m_projectParts;
|
QList<ProjectPart::Ptr> m_projectParts;
|
||||||
// The members below are (re)calculated from the project parts once a part is appended.
|
CompilerCallData m_compilerCallData;
|
||||||
|
// The members below are (re)calculated from the project parts with finish()
|
||||||
ProjectPart::HeaderPaths m_headerPaths;
|
ProjectPart::HeaderPaths m_headerPaths;
|
||||||
QSet<QString> m_sourceFiles;
|
QSet<QString> m_sourceFiles;
|
||||||
QByteArray m_defines;
|
QByteArray m_defines;
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
import qbs.FileInfo
|
import qbs.FileInfo
|
||||||
|
|
||||||
import QtcPlugin
|
|
||||||
|
|
||||||
QtcPlugin {
|
QtcPlugin {
|
||||||
name: "CppTools"
|
name: "CppTools"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
|
|
||||||
import QtcPlugin
|
|
||||||
|
|
||||||
QtcPlugin {
|
QtcPlugin {
|
||||||
name: "CVS"
|
name: "CVS"
|
||||||
|
|
||||||
|
|||||||
@@ -190,7 +190,6 @@ static inline bool fileNameMatch(const QString &f1, const QString &f2)
|
|||||||
|
|
||||||
static bool isSimilarTo(const BreakpointParameters &data, const BreakpointResponse &needle)
|
static bool isSimilarTo(const BreakpointParameters &data, const BreakpointResponse &needle)
|
||||||
{
|
{
|
||||||
// Clear hit.
|
|
||||||
// Clear miss.
|
// Clear miss.
|
||||||
if (needle.type != UnknownBreakpointType && data.type != UnknownBreakpointType
|
if (needle.type != UnknownBreakpointType && data.type != UnknownBreakpointType
|
||||||
&& data.type != needle.type)
|
&& data.type != needle.type)
|
||||||
@@ -200,6 +199,10 @@ static bool isSimilarTo(const BreakpointParameters &data, const BreakpointRespon
|
|||||||
if (data.address && data.address == needle.address)
|
if (data.address && data.address == needle.address)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// Clear hit.
|
||||||
|
if (data == needle)
|
||||||
|
return true;
|
||||||
|
|
||||||
// At least at a position we were looking for.
|
// At least at a position we were looking for.
|
||||||
// FIXME: breaks multiple breakpoints at the same location
|
// FIXME: breaks multiple breakpoints at the same location
|
||||||
if (!data.fileName.isEmpty()
|
if (!data.fileName.isEmpty()
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import qbs 1.0
|
import qbs 1.0
|
||||||
|
|
||||||
import QtcPlugin
|
|
||||||
|
|
||||||
QtcPlugin {
|
QtcPlugin {
|
||||||
name: "Debugger"
|
name: "Debugger"
|
||||||
|
|
||||||
|
|||||||
@@ -1140,14 +1140,13 @@ public:
|
|||||||
DebuggerEngine *m_currentEngine;
|
DebuggerEngine *m_currentEngine;
|
||||||
DebuggerSettings *m_debuggerSettings;
|
DebuggerSettings *m_debuggerSettings;
|
||||||
QStringList m_arguments;
|
QStringList m_arguments;
|
||||||
DebuggerToolTipManager *m_toolTipManager;
|
DebuggerToolTipManager m_toolTipManager;
|
||||||
CommonOptionsPage *m_commonOptionsPage;
|
CommonOptionsPage *m_commonOptionsPage;
|
||||||
DummyEngine *m_dummyEngine;
|
DummyEngine *m_dummyEngine;
|
||||||
const QSharedPointer<GlobalDebuggerOptions> m_globalDebuggerOptions;
|
const QSharedPointer<GlobalDebuggerOptions> m_globalDebuggerOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
DebuggerPluginPrivate::DebuggerPluginPrivate(DebuggerPlugin *plugin) :
|
DebuggerPluginPrivate::DebuggerPluginPrivate(DebuggerPlugin *plugin) :
|
||||||
m_toolTipManager(new DebuggerToolTipManager(this)),
|
|
||||||
m_dummyEngine(0),
|
m_dummyEngine(0),
|
||||||
m_globalDebuggerOptions(new GlobalDebuggerOptions)
|
m_globalDebuggerOptions(new GlobalDebuggerOptions)
|
||||||
{
|
{
|
||||||
@@ -2036,7 +2035,7 @@ void DebuggerPluginPrivate::setInitialState()
|
|||||||
setBusyCursor(false);
|
setBusyCursor(false);
|
||||||
m_reverseDirectionAction->setChecked(false);
|
m_reverseDirectionAction->setChecked(false);
|
||||||
m_reverseDirectionAction->setEnabled(false);
|
m_reverseDirectionAction->setEnabled(false);
|
||||||
m_toolTipManager->closeAllToolTips();
|
m_toolTipManager.closeAllToolTips();
|
||||||
|
|
||||||
m_startAndDebugApplicationAction->setEnabled(true);
|
m_startAndDebugApplicationAction->setEnabled(true);
|
||||||
m_attachToQmlPortAction->setEnabled(true);
|
m_attachToQmlPortAction->setEnabled(true);
|
||||||
@@ -2269,14 +2268,14 @@ void DebuggerPluginPrivate::onModeChanged(IMode *mode)
|
|||||||
m_mainWindow->onModeChanged(mode);
|
m_mainWindow->onModeChanged(mode);
|
||||||
|
|
||||||
if (mode->id() != Constants::MODE_DEBUG) {
|
if (mode->id() != Constants::MODE_DEBUG) {
|
||||||
m_toolTipManager->leavingDebugMode();
|
m_toolTipManager.leavingDebugMode();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IEditor *editor = EditorManager::currentEditor())
|
if (IEditor *editor = EditorManager::currentEditor())
|
||||||
editor->widget()->setFocus();
|
editor->widget()->setFocus();
|
||||||
|
|
||||||
m_toolTipManager->debugModeEntered();
|
m_toolTipManager.debugModeEntered();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerPluginPrivate::showSettingsDialog()
|
void DebuggerPluginPrivate::showSettingsDialog()
|
||||||
@@ -2334,7 +2333,7 @@ void DebuggerPluginPrivate::sessionLoaded()
|
|||||||
|
|
||||||
void DebuggerPluginPrivate::aboutToUnloadSession()
|
void DebuggerPluginPrivate::aboutToUnloadSession()
|
||||||
{
|
{
|
||||||
m_toolTipManager->sessionAboutToChange();
|
m_toolTipManager.sessionAboutToChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerPluginPrivate::aboutToSaveSession()
|
void DebuggerPluginPrivate::aboutToSaveSession()
|
||||||
|
|||||||
@@ -65,31 +65,45 @@
|
|||||||
using namespace Core;
|
using namespace Core;
|
||||||
using namespace TextEditor;
|
using namespace TextEditor;
|
||||||
|
|
||||||
|
namespace Debugger {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class DebuggerToolTipWidget;
|
||||||
|
QList<QPointer<DebuggerToolTipWidget>> m_tooltips;
|
||||||
|
bool m_debugModeActive;
|
||||||
|
|
||||||
// Expire tooltips after n days on (no longer load them) in order
|
// Expire tooltips after n days on (no longer load them) in order
|
||||||
// to avoid them piling up.
|
// to avoid them piling up.
|
||||||
enum { toolTipsExpiryDays = 6 };
|
enum { toolTipsExpiryDays = 6 };
|
||||||
|
|
||||||
static const char sessionSettingsKeyC[] = "DebuggerToolTips";
|
const char sessionSettingsKeyC[] = "DebuggerToolTips";
|
||||||
static const char sessionDocumentC[] = "DebuggerToolTips";
|
const char sessionDocumentC[] = "DebuggerToolTips";
|
||||||
static const char sessionVersionAttributeC[] = "version";
|
const char sessionVersionAttributeC[] = "version";
|
||||||
static const char toolTipElementC[] = "DebuggerToolTip";
|
const char toolTipElementC[] = "DebuggerToolTip";
|
||||||
static const char toolTipClassAttributeC[] = "class";
|
const char toolTipClassAttributeC[] = "class";
|
||||||
static const char fileNameAttributeC[] = "name";
|
const char fileNameAttributeC[] = "name";
|
||||||
static const char functionAttributeC[] = "function";
|
const char functionAttributeC[] = "function";
|
||||||
static const char textPositionAttributeC[] = "position";
|
const char textPositionAttributeC[] = "position";
|
||||||
static const char textLineAttributeC[] = "line";
|
const char textLineAttributeC[] = "line";
|
||||||
static const char textColumnAttributeC[] = "column";
|
const char textColumnAttributeC[] = "column";
|
||||||
static const char offsetXAttributeC[] = "offset_x";
|
const char offsetXAttributeC[] = "offset_x";
|
||||||
static const char offsetYAttributeC[] = "offset_y";
|
const char offsetYAttributeC[] = "offset_y";
|
||||||
static const char engineTypeAttributeC[] = "engine";
|
const char engineTypeAttributeC[] = "engine";
|
||||||
static const char dateAttributeC[] = "date";
|
const char dateAttributeC[] = "date";
|
||||||
static const char treeElementC[] = "tree";
|
const char treeElementC[] = "tree";
|
||||||
static const char treeExpressionAttributeC[] = "expression";
|
const char treeExpressionAttributeC[] = "expression";
|
||||||
static const char treeInameAttributeC[] = "iname";
|
const char treeInameAttributeC[] = "iname";
|
||||||
static const char modelElementC[] = "model";
|
const char modelElementC[] = "model";
|
||||||
static const char modelColumnCountAttributeC[] = "columncount";
|
const char modelColumnCountAttributeC[] = "columncount";
|
||||||
static const char modelRowElementC[] = "row";
|
const char modelRowElementC[] = "row";
|
||||||
static const char modelItemElementC[] = "item";
|
const char modelItemElementC[] = "item";
|
||||||
|
|
||||||
|
static void purgeClosedToolTips()
|
||||||
|
{
|
||||||
|
for (int i = m_tooltips.size(); --i >= 0; )
|
||||||
|
if (!m_tooltips.at(i))
|
||||||
|
m_tooltips.removeAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
// Forward a stream reader across end elements looking for the
|
// Forward a stream reader across end elements looking for the
|
||||||
// next start element of a desired type.
|
// next start element of a desired type.
|
||||||
@@ -112,19 +126,6 @@ static bool readStartElement(QXmlStreamReader &r, const char *name)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void debugMode(const QAbstractItemModel *model)
|
|
||||||
{
|
|
||||||
QDebug nospace = qDebug().nospace();
|
|
||||||
nospace << model << '\n';
|
|
||||||
for (int r = 0; r < model->rowCount(); r++)
|
|
||||||
nospace << '#' << r << ' ' << model->data(model->index(r, 0)).toString() << '\n';
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Debugger {
|
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
// A label that can be dragged to drag something else.
|
// A label that can be dragged to drag something else.
|
||||||
|
|
||||||
class DraggableLabel : public QLabel
|
class DraggableLabel : public QLabel
|
||||||
@@ -472,27 +473,134 @@ private:
|
|||||||
StandardItemTreeModelBuilder m_builder;
|
StandardItemTreeModelBuilder m_builder;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DebuggerToolTipWidget;
|
/*!
|
||||||
|
\class Debugger::Internal::DebuggerToolTipTreeView
|
||||||
|
|
||||||
class DebuggerToolTipManagerData
|
\brief The DebuggerToolTipTreeView class is a treeview that adapts its size
|
||||||
|
to the model contents (also while expanding)
|
||||||
|
to be used within DebuggerTreeViewToolTipWidget.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DebuggerToolTipTreeView : public QTreeView
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DebuggerToolTipManagerData()
|
explicit DebuggerToolTipTreeView(QWidget *parent = 0);
|
||||||
: m_debugModeActive(false)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void purgeClosedToolTips()
|
QSize sizeHint() const { return m_size; }
|
||||||
{
|
|
||||||
for (int i = m_tooltips.size(); --i >= 0; )
|
|
||||||
if (!m_tooltips.at(i))
|
|
||||||
m_tooltips.removeAt(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QPointer<DebuggerToolTipWidget> > m_tooltips;
|
void computeSize();
|
||||||
bool m_debugModeActive;
|
|
||||||
|
private:
|
||||||
|
void expandNode(const QModelIndex &idx);
|
||||||
|
void collapseNode(const QModelIndex &idx);
|
||||||
|
int computeHeight(const QModelIndex &index) const;
|
||||||
|
|
||||||
|
QSize m_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
static DebuggerToolTipManagerData *d = 0;
|
DebuggerToolTipTreeView::DebuggerToolTipTreeView(QWidget *parent) :
|
||||||
|
QTreeView(parent)
|
||||||
|
{
|
||||||
|
setHeaderHidden(true);
|
||||||
|
setEditTriggers(NoEditTriggers);
|
||||||
|
|
||||||
|
setUniformRowHeights(true);
|
||||||
|
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
|
||||||
|
connect(this, &QTreeView::collapsed, this, &DebuggerToolTipTreeView::computeSize,
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
connect(this, &QTreeView::expanded, this, &DebuggerToolTipTreeView::computeSize,
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
|
connect(this, &QTreeView::expanded,
|
||||||
|
this, &DebuggerToolTipTreeView::expandNode);
|
||||||
|
connect(this, &QTreeView::collapsed,
|
||||||
|
this, &DebuggerToolTipTreeView::collapseNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebuggerToolTipTreeView::expandNode(const QModelIndex &idx)
|
||||||
|
{
|
||||||
|
model()->setData(idx, true, LocalsExpandedRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebuggerToolTipTreeView::collapseNode(const QModelIndex &idx)
|
||||||
|
{
|
||||||
|
model()->setData(idx, false, LocalsExpandedRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
int DebuggerToolTipTreeView::computeHeight(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
int s = rowHeight(index);
|
||||||
|
const int rowCount = model()->rowCount(index);
|
||||||
|
for (int i = 0; i < rowCount; ++i)
|
||||||
|
s += computeHeight(model()->index(i, 0, index));
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebuggerToolTipTreeView::computeSize()
|
||||||
|
{
|
||||||
|
int columns = 30; // Decoration
|
||||||
|
int rows = 0;
|
||||||
|
bool rootDecorated = false;
|
||||||
|
|
||||||
|
if (QAbstractItemModel *m = model()) {
|
||||||
|
WatchTreeView::reexpand(this, m->index(0, 0));
|
||||||
|
const int columnCount = m->columnCount();
|
||||||
|
rootDecorated = m->rowCount() > 0;
|
||||||
|
if (rootDecorated)
|
||||||
|
for (int i = 0; i < columnCount; ++i) {
|
||||||
|
resizeColumnToContents(i);
|
||||||
|
columns += sizeHintForColumn(i);
|
||||||
|
}
|
||||||
|
if (columns < 100)
|
||||||
|
columns = 100; // Prevent toolbar from shrinking when displaying 'Previous'
|
||||||
|
rows += computeHeight(QModelIndex());
|
||||||
|
|
||||||
|
// Fit tooltip to screen, showing/hiding scrollbars as needed.
|
||||||
|
// Add a bit of space to account for tooltip border, and not
|
||||||
|
// touch the border of the screen.
|
||||||
|
QPoint pos(x(), y());
|
||||||
|
QTC_ASSERT(QApplication::desktop(), return);
|
||||||
|
QRect desktopRect = QApplication::desktop()->availableGeometry(pos);
|
||||||
|
const int maxWidth = desktopRect.right() - pos.x() - 5 - 5;
|
||||||
|
const int maxHeight = desktopRect.bottom() - pos.y() - 5 - 5;
|
||||||
|
|
||||||
|
if (columns > maxWidth)
|
||||||
|
rows += horizontalScrollBar()->height();
|
||||||
|
|
||||||
|
if (rows > maxHeight) {
|
||||||
|
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||||
|
rows = maxHeight;
|
||||||
|
columns += verticalScrollBar()->width();
|
||||||
|
} else {
|
||||||
|
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (columns > maxWidth) {
|
||||||
|
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||||
|
columns = maxWidth;
|
||||||
|
} else {
|
||||||
|
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_size = QSize(columns + 5, rows + 5);
|
||||||
|
setMinimumSize(m_size);
|
||||||
|
setMaximumSize(m_size);
|
||||||
|
setRootIsDecorated(rootDecorated);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DebuggerToolTipManager::treeModelClipboardContents(const QAbstractItemModel *model)
|
||||||
|
{
|
||||||
|
QString rc;
|
||||||
|
QTC_ASSERT(model, return rc);
|
||||||
|
QTextStream str(&rc);
|
||||||
|
DumpTreeModelVisitor v(model, DumpTreeModelVisitor::ClipboardMode, str);
|
||||||
|
v.run();
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
@@ -503,8 +611,6 @@ static DebuggerToolTipManagerData *d = 0;
|
|||||||
|
|
||||||
class DebuggerToolTipWidget : public QWidget
|
class DebuggerToolTipWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DebuggerToolTipWidget(const DebuggerToolTipContext &context);
|
DebuggerToolTipWidget(const DebuggerToolTipContext &context);
|
||||||
|
|
||||||
@@ -519,10 +625,13 @@ public:
|
|||||||
void releaseEngine();
|
void releaseEngine();
|
||||||
|
|
||||||
void saveSessionData(QXmlStreamWriter &w) const;
|
void saveSessionData(QXmlStreamWriter &w) const;
|
||||||
void setWatchModel(QAbstractItemModel *watchModel);
|
void setWatchModel(WatchModelBase *watchModel);
|
||||||
void handleStackFrameCompleted(const QString &frameFile, const QString &frameFunction);
|
void handleStackFrameCompleted(const QString &frameFile, const QString &frameFunction);
|
||||||
|
|
||||||
public slots:
|
void copy();
|
||||||
|
void positionShow(const TextEditorWidget *editorWidget);
|
||||||
|
void pin();
|
||||||
|
|
||||||
void handleItemIsExpanded(const QModelIndex &sourceIdx)
|
void handleItemIsExpanded(const QModelIndex &sourceIdx)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_filterModel.sourceModel() == sourceIdx.model(), return);
|
QTC_ASSERT(m_filterModel.sourceModel() == sourceIdx.model(), return);
|
||||||
@@ -531,10 +640,6 @@ public slots:
|
|||||||
m_treeView->expand(mappedIdx);
|
m_treeView->expand(mappedIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void copy();
|
|
||||||
void positionShow(const TextEditorWidget *editorWidget);
|
|
||||||
void pin();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool m_isPinned;
|
bool m_isPinned;
|
||||||
QToolButton *m_toolButton;
|
QToolButton *m_toolButton;
|
||||||
@@ -546,6 +651,13 @@ public:
|
|||||||
QStandardItemModel m_defaultModel;
|
QStandardItemModel m_defaultModel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void hideAllToolTips()
|
||||||
|
{
|
||||||
|
purgeClosedToolTips();
|
||||||
|
foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips)
|
||||||
|
tw->hide();
|
||||||
|
}
|
||||||
|
|
||||||
void DebuggerToolTipWidget::pin()
|
void DebuggerToolTipWidget::pin()
|
||||||
{
|
{
|
||||||
if (m_isPinned)
|
if (m_isPinned)
|
||||||
@@ -662,6 +774,7 @@ DebuggerToolTipWidget::DebuggerToolTipWidget(const DebuggerToolTipContext &conte
|
|||||||
m_titleLabel = new DraggableLabel(this);
|
m_titleLabel = new DraggableLabel(this);
|
||||||
m_titleLabel->setText(msgReleasedText());
|
m_titleLabel->setText(msgReleasedText());
|
||||||
m_titleLabel->setMinimumWidth(40); // Ensure a draggable area even if text is empty.
|
m_titleLabel->setMinimumWidth(40); // Ensure a draggable area even if text is empty.
|
||||||
|
m_titleLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
|
||||||
|
|
||||||
auto toolBar = new QToolBar(this);
|
auto toolBar = new QToolBar(this);
|
||||||
toolBar->setProperty("_q_custom_style_disabled", QVariant(true));
|
toolBar->setProperty("_q_custom_style_disabled", QVariant(true));
|
||||||
@@ -669,8 +782,8 @@ DebuggerToolTipWidget::DebuggerToolTipWidget(const DebuggerToolTipContext &conte
|
|||||||
if (!pinIconSizes.isEmpty())
|
if (!pinIconSizes.isEmpty())
|
||||||
toolBar->setIconSize(pinIconSizes.front());
|
toolBar->setIconSize(pinIconSizes.front());
|
||||||
toolBar->addWidget(m_toolButton);
|
toolBar->addWidget(m_toolButton);
|
||||||
toolBar->addWidget(m_titleLabel);
|
|
||||||
toolBar->addWidget(copyButton);
|
toolBar->addWidget(copyButton);
|
||||||
|
toolBar->addWidget(m_titleLabel);
|
||||||
|
|
||||||
m_treeView = new DebuggerToolTipTreeView(this);
|
m_treeView = new DebuggerToolTipTreeView(this);
|
||||||
m_treeView->setFocusPolicy(Qt::NoFocus);
|
m_treeView->setFocusPolicy(Qt::NoFocus);
|
||||||
@@ -691,14 +804,14 @@ DebuggerToolTipWidget::DebuggerToolTipWidget(const DebuggerToolTipContext &conte
|
|||||||
connect(copyButton, &QAbstractButton::clicked, this, &DebuggerToolTipWidget::copy);
|
connect(copyButton, &QAbstractButton::clicked, this, &DebuggerToolTipWidget::copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerToolTipWidget::setWatchModel(QAbstractItemModel *watchModel)
|
void DebuggerToolTipWidget::setWatchModel(WatchModelBase *watchModel)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(watchModel, return);
|
QTC_ASSERT(watchModel, return);
|
||||||
m_filterModel.setSourceModel(watchModel);
|
m_filterModel.setSourceModel(watchModel);
|
||||||
connect(watchModel, SIGNAL(itemIsExpanded(QModelIndex)),
|
connect(watchModel, &WatchModelBase::itemIsExpanded,
|
||||||
this, SLOT(handleItemIsExpanded(QModelIndex)), Qt::UniqueConnection);
|
this, &DebuggerToolTipWidget::handleItemIsExpanded, Qt::UniqueConnection);
|
||||||
connect(watchModel, SIGNAL(columnAdjustmentRequested()),
|
connect(watchModel, &WatchModelBase::columnAdjustmentRequested,
|
||||||
m_treeView, SLOT(computeSize()), Qt::UniqueConnection);
|
m_treeView, &DebuggerToolTipTreeView::computeSize, Qt::UniqueConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerToolTipWidget::handleStackFrameCompleted(const QString &frameFile, const QString &frameFunction)
|
void DebuggerToolTipWidget::handleStackFrameCompleted(const QString &frameFile, const QString &frameFunction)
|
||||||
@@ -780,7 +893,7 @@ void DebuggerToolTipWidget::positionShow(const TextEditorWidget *editorWidget)
|
|||||||
|
|
||||||
static DebuggerToolTipWidget *findOrCreateWidget(const DebuggerToolTipContext &context)
|
static DebuggerToolTipWidget *findOrCreateWidget(const DebuggerToolTipContext &context)
|
||||||
{
|
{
|
||||||
foreach (const QPointer<DebuggerToolTipWidget> &tw, d->m_tooltips)
|
foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips)
|
||||||
if (tw && tw->m_context.isSame(context))
|
if (tw && tw->m_context.isSame(context))
|
||||||
return tw;
|
return tw;
|
||||||
|
|
||||||
@@ -789,7 +902,7 @@ static DebuggerToolTipWidget *findOrCreateWidget(const DebuggerToolTipContext &c
|
|||||||
tw->setObjectName(QLatin1String("DebuggerTreeViewToolTipWidget: ") + QLatin1String(context.iname));
|
tw->setObjectName(QLatin1String("DebuggerTreeViewToolTipWidget: ") + QLatin1String(context.iname));
|
||||||
tw->m_context.creationDate = QDate::currentDate();
|
tw->m_context.creationDate = QDate::currentDate();
|
||||||
|
|
||||||
d->m_tooltips.push_back(tw);
|
m_tooltips.push_back(tw);
|
||||||
|
|
||||||
return tw;
|
return tw;
|
||||||
}
|
}
|
||||||
@@ -839,7 +952,7 @@ static QDate dateFromString(const QString &date)
|
|||||||
QDate();
|
QDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loadSessionDataI(QXmlStreamReader &r)
|
static void loadSessionDataHelper(QXmlStreamReader &r)
|
||||||
{
|
{
|
||||||
if (!readStartElement(r, toolTipElementC))
|
if (!readStartElement(r, toolTipElementC))
|
||||||
return;
|
return;
|
||||||
@@ -919,118 +1032,6 @@ void DebuggerToolTipWidget::saveSessionData(QXmlStreamWriter &w) const
|
|||||||
w.writeEndElement();
|
w.writeEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
\class Debugger::Internal::DebuggerToolTipTreeView
|
|
||||||
|
|
||||||
\brief The DebuggerToolTipTreeView class is a treeview that adapts its size
|
|
||||||
to the model contents (also while expanding)
|
|
||||||
to be used within DebuggerTreeViewToolTipWidget.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
DebuggerToolTipTreeView::DebuggerToolTipTreeView(QWidget *parent) :
|
|
||||||
QTreeView(parent)
|
|
||||||
{
|
|
||||||
setHeaderHidden(true);
|
|
||||||
setEditTriggers(NoEditTriggers);
|
|
||||||
|
|
||||||
setUniformRowHeights(true);
|
|
||||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
||||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
||||||
|
|
||||||
connect(this, SIGNAL(collapsed(QModelIndex)), this, SLOT(computeSize()),
|
|
||||||
Qt::QueuedConnection);
|
|
||||||
connect(this, SIGNAL(expanded(QModelIndex)), this, SLOT(computeSize()),
|
|
||||||
Qt::QueuedConnection);
|
|
||||||
|
|
||||||
connect(this, SIGNAL(expanded(QModelIndex)),
|
|
||||||
SLOT(expandNode(QModelIndex)));
|
|
||||||
connect(this, SIGNAL(collapsed(QModelIndex)),
|
|
||||||
SLOT(collapseNode(QModelIndex)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebuggerToolTipTreeView::expandNode(const QModelIndex &idx)
|
|
||||||
{
|
|
||||||
model()->setData(idx, true, LocalsExpandedRole);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebuggerToolTipTreeView::collapseNode(const QModelIndex &idx)
|
|
||||||
{
|
|
||||||
model()->setData(idx, false, LocalsExpandedRole);
|
|
||||||
}
|
|
||||||
|
|
||||||
int DebuggerToolTipTreeView::computeHeight(const QModelIndex &index) const
|
|
||||||
{
|
|
||||||
int s = rowHeight(index);
|
|
||||||
const int rowCount = model()->rowCount(index);
|
|
||||||
for (int i = 0; i < rowCount; ++i)
|
|
||||||
s += computeHeight(model()->index(i, 0, index));
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebuggerToolTipTreeView::computeSize()
|
|
||||||
{
|
|
||||||
int columns = 30; // Decoration
|
|
||||||
int rows = 0;
|
|
||||||
bool rootDecorated = false;
|
|
||||||
|
|
||||||
if (QAbstractItemModel *m = model()) {
|
|
||||||
WatchTreeView::reexpand(this, m->index(0, 0));
|
|
||||||
const int columnCount = m->columnCount();
|
|
||||||
rootDecorated = m->rowCount() > 0;
|
|
||||||
if (rootDecorated)
|
|
||||||
for (int i = 0; i < columnCount; ++i) {
|
|
||||||
resizeColumnToContents(i);
|
|
||||||
columns += sizeHintForColumn(i);
|
|
||||||
}
|
|
||||||
if (columns < 100)
|
|
||||||
columns = 100; // Prevent toolbar from shrinking when displaying 'Previous'
|
|
||||||
rows += computeHeight(QModelIndex());
|
|
||||||
|
|
||||||
// Fit tooltip to screen, showing/hiding scrollbars as needed.
|
|
||||||
// Add a bit of space to account for tooltip border, and not
|
|
||||||
// touch the border of the screen.
|
|
||||||
QPoint pos(x(), y());
|
|
||||||
QTC_ASSERT(QApplication::desktop(), return);
|
|
||||||
QRect desktopRect = QApplication::desktop()->availableGeometry(pos);
|
|
||||||
const int maxWidth = desktopRect.right() - pos.x() - 5 - 5;
|
|
||||||
const int maxHeight = desktopRect.bottom() - pos.y() - 5 - 5;
|
|
||||||
|
|
||||||
if (columns > maxWidth)
|
|
||||||
rows += horizontalScrollBar()->height();
|
|
||||||
|
|
||||||
if (rows > maxHeight) {
|
|
||||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
|
||||||
rows = maxHeight;
|
|
||||||
columns += verticalScrollBar()->width();
|
|
||||||
} else {
|
|
||||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (columns > maxWidth) {
|
|
||||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
|
||||||
columns = maxWidth;
|
|
||||||
} else {
|
|
||||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_size = QSize(columns + 5, rows + 5);
|
|
||||||
setMinimumSize(m_size);
|
|
||||||
setMaximumSize(m_size);
|
|
||||||
setRootIsDecorated(rootDecorated);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString DebuggerToolTipManager::treeModelClipboardContents(const QAbstractItemModel *model)
|
|
||||||
{
|
|
||||||
QString rc;
|
|
||||||
QTC_ASSERT(model, return rc);
|
|
||||||
QTextStream str(&rc);
|
|
||||||
DumpTreeModelVisitor v(model, DumpTreeModelVisitor::ClipboardMode, str);
|
|
||||||
v.run();
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class Debugger::Internal::DebuggerToolTipManager
|
\class Debugger::Internal::DebuggerToolTipManager
|
||||||
|
|
||||||
@@ -1046,19 +1047,13 @@ QString DebuggerToolTipManager::treeModelClipboardContents(const QAbstractItemMo
|
|||||||
(by file name and function) acquire the engine, others release.
|
(by file name and function) acquire the engine, others release.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static DebuggerToolTipManager *m_instance = 0;
|
|
||||||
|
|
||||||
DebuggerToolTipManager::DebuggerToolTipManager(QObject *parent) :
|
DebuggerToolTipManager::DebuggerToolTipManager()
|
||||||
QObject(parent)
|
|
||||||
{
|
{
|
||||||
d = new DebuggerToolTipManagerData;
|
|
||||||
m_instance = this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DebuggerToolTipManager::~DebuggerToolTipManager()
|
DebuggerToolTipManager::~DebuggerToolTipManager()
|
||||||
{
|
{
|
||||||
delete d;
|
|
||||||
m_instance = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerToolTipManager::registerEngine(DebuggerEngine *)
|
void DebuggerToolTipManager::registerEngine(DebuggerEngine *)
|
||||||
@@ -1066,11 +1061,42 @@ void DebuggerToolTipManager::registerEngine(DebuggerEngine *)
|
|||||||
loadSessionData();
|
loadSessionData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebuggerToolTipManager::slotUpdateVisibleToolTips()
|
||||||
|
{
|
||||||
|
purgeClosedToolTips();
|
||||||
|
if (m_tooltips.isEmpty())
|
||||||
|
return;
|
||||||
|
if (!m_debugModeActive) {
|
||||||
|
hideAllToolTips();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseTextEditor *toolTipEditor = BaseTextEditor::currentTextEditor();
|
||||||
|
if (!toolTipEditor) {
|
||||||
|
hideAllToolTips();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString fileName = toolTipEditor->textDocument()->filePath();
|
||||||
|
if (fileName.isEmpty()) {
|
||||||
|
hideAllToolTips();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reposition and show all tooltips of that file.
|
||||||
|
foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips) {
|
||||||
|
if (tw->fileName() == fileName)
|
||||||
|
tw->positionShow(toolTipEditor->editorWidget());
|
||||||
|
else
|
||||||
|
tw->hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DebuggerToolTipManager::updateEngine(DebuggerEngine *engine)
|
void DebuggerToolTipManager::updateEngine(DebuggerEngine *engine)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(engine, return);
|
QTC_ASSERT(engine, return);
|
||||||
d->purgeClosedToolTips();
|
purgeClosedToolTips();
|
||||||
if (d->m_tooltips.isEmpty())
|
if (m_tooltips.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Stack frame changed: All tooltips of that file acquire the engine,
|
// Stack frame changed: All tooltips of that file acquire the engine,
|
||||||
@@ -1085,7 +1111,7 @@ void DebuggerToolTipManager::updateEngine(DebuggerEngine *engine)
|
|||||||
function = frame.function;
|
function = frame.function;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (const QPointer<DebuggerToolTipWidget> &tw, d->m_tooltips)
|
foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips)
|
||||||
tw->handleStackFrameCompleted(fileName, function);
|
tw->handleStackFrameCompleted(fileName, function);
|
||||||
slotUpdateVisibleToolTips(); // Move out when stepping in same file.
|
slotUpdateVisibleToolTips(); // Move out when stepping in same file.
|
||||||
}
|
}
|
||||||
@@ -1093,7 +1119,7 @@ void DebuggerToolTipManager::updateEngine(DebuggerEngine *engine)
|
|||||||
void DebuggerToolTipManager::deregisterEngine(DebuggerEngine *engine)
|
void DebuggerToolTipManager::deregisterEngine(DebuggerEngine *engine)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(engine, return);
|
QTC_ASSERT(engine, return);
|
||||||
foreach (const QPointer<DebuggerToolTipWidget> &tw, d->m_tooltips)
|
foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips)
|
||||||
if (tw && tw->m_context.engineType == engine->objectName())
|
if (tw && tw->m_context.engineType == engine->objectName())
|
||||||
tw->releaseEngine();
|
tw->releaseEngine();
|
||||||
saveSessionData();
|
saveSessionData();
|
||||||
@@ -1101,7 +1127,7 @@ void DebuggerToolTipManager::deregisterEngine(DebuggerEngine *engine)
|
|||||||
|
|
||||||
bool DebuggerToolTipManager::hasToolTips()
|
bool DebuggerToolTipManager::hasToolTips()
|
||||||
{
|
{
|
||||||
return !d->m_tooltips.isEmpty();
|
return !m_tooltips.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerToolTipManager::showToolTip
|
void DebuggerToolTipManager::showToolTip
|
||||||
@@ -1118,37 +1144,6 @@ void DebuggerToolTipManager::showToolTip
|
|||||||
Utils::ToolTip::show(context.mousePosition, widgetContent, Internal::mainWindow());
|
Utils::ToolTip::show(context.mousePosition, widgetContent, Internal::mainWindow());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DebuggerToolTipManager::eventFilter(QObject *o, QEvent *e)
|
|
||||||
{
|
|
||||||
if (!hasToolTips())
|
|
||||||
return false;
|
|
||||||
switch (e->type()) {
|
|
||||||
case QEvent::Move: { // Move along with parent (toplevel)
|
|
||||||
const QMoveEvent *me = static_cast<const QMoveEvent *>(e);
|
|
||||||
const QPoint dist = me->pos() - me->oldPos();
|
|
||||||
d->purgeClosedToolTips();
|
|
||||||
foreach (const QPointer<DebuggerToolTipWidget> &tw, d->m_tooltips)
|
|
||||||
if (tw->isVisible())
|
|
||||||
tw->move(tw->pos() + dist);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case QEvent::WindowStateChange: { // Hide/Show along with parent (toplevel)
|
|
||||||
const QWindowStateChangeEvent *se = static_cast<const QWindowStateChangeEvent *>(e);
|
|
||||||
const bool wasMinimized = se->oldState() & Qt::WindowMinimized;
|
|
||||||
const bool isMinimized = static_cast<const QWidget *>(o)->windowState() & Qt::WindowMinimized;
|
|
||||||
if (wasMinimized ^ isMinimized) {
|
|
||||||
d->purgeClosedToolTips();
|
|
||||||
foreach (const QPointer<DebuggerToolTipWidget> &tw, d->m_tooltips)
|
|
||||||
tw->setVisible(!isMinimized);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebuggerToolTipManager::sessionAboutToChange()
|
void DebuggerToolTipManager::sessionAboutToChange()
|
||||||
{
|
{
|
||||||
closeAllToolTips();
|
closeAllToolTips();
|
||||||
@@ -1161,19 +1156,19 @@ void DebuggerToolTipManager::loadSessionData()
|
|||||||
r.readNextStartElement();
|
r.readNextStartElement();
|
||||||
if (r.tokenType() == QXmlStreamReader::StartElement && r.name() == QLatin1String(sessionDocumentC))
|
if (r.tokenType() == QXmlStreamReader::StartElement && r.name() == QLatin1String(sessionDocumentC))
|
||||||
while (!r.atEnd())
|
while (!r.atEnd())
|
||||||
loadSessionDataI(r);
|
loadSessionDataHelper(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerToolTipManager::saveSessionData()
|
void DebuggerToolTipManager::saveSessionData()
|
||||||
{
|
{
|
||||||
QString data;
|
QString data;
|
||||||
d->purgeClosedToolTips();
|
purgeClosedToolTips();
|
||||||
|
|
||||||
QXmlStreamWriter w(&data);
|
QXmlStreamWriter w(&data);
|
||||||
w.writeStartDocument();
|
w.writeStartDocument();
|
||||||
w.writeStartElement(QLatin1String(sessionDocumentC));
|
w.writeStartElement(QLatin1String(sessionDocumentC));
|
||||||
w.writeAttribute(QLatin1String(sessionVersionAttributeC), QLatin1String("1.0"));
|
w.writeAttribute(QLatin1String(sessionVersionAttributeC), QLatin1String("1.0"));
|
||||||
foreach (const QPointer<DebuggerToolTipWidget> &tw, d->m_tooltips)
|
foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips)
|
||||||
if (tw->isPinned())
|
if (tw->isPinned())
|
||||||
tw->saveSessionData(w);
|
tw->saveSessionData(w);
|
||||||
w.writeEndDocument();
|
w.writeEndDocument();
|
||||||
@@ -1183,119 +1178,13 @@ void DebuggerToolTipManager::saveSessionData()
|
|||||||
|
|
||||||
void DebuggerToolTipManager::closeAllToolTips()
|
void DebuggerToolTipManager::closeAllToolTips()
|
||||||
{
|
{
|
||||||
d->purgeClosedToolTips();
|
purgeClosedToolTips();
|
||||||
foreach (const QPointer<DebuggerToolTipWidget> &tw, d->m_tooltips)
|
foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips)
|
||||||
tw->close();
|
tw->close();
|
||||||
d->m_tooltips.clear();
|
m_tooltips.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerToolTipManager::hide()
|
static void slotTooltipOverrideRequested
|
||||||
{
|
|
||||||
d->purgeClosedToolTips();
|
|
||||||
foreach (const QPointer<DebuggerToolTipWidget> &tw, d->m_tooltips)
|
|
||||||
tw->hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebuggerToolTipManager::slotUpdateVisibleToolTips()
|
|
||||||
{
|
|
||||||
d->purgeClosedToolTips();
|
|
||||||
if (d->m_tooltips.isEmpty())
|
|
||||||
return;
|
|
||||||
if (!d->m_debugModeActive) {
|
|
||||||
hide();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseTextEditor *toolTipEditor = BaseTextEditor::currentTextEditor();
|
|
||||||
if (!toolTipEditor) {
|
|
||||||
hide();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString fileName = toolTipEditor->textDocument()->filePath();
|
|
||||||
if (fileName.isEmpty()) {
|
|
||||||
hide();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reposition and show all tooltips of that file.
|
|
||||||
foreach (const QPointer<DebuggerToolTipWidget> &tw, d->m_tooltips) {
|
|
||||||
if (tw->fileName() == fileName)
|
|
||||||
tw->positionShow(toolTipEditor->editorWidget());
|
|
||||||
else
|
|
||||||
tw->hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebuggerToolTipManager::slotDebuggerStateChanged(DebuggerState state)
|
|
||||||
{
|
|
||||||
const QObject *engine = sender();
|
|
||||||
QTC_ASSERT(engine, return);
|
|
||||||
|
|
||||||
// Release at earliest possible convenience.
|
|
||||||
switch (state) {
|
|
||||||
case InferiorShutdownRequested:
|
|
||||||
case EngineShutdownRequested:
|
|
||||||
case DebuggerFinished:
|
|
||||||
case EngineShutdownOk: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebuggerToolTipManager::slotEditorOpened(IEditor *e)
|
|
||||||
{
|
|
||||||
// Move tooltip along when scrolled.
|
|
||||||
if (BaseTextEditor *textEditor = qobject_cast<BaseTextEditor *>(e)) {
|
|
||||||
TextEditorWidget *widget = textEditor->editorWidget();
|
|
||||||
connect(widget->verticalScrollBar(), &QScrollBar::valueChanged,
|
|
||||||
this, &DebuggerToolTipManager::slotUpdateVisibleToolTips);
|
|
||||||
connect(widget, &TextEditorWidget::tooltipOverrideRequested,
|
|
||||||
this, &DebuggerToolTipManager::slotTooltipOverrideRequested);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebuggerToolTipManager::debugModeEntered()
|
|
||||||
{
|
|
||||||
// Hook up all signals in debug mode.
|
|
||||||
if (!d->m_debugModeActive) {
|
|
||||||
d->m_debugModeActive = true;
|
|
||||||
QWidget *topLevel = ICore::mainWindow()->topLevelWidget();
|
|
||||||
topLevel->installEventFilter(this);
|
|
||||||
EditorManager *em = EditorManager::instance();
|
|
||||||
connect(em, &EditorManager::currentEditorChanged,
|
|
||||||
this, &DebuggerToolTipManager::slotUpdateVisibleToolTips);
|
|
||||||
connect(em, &EditorManager::editorOpened,
|
|
||||||
this, &DebuggerToolTipManager::slotEditorOpened);
|
|
||||||
foreach (IEditor *e, DocumentModel::editorsForOpenedDocuments())
|
|
||||||
slotEditorOpened(e);
|
|
||||||
// Position tooltips delayed once all the editor placeholder layouting is done.
|
|
||||||
if (!d->m_tooltips.isEmpty())
|
|
||||||
QTimer::singleShot(0, this, SLOT(slotUpdateVisibleToolTips()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebuggerToolTipManager::leavingDebugMode()
|
|
||||||
{
|
|
||||||
// Remove all signals in debug mode.
|
|
||||||
if (d->m_debugModeActive) {
|
|
||||||
d->m_debugModeActive = false;
|
|
||||||
hide();
|
|
||||||
if (QWidget *topLevel = ICore::mainWindow()->topLevelWidget())
|
|
||||||
topLevel->removeEventFilter(this);
|
|
||||||
foreach (IEditor *e, DocumentModel::editorsForOpenedDocuments()) {
|
|
||||||
if (BaseTextEditor *toolTipEditor = qobject_cast<BaseTextEditor *>(e)) {
|
|
||||||
toolTipEditor->editorWidget()->verticalScrollBar()->disconnect(this);
|
|
||||||
toolTipEditor->disconnect(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EditorManager::instance()->disconnect(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebuggerToolTipManager::slotTooltipOverrideRequested
|
|
||||||
(TextEditorWidget *editorWidget, const QPoint &point, int pos, bool *handled)
|
(TextEditorWidget *editorWidget, const QPoint &point, int pos, bool *handled)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(handled, return);
|
QTC_ASSERT(handled, return);
|
||||||
@@ -1319,7 +1208,7 @@ void DebuggerToolTipManager::slotTooltipOverrideRequested
|
|||||||
context.expression = fixCppExpression(raw);
|
context.expression = fixCppExpression(raw);
|
||||||
|
|
||||||
if (context.expression.isEmpty()) {
|
if (context.expression.isEmpty()) {
|
||||||
const Utils::WidgetContent widgetContent(new QLabel(tr("No valid expression")), true);
|
const Utils::WidgetContent widgetContent(new QLabel(DebuggerToolTipManager::tr("No valid expression")), true);
|
||||||
Utils::ToolTip::show(context.mousePosition, widgetContent, Internal::mainWindow());
|
Utils::ToolTip::show(context.mousePosition, widgetContent, Internal::mainWindow());
|
||||||
*handled = true;
|
*handled = true;
|
||||||
return;
|
return;
|
||||||
@@ -1331,7 +1220,7 @@ void DebuggerToolTipManager::slotTooltipOverrideRequested
|
|||||||
if (context.expression.isEmpty())
|
if (context.expression.isEmpty())
|
||||||
context.expression = localVariable->name;
|
context.expression = localVariable->name;
|
||||||
context.iname = localVariable->iname;
|
context.iname = localVariable->iname;
|
||||||
showToolTip(context, engine);
|
DebuggerToolTipManager::showToolTip(context, engine);
|
||||||
*handled = true;
|
*handled = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1345,18 +1234,97 @@ void DebuggerToolTipManager::slotTooltipOverrideRequested
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void slotEditorOpened(IEditor *e)
|
||||||
|
{
|
||||||
|
// Move tooltip along when scrolled.
|
||||||
|
if (BaseTextEditor *textEditor = qobject_cast<BaseTextEditor *>(e)) {
|
||||||
|
TextEditorWidget *widget = textEditor->editorWidget();
|
||||||
|
QObject::connect(widget->verticalScrollBar(), &QScrollBar::valueChanged,
|
||||||
|
&DebuggerToolTipManager::slotUpdateVisibleToolTips);
|
||||||
|
QObject::connect(widget, &TextEditorWidget::tooltipOverrideRequested,
|
||||||
|
slotTooltipOverrideRequested);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebuggerToolTipManager::debugModeEntered()
|
||||||
|
{
|
||||||
|
// Hook up all signals in debug mode.
|
||||||
|
if (!m_debugModeActive) {
|
||||||
|
m_debugModeActive = true;
|
||||||
|
QWidget *topLevel = ICore::mainWindow()->topLevelWidget();
|
||||||
|
topLevel->installEventFilter(this);
|
||||||
|
EditorManager *em = EditorManager::instance();
|
||||||
|
connect(em, &EditorManager::currentEditorChanged,
|
||||||
|
&DebuggerToolTipManager::slotUpdateVisibleToolTips);
|
||||||
|
connect(em, &EditorManager::editorOpened, slotEditorOpened);
|
||||||
|
|
||||||
|
foreach (IEditor *e, DocumentModel::editorsForOpenedDocuments())
|
||||||
|
slotEditorOpened(e);
|
||||||
|
// Position tooltips delayed once all the editor placeholder layouting is done.
|
||||||
|
if (!m_tooltips.isEmpty())
|
||||||
|
QTimer::singleShot(0, this, SLOT(slotUpdateVisibleToolTips()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebuggerToolTipManager::leavingDebugMode()
|
||||||
|
{
|
||||||
|
// Remove all signals in debug mode.
|
||||||
|
if (m_debugModeActive) {
|
||||||
|
m_debugModeActive = false;
|
||||||
|
hideAllToolTips();
|
||||||
|
if (QWidget *topLevel = ICore::mainWindow()->topLevelWidget())
|
||||||
|
topLevel->removeEventFilter(this);
|
||||||
|
foreach (IEditor *e, DocumentModel::editorsForOpenedDocuments()) {
|
||||||
|
if (BaseTextEditor *toolTipEditor = qobject_cast<BaseTextEditor *>(e)) {
|
||||||
|
toolTipEditor->editorWidget()->verticalScrollBar()->disconnect(this);
|
||||||
|
toolTipEditor->disconnect(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EditorManager::instance()->disconnect(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DebuggerToolTipContexts DebuggerToolTipManager::treeWidgetExpressions
|
DebuggerToolTipContexts DebuggerToolTipManager::treeWidgetExpressions
|
||||||
(DebuggerEngine *, const QString &fileName, const QString &function)
|
(DebuggerEngine *, const QString &fileName, const QString &function)
|
||||||
{
|
{
|
||||||
DebuggerToolTipContexts rc;
|
DebuggerToolTipContexts rc;
|
||||||
foreach (const QPointer<DebuggerToolTipWidget> &tw, d->m_tooltips) {
|
foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips) {
|
||||||
if (tw && tw->context().matchesFrame(fileName, function))
|
if (tw && tw->context().matchesFrame(fileName, function))
|
||||||
rc.push_back(tw->context());
|
rc.push_back(tw->context());
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DebuggerToolTipManager::eventFilter(QObject *o, QEvent *e)
|
||||||
|
{
|
||||||
|
if (m_tooltips.isEmpty())
|
||||||
|
return false;
|
||||||
|
switch (e->type()) {
|
||||||
|
case QEvent::Move: { // Move along with parent (toplevel)
|
||||||
|
const QMoveEvent *me = static_cast<const QMoveEvent *>(e);
|
||||||
|
const QPoint dist = me->pos() - me->oldPos();
|
||||||
|
purgeClosedToolTips();
|
||||||
|
foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips)
|
||||||
|
if (tw->isVisible())
|
||||||
|
tw->move(tw->pos() + dist);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case QEvent::WindowStateChange: { // Hide/Show along with parent (toplevel)
|
||||||
|
const QWindowStateChangeEvent *se = static_cast<const QWindowStateChangeEvent *>(e);
|
||||||
|
const bool wasMinimized = se->oldState() & Qt::WindowMinimized;
|
||||||
|
const bool isMinimized = static_cast<const QWidget *>(o)->windowState() & Qt::WindowMinimized;
|
||||||
|
if (wasMinimized ^ isMinimized) {
|
||||||
|
purgeClosedToolTips();
|
||||||
|
foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips)
|
||||||
|
tw->setVisible(!isMinimized);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|
||||||
#include "debuggertooltipmanager.moc"
|
|
||||||
|
|||||||
@@ -33,18 +33,16 @@
|
|||||||
|
|
||||||
#include "debuggerconstants.h"
|
#include "debuggerconstants.h"
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
#include <QDate>
|
#include <QDate>
|
||||||
#include <QPointer>
|
#include <QPoint>
|
||||||
#include <QTreeView>
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QDebug;
|
class QAbstractItemModel;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace Core { class IEditor; }
|
|
||||||
namespace TextEditor { class BaseTextEditor; class TextEditorWidget; }
|
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
|
|
||||||
class DebuggerEngine;
|
class DebuggerEngine;
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -72,36 +70,12 @@ public:
|
|||||||
|
|
||||||
typedef QList<DebuggerToolTipContext> DebuggerToolTipContexts;
|
typedef QList<DebuggerToolTipContext> DebuggerToolTipContexts;
|
||||||
|
|
||||||
|
|
||||||
QDebug operator<<(QDebug, const DebuggerToolTipContext &);
|
|
||||||
|
|
||||||
class DebuggerToolTipTreeView : public QTreeView
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit DebuggerToolTipTreeView(QWidget *parent = 0);
|
|
||||||
|
|
||||||
QAbstractItemModel *swapModel(QAbstractItemModel *model);
|
|
||||||
QSize sizeHint() const { return m_size; }
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void computeSize();
|
|
||||||
void expandNode(const QModelIndex &idx);
|
|
||||||
void collapseNode(const QModelIndex &idx);
|
|
||||||
|
|
||||||
private:
|
|
||||||
int computeHeight(const QModelIndex &index) const;
|
|
||||||
|
|
||||||
QSize m_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DebuggerToolTipManager : public QObject
|
class DebuggerToolTipManager : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DebuggerToolTipManager(QObject *parent = 0);
|
DebuggerToolTipManager();
|
||||||
~DebuggerToolTipManager();
|
~DebuggerToolTipManager();
|
||||||
|
|
||||||
static void registerEngine(DebuggerEngine *engine);
|
static void registerEngine(DebuggerEngine *engine);
|
||||||
@@ -120,21 +94,15 @@ public:
|
|||||||
|
|
||||||
static QString treeModelClipboardContents(const QAbstractItemModel *model);
|
static QString treeModelClipboardContents(const QAbstractItemModel *model);
|
||||||
|
|
||||||
public slots:
|
|
||||||
void debugModeEntered();
|
void debugModeEntered();
|
||||||
void leavingDebugMode();
|
void leavingDebugMode();
|
||||||
void sessionAboutToChange();
|
void sessionAboutToChange();
|
||||||
static void loadSessionData();
|
static void loadSessionData();
|
||||||
static void saveSessionData();
|
static void saveSessionData();
|
||||||
static void closeAllToolTips();
|
static void closeAllToolTips();
|
||||||
static void hide();
|
|
||||||
|
|
||||||
private slots:
|
public slots:
|
||||||
static void slotUpdateVisibleToolTips();
|
static void slotUpdateVisibleToolTips();
|
||||||
void slotDebuggerStateChanged(Debugger::DebuggerState);
|
|
||||||
void slotEditorOpened(Core::IEditor *);
|
|
||||||
void slotTooltipOverrideRequested(TextEditor::TextEditorWidget *editorWidget,
|
|
||||||
const QPoint &point, int pos, bool *handled);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user