Merge remote-tracking branch 'origin/4.6'
Conflicts: src/plugins/coreplugin/helpmanager.cpp Change-Id: I2feb60ec0afb2f22f75dc137a01c3fa217b299d8
148
dist/clang/patches/200_D36390_Fix-overloaded-static-functions-in-SemaCodeComplete.patch
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
--- a/include/clang/Sema/Sema.h
|
||||
+++ b/include/clang/Sema/Sema.h
|
||||
@@ -2707,7 +2707,8 @@
|
||||
OverloadCandidateSet &CandidateSet,
|
||||
TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr,
|
||||
bool SuppressUserConversions = false,
|
||||
- bool PartialOverloading = false);
|
||||
+ bool PartialOverloading = false,
|
||||
+ bool FirstArgumentIsBase = false);
|
||||
void AddMethodCandidate(DeclAccessPair FoundDecl,
|
||||
QualType ObjectType,
|
||||
Expr::Classification ObjectClassification,
|
||||
--- a/lib/Sema/SemaCodeComplete.cpp
|
||||
+++ b/lib/Sema/SemaCodeComplete.cpp
|
||||
@@ -4396,9 +4396,11 @@
|
||||
ArgExprs.append(Args.begin(), Args.end());
|
||||
UnresolvedSet<8> Decls;
|
||||
Decls.append(UME->decls_begin(), UME->decls_end());
|
||||
+ const bool FirstArgumentIsBase = !UME->isImplicitAccess() && UME->getBase();
|
||||
AddFunctionCandidates(Decls, ArgExprs, CandidateSet, TemplateArgs,
|
||||
/*SuppressUsedConversions=*/false,
|
||||
- /*PartialOverloading=*/true);
|
||||
+ /*PartialOverloading=*/true,
|
||||
+ FirstArgumentIsBase);
|
||||
} else {
|
||||
FunctionDecl *FD = nullptr;
|
||||
if (auto MCE = dyn_cast<MemberExpr>(NakedFn))
|
||||
--- a/lib/Sema/SemaOverload.cpp
|
||||
+++ b/lib/Sema/SemaOverload.cpp
|
||||
@@ -6343,24 +6343,36 @@
|
||||
OverloadCandidateSet& CandidateSet,
|
||||
TemplateArgumentListInfo *ExplicitTemplateArgs,
|
||||
bool SuppressUserConversions,
|
||||
- bool PartialOverloading) {
|
||||
+ bool PartialOverloading,
|
||||
+ bool FirstArgumentIsBase) {
|
||||
for (UnresolvedSetIterator F = Fns.begin(), E = Fns.end(); F != E; ++F) {
|
||||
NamedDecl *D = F.getDecl()->getUnderlyingDecl();
|
||||
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
+ ArrayRef<Expr *> FunctionArgs = Args;
|
||||
if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic()) {
|
||||
QualType ObjectType;
|
||||
Expr::Classification ObjectClassification;
|
||||
- if (Expr *E = Args[0]) {
|
||||
- // Use the explit base to restrict the lookup:
|
||||
- ObjectType = E->getType();
|
||||
- ObjectClassification = E->Classify(Context);
|
||||
- } // .. else there is an implit base.
|
||||
+ if (Args.size() > 0) {
|
||||
+ if (Expr *E = Args[0]) {
|
||||
+ // Use the explit base to restrict the lookup:
|
||||
+ ObjectType = E->getType();
|
||||
+ ObjectClassification = E->Classify(Context);
|
||||
+ } // .. else there is an implit base.
|
||||
+ FunctionArgs = Args.slice(1);
|
||||
+ }
|
||||
AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getPair(),
|
||||
cast<CXXMethodDecl>(FD)->getParent(), ObjectType,
|
||||
- ObjectClassification, Args.slice(1), CandidateSet,
|
||||
+ ObjectClassification, FunctionArgs, CandidateSet,
|
||||
SuppressUserConversions, PartialOverloading);
|
||||
} else {
|
||||
- AddOverloadCandidate(FD, F.getPair(), Args, CandidateSet,
|
||||
+ // Slice the first argument (which is the base) when we access
|
||||
+ // static method as non-static
|
||||
+ if (Args.size() > 0 && (!Args[0] || (FirstArgumentIsBase && isa<CXXMethodDecl>(FD) &&
|
||||
+ !isa<CXXConstructorDecl>(FD)))) {
|
||||
+ assert(cast<CXXMethodDecl>(FD)->isStatic());
|
||||
+ FunctionArgs = Args.slice(1);
|
||||
+ }
|
||||
+ AddOverloadCandidate(FD, F.getPair(), FunctionArgs, CandidateSet,
|
||||
SuppressUserConversions, PartialOverloading);
|
||||
}
|
||||
} else {
|
||||
--- a/test/Index/complete-call.cpp
|
||||
+++ b/test/Index/complete-call.cpp
|
||||
@@ -94,6 +94,24 @@
|
||||
s.foo_7(42,);
|
||||
}
|
||||
|
||||
+struct Bar {
|
||||
+ static void foo_1();
|
||||
+ void foo_1(float);
|
||||
+ static void foo_1(int);
|
||||
+};
|
||||
+
|
||||
+void test() {
|
||||
+ Bar::foo_1();
|
||||
+ Bar b;
|
||||
+ b.foo_1();
|
||||
+}
|
||||
+
|
||||
+struct Bar2 : public Bar {
|
||||
+ Bar2() {
|
||||
+ Bar::foo_1();
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
// RUN: c-index-test -code-completion-at=%s:47:9 %s | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
// CHECK-CC1: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1)
|
||||
// CHECK-CC1: Completion contexts:
|
||||
@@ -803,3 +821,46 @@
|
||||
// CHECK-CC59-NEXT: Class name
|
||||
// CHECK-CC59-NEXT: Nested name specifier
|
||||
// CHECK-CC59-NEXT: Objective-C interface
|
||||
+
|
||||
+// RUN: c-index-test -code-completion-at=%s:104:14 %s | FileCheck -check-prefix=CHECK-CC60 %s
|
||||
+// CHECK-CC60: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1)
|
||||
+// CHECK-CC60: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1)
|
||||
+// CHECK-CC60: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1)
|
||||
+// CHECK-CC60: Completion contexts:
|
||||
+// CHECK-CC60-NEXT: Any type
|
||||
+// CHECK-CC60-NEXT: Any value
|
||||
+// CHECK-CC60-NEXT: Enum tag
|
||||
+// CHECK-CC60-NEXT: Union tag
|
||||
+// CHECK-CC60-NEXT: Struct tag
|
||||
+// CHECK-CC60-NEXT: Class name
|
||||
+// CHECK-CC60-NEXT: Nested name specifier
|
||||
+// CHECK-CC60-NEXT: Objective-C interface
|
||||
+
|
||||
+// RUN: c-index-test -code-completion-at=%s:106:11 %s | FileCheck -check-prefix=CHECK-CC61 %s
|
||||
+// CHECK-CC61: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1)
|
||||
+// CHECK-CC61: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1)
|
||||
+// CHECK-CC61: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1)
|
||||
+// CHECK-CC61: Completion contexts:
|
||||
+// CHECK-CC61-NEXT: Any type
|
||||
+// CHECK-CC61-NEXT: Any value
|
||||
+// CHECK-CC61-NEXT: Enum tag
|
||||
+// CHECK-CC61-NEXT: Union tag
|
||||
+// CHECK-CC61-NEXT: Struct tag
|
||||
+// CHECK-CC61-NEXT: Class name
|
||||
+// CHECK-CC61-NEXT: Nested name specifier
|
||||
+// CHECK-CC61-NEXT: Objective-C interface
|
||||
+
|
||||
+// RUN: c-index-test -code-completion-at=%s:111:16 %s | FileCheck -check-prefix=CHECK-CC62 %s
|
||||
+// CHECK-CC62: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1)
|
||||
+// CHECK-CC62: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1)
|
||||
+// CHECK-CC62: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1)
|
||||
+// CHECK-CC62: Completion contexts:
|
||||
+// CHECK-CC62-NEXT: Any type
|
||||
+// CHECK-CC62-NEXT: Any value
|
||||
+// CHECK-CC62-NEXT: Enum tag
|
||||
+// CHECK-CC62-NEXT: Union tag
|
||||
+// CHECK-CC62-NEXT: Struct tag
|
||||
+// CHECK-CC62-NEXT: Class name
|
||||
+// CHECK-CC62-NEXT: Nested name specifier
|
||||
+// CHECK-CC62-NEXT: Objective-C interface
|
||||
+
|
||||
168
dist/clang/patches/210_D43453_Fix-overloaded-static-functions-for-templates.patch
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
|
||||
index 1b07ec60ce..46ed08d1cf 100644
|
||||
--- a/lib/Sema/SemaOverload.cpp
|
||||
+++ b/lib/Sema/SemaOverload.cpp
|
||||
@@ -6371,57 +6371,54 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns,
|
||||
bool FirstArgumentIsBase) {
|
||||
for (UnresolvedSetIterator F = Fns.begin(), E = Fns.end(); F != E; ++F) {
|
||||
NamedDecl *D = F.getDecl()->getUnderlyingDecl();
|
||||
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
- ArrayRef<Expr *> FunctionArgs = Args;
|
||||
- if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic()) {
|
||||
- QualType ObjectType;
|
||||
- Expr::Classification ObjectClassification;
|
||||
- if (Args.size() > 0) {
|
||||
- if (Expr *E = Args[0]) {
|
||||
- // Use the explit base to restrict the lookup:
|
||||
- ObjectType = E->getType();
|
||||
- ObjectClassification = E->Classify(Context);
|
||||
- } // .. else there is an implit base.
|
||||
- FunctionArgs = Args.slice(1);
|
||||
- }
|
||||
- AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getPair(),
|
||||
- cast<CXXMethodDecl>(FD)->getParent(), ObjectType,
|
||||
- ObjectClassification, FunctionArgs, CandidateSet,
|
||||
- SuppressUserConversions, PartialOverloading);
|
||||
- } else {
|
||||
- // Slice the first argument (which is the base) when we access
|
||||
- // static method as non-static
|
||||
- if (Args.size() > 0 && (!Args[0] || (FirstArgumentIsBase && isa<CXXMethodDecl>(FD) &&
|
||||
- !isa<CXXConstructorDecl>(FD)))) {
|
||||
- assert(cast<CXXMethodDecl>(FD)->isStatic());
|
||||
- FunctionArgs = Args.slice(1);
|
||||
- }
|
||||
- AddOverloadCandidate(FD, F.getPair(), FunctionArgs, CandidateSet,
|
||||
- SuppressUserConversions, PartialOverloading);
|
||||
- }
|
||||
- } else {
|
||||
- FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(D);
|
||||
- if (isa<CXXMethodDecl>(FunTmpl->getTemplatedDecl()) &&
|
||||
- !cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl())->isStatic()) {
|
||||
- QualType ObjectType;
|
||||
- Expr::Classification ObjectClassification;
|
||||
+ ArrayRef<Expr *> FunctionArgs = Args;
|
||||
+
|
||||
+ FunctionTemplateDecl *FunTmpl = nullptr;
|
||||
+ FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
|
||||
+
|
||||
+ const bool IsTemplate = FD ? false : true;
|
||||
+ if (IsTemplate) {
|
||||
+ FunTmpl = cast<FunctionTemplateDecl>(D);
|
||||
+ FD = FunTmpl->getTemplatedDecl();
|
||||
+ }
|
||||
+
|
||||
+ if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic()) {
|
||||
+ QualType ObjectType;
|
||||
+ Expr::Classification ObjectClassification;
|
||||
+ if (Args.size() > 0) {
|
||||
if (Expr *E = Args[0]) {
|
||||
- // Use the explit base to restrict the lookup:
|
||||
+ // Use the explicit base to restrict the lookup:
|
||||
ObjectType = E->getType();
|
||||
ObjectClassification = E->Classify(Context);
|
||||
} // .. else there is an implit base.
|
||||
+ FunctionArgs = Args.slice(1);
|
||||
+ }
|
||||
+ if (IsTemplate)
|
||||
AddMethodTemplateCandidate(
|
||||
- FunTmpl, F.getPair(),
|
||||
- cast<CXXRecordDecl>(FunTmpl->getDeclContext()),
|
||||
- ExplicitTemplateArgs, ObjectType, ObjectClassification,
|
||||
- Args.slice(1), CandidateSet, SuppressUserConversions,
|
||||
- PartialOverloading);
|
||||
- } else {
|
||||
- AddTemplateOverloadCandidate(FunTmpl, F.getPair(),
|
||||
- ExplicitTemplateArgs, Args,
|
||||
- CandidateSet, SuppressUserConversions,
|
||||
- PartialOverloading);
|
||||
+ FunTmpl, F.getPair(), cast<CXXRecordDecl>(FD), ExplicitTemplateArgs,
|
||||
+ ObjectType, ObjectClassification, FunctionArgs, CandidateSet,
|
||||
+ SuppressUserConversions, PartialOverloading);
|
||||
+ else
|
||||
+ AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getPair(),
|
||||
+ cast<CXXMethodDecl>(FD)->getParent(), ObjectType,
|
||||
+ ObjectClassification, FunctionArgs, CandidateSet,
|
||||
+ SuppressUserConversions, PartialOverloading);
|
||||
+ } else {
|
||||
+ // Slice the first argument (which is the base) when we access
|
||||
+ // static method as non-static
|
||||
+ if (Args.size() > 0 &&
|
||||
+ (!Args[0] || (FirstArgumentIsBase && isa<CXXMethodDecl>(FD) &&
|
||||
+ !isa<CXXConstructorDecl>(FD)))) {
|
||||
+ assert(cast<CXXMethodDecl>(FD)->isStatic());
|
||||
+ FunctionArgs = Args.slice(1);
|
||||
}
|
||||
+ if (IsTemplate)
|
||||
+ AddTemplateOverloadCandidate(
|
||||
+ FunTmpl, F.getPair(), ExplicitTemplateArgs, FunctionArgs,
|
||||
+ CandidateSet, SuppressUserConversions, PartialOverloading);
|
||||
+ else
|
||||
+ AddOverloadCandidate(FD, F.getPair(), FunctionArgs, CandidateSet,
|
||||
+ SuppressUserConversions, PartialOverloading);
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/test/Index/complete-call.cpp b/test/Index/complete-call.cpp
|
||||
index ca116485ac..35f2009066 100644
|
||||
--- a/test/Index/complete-call.cpp
|
||||
+++ b/test/Index/complete-call.cpp
|
||||
@@ -112,6 +112,33 @@ struct Bar2 : public Bar {
|
||||
}
|
||||
};
|
||||
|
||||
+struct BarTemplates {
|
||||
+ static void foo_1() {}
|
||||
+ void foo_1(float) {}
|
||||
+ static void foo_1(int) {}
|
||||
+
|
||||
+ template<class T1, class T2>
|
||||
+ static void foo_1(T1 a, T2 b) { a + b; }
|
||||
+
|
||||
+ template<class T1, class T2>
|
||||
+ void foo_1(T1 a, T2 b, float c) { a + b + c; }
|
||||
+
|
||||
+ template<class T1, class T2>
|
||||
+ static void foo_1(T2 a, int b, T1 c) { a + b + c; }
|
||||
+};
|
||||
+
|
||||
+void testTemplates() {
|
||||
+ BarTemplates::foo_1();
|
||||
+ BarTemplates b;
|
||||
+ b.foo_1();
|
||||
+}
|
||||
+
|
||||
+struct Bar2Template : public BarTemplates {
|
||||
+ Bar2Template() {
|
||||
+ BarTemplates::foo_1();
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
// RUN: c-index-test -code-completion-at=%s:47:9 %s | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
// CHECK-CC1: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1)
|
||||
// CHECK-CC1: Completion contexts:
|
||||
@@ -864,3 +891,25 @@ struct Bar2 : public Bar {
|
||||
// CHECK-CC62-NEXT: Nested name specifier
|
||||
// CHECK-CC62-NEXT: Objective-C interface
|
||||
|
||||
+// RUN: c-index-test -code-completion-at=%s:131:23 %s | FileCheck -check-prefix=CHECK-CC63 %s
|
||||
+// CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1)
|
||||
+// CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1)
|
||||
+// CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1)
|
||||
+// CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T1 a}{Comma , }{Placeholder T2 b}{RightParen )} (1)
|
||||
+// CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T1 a}{Comma , }{Placeholder T2 b}{Comma , }{Placeholder float c}{RightParen )} (1)
|
||||
+// CHECK-CC63: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T2 a}{Comma , }{Placeholder int b}{Comma , }{Placeholder T1 c}{RightParen )} (1)
|
||||
+
|
||||
+// RUN: c-index-test -code-completion-at=%s:133:11 %s | FileCheck -check-prefix=CHECK-CC64 %s
|
||||
+// CHECK-CC64: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1)
|
||||
+// CHECK-CC64: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1)
|
||||
+// CHECK-CC64: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1)
|
||||
+// CHECK-CC64: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T1 a}{Comma , }{Placeholder T2 b}{RightParen )} (1)
|
||||
+// CHECK-CC64: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T2 a}{Comma , }{Placeholder int b}{Comma , }{Placeholder T1 c}{RightParen )} (1)
|
||||
+
|
||||
+// RUN: c-index-test -code-completion-at=%s:138:25 %s | FileCheck -check-prefix=CHECK-CC65 %s
|
||||
+// CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{RightParen )} (1)
|
||||
+// CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter float}{RightParen )} (1)
|
||||
+// CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter int}{RightParen )} (1)
|
||||
+// CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T1 a}{Comma , }{Placeholder T2 b}{RightParen )} (1)
|
||||
+// CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T1 a}{Comma , }{Placeholder T2 b}{Comma , }{Placeholder float c}{RightParen )} (1)
|
||||
+// CHECK-CC65: OverloadCandidate:{ResultType void}{Text foo_1}{LeftParen (}{CurrentParameter T2 a}{Comma , }{Placeholder int b}{Comma , }{Placeholder T1 c}{RightParen )} (1)
|
||||
17
dist/clang/patches/README.md
vendored
@@ -112,3 +112,20 @@ Significantly reduces problems when saving a header file on Windows.
|
||||
|
||||
Builds Clazy as an LLVM part and forces link for Clazy plugin registry entry.
|
||||
|
||||
##### 200_D36390_Fix-overloaded-static-functions-in-SemaCodeComplete.patch
|
||||
|
||||
* <https://reviews.llvm.org/D36390>
|
||||
* <https://bugs.llvm.org/show_bug.cgi?id=33904>
|
||||
|
||||
Fix overloaded static functions in SemaCodeComplete
|
||||
|
||||
Happens when static function is accessed via the class variable.
|
||||
That leads to incorrect overloads number because the variable is considered as the first argument.
|
||||
|
||||
##### 210_D43453_Fix-overloaded-static-functions-for-templates.patch
|
||||
|
||||
* <https://reviews.llvm.org/D43453>
|
||||
|
||||
Fix overloaded static functions for templates
|
||||
|
||||
Apply almost the same fix as D36390 but for templates
|
||||
|
||||
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 59 KiB |
BIN
doc/images/qtcreator-clang-tidy.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
doc/images/qtcreator-clazy.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
@@ -93,27 +93,68 @@
|
||||
\li Code completion
|
||||
\li Syntactic and semantic highlighting
|
||||
\li Diagnostics
|
||||
\li Clang-Tidy checks
|
||||
\li Clazy checks
|
||||
\li Tooltips
|
||||
\li Clang-Tidy and Clazy checks
|
||||
\li Renaming of local symbols
|
||||
|
||||
\endlist
|
||||
|
||||
To use the plugin, you must activate it and configure it in \QC.
|
||||
|
||||
\section1 Using Clang-Tidy and Clazy
|
||||
\section1 Code Model Warnings
|
||||
|
||||
\l{https://clang.llvm.org/extra/clang-tidy/}{Clang-Tidy} and
|
||||
\l{https://github.com/KDE/clazy/blob/master/README.md}{Clazy} are delivered
|
||||
as parts of the Clang library delivered with \QC.
|
||||
The predefined configurations request Clang warnings at the following
|
||||
levels:
|
||||
|
||||
Clang-Tidy provides an extensible framework for diagnosing and fixing
|
||||
typical programming errors, such as style violations, interface misuse, or
|
||||
issues that can be found via static analysis.
|
||||
\list
|
||||
|
||||
Clazy helps Clang understand Qt semantics. It prints out Qt related compiler
|
||||
warnings, ranging from unnecessary memory allocation to misuse of API and
|
||||
provides refactoring actions for fixing some of the issues.
|
||||
\li \uicontrol {Pedantic Warnings} uses the \c -Wpendantic option that
|
||||
requests all the warnings demanded by strict ISO C and ISO C++.
|
||||
|
||||
\li \uicontrol {Warnings for Questionable Constructs} combines the
|
||||
\c -Wall and \c -Wextra options to request all warnings about easily
|
||||
avoidable questionable constructions and some additional warnings.
|
||||
|
||||
\li \uicontrol {Warnings for Almost Everything} uses the \c -Weverything
|
||||
option with negative options to suppress some warnings.
|
||||
|
||||
\endlist
|
||||
|
||||
You can edit the predefined configurations to request specific warnings
|
||||
beginning with \c -W. Each of these warnings also has a negative version
|
||||
that begins with \c -Wno.
|
||||
|
||||
Keep in mind that some options turn on other options. For more information,
|
||||
see \l{https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html}
|
||||
{Options to Request or Suppress Warnings} or the GCC or Clang manual pages.
|
||||
|
||||
\section1 Using Clang-Tidy Checks
|
||||
|
||||
\l{https://clang.llvm.org/extra/clang-tidy/}{Clang-Tidy} is delivered
|
||||
as a part of the Clang library delivered with \QC. It provides diagnostics
|
||||
and fixes for typical programming errors, such as style violations,
|
||||
interface misuse, or issues that can be found via static analysis.
|
||||
|
||||
\QC integrates the fixes and diagnostics into the Clang library, and
|
||||
therefore they cannot be easily changed or extended when used with \QC.
|
||||
|
||||
\section1 Using Clazy
|
||||
|
||||
\l{https://github.com/KDE/clazy/blob/master/README.md}{Clazy} is delivered
|
||||
as a part of the Clang library delivered with \QC. It helps Clang understand
|
||||
Qt semantics. It prints out Qt related compiler warnings, ranging from
|
||||
unnecessary memory allocation to misuse of API and provides refactoring
|
||||
actions for fixing some of the issues.
|
||||
|
||||
The Clazy checks are divided into levels from 0 to 3. Each level adds checks
|
||||
to the previous level. The checks at level 0 are very stable and provide
|
||||
hardly any false positives, while the checks at level 3 can be considered
|
||||
experimental.
|
||||
|
||||
For more information about the checks run at each level, see
|
||||
\l{https://github.com/KDE/clazy/blob/master/README.md#list-of-checks}
|
||||
{List of Checks} in the Clazy documentation.
|
||||
|
||||
\section1 Activating Clang Code Model
|
||||
|
||||
@@ -159,44 +200,31 @@
|
||||
edit the value for the \uicontrol {Do not index files greater than}
|
||||
check box. To index all files, deselect the check box.
|
||||
|
||||
\li In the \uicontrol {Clang Code Model Warnings} group, configure the
|
||||
diagnostics that Clang should issue.
|
||||
\li In \uicontrol {Clang Dianostics}, select one of the predefined
|
||||
configurations, or select \uicontrol Copy to create a copy of a
|
||||
configuration and edit it to fit your needs.
|
||||
|
||||
\list
|
||||
|
||||
\li In the \uicontrol {Configuration to use} list, select one of
|
||||
the predefined configurations, or select \uicontrol Copy to
|
||||
create a copy of a configuration and edit it to fit your
|
||||
needs.
|
||||
\li In the \uicontrol Clang tab, edit the predefined
|
||||
configuration to request specific warnings.
|
||||
|
||||
\li \uicontrol {Pedantic Warnings} uses the \c -Wpendantic
|
||||
option that requests all the warnings demanded by strict
|
||||
ISO C and ISO C++.
|
||||
\li In the \uicontrol {Clang-Tidy} tab, select the checks to
|
||||
perform.
|
||||
|
||||
\li \uicontrol {Warnings for Questionable Constructs} combines
|
||||
the \c -Wall and \c -Wextra options to request all warnings
|
||||
about easily avoidable questionable constructions and some
|
||||
additional warnings.
|
||||
\image qtcreator-clang-tidy.png
|
||||
|
||||
\li \uicontrol {Warnings for Almost Everything} uses the \c
|
||||
-Weverything option with negative options to suppress some
|
||||
warnings.
|
||||
\li In the \uicontrol Clazy tab, select the level of Clazy
|
||||
checks to perform.
|
||||
|
||||
\image qtcreator-clazy.png
|
||||
|
||||
\endlist
|
||||
|
||||
You can edit the predefined configurations to request specific
|
||||
warnings beginning with \c -W. Each of these warnings also has a
|
||||
negative version that begins with \c -Wno. Keep in mind that some
|
||||
options turn on other options. For more information, see
|
||||
\l{https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html}
|
||||
{Options to Request or Suppress Warnings} or the GCC or Clang
|
||||
manual pages.
|
||||
|
||||
\li In the \uicontrol {Clang Plugins} field, select the Clang-Tidy and
|
||||
Clazy checks to perform.
|
||||
|
||||
\endlist
|
||||
|
||||
\section1 Specifying Clang Settings at Project Level
|
||||
|
||||
You can specify Clang settings at project level in the build settings of
|
||||
the project by selecting \uicontrol Projects >
|
||||
\uicontrol {Clang Code Model}. In addition to configuring the diagnostics,
|
||||
|
||||
@@ -38,15 +38,32 @@ qdoc2tasks.pl - Convert qdoc warnings into Qt Creator task files.
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $lastDiagnostic;
|
||||
|
||||
while (my $line = <STDIN>) {
|
||||
chomp($line);
|
||||
# --- extract file name based matching:
|
||||
# Qt 5.10: D:/.../qaxbase.cpp:3231: warning: Cannot tie this documentation to anything
|
||||
# Qt 5.11: D:/.../qaxbase.cpp:3231: (qdoc) warning: Cannot tie this documentation to anything
|
||||
if ($line =~ /^(..[^:]*):(\d+): (?:\(qdoc\) )?warning: (.*)$/) {
|
||||
if (defined($lastDiagnostic)) {
|
||||
print $lastDiagnostic, "\n";
|
||||
$lastDiagnostic = undef;
|
||||
}
|
||||
my $fileName = $1;
|
||||
my $lineNumber = $2;
|
||||
my $text = $3;
|
||||
print $fileName, "\t", $lineNumber, "\twarn\t", $text,"\n";
|
||||
my $message = $fileName . "\t" . $lineNumber . "\twarn\t" . $text;
|
||||
if (index($message, 'clang found diagnostics parsing') >= 0) {
|
||||
$lastDiagnostic = $message;
|
||||
} else {
|
||||
print $message, "\n";
|
||||
}
|
||||
} elsif (defined($lastDiagnostic) && $line =~ /^ /) {
|
||||
$line =~ s/^\s+//;
|
||||
$line =~ s/\s+$//;
|
||||
$lastDiagnostic .= ' ' . $line;
|
||||
}
|
||||
}
|
||||
|
||||
print $lastDiagnostic, "\n" if defined($lastDiagnostic);
|
||||
|
||||
54
scripts/sphinx2tasks.pl
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
############################################################################
|
||||
#
|
||||
# Copyright (C) 2018 The Qt Company Ltd.
|
||||
# Contact: https://www.qt.io/licensing/
|
||||
#
|
||||
# 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 The Qt Company. For licensing terms
|
||||
# and conditions see https://www.qt.io/terms-conditions. For further
|
||||
# information use the contact form at https://www.qt.io/contact-us.
|
||||
#
|
||||
# GNU General Public License Usage
|
||||
# Alternatively, this file may be used under the terms of the GNU
|
||||
# General Public License version 3 as published by the Free Software
|
||||
# Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
# included in the packaging of this file. Please review the following
|
||||
# information to ensure the GNU General Public License requirements will
|
||||
# be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
=head1 NAME
|
||||
|
||||
sphinx2tasks.pl - Convert sphinx (Python documentation) warnings into Qt Creator task files.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
sphinx2tasks.pl < logfile > taskfile
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
while (my $line = <STDIN>) {
|
||||
chomp($line);
|
||||
# Strip terminal control characters
|
||||
my $len = length($line);
|
||||
$line = substr($line, 5, $len - 17) if ($len > 0 && ord(substr($line, 0, 1)) == 0x1B);
|
||||
# --- extract file name based matching:
|
||||
# file.rst:698: WARNING: undefined label: xquer (if the link....)
|
||||
if ($line =~ /^[^\/]*([^:]+\.rst):(\d*): WARNING: (.*)$/) {
|
||||
my $fileName = $1;
|
||||
my $lineNumber = $2 eq '' ? '1' : $2;
|
||||
my $text = $3;
|
||||
print $fileName, "\t", $lineNumber, "\twarn\t", $text,"\n";
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,13 @@
|
||||
"Qt.labs.settings 1.0",
|
||||
"Qt.labs.platform 1.0",
|
||||
"Qt.WebSockets 1.0",
|
||||
"Qt3D.Animation 2.9",
|
||||
"Qt3D.Core 2.0",
|
||||
"Qt3D.Extras 2.0",
|
||||
"Qt3D.Input 2.0",
|
||||
"Qt3D.Logic 2.0",
|
||||
"Qt3D.Render 2.0",
|
||||
"Qt3D.Scene2D 2.9",
|
||||
"QtAudioEngine 1.0",
|
||||
"QtBluetooth 5.0",
|
||||
"QtBluetooth 5.2",
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
#include <QQmlComponent>
|
||||
#include <QFileInfo>
|
||||
|
||||
#include <private/qabstractfileengine_p.h>
|
||||
#include <private/qfsfileengine_p.h>
|
||||
|
||||
#include <private/qquickdesignersupport_p.h>
|
||||
#include <private/qquickdesignersupportmetainfo_p.h>
|
||||
#include <private/qquickdesignersupportitems_p.h>
|
||||
@@ -419,9 +422,57 @@ ComponentCompleteDisabler::~ComponentCompleteDisabler()
|
||||
DesignerSupport::enableComponentComplete();
|
||||
}
|
||||
|
||||
class QrcEngineHandler : public QAbstractFileEngineHandler
|
||||
{
|
||||
public:
|
||||
QAbstractFileEngine *create(const QString &fileName) const;
|
||||
};
|
||||
|
||||
QAbstractFileEngine *QrcEngineHandler::create(const QString &fileName) const
|
||||
{
|
||||
if (fileName.startsWith(":/qt-project.org"))
|
||||
return nullptr;
|
||||
|
||||
if (fileName.startsWith(":/qtquickplugin"))
|
||||
return nullptr;
|
||||
|
||||
if (fileName.startsWith(":/")) {
|
||||
const QStringList searchPaths = qmlDesignerRCPath().split(';');
|
||||
foreach (const QString &qrcPath, searchPaths) {
|
||||
const QStringList qrcDefintion = qrcPath.split('=');
|
||||
if (qrcDefintion.count() == 2) {
|
||||
QString fixedPath = fileName;
|
||||
fixedPath.replace(":" + qrcDefintion.first(), qrcDefintion.last() + '/');
|
||||
|
||||
if (QFileInfo::exists(fixedPath)) {
|
||||
fixedPath.replace("//", "/");
|
||||
fixedPath.replace('\\', '/');
|
||||
return new QFSFileEngine(fixedPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static QrcEngineHandler* s_qrcEngineHandler = nullptr;
|
||||
|
||||
class EngineHandlerDeleter
|
||||
{
|
||||
public:
|
||||
EngineHandlerDeleter()
|
||||
{}
|
||||
~EngineHandlerDeleter()
|
||||
{ delete s_qrcEngineHandler; }
|
||||
};
|
||||
|
||||
void registerFixResourcePathsForObjectCallBack()
|
||||
{
|
||||
QQuickDesignerSupportItems::registerFixResourcePathsForObjectCallBack(&fixResourcePathsForObject);
|
||||
static EngineHandlerDeleter deleter;
|
||||
|
||||
if (!s_qrcEngineHandler)
|
||||
s_qrcEngineHandler = new QrcEngineHandler();
|
||||
}
|
||||
|
||||
} // namespace QmlPrivateGate
|
||||
|
||||
@@ -162,6 +162,7 @@ Welcome_ButtonBackgroundColor=normalBackground
|
||||
Welcome_DividerColor=ff555555
|
||||
Welcome_HoverColor=ff444444
|
||||
Welcome_LinkColor=ff78bb39
|
||||
Welcome_DisabledLinkColor=textDisabled
|
||||
|
||||
Timeline_TextColor=text
|
||||
Timeline_BackgroundColor1=normalBackground
|
||||
|
||||
@@ -154,6 +154,7 @@ Welcome_ButtonBackgroundColor=ffdfdfdf
|
||||
Welcome_DividerColor=ffd6d6d6
|
||||
Welcome_HoverColor=ffe8e8e8
|
||||
Welcome_LinkColor=ff5caa15
|
||||
Welcome_DisabledLinkColor=textDisabled
|
||||
|
||||
Timeline_TextColor=darkText
|
||||
Timeline_BackgroundColor1=ffffffff
|
||||
|
||||
@@ -167,6 +167,7 @@ Welcome_ButtonBackgroundColor=normalBackground
|
||||
Welcome_DividerColor=ff555555
|
||||
Welcome_HoverColor=ff444444
|
||||
Welcome_LinkColor=ff7fc63c
|
||||
Welcome_DisabledLinkColor=textDisabled
|
||||
|
||||
Timeline_TextColor=text
|
||||
Timeline_BackgroundColor1=normalBackground
|
||||
|
||||
@@ -165,6 +165,7 @@ Welcome_ButtonBackgroundColor=normalBackground
|
||||
Welcome_DividerColor=ffd6d6d6
|
||||
Welcome_HoverColor=fff6f6f6
|
||||
Welcome_LinkColor=ff5caa15
|
||||
Welcome_DisabledLinkColor=textDisabled
|
||||
|
||||
Timeline_TextColor=text
|
||||
Timeline_BackgroundColor1=normalBackground
|
||||
|
||||
@@ -163,6 +163,7 @@ Welcome_ButtonBackgroundColor=normalBackground
|
||||
Welcome_DividerColor=ffd6d6d6
|
||||
Welcome_HoverColor=fff6f6f6
|
||||
Welcome_LinkColor=ff5caa15
|
||||
Welcome_DisabledLinkColor=textDisabled
|
||||
|
||||
Timeline_TextColor=text
|
||||
Timeline_BackgroundColor1=normalBackground
|
||||
|
||||
9
share/qtcreator/translations/extract-snippets.xq
Normal file
@@ -0,0 +1,9 @@
|
||||
let $prefix := string("QT_TRANSLATE_NOOP3("TextEditor::Internal::Snippets", "")
|
||||
let $midfix := string("", "")
|
||||
let $suffix := concat("")", codepoints-to-string(10))
|
||||
for $file in tokenize($files, string("\|"))
|
||||
for $snippet in (doc($file)/*/snippet)
|
||||
let $group := fn:concat(string("group:'"), data($snippet/@group), string("' "))
|
||||
let $trigger := fn:concat(string("trigger:'"), data($snippet/@trigger), string("'"))
|
||||
where ($snippet/@complement)
|
||||
return fn:concat($prefix, data($snippet/@complement), $midfix, $group, $trigger, $suffix)
|
||||
@@ -27,6 +27,7 @@ JSONWIZARD_TR_H = $$OUT_PWD/jsonwizard_tr.h
|
||||
QMLWIZARD_TR_H = $$OUT_PWD/qmlwizard_tr.h
|
||||
QTQUICKWIZARD_TR_H = $$OUT_PWD/qtquickwizard_tr.h
|
||||
EXTERNALTOOLS_TR_H = $$OUT_PWD/externaltools_tr.h
|
||||
SNIPPETS_TR_H = $$OUT_PWD/snippets_tr.h
|
||||
|
||||
win32: \
|
||||
PREFIX = "file:///"
|
||||
@@ -48,12 +49,16 @@ QTQUICKWIZARD_FILES = \"$$join(QTQUICKWIZARD_FILES, "|$$PREFIX", "$$PREFIX")\"
|
||||
for(file, $$list($$files($$IDE_SOURCE_TREE/src/share/qtcreator/externaltools/*))):EXTERNALTOOLS_FILES += $$files($$file)
|
||||
EXTERNALTOOLS_FILES = \"$$join(EXTERNALTOOLS_FILES, "|$$PREFIX", "$$PREFIX")\"
|
||||
|
||||
for(file, $$list($$files($$IDE_SOURCE_TREE/share/qtcreator/snippets/*))):SNIPPETS_FILES += $$files($$file)
|
||||
SNIPPETS_FILES = \"$$join(SNIPPETS_FILES, "|$$PREFIX", "$$PREFIX")\"
|
||||
|
||||
extract.commands += \
|
||||
$$XMLPATTERNS -output $$MIME_TR_H -param files=$$MIMETYPES_FILES $$PWD/extract-mimetypes.xq $$escape_expand(\\n\\t) \
|
||||
$$XMLPATTERNS -output $$CUSTOMWIZARD_TR_H -param files=$$CUSTOMWIZARD_FILES $$PWD/extract-customwizards.xq $$escape_expand(\\n\\t) \
|
||||
$$XMLPATTERNS -output $$QMLWIZARD_TR_H -param files=$$QMLWIZARD_FILES $$PWD/extract-qmlwizards.xq $$escape_expand(\\n\\t) \
|
||||
$$XMLPATTERNS -output $$QTQUICKWIZARD_TR_H -param files=$$QTQUICKWIZARD_FILES $$PWD/extract-qtquickwizards.xq $$escape_expand(\\n\\t) \
|
||||
$$XMLPATTERNS -output $$EXTERNALTOOLS_TR_H -param files=$$EXTERNALTOOLS_FILES $$PWD/extract-externaltools.xq $$escape_expand(\\n\\t) \
|
||||
$$XMLPATTERNS -output $$SNIPPETS_TR_H -param files=$$SNIPPETS_FILES $$PWD/extract-snippets.xq $$escape_expand(\\n\\t) \
|
||||
$(QMAKE) -o Makefile.jsonwizard JSONWIZARD_TR_H=\"$$JSONWIZARD_TR_H\" TOP_LEVEL=\"$$IDE_SOURCE_TREE/share/qtcreator/templates/wizards\" $$PWD/jsonwizard_tr.pro
|
||||
QMAKE_EXTRA_TARGETS += extract
|
||||
|
||||
@@ -77,12 +82,12 @@ files = $$files($$PWD/*_??.ts) $$PWD/qtcreator_untranslated.ts
|
||||
for(file, files) {
|
||||
lang = $$replace(file, .*_([^/]*)\\.ts, \\1)
|
||||
v = ts-$${lang}.commands
|
||||
$$v = cd $$wd && $$LUPDATE $$include_options $$sources $$MIME_TR_H $$CUSTOMWIZARD_TR_H $$JSONWIZARD_TR_H $$QMLWIZARD_TR_H $$QTQUICKWIZARD_TR_H $$EXTERNALTOOLS_TR_H -ts $$file
|
||||
$$v = cd $$wd && $$LUPDATE $$include_options $$sources $$MIME_TR_H $$CUSTOMWIZARD_TR_H $$JSONWIZARD_TR_H $$QMLWIZARD_TR_H $$QTQUICKWIZARD_TR_H $$EXTERNALTOOLS_TR_H $$SNIPPETS_TR_H -ts $$file
|
||||
v = ts-$${lang}.depends
|
||||
$$v = extract
|
||||
QMAKE_EXTRA_TARGETS += ts-$$lang
|
||||
}
|
||||
ts-all.commands = cd $$wd && $$LUPDATE $$include_options $$sources $$MIME_TR_H $$CUSTOMWIZARD_TR_H $$JSONWIZARD_TR_H $$QMLWIZARD_TR_H $$QTQUICKWIZARD_TR_H $$EXTERNALTOOLS_TR_H -ts $$files
|
||||
ts-all.commands = cd $$wd && $$LUPDATE $$include_options $$sources $$MIME_TR_H $$CUSTOMWIZARD_TR_H $$JSONWIZARD_TR_H $$QMLWIZARD_TR_H $$QTQUICKWIZARD_TR_H $$EXTERNALTOOLS_TR_H SNIPPETS_TR_H -ts $$files
|
||||
ts-all.depends = extract
|
||||
QMAKE_EXTRA_TARGETS += ts-all
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ Item {
|
||||
signal toggleSelectionLocked
|
||||
signal clearSelection
|
||||
|
||||
width: col.width + 25
|
||||
width: col.width + 20
|
||||
height: hasContents ? contentArea.height + titleBar.height : 0
|
||||
|
||||
function hide() {
|
||||
@@ -75,9 +75,11 @@ Item {
|
||||
|
||||
ListModel {
|
||||
id: eventInfo
|
||||
property bool ready: false
|
||||
}
|
||||
|
||||
function showInfo(model, item) {
|
||||
eventInfo.ready = false;
|
||||
// make sure we don't accidentally save the old text for the new event
|
||||
noteEdit.focus = false;
|
||||
|
||||
@@ -94,6 +96,7 @@ Item {
|
||||
eventInfo.append({content : eventData[k]});
|
||||
}
|
||||
}
|
||||
eventInfo.ready = true;
|
||||
hasContents = eventInfo.count > 0;
|
||||
|
||||
var location = timelineModel.location(selectedItem)
|
||||
@@ -175,21 +178,20 @@ Item {
|
||||
y: 5
|
||||
spacing: 5
|
||||
columns: 2
|
||||
property int minimumWidth: {
|
||||
property int minimumWidth: 150
|
||||
|
||||
onChildrenChanged: {
|
||||
// max(width of longest label * 2, 150)
|
||||
var result = 150;
|
||||
for (var i = 0; i < children.length; i += 2)
|
||||
result = Math.max(children[i].implicitWidth * 2 + spacing, result);
|
||||
return result + 20;
|
||||
}
|
||||
|
||||
onMinimumWidthChanged: {
|
||||
minimumWidth = result + 20;
|
||||
if (dragHandle.x < minimumWidth)
|
||||
dragHandle.x = minimumWidth;
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: eventInfo
|
||||
model: eventInfo.ready ? eventInfo : 0
|
||||
Detail {
|
||||
valueWidth: (dragHandle.x - col.minimumWidth / 2 - col.spacing)
|
||||
isLabel: index % 2 === 0
|
||||
|
||||
@@ -114,16 +114,10 @@ QColor StyleHelper::m_requestedBaseColor;
|
||||
|
||||
QColor StyleHelper::baseColor(bool lightColored)
|
||||
{
|
||||
static const QColor windowColor = QApplication::palette().color(QPalette::Window);
|
||||
static const bool windowColorAsBase = creatorTheme()->flag(Theme::WindowColorAsBase);
|
||||
if (windowColorAsBase) {
|
||||
static const QColor windowColor = QApplication::palette().color(QPalette::Window);
|
||||
return windowColor;
|
||||
}
|
||||
|
||||
if (!lightColored)
|
||||
return m_baseColor;
|
||||
else
|
||||
return m_baseColor.lighter(230);
|
||||
return (lightColored || windowColorAsBase) ? windowColor : m_baseColor;
|
||||
}
|
||||
|
||||
QColor StyleHelper::highlightColor(bool lightColored)
|
||||
|
||||
@@ -252,6 +252,7 @@ public:
|
||||
Welcome_DividerColor,
|
||||
Welcome_LinkColor,
|
||||
Welcome_HoverColor,
|
||||
Welcome_DisabledLinkColor,
|
||||
|
||||
/* Timeline Library */
|
||||
Timeline_TextColor,
|
||||
|
||||
@@ -326,7 +326,7 @@ void QtTestOutputReader::processPlainTextOutput(const QByteArray &outputLine)
|
||||
static QRegExp finish("^[*]{9} Finished testing of (.*) [*]{9}$");
|
||||
|
||||
static QRegExp result("^(PASS |FAIL! |XFAIL |XPASS |SKIP |BPASS |BFAIL |RESULT "
|
||||
"|INFO |QWARN |WARNING|QDEBUG ): (.*)$");
|
||||
"|INFO |QWARN |WARNING|QDEBUG |QSYSTEM): (.*)$");
|
||||
|
||||
static QRegExp benchDetails("^\\s+([\\d,.]+ .* per iteration \\(total: [\\d,.]+, iterations: \\d+\\))$");
|
||||
static QRegExp locationUnix("^ Loc: \\[(.*)\\]$");
|
||||
|
||||
@@ -85,7 +85,7 @@ Result::Type TestResult::resultFromString(const QString &resultString)
|
||||
return Result::MessageWarn;
|
||||
if (resultString == "qfatal")
|
||||
return Result::MessageFatal;
|
||||
if (resultString == "system")
|
||||
if ((resultString == "system") || (resultString == "qsystem"))
|
||||
return Result::MessageSystem;
|
||||
if (resultString == "bpass")
|
||||
return Result::BlacklistedPass;
|
||||
|
||||
@@ -114,7 +114,6 @@ void TestResultItem::updateResult(bool &changed, Result::Type addedChildType)
|
||||
switch (addedChildType) {
|
||||
case Result::Fail:
|
||||
case Result::MessageFatal:
|
||||
case Result::MessageSystem:
|
||||
case Result::UnexpectedPass:
|
||||
case Result::MessageTestCaseFail:
|
||||
newResult = (old == Result::MessageTestCaseSuccessWarn) ? Result::MessageTestCaseFailWarn
|
||||
@@ -125,6 +124,7 @@ void TestResultItem::updateResult(bool &changed, Result::Type addedChildType)
|
||||
break;
|
||||
case Result::ExpectedFail:
|
||||
case Result::MessageWarn:
|
||||
case Result::MessageSystem:
|
||||
case Result::Skip:
|
||||
case Result::BlacklistedFail:
|
||||
case Result::BlacklistedPass:
|
||||
@@ -377,12 +377,16 @@ void TestResultFilterModel::toggleTestResultType(Result::Type type)
|
||||
m_enabled.remove(Result::MessageTestCaseEnd);
|
||||
if (type == Result::MessageDebug)
|
||||
m_enabled.remove(Result::MessageInfo);
|
||||
if (type == Result::MessageWarn)
|
||||
m_enabled.remove(Result::MessageSystem);
|
||||
} else {
|
||||
m_enabled.insert(type);
|
||||
if (type == Result::MessageInternal)
|
||||
m_enabled.insert(Result::MessageTestCaseEnd);
|
||||
if (type == Result::MessageDebug)
|
||||
m_enabled.insert(Result::MessageInfo);
|
||||
if (type == Result::MessageWarn)
|
||||
m_enabled.insert(Result::MessageSystem);
|
||||
}
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ class BookmarkManager;
|
||||
|
||||
class BookmarkFilter : public Core::ILocatorFilter
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit BookmarkFilter(BookmarkManager *manager);
|
||||
QList<Core::LocatorFilterEntry> matchesFor(QFutureInterface<Core::LocatorFilterEntry> &future,
|
||||
|
||||
@@ -47,32 +47,30 @@ void RefactoringEngine::startLocalRenaming(const CppTools::CursorInEditor &data,
|
||||
if (!processor)
|
||||
return defaultCallback();
|
||||
|
||||
QFuture<CppTools::CursorInfo> future = processor->requestLocalReferences(data.cursor());
|
||||
if (future.isCanceled())
|
||||
QFuture<CppTools::CursorInfo> cursorFuture = processor->requestLocalReferences(data.cursor());
|
||||
if (cursorFuture.isCanceled())
|
||||
return defaultCallback();
|
||||
|
||||
// QFuture::waitForFinished seems to block completely, not even
|
||||
// allowing to process events from QLocalSocket.
|
||||
while (!future.isFinished()) {
|
||||
if (future.isCanceled())
|
||||
QObject::connect(&m_watcher, &FutureCursorWatcher::finished, [=]() {
|
||||
const CppTools::CursorInfo info = m_watcher.result();
|
||||
if (info.useRanges.empty())
|
||||
return defaultCallback();
|
||||
|
||||
QTC_ASSERT(startRevision == data.cursor().document()->revision(), return;);
|
||||
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
}
|
||||
QTextCursor cursor = Utils::Text::wordStartCursor(data.cursor());
|
||||
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor,
|
||||
info.useRanges.first().length);
|
||||
const QString symbolName = cursor.selectedText();
|
||||
ClangBackEnd::SourceLocationsContainer container;
|
||||
for (auto& use : info.useRanges) {
|
||||
container.insertSourceLocation(ClangBackEnd::FilePathId(),
|
||||
use.line,
|
||||
use.column,
|
||||
use.length);
|
||||
}
|
||||
renameSymbolsCallback(symbolName, container, data.cursor().document()->revision());
|
||||
});
|
||||
|
||||
const CppTools::CursorInfo info = future.result();
|
||||
if (info.useRanges.empty())
|
||||
return defaultCallback();
|
||||
|
||||
QTextCursor cursor = Utils::Text::wordStartCursor(data.cursor());
|
||||
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor,
|
||||
info.useRanges.first().length);
|
||||
const QString symbolName = cursor.selectedText();
|
||||
ClangBackEnd::SourceLocationsContainer container;
|
||||
for (auto& use : info.useRanges)
|
||||
container.insertSourceLocation(ClangBackEnd::FilePathId(), use.line, use.column, use.length);
|
||||
renameSymbolsCallback(symbolName, container, data.cursor().document()->revision());
|
||||
m_watcher.setFuture(cursorFuture);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <cpptools/refactoringengineinterface.h>
|
||||
#include <cpptools/cppcursorinfo.h>
|
||||
|
||||
#include <QFutureWatcher>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
class RefactoringClientInterface;
|
||||
@@ -49,6 +52,10 @@ public:
|
||||
{
|
||||
return Link();
|
||||
}
|
||||
|
||||
private:
|
||||
using FutureCursorWatcher = QFutureWatcher<CppTools::CursorInfo>;
|
||||
FutureCursorWatcher m_watcher;
|
||||
};
|
||||
|
||||
} // namespace ClangRefactoring
|
||||
|
||||
@@ -76,9 +76,8 @@ void DocumentModelPrivate::addEntry(DocumentModel::Entry *entry)
|
||||
fixedPath = DocumentManager::filePathKey(fileName.toString(), DocumentManager::ResolveLinks);
|
||||
|
||||
// replace a non-loaded entry (aka 'suspended') if possible
|
||||
int previousIndex = indexOfFilePath(fileName);
|
||||
if (previousIndex >= 0) {
|
||||
DocumentModel::Entry *previousEntry = m_entries.at(previousIndex);
|
||||
DocumentModel::Entry *previousEntry = DocumentModel::entryForFilePath(fileName);
|
||||
if (previousEntry) {
|
||||
const bool replace = !entry->isSuspended && previousEntry->isSuspended;
|
||||
if (replace) {
|
||||
previousEntry->isSuspended = false;
|
||||
@@ -180,13 +179,16 @@ QIcon DocumentModelPrivate::lockedIcon()
|
||||
return icon;
|
||||
}
|
||||
|
||||
int DocumentModelPrivate::indexOfFilePath(const Utils::FileName &filePath) const
|
||||
Utils::optional<int> DocumentModelPrivate::indexOfFilePath(const Utils::FileName &filePath) const
|
||||
{
|
||||
if (filePath.isEmpty())
|
||||
return -1;
|
||||
return Utils::nullopt;
|
||||
const QString fixedPath = DocumentManager::filePathKey(filePath.toString(),
|
||||
DocumentManager::ResolveLinks);
|
||||
return m_entries.indexOf(m_entryByFixedPath.value(fixedPath));
|
||||
const int index = m_entries.indexOf(m_entryByFixedPath.value(fixedPath));
|
||||
if (index < 0)
|
||||
return Utils::nullopt;
|
||||
return index;
|
||||
}
|
||||
|
||||
void DocumentModelPrivate::removeDocument(int idx)
|
||||
@@ -210,11 +212,14 @@ void DocumentModelPrivate::removeDocument(int idx)
|
||||
delete entry;
|
||||
}
|
||||
|
||||
int DocumentModelPrivate::indexOfDocument(IDocument *document) const
|
||||
Utils::optional<int> DocumentModelPrivate::indexOfDocument(IDocument *document) const
|
||||
{
|
||||
return Utils::indexOf(m_entries, [&document](DocumentModel::Entry *entry) {
|
||||
const int index = Utils::indexOf(m_entries, [&document](DocumentModel::Entry *entry) {
|
||||
return entry->document == document;
|
||||
});
|
||||
if (index < 0)
|
||||
return Utils::nullopt;
|
||||
return index;
|
||||
}
|
||||
|
||||
Qt::ItemFlags DocumentModelPrivate::flags(const QModelIndex &index) const
|
||||
@@ -292,14 +297,14 @@ void DocumentModelPrivate::itemChanged()
|
||||
{
|
||||
IDocument *document = qobject_cast<IDocument *>(sender());
|
||||
|
||||
int idx = indexOfDocument(document);
|
||||
if (idx < 0)
|
||||
const Utils::optional<int> idx = indexOfDocument(document);
|
||||
if (!idx)
|
||||
return;
|
||||
const QString fileName = document->filePath().toString();
|
||||
QString fixedPath;
|
||||
if (!fileName.isEmpty())
|
||||
fixedPath = DocumentManager::filePathKey(fileName, DocumentManager::ResolveLinks);
|
||||
DocumentModel::Entry *entry = m_entries.at(idx);
|
||||
DocumentModel::Entry *entry = m_entries.at(idx.value());
|
||||
bool found = false;
|
||||
// The entry's fileName might have changed, so find the previous fileName that was associated
|
||||
// with it and remove it, then add the new fileName.
|
||||
@@ -316,8 +321,8 @@ void DocumentModelPrivate::itemChanged()
|
||||
}
|
||||
if (!found && !fixedPath.isEmpty())
|
||||
m_entryByFixedPath[fixedPath] = entry;
|
||||
if (!disambiguateDisplayNames(m_entries.at(idx))) {
|
||||
QModelIndex mindex = index(idx + 1/*<no document>*/, 0);
|
||||
if (!disambiguateDisplayNames(m_entries.at(idx.value()))) {
|
||||
QModelIndex mindex = index(idx.value() + 1/*<no document>*/, 0);
|
||||
emit dataChanged(mindex, mindex);
|
||||
}
|
||||
}
|
||||
@@ -507,11 +512,16 @@ QList<IEditor *> DocumentModel::editorsForDocuments(const QList<IDocument *> &do
|
||||
return result;
|
||||
}
|
||||
|
||||
int DocumentModel::indexOfDocument(IDocument *document)
|
||||
Utils::optional<int> DocumentModel::indexOfDocument(IDocument *document)
|
||||
{
|
||||
return d->indexOfDocument(document);
|
||||
}
|
||||
|
||||
Utils::optional<int> DocumentModel::indexOfFilePath(const Utils::FileName &filePath)
|
||||
{
|
||||
return d->indexOfFilePath(filePath);
|
||||
}
|
||||
|
||||
DocumentModel::Entry *DocumentModel::entryForDocument(IDocument *document)
|
||||
{
|
||||
return Utils::findOrDefault(d->m_entries,
|
||||
@@ -520,10 +530,10 @@ DocumentModel::Entry *DocumentModel::entryForDocument(IDocument *document)
|
||||
|
||||
DocumentModel::Entry *DocumentModel::entryForFilePath(const Utils::FileName &filePath)
|
||||
{
|
||||
const int index = d->indexOfFilePath(filePath);
|
||||
if (index < 0)
|
||||
const Utils::optional<int> index = d->indexOfFilePath(filePath);
|
||||
if (!index)
|
||||
return nullptr;
|
||||
return d->m_entries.at(index);
|
||||
return d->m_entries.at(index.value());
|
||||
}
|
||||
|
||||
QList<IDocument *> DocumentModel::openedDocuments()
|
||||
@@ -533,10 +543,10 @@ QList<IDocument *> DocumentModel::openedDocuments()
|
||||
|
||||
IDocument *DocumentModel::documentForFilePath(const QString &filePath)
|
||||
{
|
||||
const int index = d->indexOfFilePath(Utils::FileName::fromString(filePath));
|
||||
if (index < 0)
|
||||
return 0;
|
||||
return d->m_entries.at(index)->document;
|
||||
const Utils::optional<int> index = d->indexOfFilePath(Utils::FileName::fromString(filePath));
|
||||
if (!index)
|
||||
return nullptr;
|
||||
return d->m_entries.at(index.value())->document;
|
||||
}
|
||||
|
||||
QList<IEditor *> DocumentModel::editorsForFilePath(const QString &filePath)
|
||||
@@ -560,11 +570,14 @@ int DocumentModel::entryCount()
|
||||
return d->m_entries.count();
|
||||
}
|
||||
|
||||
int DocumentModel::rowOfDocument(IDocument *document)
|
||||
Utils::optional<int> DocumentModel::rowOfDocument(IDocument *document)
|
||||
{
|
||||
if (!document)
|
||||
return 0 /*<no document>*/;
|
||||
return indexOfDocument(document) + 1/*<no document>*/;
|
||||
const Utils::optional<int> index = indexOfDocument(document);
|
||||
if (index)
|
||||
return index.value() + 1/*correction for <no document>*/;
|
||||
return Utils::nullopt;
|
||||
}
|
||||
|
||||
QList<DocumentModel::Entry *> DocumentModel::entries()
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "../id.h"
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/optional.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAbstractItemModel;
|
||||
@@ -63,11 +64,12 @@ public:
|
||||
};
|
||||
|
||||
static Entry *entryAtRow(int row);
|
||||
static int rowOfDocument(IDocument *document);
|
||||
static Utils::optional<int> rowOfDocument(IDocument *document);
|
||||
|
||||
static int entryCount();
|
||||
static QList<Entry *> entries();
|
||||
static int indexOfDocument(IDocument *document);
|
||||
static Utils::optional<int> indexOfDocument(IDocument *document);
|
||||
static Utils::optional<int> indexOfFilePath(const Utils::FileName &filePath);
|
||||
static Entry *entryForDocument(IDocument *document);
|
||||
static Entry *entryForFilePath(const Utils::FileName &filePath);
|
||||
static QList<IDocument *> openedDocuments();
|
||||
|
||||
@@ -58,8 +58,8 @@ public:
|
||||
void addEntry(DocumentModel::Entry *entry);
|
||||
void removeDocument(int idx);
|
||||
|
||||
int indexOfFilePath(const Utils::FileName &filePath) const;
|
||||
int indexOfDocument(IDocument *document) const;
|
||||
Utils::optional<int> indexOfFilePath(const Utils::FileName &filePath) const;
|
||||
Utils::optional<int> indexOfDocument(IDocument *document) const;
|
||||
|
||||
bool disambiguateDisplayNames(DocumentModel::Entry *entry);
|
||||
|
||||
|
||||
@@ -268,11 +268,10 @@ void EditorView::updateEditorHistory(IEditor *editor, QList<EditLocation> &histo
|
||||
location.state = QVariant(state);
|
||||
|
||||
for (int i = 0; i < history.size(); ++i) {
|
||||
if (history.at(i).document == 0
|
||||
|| history.at(i).document == document
|
||||
){
|
||||
const EditLocation &item = history.at(i);
|
||||
if (item.document == document
|
||||
|| !DocumentModel::indexOfFilePath(FileName::fromString(item.fileName))) {
|
||||
history.removeAt(i--);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
history.prepend(location);
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/actionmanager/command.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QMenu>
|
||||
@@ -70,15 +71,15 @@ OpenEditorsWidget::~OpenEditorsWidget()
|
||||
|
||||
void OpenEditorsWidget::updateCurrentItem(IEditor *editor)
|
||||
{
|
||||
IDocument *document = editor ? editor->document() : 0;
|
||||
QModelIndex index = m_model->index(DocumentModel::indexOfDocument(document), 0);
|
||||
if (!index.isValid()) {
|
||||
if (!editor) {
|
||||
clearSelection();
|
||||
return;
|
||||
}
|
||||
setCurrentIndex(index);
|
||||
const Utils::optional<int> index = DocumentModel::indexOfDocument(editor->document());
|
||||
if (QTC_GUARD(index))
|
||||
setCurrentIndex(m_model->index(index.value(), 0));
|
||||
selectionModel()->select(currentIndex(),
|
||||
QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
|
||||
QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
|
||||
scrollTo(currentIndex());
|
||||
}
|
||||
|
||||
|
||||
@@ -320,7 +320,9 @@ void EditorToolBar::setMenuProvider(const EditorToolBar::MenuProvider &provider)
|
||||
void EditorToolBar::setCurrentEditor(IEditor *editor)
|
||||
{
|
||||
IDocument *document = editor ? editor->document() : 0;
|
||||
d->m_editorList->setCurrentIndex(DocumentModel::rowOfDocument(document));
|
||||
const Utils::optional<int> index = DocumentModel::rowOfDocument(document);
|
||||
if (QTC_GUARD(index))
|
||||
d->m_editorList->setCurrentIndex(index.value());
|
||||
|
||||
// If we never added the toolbar from the editor, we will never change
|
||||
// the editor, so there's no need to update the toolbar either.
|
||||
@@ -332,8 +334,11 @@ void EditorToolBar::setCurrentEditor(IEditor *editor)
|
||||
|
||||
void EditorToolBar::updateEditorListSelection(IEditor *newSelection)
|
||||
{
|
||||
if (newSelection)
|
||||
d->m_editorList->setCurrentIndex(DocumentModel::rowOfDocument(newSelection->document()));
|
||||
if (newSelection) {
|
||||
const Utils::optional<int> index = DocumentModel::rowOfDocument(newSelection->document());
|
||||
if (QTC_GUARD(index))
|
||||
d->m_editorList->setCurrentIndex(index.value());
|
||||
}
|
||||
}
|
||||
|
||||
void EditorToolBar::changeActiveEditor(int row)
|
||||
@@ -403,7 +408,9 @@ void EditorToolBar::updateDocumentStatus(IDocument *document)
|
||||
return;
|
||||
}
|
||||
|
||||
d->m_editorList->setCurrentIndex(DocumentModel::rowOfDocument(document));
|
||||
const Utils::optional<int> index = DocumentModel::rowOfDocument(document);
|
||||
if (QTC_GUARD(index))
|
||||
d->m_editorList->setCurrentIndex(index.value());
|
||||
|
||||
if (document->filePath().isEmpty()) {
|
||||
d->m_lockButton->setIcon(QIcon());
|
||||
|
||||
@@ -973,16 +973,12 @@ void FindToolBar::setBackward(bool backward)
|
||||
void FindToolBar::setLightColoredIcon(bool lightColored)
|
||||
{
|
||||
if (lightColored) {
|
||||
m_ui.findNextButton->setIcon(QIcon());
|
||||
m_ui.findNextButton->setArrowType(Qt::RightArrow);
|
||||
m_ui.findPreviousButton->setIcon(QIcon());
|
||||
m_ui.findPreviousButton->setArrowType(Qt::LeftArrow);
|
||||
m_ui.findNextButton->setIcon(Utils::Icons::NEXT.icon());
|
||||
m_ui.findPreviousButton->setIcon(Utils::Icons::PREV.icon());
|
||||
m_ui.close->setIcon(Utils::Icons::CLOSE_FOREGROUND.icon());
|
||||
} else {
|
||||
m_ui.findNextButton->setIcon(Utils::Icons::NEXT_TOOLBAR.icon());
|
||||
m_ui.findNextButton->setArrowType(Qt::NoArrow);
|
||||
m_ui.findPreviousButton->setIcon(Utils::Icons::PREV_TOOLBAR.icon());
|
||||
m_ui.findPreviousButton->setArrowType(Qt::NoArrow);
|
||||
m_ui.close->setIcon(Utils::Icons::CLOSE_TOOLBAR.icon());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,6 +157,7 @@ void HelpManager::registerDocumentationNow(QFutureInterface<bool> &futureInterfa
|
||||
|
||||
QHelpEngineCore helpEngine(collectionFilePath());
|
||||
bool docsChanged = false;
|
||||
QStringList nameSpaces = d->m_helpEngine->registeredDocumentations();
|
||||
for (const QString &file : files) {
|
||||
if (futureInterface.isCanceled())
|
||||
break;
|
||||
@@ -164,8 +165,9 @@ void HelpManager::registerDocumentationNow(QFutureInterface<bool> &futureInterfa
|
||||
const QString &nameSpace = helpEngine.namespaceName(file);
|
||||
if (nameSpace.isEmpty())
|
||||
continue;
|
||||
if (!helpEngine.registeredDocumentations().contains(nameSpace)) {
|
||||
if (!nameSpaces.contains(nameSpace)) {
|
||||
if (helpEngine.registerDocumentation(file)) {
|
||||
nameSpaces.append(nameSpace);
|
||||
docsChanged = true;
|
||||
} else {
|
||||
qWarning() << "Error registering namespace '" << nameSpace
|
||||
|
||||
@@ -288,6 +288,12 @@ void ManhattanStyle::polish(QWidget *widget)
|
||||
} else if (qobject_cast<QStatusBar*>(widget)) {
|
||||
widget->setFixedHeight(StyleHelper::navigationWidgetHeight() + 2);
|
||||
} else if (qobject_cast<QComboBox*>(widget)) {
|
||||
const bool isLightColored = lightColored(widget);
|
||||
QPalette palette = panelPalette(widget->palette(), isLightColored);
|
||||
if (!isLightColored)
|
||||
palette.setBrush(QPalette::All, QPalette::Foreground,
|
||||
creatorTheme()->color(Theme::ComboBoxTextColor));
|
||||
widget->setPalette(palette);
|
||||
widget->setMaximumHeight(StyleHelper::navigationWidgetHeight() - 2);
|
||||
widget->setAttribute(Qt::WA_Hover);
|
||||
}
|
||||
@@ -730,9 +736,9 @@ void ManhattanStyle::drawControl(ControlElement element, const QStyleOption *opt
|
||||
painter->setPen(StyleHelper::toolBarDropShadowColor());
|
||||
painter->drawText(editRect.adjusted(1, 0, -1, 0), Qt::AlignLeft | Qt::AlignVCenter, text);
|
||||
}
|
||||
painter->setPen(creatorTheme()->color((option->state & State_Enabled)
|
||||
? Theme::ComboBoxTextColor
|
||||
: Theme::IconsDisabledColor));
|
||||
painter->setPen((option->state & State_Enabled)
|
||||
? option->palette.color(QPalette::Foreground)
|
||||
: creatorTheme()->color(Theme::IconsDisabledColor));
|
||||
painter->drawText(editRect.adjusted(1, 0, -1, 0), Qt::AlignLeft | Qt::AlignVCenter, text);
|
||||
|
||||
painter->restore();
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace Internal {
|
||||
|
||||
class MenuBarFilter : public ILocatorFilter
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MenuBarFilter();
|
||||
|
||||
|
||||
@@ -255,7 +255,13 @@ void ClangDiagnosticConfigsWidget::syncOtherWidgetsToComboBox()
|
||||
? m_notAcceptedOptions.value(config.id())
|
||||
: config.clangOptions().join(QLatin1Char(' '));
|
||||
setDiagnosticOptions(options);
|
||||
m_clangBaseChecks->diagnosticOptionsTextEdit->setReadOnly(config.isReadOnly());
|
||||
m_clangBaseChecksWidget->setEnabled(!config.isReadOnly());
|
||||
|
||||
if (config.isReadOnly()) {
|
||||
m_ui->infoIcon->setPixmap(Utils::Icons::INFO.pixmap());
|
||||
m_ui->infoLabel->setText(tr("Copy this configuration to customize it."));
|
||||
m_ui->infoLabel->setStyleSheet(QString());
|
||||
}
|
||||
|
||||
syncClangTidyWidgets(config);
|
||||
syncClazyWidgets(config);
|
||||
@@ -326,14 +332,13 @@ void ClangDiagnosticConfigsWidget::setDiagnosticOptions(const QString &options)
|
||||
{
|
||||
if (options != m_clangBaseChecks->diagnosticOptionsTextEdit->document()->toPlainText()) {
|
||||
disconnectDiagnosticOptionsChanged();
|
||||
|
||||
m_clangBaseChecks->diagnosticOptionsTextEdit->document()->setPlainText(options);
|
||||
const QString errorMessage
|
||||
= validateDiagnosticOptions(normalizeDiagnosticInputOptions(options));
|
||||
updateValidityWidgets(errorMessage);
|
||||
|
||||
connectDiagnosticOptionsChanged();
|
||||
}
|
||||
|
||||
const QString errorMessage
|
||||
= validateDiagnosticOptions(normalizeDiagnosticInputOptions(options));
|
||||
updateValidityWidgets(errorMessage);
|
||||
}
|
||||
|
||||
void ClangDiagnosticConfigsWidget::updateValidityWidgets(const QString &errorMessage)
|
||||
@@ -350,9 +355,9 @@ void ClangDiagnosticConfigsWidget::updateValidityWidgets(const QString &errorMes
|
||||
styleSheet = "color: red;";
|
||||
}
|
||||
|
||||
m_ui->validationResultIcon->setPixmap(icon->pixmap());
|
||||
m_ui->validationResultLabel->setText(validationResult);
|
||||
m_ui->validationResultLabel->setStyleSheet(styleSheet);
|
||||
m_ui->infoIcon->setPixmap(icon->pixmap());
|
||||
m_ui->infoLabel->setText(validationResult);
|
||||
m_ui->infoLabel->setStyleSheet(styleSheet);
|
||||
}
|
||||
|
||||
void ClangDiagnosticConfigsWidget::connectClangTidyItemChanged()
|
||||
|
||||
@@ -47,16 +47,16 @@
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="validationResultIcon">
|
||||
<widget class="QLabel" name="infoIcon">
|
||||
<property name="text">
|
||||
<string>ValidationIcon</string>
|
||||
<string>InfoIcon</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="validationResultLabel">
|
||||
<widget class="QLabel" name="infoLabel">
|
||||
<property name="text">
|
||||
<string>ValidationText</string>
|
||||
<string>InfoText</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@@ -289,12 +289,12 @@ DiffEditor::DiffEditor()
|
||||
connect(m_viewSwitcherAction, &QAction::triggered, this, [this]() { showDiffView(nextView()); });
|
||||
}
|
||||
|
||||
void DiffEditor::setDocument(QSharedPointer<DiffEditorDocument>(doc))
|
||||
void DiffEditor::setDocument(QSharedPointer<DiffEditorDocument> doc)
|
||||
{
|
||||
QTC_ASSERT(m_document.isNull(), return);
|
||||
QTC_ASSERT(doc, return);
|
||||
|
||||
m_document = QSharedPointer<DiffEditorDocument>(doc);
|
||||
m_document = doc;
|
||||
|
||||
connect(m_descriptionWidget, &DescriptionEditorWidget::requestBranchList,
|
||||
m_document.data(), &DiffEditorDocument::requestMoreInformation);
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "diffeditorcontroller.h"
|
||||
|
||||
#include <coreplugin/editormanager/ieditor.h>
|
||||
#include <coreplugin/idocument.h>
|
||||
#include <utils/guard.h>
|
||||
|
||||
@@ -71,9 +71,10 @@ QString DiffEditorController::revisionFromDescription() const
|
||||
return m_document->description().mid(7, 12);
|
||||
}
|
||||
|
||||
QString DiffEditorController::makePatch(PatchOptions options) const
|
||||
QString DiffEditorController::makePatch(int fileIndex, int chunkIndex,
|
||||
PatchOptions options) const
|
||||
{
|
||||
return m_document->makePatch(m_diffFileIndex, m_chunkIndex,
|
||||
return m_document->makePatch(fileIndex, chunkIndex,
|
||||
options & Revert, options & AddPrefix);
|
||||
}
|
||||
|
||||
@@ -152,11 +153,27 @@ void DiffEditorController::reloadFinished(bool success)
|
||||
m_isReloading = false;
|
||||
}
|
||||
|
||||
void DiffEditorController::requestChunkActions(QMenu *menu, int diffFileIndex, int chunkIndex)
|
||||
void DiffEditorController::requestChunkActions(QMenu *menu, int fileIndex, int chunkIndex)
|
||||
{
|
||||
m_diffFileIndex = diffFileIndex;
|
||||
m_chunkIndex = chunkIndex;
|
||||
emit chunkActionsRequested(menu, diffFileIndex >= 0 && chunkIndex >= 0);
|
||||
emit chunkActionsRequested(menu, fileIndex, chunkIndex);
|
||||
}
|
||||
|
||||
bool DiffEditorController::chunkExists(int fileIndex, int chunkIndex) const
|
||||
{
|
||||
if (!m_document)
|
||||
return false;
|
||||
|
||||
if (fileIndex < 0 || chunkIndex < 0)
|
||||
return false;
|
||||
|
||||
if (fileIndex >= m_document->diffFiles().count())
|
||||
return false;
|
||||
|
||||
const FileData fileData = m_document->diffFiles().at(fileIndex);
|
||||
if (chunkIndex >= fileData.chunks.count())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace DiffEditor
|
||||
|
||||
@@ -59,16 +59,18 @@ public:
|
||||
AddPrefix = 2
|
||||
};
|
||||
Q_DECLARE_FLAGS(PatchOptions, PatchOption)
|
||||
QString makePatch(PatchOptions options) const;
|
||||
QString makePatch(int fileIndex, int chunkIndex, PatchOptions options) const;
|
||||
|
||||
static Core::IDocument *findOrCreateDocument(const QString &vcsId,
|
||||
const QString &displayName);
|
||||
static DiffEditorController *controller(Core::IDocument *document);
|
||||
|
||||
void branchesReceived(const QString &branches);
|
||||
void requestChunkActions(QMenu *menu, int fileIndex, int chunkIndex);
|
||||
bool chunkExists(int fileIndex, int chunkIndex) const;
|
||||
|
||||
signals:
|
||||
void chunkActionsRequested(QMenu *menu, bool isValid);
|
||||
void chunkActionsRequested(QMenu *menu, int fileIndex, int chunkIndex);
|
||||
void requestInformationForCommit(const QString &revision);
|
||||
|
||||
protected:
|
||||
@@ -87,15 +89,14 @@ protected:
|
||||
|
||||
private:
|
||||
void requestMoreInformation();
|
||||
void requestChunkActions(QMenu *menu, int diffFileIndex, int chunkIndex);
|
||||
|
||||
Internal::DiffEditorDocument *const m_document;
|
||||
|
||||
bool m_isReloading = false;
|
||||
int m_diffFileIndex = -1;
|
||||
int m_chunkIndex = -1;
|
||||
|
||||
friend class Internal::DiffEditorDocument;
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(DiffEditorController::PatchOptions)
|
||||
|
||||
} // namespace DiffEditor
|
||||
|
||||
@@ -71,8 +71,6 @@ void DiffEditorDocument::setController(DiffEditorController *controller)
|
||||
m_controller = controller;
|
||||
|
||||
if (m_controller) {
|
||||
connect(this, &DiffEditorDocument::chunkActionsRequested,
|
||||
m_controller, &DiffEditorController::requestChunkActions);
|
||||
connect(this, &DiffEditorDocument::requestMoreInformation,
|
||||
m_controller, &DiffEditorController::requestMoreInformation);
|
||||
}
|
||||
|
||||
@@ -90,7 +90,6 @@ signals:
|
||||
void temporaryStateChanged();
|
||||
void documentChanged();
|
||||
void descriptionChanged();
|
||||
void chunkActionsRequested(QMenu *menu, int diffFileIndex, int chunkIndex);
|
||||
void requestMoreInformation();
|
||||
|
||||
private:
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "diffeditorwidgetcontroller.h"
|
||||
#include "diffeditorconstants.h"
|
||||
#include "diffeditorcontroller.h"
|
||||
#include "diffeditordocument.h"
|
||||
|
||||
#include <coreplugin/documentmanager.h>
|
||||
@@ -122,11 +123,14 @@ void DiffEditorWidgetController::hideProgress()
|
||||
m_progressIndicator->hide();
|
||||
}
|
||||
|
||||
void DiffEditorWidgetController::patch(bool revert)
|
||||
void DiffEditorWidgetController::patch(bool revert, int fileIndex, int chunkIndex)
|
||||
{
|
||||
if (!m_document)
|
||||
return;
|
||||
|
||||
if (!chunkExists(fileIndex, chunkIndex))
|
||||
return;
|
||||
|
||||
const QString title = revert ? tr("Revert Chunk") : tr("Apply Chunk");
|
||||
const QString question = revert
|
||||
? tr("Would you like to revert the chunk?")
|
||||
@@ -138,7 +142,7 @@ void DiffEditorWidgetController::patch(bool revert)
|
||||
return;
|
||||
}
|
||||
|
||||
const FileData fileData = m_contextFileData.at(m_contextMenuFileIndex);
|
||||
const FileData fileData = m_contextFileData.at(fileIndex);
|
||||
const QString fileName = revert
|
||||
? fileData.rightFileInfo.fileName
|
||||
: fileData.leftFileInfo.fileName;
|
||||
@@ -154,7 +158,7 @@ void DiffEditorWidgetController::patch(bool revert)
|
||||
if (patchBehaviour == DiffFileInfo::PatchFile) {
|
||||
const int strip = m_document->baseDirectory().isEmpty() ? -1 : 0;
|
||||
|
||||
const QString patch = m_document->makePatch(m_contextMenuFileIndex, m_contextMenuChunkIndex, revert);
|
||||
const QString patch = m_document->makePatch(fileIndex, chunkIndex, revert);
|
||||
|
||||
if (patch.isEmpty())
|
||||
return;
|
||||
@@ -179,8 +183,8 @@ void DiffEditorWidgetController::patch(bool revert)
|
||||
const QString contentsCopyFileName = contentsCopy.fileName();
|
||||
const QString contentsCopyDir = QFileInfo(contentsCopyFileName).absolutePath();
|
||||
|
||||
const QString patch = m_document->makePatch(m_contextMenuFileIndex,
|
||||
m_contextMenuChunkIndex, revert, false, QFileInfo(contentsCopyFileName).fileName());
|
||||
const QString patch = m_document->makePatch(fileIndex,
|
||||
chunkIndex, revert, false, QFileInfo(contentsCopyFileName).fileName());
|
||||
|
||||
if (patch.isEmpty())
|
||||
return;
|
||||
@@ -218,64 +222,59 @@ void DiffEditorWidgetController::setFontSettings(const FontSettings &fontSetting
|
||||
m_rightCharFormat = fontSettings.toTextCharFormat(C_DIFF_DEST_CHAR);
|
||||
}
|
||||
|
||||
void DiffEditorWidgetController::addCodePasterAction(QMenu *menu)
|
||||
void DiffEditorWidgetController::addCodePasterAction(QMenu *menu, int fileIndex, int chunkIndex)
|
||||
{
|
||||
if (ExtensionSystem::PluginManager::getObject<CodePaster::Service>()) {
|
||||
// optional code pasting service
|
||||
QAction *sendChunkToCodePasterAction = menu->addAction(tr("Send Chunk to CodePaster..."));
|
||||
connect(sendChunkToCodePasterAction, &QAction::triggered,
|
||||
this, &DiffEditorWidgetController::slotSendChunkToCodePaster);
|
||||
connect(sendChunkToCodePasterAction, &QAction::triggered, [this, fileIndex, chunkIndex]() {
|
||||
sendChunkToCodePaster(fileIndex, chunkIndex);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bool DiffEditorWidgetController::setAndVerifyIndexes(QMenu *menu,
|
||||
int diffFileIndex, int chunkIndex)
|
||||
bool DiffEditorWidgetController::chunkExists(int fileIndex, int chunkIndex) const
|
||||
{
|
||||
if (!m_document)
|
||||
return false;
|
||||
|
||||
m_contextMenuFileIndex = diffFileIndex;
|
||||
m_contextMenuChunkIndex = chunkIndex;
|
||||
if (DiffEditorController *controller = m_document->controller())
|
||||
return controller->chunkExists(fileIndex, chunkIndex);
|
||||
|
||||
if (m_contextMenuFileIndex < 0 || m_contextMenuChunkIndex < 0)
|
||||
return false;
|
||||
|
||||
if (m_contextMenuFileIndex >= m_contextFileData.count())
|
||||
return false;
|
||||
|
||||
const FileData fileData = m_contextFileData.at(m_contextMenuFileIndex);
|
||||
if (m_contextMenuChunkIndex >= fileData.chunks.count())
|
||||
return false;
|
||||
|
||||
m_document->chunkActionsRequested(menu, diffFileIndex, chunkIndex);
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DiffEditorWidgetController::fileNamesAreDifferent() const
|
||||
bool DiffEditorWidgetController::fileNamesAreDifferent(int fileIndex) const
|
||||
{
|
||||
const FileData fileData = m_contextFileData.at(m_contextMenuFileIndex);
|
||||
const FileData fileData = m_contextFileData.at(fileIndex);
|
||||
return fileData.leftFileInfo.fileName != fileData.rightFileInfo.fileName;
|
||||
}
|
||||
|
||||
void DiffEditorWidgetController::addApplyAction(QMenu *menu, int diffFileIndex,
|
||||
int chunkIndex)
|
||||
void DiffEditorWidgetController::addApplyAction(QMenu *menu, int fileIndex, int chunkIndex)
|
||||
{
|
||||
QAction *applyAction = menu->addAction(tr("Apply Chunk..."));
|
||||
connect(applyAction, &QAction::triggered, this, &DiffEditorWidgetController::slotApplyChunk);
|
||||
applyAction->setEnabled(setAndVerifyIndexes(menu, diffFileIndex, chunkIndex)
|
||||
&& fileNamesAreDifferent());
|
||||
connect(applyAction, &QAction::triggered, [this, fileIndex, chunkIndex]() {
|
||||
patch(false, fileIndex, chunkIndex);
|
||||
});
|
||||
applyAction->setEnabled(chunkExists(fileIndex, chunkIndex) && fileNamesAreDifferent(fileIndex));
|
||||
}
|
||||
|
||||
void DiffEditorWidgetController::addRevertAction(QMenu *menu, int diffFileIndex,
|
||||
int chunkIndex)
|
||||
void DiffEditorWidgetController::addRevertAction(QMenu *menu, int fileIndex, int chunkIndex)
|
||||
{
|
||||
QAction *revertAction = menu->addAction(tr("Revert Chunk..."));
|
||||
connect(revertAction, &QAction::triggered, this, &DiffEditorWidgetController::slotRevertChunk);
|
||||
revertAction->setEnabled(setAndVerifyIndexes(menu, diffFileIndex, chunkIndex));
|
||||
connect(revertAction, &QAction::triggered, [this, fileIndex, chunkIndex]() {
|
||||
patch(true, fileIndex, chunkIndex);
|
||||
});
|
||||
revertAction->setEnabled(chunkExists(fileIndex, chunkIndex));
|
||||
}
|
||||
|
||||
void DiffEditorWidgetController::slotSendChunkToCodePaster()
|
||||
void DiffEditorWidgetController::addExtraActions(QMenu *menu, int fileIndex, int chunkIndex)
|
||||
{
|
||||
if (DiffEditorController *controller = m_document->controller())
|
||||
controller->requestChunkActions(menu, fileIndex, chunkIndex);
|
||||
}
|
||||
|
||||
void DiffEditorWidgetController::sendChunkToCodePaster(int fileIndex, int chunkIndex)
|
||||
{
|
||||
if (!m_document)
|
||||
return;
|
||||
@@ -284,7 +283,7 @@ void DiffEditorWidgetController::slotSendChunkToCodePaster()
|
||||
auto pasteService = ExtensionSystem::PluginManager::getObject<CodePaster::Service>();
|
||||
QTC_ASSERT(pasteService, return);
|
||||
|
||||
const QString patch = m_document->makePatch(m_contextMenuFileIndex, m_contextMenuChunkIndex, false);
|
||||
const QString patch = m_document->makePatch(fileIndex, chunkIndex, false);
|
||||
|
||||
if (patch.isEmpty())
|
||||
return;
|
||||
@@ -292,15 +291,5 @@ void DiffEditorWidgetController::slotSendChunkToCodePaster()
|
||||
pasteService->postText(patch, Constants::DIFF_EDITOR_MIMETYPE);
|
||||
}
|
||||
|
||||
void DiffEditorWidgetController::slotApplyChunk()
|
||||
{
|
||||
patch(false);
|
||||
}
|
||||
|
||||
void DiffEditorWidgetController::slotRevertChunk()
|
||||
{
|
||||
patch(true);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace DiffEditor
|
||||
|
||||
@@ -52,13 +52,13 @@ public:
|
||||
void setDocument(DiffEditorDocument *document);
|
||||
DiffEditorDocument *document() const;
|
||||
|
||||
void patch(bool revert);
|
||||
void jumpToOriginalFile(const QString &fileName, int lineNumber,
|
||||
int columnNumber);
|
||||
void setFontSettings(const TextEditor::FontSettings &fontSettings);
|
||||
void addCodePasterAction(QMenu *menu);
|
||||
void addApplyAction(QMenu *menu, int diffFileIndex, int chunkIndex);
|
||||
void addRevertAction(QMenu *menu, int diffFileIndex, int chunkIndex);
|
||||
void addCodePasterAction(QMenu *menu, int fileIndex, int chunkIndex);
|
||||
void addApplyAction(QMenu *menu, int fileIndex, int chunkIndex);
|
||||
void addRevertAction(QMenu *menu, int fileIndex, int chunkIndex);
|
||||
void addExtraActions(QMenu *menu, int fileIndex, int chunkIndex);
|
||||
|
||||
bool m_ignoreCurrentIndexChange = false;
|
||||
QList<FileData> m_contextFileData; // ultimate data to be shown
|
||||
@@ -71,11 +71,10 @@ public:
|
||||
QTextCharFormat m_rightCharFormat;
|
||||
|
||||
private:
|
||||
void slotSendChunkToCodePaster();
|
||||
void slotApplyChunk();
|
||||
void slotRevertChunk();
|
||||
bool setAndVerifyIndexes(QMenu *menu, int diffFileIndex, int chunkIndex);
|
||||
bool fileNamesAreDifferent() const;
|
||||
void patch(bool revert, int fileIndex, int chunkIndex);
|
||||
void sendChunkToCodePaster(int fileIndex, int chunkIndex);
|
||||
bool chunkExists(int fileIndex, int chunkIndex) const;
|
||||
bool fileNamesAreDifferent(int fileIndex) const;
|
||||
|
||||
void scheduleShowProgress();
|
||||
void showProgress();
|
||||
@@ -85,9 +84,6 @@ private:
|
||||
|
||||
DiffEditorDocument *m_document = nullptr;
|
||||
|
||||
int m_contextMenuFileIndex = -1;
|
||||
int m_contextMenuChunkIndex = -1;
|
||||
|
||||
Utils::ProgressIndicator *m_progressIndicator = nullptr;
|
||||
QTimer m_timer;
|
||||
};
|
||||
|
||||
@@ -1059,59 +1059,79 @@ void SideBySideDiffEditorWidget::slotRightJumpToOriginalFileRequested(
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::slotLeftContextMenuRequested(QMenu *menu,
|
||||
int diffFileIndex,
|
||||
int fileIndex,
|
||||
int chunkIndex)
|
||||
{
|
||||
menu->addSeparator();
|
||||
|
||||
m_controller.addCodePasterAction(menu);
|
||||
m_controller.addApplyAction(menu, diffFileIndex, chunkIndex);
|
||||
m_controller.addCodePasterAction(menu, fileIndex, chunkIndex);
|
||||
m_controller.addApplyAction(menu, fileIndex, chunkIndex);
|
||||
m_controller.addExtraActions(menu, fileIndex, chunkIndex);
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::slotRightContextMenuRequested(QMenu *menu,
|
||||
int diffFileIndex,
|
||||
int fileIndex,
|
||||
int chunkIndex)
|
||||
{
|
||||
menu->addSeparator();
|
||||
|
||||
m_controller.addCodePasterAction(menu);
|
||||
m_controller.addRevertAction(menu, diffFileIndex, chunkIndex);
|
||||
m_controller.addCodePasterAction(menu, fileIndex, chunkIndex);
|
||||
m_controller.addRevertAction(menu, fileIndex, chunkIndex);
|
||||
m_controller.addExtraActions(menu, fileIndex, chunkIndex);
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::leftVSliderChanged()
|
||||
{
|
||||
if (m_controller.m_ignoreCurrentIndexChange)
|
||||
return;
|
||||
|
||||
m_rightEditor->verticalScrollBar()->setValue(m_leftEditor->verticalScrollBar()->value());
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::rightVSliderChanged()
|
||||
{
|
||||
if (m_controller.m_ignoreCurrentIndexChange)
|
||||
return;
|
||||
|
||||
m_leftEditor->verticalScrollBar()->setValue(m_rightEditor->verticalScrollBar()->value());
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::leftHSliderChanged()
|
||||
{
|
||||
if (m_controller.m_ignoreCurrentIndexChange)
|
||||
return;
|
||||
|
||||
if (m_horizontalSync)
|
||||
m_rightEditor->horizontalScrollBar()->setValue(m_leftEditor->horizontalScrollBar()->value());
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::rightHSliderChanged()
|
||||
{
|
||||
if (m_controller.m_ignoreCurrentIndexChange)
|
||||
return;
|
||||
|
||||
if (m_horizontalSync)
|
||||
m_leftEditor->horizontalScrollBar()->setValue(m_rightEditor->horizontalScrollBar()->value());
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::leftCursorPositionChanged()
|
||||
{
|
||||
if (m_controller.m_ignoreCurrentIndexChange)
|
||||
return;
|
||||
|
||||
handlePositionChange(m_leftEditor, m_rightEditor);
|
||||
leftVSliderChanged();
|
||||
leftHSliderChanged();
|
||||
handlePositionChange(m_leftEditor, m_rightEditor);
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::rightCursorPositionChanged()
|
||||
{
|
||||
if (m_controller.m_ignoreCurrentIndexChange)
|
||||
return;
|
||||
|
||||
handlePositionChange(m_rightEditor, m_leftEditor);
|
||||
rightVSliderChanged();
|
||||
rightHSliderChanged();
|
||||
handlePositionChange(m_rightEditor, m_leftEditor);
|
||||
}
|
||||
|
||||
void SideBySideDiffEditorWidget::handlePositionChange(SideDiffEditorWidget *source, SideDiffEditorWidget *dest)
|
||||
@@ -1129,6 +1149,8 @@ void SideBySideDiffEditorWidget::handlePositionChange(SideDiffEditorWidget *sour
|
||||
|
||||
void SideBySideDiffEditorWidget::syncCursor(SideDiffEditorWidget *source, SideDiffEditorWidget *dest)
|
||||
{
|
||||
const int oldHSliderPos = dest->horizontalScrollBar()->value();
|
||||
|
||||
const QTextCursor sourceCursor = source->textCursor();
|
||||
const int sourceLine = sourceCursor.blockNumber();
|
||||
const int sourceColumn = sourceCursor.positionInBlock();
|
||||
@@ -1139,6 +1161,7 @@ void SideBySideDiffEditorWidget::syncCursor(SideDiffEditorWidget *source, SideDi
|
||||
destCursor.setPosition(destPosition);
|
||||
dest->setTextCursor(destCursor);
|
||||
|
||||
dest->horizontalScrollBar()->setValue(oldHSliderPos);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -85,9 +85,9 @@ private:
|
||||
int lineNumber, int columnNumber);
|
||||
void slotRightJumpToOriginalFileRequested(int diffFileIndex,
|
||||
int lineNumber, int columnNumber);
|
||||
void slotLeftContextMenuRequested(QMenu *menu, int diffFileIndex,
|
||||
void slotLeftContextMenuRequested(QMenu *menu, int fileIndex,
|
||||
int chunkIndex);
|
||||
void slotRightContextMenuRequested(QMenu *menu, int diffFileIndex,
|
||||
void slotRightContextMenuRequested(QMenu *menu, int fileIndex,
|
||||
int chunkIndex);
|
||||
void leftVSliderChanged();
|
||||
void rightVSliderChanged();
|
||||
|
||||
@@ -190,14 +190,15 @@ void UnifiedDiffEditorWidget::contextMenuEvent(QContextMenuEvent *e)
|
||||
}
|
||||
|
||||
void UnifiedDiffEditorWidget::addContextMenuActions(QMenu *menu,
|
||||
int diffFileIndex,
|
||||
int fileIndex,
|
||||
int chunkIndex)
|
||||
{
|
||||
menu->addSeparator();
|
||||
|
||||
m_controller.addCodePasterAction(menu);
|
||||
m_controller.addApplyAction(menu, diffFileIndex, chunkIndex);
|
||||
m_controller.addRevertAction(menu, diffFileIndex, chunkIndex);
|
||||
m_controller.addCodePasterAction(menu, fileIndex, chunkIndex);
|
||||
m_controller.addApplyAction(menu, fileIndex, chunkIndex);
|
||||
m_controller.addRevertAction(menu, fileIndex, chunkIndex);
|
||||
m_controller.addExtraActions(menu, fileIndex, chunkIndex);
|
||||
}
|
||||
|
||||
void UnifiedDiffEditorWidget::clear(const QString &message)
|
||||
|
||||
@@ -96,7 +96,7 @@ private:
|
||||
int chunkIndexForBlockNumber(int blockNumber) const;
|
||||
void jumpToOriginalFile(const QTextCursor &cursor);
|
||||
void addContextMenuActions(QMenu *menu,
|
||||
int diffFileIndex,
|
||||
int fileIndex,
|
||||
int chunkIndex);
|
||||
|
||||
// block number, visual line number.
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/pathchooser.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/savedaction.h>
|
||||
#include <utils/stylehelper.h>
|
||||
|
||||
@@ -2120,9 +2121,12 @@ void FakeVimPluginPrivate::highlightMatches(FakeVimHandler *, const QString &nee
|
||||
int FakeVimPluginPrivate::currentFile() const
|
||||
{
|
||||
IEditor *editor = EditorManager::currentEditor();
|
||||
if (!editor)
|
||||
return -1;
|
||||
return DocumentModel::indexOfDocument(editor->document());
|
||||
if (editor) {
|
||||
const Utils::optional<int> index = DocumentModel::indexOfDocument(editor->document());
|
||||
if (QTC_GUARD(index))
|
||||
return index.value();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void FakeVimPluginPrivate::switchToFile(int n)
|
||||
|
||||
@@ -596,56 +596,49 @@ QTextCodec *GitClient::codecFor(GitClient::CodecType codecType, const QString &s
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void GitClient::slotChunkActionsRequested(QMenu *menu, bool isValid)
|
||||
void GitClient::chunkActionsRequested(QMenu *menu, int fileIndex, int chunkIndex)
|
||||
{
|
||||
QPointer<DiffEditor::DiffEditorController> diffController
|
||||
= qobject_cast<DiffEditorController *>(sender());
|
||||
|
||||
auto stageChunk = [this](QPointer<DiffEditor::DiffEditorController> diffController,
|
||||
int fileIndex, int chunkIndex, bool revert) {
|
||||
if (diffController.isNull())
|
||||
return;
|
||||
|
||||
DiffEditorController::PatchOptions options = DiffEditorController::AddPrefix;
|
||||
if (revert)
|
||||
options |= DiffEditorController::Revert;
|
||||
const QString patch = diffController->makePatch(fileIndex, chunkIndex, options);
|
||||
stage(diffController, patch, revert);
|
||||
};
|
||||
|
||||
menu->addSeparator();
|
||||
QAction *stageChunkAction = menu->addAction(tr("Stage Chunk"));
|
||||
connect(stageChunkAction, &QAction::triggered, this, &GitClient::slotStageChunk);
|
||||
connect(stageChunkAction, &QAction::triggered,
|
||||
[this, stageChunk, diffController, fileIndex, chunkIndex]() {
|
||||
stageChunk(diffController, fileIndex, chunkIndex, false);
|
||||
});
|
||||
QAction *unstageChunkAction = menu->addAction(tr("Unstage Chunk"));
|
||||
connect(unstageChunkAction, &QAction::triggered, this, &GitClient::slotUnstageChunk);
|
||||
connect(unstageChunkAction, &QAction::triggered,
|
||||
[this, stageChunk, diffController, fileIndex, chunkIndex]() {
|
||||
stageChunk(diffController, fileIndex, chunkIndex, true);
|
||||
});
|
||||
|
||||
m_contextController = qobject_cast<DiffEditorController *>(sender());
|
||||
|
||||
if (!isValid || !m_contextController) {
|
||||
if (!diffController || !diffController->chunkExists(fileIndex, chunkIndex)) {
|
||||
stageChunkAction->setEnabled(false);
|
||||
unstageChunkAction->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void GitClient::slotStageChunk()
|
||||
{
|
||||
if (m_contextController.isNull())
|
||||
return;
|
||||
|
||||
DiffEditorController::PatchOptions options = DiffEditorController::AddPrefix;
|
||||
const QString patch = m_contextController->makePatch(options);
|
||||
if (patch.isEmpty())
|
||||
return;
|
||||
|
||||
stage(patch, false);
|
||||
}
|
||||
|
||||
void GitClient::slotUnstageChunk()
|
||||
{
|
||||
if (m_contextController.isNull())
|
||||
return;
|
||||
|
||||
DiffEditorController::PatchOptions options = DiffEditorController::AddPrefix;
|
||||
options |= DiffEditorController::Revert;
|
||||
const QString patch = m_contextController->makePatch(options);
|
||||
if (patch.isEmpty())
|
||||
return;
|
||||
|
||||
stage(patch, true);
|
||||
}
|
||||
|
||||
void GitClient::stage(const QString &patch, bool revert)
|
||||
void GitClient::stage(DiffEditor::DiffEditorController *diffController,
|
||||
const QString &patch, bool revert)
|
||||
{
|
||||
Utils::TemporaryFile patchFile("git-patchfile");
|
||||
if (!patchFile.open())
|
||||
return;
|
||||
|
||||
const QString baseDir = m_contextController->baseDirectory();
|
||||
const QString baseDir = diffController->baseDirectory();
|
||||
QTextCodec *codec = EditorManager::defaultTextCodec();
|
||||
const QByteArray patchData = codec
|
||||
? codec->fromUnicode(patch) : patch.toLocal8Bit();
|
||||
@@ -666,7 +659,7 @@ void GitClient::stage(const QString &patch, bool revert)
|
||||
} else {
|
||||
VcsOutputWindow::appendError(errorMessage);
|
||||
}
|
||||
m_contextController->requestReload();
|
||||
diffController->requestReload();
|
||||
} else {
|
||||
VcsOutputWindow::appendError(errorMessage);
|
||||
}
|
||||
@@ -685,7 +678,7 @@ void GitClient::requestReload(const QString &documentId, const QString &source,
|
||||
QTC_ASSERT(controller, return);
|
||||
|
||||
connect(controller, &DiffEditorController::chunkActionsRequested,
|
||||
this, &GitClient::slotChunkActionsRequested, Qt::DirectConnection);
|
||||
this, &GitClient::chunkActionsRequested, Qt::DirectConnection);
|
||||
connect(controller, &DiffEditorController::requestInformationForCommit,
|
||||
this, &GitClient::branchesForCommit);
|
||||
|
||||
|
||||
@@ -329,12 +329,11 @@ public:
|
||||
|
||||
private:
|
||||
void finishSubmoduleUpdate();
|
||||
void slotChunkActionsRequested(QMenu *menu, bool isValid);
|
||||
void slotStageChunk();
|
||||
void slotUnstageChunk();
|
||||
void chunkActionsRequested(QMenu *menu, int fileIndex, int chunkIndex);
|
||||
void branchesForCommit(const QString &revision);
|
||||
|
||||
void stage(const QString &patch, bool revert);
|
||||
void stage(DiffEditor::DiffEditorController *diffController,
|
||||
const QString &patch, bool revert);
|
||||
|
||||
enum CodecType { CodecSource, CodecLogOutput, CodecNone };
|
||||
QTextCodec *codecFor(CodecType codecType, const QString &source = QString()) const;
|
||||
@@ -378,7 +377,6 @@ private:
|
||||
QMap<QString, StashInfo> m_stashInfo;
|
||||
QStringList m_updatedSubmodules;
|
||||
bool m_disableEditor;
|
||||
QPointer<DiffEditor::DiffEditorController> m_contextController;
|
||||
QFutureSynchronizer<void> m_synchronizer; // for commit updates
|
||||
};
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@ const char C_FOLDERNAVIGATIONWIDGET[] = "ProjectExplorer.FolderNavigationWidget"
|
||||
const char kSettingsBase[] = "FolderNavigationWidget.";
|
||||
const char kHiddenFilesKey[] = ".HiddenFilesFilter";
|
||||
const char kSyncKey[] = ".SyncWithEditor";
|
||||
const char kShowBreadCrumbs[] = ".ShowBreadCrumbs";
|
||||
|
||||
namespace ProjectExplorer {
|
||||
namespace Internal {
|
||||
@@ -202,7 +203,7 @@ bool FolderNavigationModel::setData(const QModelIndex &index, const QVariant &va
|
||||
if (!failedNodes.isEmpty()) {
|
||||
const QString projects = projectNames(failedNodes).join(", ");
|
||||
const QString errorMessage
|
||||
= tr("The file \"%1\" was renamed to \"%2\", "
|
||||
= FolderNavigationWidget::tr("The file \"%1\" was renamed to \"%2\", "
|
||||
"but the following projects could not be automatically changed: %3")
|
||||
.arg(beforeFilePath, afterFilePath, projects);
|
||||
QTimer::singleShot(0, Core::ICore::instance(), [errorMessage] {
|
||||
@@ -246,6 +247,7 @@ FolderNavigationWidget::FolderNavigationWidget(QWidget *parent) : QWidget(parent
|
||||
m_listView(new Utils::NavigationTreeView(this)),
|
||||
m_fileSystemModel(new FolderNavigationModel(this)),
|
||||
m_filterHiddenFilesAction(new QAction(tr("Show Hidden Files"), this)),
|
||||
m_showBreadCrumbsAction(new QAction(tr("Show Bread Crumbs"), this)),
|
||||
m_toggleSync(new QToolButton(this)),
|
||||
m_rootSelector(new QComboBox),
|
||||
m_crumbLabel(new DelayedFileCrumbLabel(this))
|
||||
@@ -266,6 +268,8 @@ FolderNavigationWidget::FolderNavigationWidget(QWidget *parent) : QWidget(parent
|
||||
m_fileSystemModel->setRootPath(QString());
|
||||
m_filterHiddenFilesAction->setCheckable(true);
|
||||
setHiddenFilesFilter(false);
|
||||
m_showBreadCrumbsAction->setCheckable(true);
|
||||
setShowBreadCrumbs(true);
|
||||
m_listView->setIconSize(QSize(16,16));
|
||||
m_listView->setModel(m_fileSystemModel);
|
||||
m_listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
@@ -320,8 +324,14 @@ FolderNavigationWidget::FolderNavigationWidget(QWidget *parent) : QWidget(parent
|
||||
&QAction::toggled,
|
||||
this,
|
||||
&FolderNavigationWidget::setHiddenFilesFilter);
|
||||
connect(m_toggleSync, &QAbstractButton::clicked,
|
||||
this, &FolderNavigationWidget::toggleAutoSynchronization);
|
||||
connect(m_showBreadCrumbsAction,
|
||||
&QAction::toggled,
|
||||
this,
|
||||
&FolderNavigationWidget::setShowBreadCrumbs);
|
||||
connect(m_toggleSync,
|
||||
&QAbstractButton::clicked,
|
||||
this,
|
||||
&FolderNavigationWidget::toggleAutoSynchronization);
|
||||
connect(m_rootSelector,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
this,
|
||||
@@ -348,6 +358,12 @@ void FolderNavigationWidget::toggleAutoSynchronization()
|
||||
setAutoSynchronization(!m_autoSync);
|
||||
}
|
||||
|
||||
void FolderNavigationWidget::setShowBreadCrumbs(bool show)
|
||||
{
|
||||
m_showBreadCrumbsAction->setChecked(show);
|
||||
m_crumbLabel->setVisible(show);
|
||||
}
|
||||
|
||||
static bool itemLessThan(QComboBox *combo,
|
||||
int index,
|
||||
const FolderNavigationWidgetFactory::RootDirectory &directory)
|
||||
@@ -582,7 +598,13 @@ void FolderNavigationWidget::setCrumblePath(const QModelIndex &index, const QMod
|
||||
// try to fix scroll position, otherwise delay layouting
|
||||
QScrollBar *bar = m_listView->verticalScrollBar();
|
||||
const int newBarValue = bar ? bar->value() + diff : 0;
|
||||
if (bar && bar->minimum() <= newBarValue && bar->maximum() >= newBarValue) {
|
||||
const QRect currentItemRect = m_listView->visualRect(index);
|
||||
const int currentItemVStart = currentItemRect.y();
|
||||
const int currentItemVEnd = currentItemVStart + currentItemRect.height();
|
||||
const bool currentItemStillVisibleAsBefore = (diff < 0 || currentItemVStart > diff
|
||||
|| currentItemVEnd <= 0);
|
||||
if (bar && bar->minimum() <= newBarValue && bar->maximum() >= newBarValue
|
||||
&& currentItemStillVisibleAsBefore) {
|
||||
// we need to set the scroll bar when the layout request from the crumble path is
|
||||
// handled, otherwise it will flicker
|
||||
m_crumbLabel->setScrollBarOnce(bar, newBarValue);
|
||||
@@ -669,6 +691,11 @@ bool FolderNavigationWidget::hiddenFilesFilter() const
|
||||
return m_filterHiddenFilesAction->isChecked();
|
||||
}
|
||||
|
||||
bool FolderNavigationWidget::isShowingBreadCrumbs() const
|
||||
{
|
||||
return m_showBreadCrumbsAction->isChecked();
|
||||
}
|
||||
|
||||
QStringList FolderNavigationWidget::projectFilesInDirectory(const QString &path)
|
||||
{
|
||||
QDir dir(path);
|
||||
@@ -722,11 +749,12 @@ Core::NavigationView FolderNavigationWidgetFactory::createWidget()
|
||||
n.widget = fnw;
|
||||
auto filter = new QToolButton;
|
||||
filter->setIcon(Utils::Icons::FILTER.icon());
|
||||
filter->setToolTip(tr("Filter Files"));
|
||||
filter->setToolTip(tr("Options"));
|
||||
filter->setPopupMode(QToolButton::InstantPopup);
|
||||
filter->setProperty("noArrow", true);
|
||||
auto filterMenu = new QMenu(filter);
|
||||
filterMenu->addAction(fnw->m_filterHiddenFilesAction);
|
||||
filterMenu->addAction(fnw->m_showBreadCrumbsAction);
|
||||
filter->setMenu(filterMenu);
|
||||
n.dockToolBarWidgets << filter << fnw->m_toggleSync;
|
||||
return n;
|
||||
@@ -739,6 +767,7 @@ void FolderNavigationWidgetFactory::saveSettings(QSettings *settings, int positi
|
||||
const QString base = kSettingsBase + QString::number(position);
|
||||
settings->setValue(base + kHiddenFilesKey, fnw->hiddenFilesFilter());
|
||||
settings->setValue(base + kSyncKey, fnw->autoSynchronization());
|
||||
settings->setValue(base + kShowBreadCrumbs, fnw->isShowingBreadCrumbs());
|
||||
}
|
||||
|
||||
void FolderNavigationWidgetFactory::restoreSettings(QSettings *settings, int position, QWidget *widget)
|
||||
@@ -748,6 +777,7 @@ void FolderNavigationWidgetFactory::restoreSettings(QSettings *settings, int pos
|
||||
const QString base = kSettingsBase + QString::number(position);
|
||||
fnw->setHiddenFilesFilter(settings->value(base + kHiddenFilesKey, false).toBool());
|
||||
fnw->setAutoSynchronization(settings->value(base + kSyncKey, true).toBool());
|
||||
fnw->setShowBreadCrumbs(settings->value(base + kShowBreadCrumbs, true).toBool());
|
||||
}
|
||||
|
||||
void FolderNavigationWidgetFactory::insertRootDirectory(const RootDirectory &directory)
|
||||
@@ -821,6 +851,7 @@ int DelayedFileCrumbLabel::immediateHeightForWidth(int w) const
|
||||
|
||||
int DelayedFileCrumbLabel::heightForWidth(int w) const
|
||||
{
|
||||
static const int doubleDefaultInterval = 800;
|
||||
static QHash<int, int> oldHeight;
|
||||
setScrollBarOnce();
|
||||
int newHeight = Utils::FileCrumbLabel::heightForWidth(w);
|
||||
@@ -828,11 +859,13 @@ int DelayedFileCrumbLabel::heightForWidth(int w) const
|
||||
oldHeight.insert(w, newHeight);
|
||||
} else if (oldHeight.value(w) != newHeight){
|
||||
auto that = const_cast<DelayedFileCrumbLabel *>(this);
|
||||
QTimer::singleShot(QApplication::doubleClickInterval(), that, [that, w, newHeight] {
|
||||
oldHeight.insert(w, newHeight);
|
||||
that->m_delaying = false;
|
||||
that->updateGeometry();
|
||||
});
|
||||
QTimer::singleShot(std::max(2 * QApplication::doubleClickInterval(), doubleDefaultInterval),
|
||||
that,
|
||||
[that, w, newHeight] {
|
||||
oldHeight.insert(w, newHeight);
|
||||
that->m_delaying = false;
|
||||
that->updateGeometry();
|
||||
});
|
||||
}
|
||||
return oldHeight.value(w);
|
||||
}
|
||||
|
||||
@@ -99,9 +99,11 @@ public:
|
||||
|
||||
bool autoSynchronization() const;
|
||||
bool hiddenFilesFilter() const;
|
||||
bool isShowingBreadCrumbs() const;
|
||||
|
||||
void setAutoSynchronization(bool sync);
|
||||
void toggleAutoSynchronization();
|
||||
void setShowBreadCrumbs(bool show);
|
||||
|
||||
void insertRootDirectory(const FolderNavigationWidgetFactory::RootDirectory &directory);
|
||||
void removeRootDirectory(const QString &id);
|
||||
@@ -129,6 +131,7 @@ private:
|
||||
Utils::NavigationTreeView *m_listView = nullptr;
|
||||
QFileSystemModel *m_fileSystemModel = nullptr;
|
||||
QAction *m_filterHiddenFilesAction = nullptr;
|
||||
QAction *m_showBreadCrumbsAction = nullptr;
|
||||
bool m_autoSync = false;
|
||||
QToolButton *m_toggleSync = nullptr;
|
||||
QComboBox *m_rootSelector = nullptr;
|
||||
|
||||
@@ -336,8 +336,9 @@ public:
|
||||
const QString &action = actions.at(i);
|
||||
const int ww = fm.width(action);
|
||||
const QRect actionRect(xx, yy - 10, ww, 15);
|
||||
const bool isActive = actionRect.contains(mousePos);
|
||||
painter->setPen(linkColor);
|
||||
const bool isForcedDisabled = (i != 0 && sessionName == "default");
|
||||
const bool isActive = actionRect.contains(mousePos) && !isForcedDisabled;
|
||||
painter->setPen(isForcedDisabled ? disabledLinkColor : linkColor);
|
||||
painter->setFont(sizedFont(12, option.widget, isActive));
|
||||
painter->drawText(xx, yy, action);
|
||||
if (i < 2) {
|
||||
@@ -404,6 +405,7 @@ private:
|
||||
const QColor hoverColor = themeColor(Theme::Welcome_HoverColor);
|
||||
const QColor textColor = themeColor(Theme::Welcome_TextColor);
|
||||
const QColor linkColor = themeColor(Theme::Welcome_LinkColor);
|
||||
const QColor disabledLinkColor = themeColor(Theme::Welcome_DisabledLinkColor);
|
||||
const QColor backgroundColor = themeColor(Theme::Welcome_BackgroundColor);
|
||||
const QColor foregroundColor1 = themeColor(Theme::Welcome_ForegroundPrimaryColor); // light-ish.
|
||||
const QColor foregroundColor2 = themeColor(Theme::Welcome_ForegroundSecondaryColor); // blacker.
|
||||
|
||||
@@ -338,7 +338,10 @@ void FormEditorItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *,
|
||||
if (isInStackedContainer)
|
||||
showPlaceHolder = qmlItemNode().instanceIsRenderPixmapNull() && isContentVisible();
|
||||
|
||||
painter->setClipRegion(boundingRect().toRect());
|
||||
QRegion clipRegion = painter->clipRegion();
|
||||
if (clipRegion.contains(m_selectionBoundingRect.toRect().topLeft())
|
||||
&& clipRegion.contains(m_selectionBoundingRect.toRect().bottomRight()))
|
||||
painter->setClipRegion(boundingRect().toRect());
|
||||
painter->setClipping(true);
|
||||
|
||||
if (!hideCompletely) {
|
||||
|
||||
@@ -134,7 +134,10 @@ void FileResourcesModel::openFileDialog()
|
||||
if (!QFileInfo::exists(path))
|
||||
path = modelPath;
|
||||
|
||||
QString newFile = QFileDialog::getOpenFileName(Core::ICore::mainWindow(), tr("Open File"), path, m_filter);
|
||||
QString newFile = QFileDialog::getOpenFileName(Core::ICore::dialogParent(),
|
||||
tr("Open File"),
|
||||
path,
|
||||
m_filter);
|
||||
|
||||
if (!newFile.isEmpty()) {
|
||||
setFileNameStr(newFile);
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include <texteditor/texteditorconstants.h>
|
||||
#include <qmljseditor/qmljseditordocument.h>
|
||||
|
||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||
#include <qmljs/qmljsreformatter.h>
|
||||
#include <utils/changeset.h>
|
||||
|
||||
@@ -272,7 +273,26 @@ void TextEditorView::reformatFile()
|
||||
&& document->filePath().toString().endsWith(".ui.qml")
|
||||
&& DesignerSettings::getValue(DesignerSettingsKey::REFORMAT_UI_QML_FILES).toBool()) {
|
||||
|
||||
const QString &newText = QmlJS::reformat(document->semanticInfo().document);
|
||||
QmlJS::Document::Ptr currentDocument(document->semanticInfo().document);
|
||||
QmlJS::Snapshot snapshot = QmlJS::ModelManagerInterface::instance()->snapshot();
|
||||
|
||||
if (document->isSemanticInfoOutdated()) {
|
||||
QmlJS::Document::MutablePtr latestDocument;
|
||||
|
||||
const QString fileName = document->filePath().toString();
|
||||
latestDocument = snapshot.documentFromSource(QString::fromUtf8(document->contents()),
|
||||
fileName,
|
||||
QmlJS::ModelManagerInterface::guessLanguageOfFile(fileName));
|
||||
latestDocument->parseQml();
|
||||
snapshot.insert(latestDocument);
|
||||
|
||||
currentDocument = latestDocument;
|
||||
}
|
||||
|
||||
if (!currentDocument->isParsedCorrectly())
|
||||
return;
|
||||
|
||||
const QString &newText = QmlJS::reformat(currentDocument);
|
||||
QTextCursor tc(document->document());
|
||||
|
||||
Utils::ChangeSet changeSet;
|
||||
|
||||
@@ -81,6 +81,7 @@ static inline QHash<PropertyName, QVariant> getProperties(const ModelNode &node)
|
||||
propertyHash.remove("opacity");
|
||||
}
|
||||
}
|
||||
|
||||
return propertyHash;
|
||||
}
|
||||
|
||||
@@ -326,6 +327,21 @@ Utils::FileName DocumentManager::currentFilePath()
|
||||
return QmlDesignerPlugin::instance()->documentManager().currentDesignDocument()->fileName();
|
||||
}
|
||||
|
||||
Utils::FileName DocumentManager::currentProjectDirPath()
|
||||
{
|
||||
QTC_ASSERT(QmlDesignerPlugin::instance(), return {});
|
||||
|
||||
if (!QmlDesignerPlugin::instance()->currentDesignDocument())
|
||||
return {};
|
||||
|
||||
Utils::FileName qmlFileName = QmlDesignerPlugin::instance()->currentDesignDocument()->fileName();
|
||||
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::projectForFile(qmlFileName);
|
||||
if (!project)
|
||||
return {};
|
||||
|
||||
return project->projectDirectory();
|
||||
}
|
||||
|
||||
QStringList DocumentManager::isoIconsQmakeVariableValue(const QString &proPath)
|
||||
{
|
||||
ProjectExplorer::Node *node = ProjectExplorer::ProjectTree::nodeForFile(Utils::FileName::fromString(proPath));
|
||||
@@ -463,5 +479,22 @@ bool DocumentManager::addResourceFileToIsoProject(const QString &resourceFilePro
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DocumentManager::belongsToQmakeProject()
|
||||
{
|
||||
QTC_ASSERT(QmlDesignerPlugin::instance(), return false);
|
||||
|
||||
if (!QmlDesignerPlugin::instance()->currentDesignDocument())
|
||||
return false;
|
||||
|
||||
Utils::FileName qmlFileName = QmlDesignerPlugin::instance()->currentDesignDocument()->fileName();
|
||||
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::projectForFile(qmlFileName);
|
||||
if (!project)
|
||||
return false;
|
||||
|
||||
ProjectExplorer::Node *rootNode = project->rootProjectNode();
|
||||
QmakeProjectManager::QmakeProFileNode *proNode = dynamic_cast<QmakeProjectManager::QmakeProFileNode*>(rootNode);
|
||||
return proNode;
|
||||
}
|
||||
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
||||
@@ -56,6 +56,7 @@ public:
|
||||
static bool createFile(const QString &filePath, const QString &contents);
|
||||
static void addFileToVersionControl(const QString &directoryPath, const QString &newFilePath);
|
||||
static Utils::FileName currentFilePath();
|
||||
static Utils::FileName currentProjectDirPath();
|
||||
|
||||
static QStringList isoIconsQmakeVariableValue(const QString &proPath);
|
||||
static bool setIsoIconsQmakeVariableValue(const QString &proPath, const QStringList &value);
|
||||
@@ -63,6 +64,7 @@ public:
|
||||
QString *resourceFileProPath, const QString &isoIconsQrcFile);
|
||||
static bool isoProFileSupportsAddingExistingFiles(const QString &resourceFileProPath);
|
||||
static bool addResourceFileToIsoProject(const QString &resourceFileProPath, const QString &resourceFilePath);
|
||||
static bool belongsToQmakeProject();
|
||||
|
||||
private:
|
||||
QHash<Core::IEditor *,QPointer<DesignDocument> > m_designDocumentHash;
|
||||
|
||||
|
Before Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 8.4 KiB |
BIN
src/plugins/qtsupport/images/icons/qteventicon.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 30 KiB |
@@ -1,140 +1,169 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<instructionals module="Qt">
|
||||
<tutorials>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/buildrun.png" difficulty="" docUrl="qthelp://org.qt-project.qtcreator/doc/creator-build-example-application.html" projectPath="" name="Building and Running an Example Application">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/tutorialicon.png" difficulty="" docUrl="qthelp://org.qt-project.qtcreator/doc/creator-build-example-application.html" projectPath="" name="Help: Build and Run Examples">
|
||||
<description><![CDATA[Testing that your installation is successful by opening an existing example application project.]]></description>
|
||||
<tags>qt creator,build,compile</tags>
|
||||
<tags>qt creator,build,compile,help</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qwidget.png" difficulty="" docUrl="qthelp://org.qt-project.qtcreator/doc/creator-writing-program.html" projectPath="" name="Creating a Qt Widget Based Application">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/tutorialicon.png" difficulty="" docUrl="qthelp://org.qt-project.qtcreator/doc/creator-writing-program.html" projectPath="" name="Help: Create Qt Widget-Based Applications">
|
||||
<description><![CDATA[Using Qt Creator to create a small Qt application, Text Finder.]]></description>
|
||||
<tags>qt creator,qt designer,widgets,c++,text</tags>
|
||||
<tags>qt creator,qt designer,widgets,c++,text,help</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/tutorialicon.png" difficulty="" docUrl="qthelp://org.qt-project.qtdoc/qtdoc/gettingstartedqt.html" projectPath="" name="Getting Started Programming with Qt Widgets">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/tutorialicon.png" difficulty="" docUrl="qthelp://org.qt-project.qtdoc/qtdoc/gettingstartedqt.html" projectPath="" name="Help: Program with Qt Widgets">
|
||||
<description><![CDATA[Developing Qt applications using C++ and the Qt Widgets module.]]></description>
|
||||
<tags>qt,qt creator,qt designer,widgets,c++</tags>
|
||||
<tags>qt,qt creator,qt designer,widgets,c++,help</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qtquick.png" difficulty="" docUrl="qthelp://org.qt-project.qtcreator/doc/qtcreator-transitions-example.html" projectPath="" name="Creating a Qt Quick Application">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/tutorialicon.png" difficulty="" docUrl="qthelp://org.qt-project.qtcreator/doc/qtcreator-transitions-example.html" projectPath="" name="Help: Create Qt Quick Applications">
|
||||
<description><![CDATA[Using basic QML elements and learning about basic concepts of Qt Quick.]]></description>
|
||||
<tags>qt creator,qt quick designer,qt quick,qml,states,transitions</tags>
|
||||
<tags>qt creator,qt quick designer,qt quick,qml,states,transitions,help</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/androidapp.png" difficulty="" docUrl="qthelp://org.qt-project.qtcreator/doc/qtcreator-accelbubble-example.html" projectPath="" name="Creating a Mobile Application">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/tutorialicon.png" difficulty="" docUrl="qthelp://org.qt-project.qtcreator/doc/qtcreator-accelbubble-example.html" projectPath="" name="Help: Create Mobile Qt Applications">
|
||||
<description><![CDATA[Developing Qt Quick applications for Android and iOS devices using Qt Quick Controls.]]></description>
|
||||
<tags>qt creator,qt quick designer,qml,android,ios,controls</tags>
|
||||
<tags>qt creator,qt quick designer,qml,android,ios,controls,help</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/tutorialicon.png" difficulty="" docUrl="qthelp://org.qt-project.qtdoc/qtdoc/gettingstartedqml.html" projectPath="" name="Getting Started Programming with Qt Quick">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/tutorialicon.png" difficulty="" docUrl="qthelp://org.qt-project.qtdoc/qtdoc/gettingstartedqml.html" projectPath="" name="Help: Program with Qt Quick">
|
||||
<description><![CDATA[Developing Qt Quick applications using QML and C++.]]></description>
|
||||
<tags>qt quick,qml,c++</tags>
|
||||
<tags>qt quick,qml,c++,help</tags>
|
||||
</tutorial>
|
||||
|
||||
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Digital Instrument Cluster with Qt Quick Designer and Qt Safe Renderer" isVideo="true" videoUrl="https://www.youtube.com/watch?v=9RxxsOCeZHk" videoLength="4:06">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Digital Instrument Cluster and Qt Safe Renderer" isVideo="true" videoUrl="https://www.youtube.com/watch?v=9RxxsOCeZHk" videoLength="4:06">
|
||||
<description><![CDATA[Creating a digital instrument cluster with Qt Quick Designer and Qt Safe Renderer.]]></description>
|
||||
<tags>qt creator,qt quick,automotive,safe renderer,controls</tags>
|
||||
<tags>qt creator,qt quick,automotive,safe renderer,controls,video</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Qt for Device Creation" isVideo="true" videoUrl="https://www.youtube.com/watch?v=PercN_GtVJA" videoLength="3:01">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Qt for Device Creation - Overview" isVideo="true" videoUrl="https://www.youtube.com/watch?v=PercN_GtVJA" videoLength="3:01">
|
||||
<description><![CDATA[Creating a Qt widget based application.]]></description>
|
||||
<tags>qt creator,embedded,device creation</tags>
|
||||
<tags>qt creator,embedded,device creation,video</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Getting Started with Qt for Device Creation" isVideo="true" videoUrl="https://www.youtube.com/watch?v=QFWPw4UWL9E" videoLength="8:30">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Qt for Device Creation - Getting Started" isVideo="true" videoUrl="https://www.youtube.com/watch?v=QFWPw4UWL9E" videoLength="8:30">
|
||||
<description><![CDATA[Using Qt Creator to deploy applications to an embedded device.]]></description>
|
||||
<tags>qt creator,embedded,device creation</tags>
|
||||
<tags>qt creator,embedded,device creation,video</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Qt Quick Designer - The Coffee Machine" isVideo="true" videoUrl="https://www.youtube.com/watch?v=Ko3YPM_tStM" videoLength="3:06">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Qt Quick Designer - The Coffee Machine" isVideo="true" videoUrl="https://www.youtube.com/watch?v=Ko3YPM_tStM" videoLength="3:06">
|
||||
<description><![CDATA[Creating a UI for embedded devices.]]></description>
|
||||
<tags>qt creator,qt quick,embedded</tags>
|
||||
<tags>qt creator,qt quick,embedded,video,controls</tags>
|
||||
</tutorial>
|
||||
|
||||
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Getting started with Qt: Hello Widget World " isVideo="true" videoUrl="https://www.youtube.com/watch?v=TIUTO8GjSGo" videoLength="9:10">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Getting Started - Hello Widget World " isVideo="true" videoUrl="https://www.youtube.com/watch?v=TIUTO8GjSGo" videoLength="9:10">
|
||||
<description><![CDATA[Creating a Qt widget based application.]]></description>
|
||||
<tags>qt creator,widgets</tags>
|
||||
<tags>qt creator,widgets,video</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Getting started with Qt: Hello Quick World" isVideo="true" videoUrl="https://www.youtube.com/watch?v=nepoVgVvWEI" videoLength="13:28">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Getting Started - Hello Quick World" isVideo="true" videoUrl="https://www.youtube.com/watch?v=nepoVgVvWEI" videoLength="13:28">
|
||||
<description><![CDATA[Creating a Qt Quick application.]]></description>
|
||||
<tags>qt creator,qt quick</tags>
|
||||
<tags>qt creator,qt quick,video</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Qt SCXML and State Machine Tooling in Qt Creator" isVideo="true" videoUrl="https://youtu.be/9xqhq9nDiOg" videoLength="4:53">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Qt SCXML and Tooling in Qt Creator" isVideo="true" videoUrl="https://youtu.be/9xqhq9nDiOg" videoLength="4:53">
|
||||
<description><![CDATA[Creating state machines.]]></description>
|
||||
<tags>qt creator,SCXML</tags>
|
||||
<tags>qt creator,SCXML,video</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/worldsummit15.png" difficulty="" projectPath="" name="Introduction to Qt Creator" isVideo="true" videoUrl="https://www.youtube.com/watch?v=nGFmjOiT22Y" videoLength="50:36">
|
||||
<description><![CDATA[Getting started with using Qt Creator for cross-platform development.]]></description>
|
||||
<tags>qt creator</tags>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Using C++ Models in QML" isVideo="true" videoUrl="https://www.youtube.com/watch?v=9BcAYDlpuT8" videoLength="49:48">
|
||||
<description><![CDATA[Creating and using a C++ model in QML.]]></description>
|
||||
<tags>qt creator,qt quick,c++,video</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/worldsummit15.png" difficulty="" projectPath="" name="Custom Qt Creator Wizards" isVideo="true" videoUrl="https://www.youtube.com/watch?v=Ko3DuCgFamo" videoLength="27:21">
|
||||
<description><![CDATA[Adding custom file and project creation wizards to Qt Creator.]]></description>
|
||||
<tags>qt creator,wizard</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/ddays13.png" difficulty="" projectPath="" name="Extending Qt Creator Without Writing Code" isVideo="true" videoUrl="http://www.youtube.com/watch?v=DP0lMoLVneY" videoLength="59:49">
|
||||
<description><![CDATA[Customizing Qt Creator to fit your own or your customers' purposes.]]></description>
|
||||
<tags>qt creator,configuration</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/ddays13.png" difficulty="" projectPath="" name="Qt Creator Plugin Development" isVideo="true" videoUrl="http://www.youtube.com/watch?v=6AEYgVPjl-s" videoLength="59:49">
|
||||
<description><![CDATA[Adding plugins to Qt Creator.]]></description>
|
||||
<tags>qt creator,plugins</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/ddays14.png" difficulty="" projectPath="" name="Using the QML Profiler" isVideo="true" videoUrl="https://www.youtube.com/watch?v=TiJiF0MOOFc" videoLength="55:12">
|
||||
<description><![CDATA[Monitoring the performance of a Qt Quick application.]]></description>
|
||||
<tags>qt quick,qt creator,qml profiler</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/worldsummit15.png" difficulty="" projectPath="" name="CPU Usage Analyzer for Device Creation" isVideo="true" videoUrl="https://www.youtube.com/watch?v=G0AbgVHGdXI" videoLength="22:30">
|
||||
<description><![CDATA[Using the Linux perf tool to generate data for code analysis.]]></description>
|
||||
<tags>qt creator,cpu usage analyzer,perf,embedded,device creation</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/worldsummit16.png" difficulty="" projectPath="" name="Qt SCXML: State Machines Made Easier" isVideo="true" videoUrl="https://youtu.be/X0kEkB0ewyw" videoLength="42:22">
|
||||
<description><![CDATA[Using the Qt SCXML module and Qt Creator SCXML editor.]]></description>
|
||||
<tags>qt creator,SCXML</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/worldsummit15.png" difficulty="" projectPath="" name="Effective Multi-Platform Development with Qt Creator, Qbs, and QEMU" isVideo="true" videoUrl="https://www.youtube.com/watch?v=v4glCQt2jE0" videoLength="19:08">
|
||||
<description><![CDATA[Using Qt Creator, Qbs, and QEMU for application development.]]></description>
|
||||
<tags>qt creator,qbs,qemu</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/worldsummit16.png" difficulty="" projectPath="" name="All about Qt on Android" isVideo="true" videoUrl="https://youtu.be/dmKNxyi_YNk" videoLength="31:20">
|
||||
<description><![CDATA[Developing Qt applications for Android devices.]]></description>
|
||||
<tags>qt creator,android</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Meet Qt Creator" isVideo="true" videoUrl="https://youtu.be/zAqSiIGdj8M" videoLength="2:06">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/videotutorialicon.png" difficulty="" projectPath="" name="Online: Qt Creator - Overview" isVideo="true" videoUrl="https://youtu.be/zAqSiIGdj8M" videoLength="2:06">
|
||||
<description><![CDATA[Overview of Qt Creator.]]></description>
|
||||
<tags>qt creator</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/worldsummit16.png" difficulty="" projectPath="" name="Qt on iOS A to Z" isVideo="true" videoUrl="https://youtu.be/T_13aX5NTPk" videoLength="1:00:13">
|
||||
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Creator - Getting Started" isVideo="true" videoUrl="https://www.youtube.com/watch?v=nGFmjOiT22Y" videoLength="50:36">
|
||||
<description><![CDATA[Getting started with using Qt Creator for cross-platform development.]]></description>
|
||||
<tags>qt creator,talk,2015</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Creator - Custom Wizards" isVideo="true" videoUrl="https://www.youtube.com/watch?v=Ko3DuCgFamo" videoLength="27:21">
|
||||
<description><![CDATA[Adding custom file and project creation wizards to Qt Creator.]]></description>
|
||||
<tags>qt creator,wizard,talk,2015</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Creator - Extending Without Writing Code" isVideo="true" videoUrl="http://www.youtube.com/watch?v=DP0lMoLVneY" videoLength="59:49">
|
||||
<description><![CDATA[Customizing Qt Creator to fit your own or your customers' purposes.]]></description>
|
||||
<tags>qt creator,configuration,talk,2013</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Creator - Plugin Development" isVideo="true" videoUrl="http://www.youtube.com/watch?v=6AEYgVPjl-s" videoLength="59:49">
|
||||
<description><![CDATA[Adding plugins to Qt Creator.]]></description>
|
||||
<tags>qt creator,plugins,talk,2013</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Creator - QML Profiler" isVideo="true" videoUrl="https://www.youtube.com/watch?v=TiJiF0MOOFc" videoLength="55:12">
|
||||
<description><![CDATA[Monitoring the performance of a Qt Quick application.]]></description>
|
||||
<tags>qt quick,qt creator,qml profiler,talk,2014</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Creator - CPU Usage Analyzer" isVideo="true" videoUrl="https://www.youtube.com/watch?v=G0AbgVHGdXI" videoLength="22:30">
|
||||
<description><![CDATA[Using the Linux perf tool to generate data for code analysis.]]></description>
|
||||
<tags>qt creator,cpu usage analyzer,perf,embedded,device creation,talk,2015</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Creator - SCXML Editor" isVideo="true" videoUrl="https://youtu.be/X0kEkB0ewyw" videoLength="42:22">
|
||||
<description><![CDATA[Using the Qt SCXML module and Qt Creator SCXML editor.]]></description>
|
||||
<tags>qt creator,scxml,talk,2016</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Creator - Multi-Platform Development" isVideo="true" videoUrl="https://www.youtube.com/watch?v=v4glCQt2jE0" videoLength="19:08">
|
||||
<description><![CDATA[Using Qt Creator, Qbs, and QEMU for application development.]]></description>
|
||||
<tags>qt creator,qbs,qemu,talk,2015</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt on Android - Overview" isVideo="true" videoUrl="https://youtu.be/dmKNxyi_YNk" videoLength="31:20">
|
||||
<description><![CDATA[Developing Qt applications for Android devices.]]></description>
|
||||
<tags>qt creator,android,talk,2016</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt on iOS - Overview" isVideo="true" videoUrl="https://youtu.be/T_13aX5NTPk" videoLength="1:00:13">
|
||||
<description><![CDATA[Developing Qt applications for iOS.]]></description>
|
||||
<tags>qt creator,ios</tags>
|
||||
<tags>qt creator,ios,talk,2016</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/ddays13.png" difficulty="" projectPath="" name="Qt Creator for Bare Metal Development" isVideo="true" videoUrl="http://www.youtube.com/watch?v=hrKz63Q_Rf0" videoLength="9:35">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Creator - Bare Metal Development" isVideo="true" videoUrl="http://www.youtube.com/watch?v=hrKz63Q_Rf0" videoLength="9:35">
|
||||
<description><![CDATA[Developing Qt Applications for Bare Metal devices.]]></description>
|
||||
<tags>qt creator,baremetal</tags>
|
||||
<tags>qt creator,baremetal,talk,2013</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/worldsummit16.png" difficulty="" projectPath="" name="Integrating Universal Windows Platform to Qt" isVideo="true" videoUrl="https://youtu.be/tpNdw2Cs4KY" videoLength="47:38">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt on Universal Windows Platform" isVideo="true" videoUrl="https://youtu.be/tpNdw2Cs4KY" videoLength="47:38">
|
||||
<description><![CDATA[Qt support for Universal Windows Platform on desktop, mobile, and embedded devices.]]></description>
|
||||
<tags>windows</tags>
|
||||
<tags>uwp,talk,2016</tags>
|
||||
</tutorial>
|
||||
|
||||
<tutorial imageUrl=":qtsupport/images/icons/worldsummit16.png" difficulty="" projectPath="" name="Developing UIs with Qt Quick Controls 2" isVideo="true" videoUrl="https://youtu.be/ozpSl7WbVt4" videoLength="23:13">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Quick Controls 2 - Overview" isVideo="true" videoUrl="https://youtu.be/ozpSl7WbVt4" videoLength="23:13">
|
||||
<description><![CDATA[Using Qt Quick Controls 2 to create UIs.]]></description>
|
||||
<tags>qt quick designer,controls</tags>
|
||||
<tags>ui,qt quick designer,controls,ui,talk,2016</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/worldsummit16.png" difficulty="" projectPath="" name="Overview of GUI technologies in Qt" isVideo="true" videoUrl="https://youtu.be/WIRRoPxIerc" videoLength="40:45">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: GUI technologies in Qt" isVideo="true" videoUrl="https://youtu.be/WIRRoPxIerc" videoLength="40:45">
|
||||
<description><![CDATA[Overview of UI technologies that can be used with Qt.]]></description>
|
||||
<tags>qt quick,ui,widgets</tags>
|
||||
<tags>qt quick,ui,widgets,talk,2016</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/worldsummit16.png" difficulty="" projectPath="" name="Qt on Your Wrist – Qt on Android Wear" isVideo="true" videoUrl="https://youtu.be/Rd187QxihRo" videoLength="8:08">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt on Android Wear" isVideo="true" videoUrl="https://youtu.be/Rd187QxihRo" videoLength="8:08">
|
||||
<description><![CDATA[Running Qt apps on Android Wear devices.]]></description>
|
||||
<tags>qt creator,android</tags>
|
||||
<tags>qt creator,android,talk,2016</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/worldsummit16.png" difficulty="" projectPath="" name="Qt on macOS Updates" isVideo="true" videoUrl="https://youtu.be/qfyxXxeC73Y" videoLength="25:51">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt on macOS - Updates" isVideo="true" videoUrl="https://youtu.be/qfyxXxeC73Y" videoLength="25:51">
|
||||
<description><![CDATA[Using Qt with macOS native windows.]]></description>
|
||||
<tags>macos</tags>
|
||||
<tags>macos,talk,2016</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/worldsummit15.png" difficulty="" projectPath="" name="Qt's Web Offering - An Overview" isVideo="true" videoUrl="https://www.youtube.com/watch?v=XW-oTBCj1JQ" videoLength="23:32">
|
||||
<description><![CDATA[Overview of the Qt modules that provide functions for embedding web content into applications.]]></description>
|
||||
<tags>qt webengine</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/worldsummit16.png" difficulty="" projectPath="" name="New Possibilities with Qt WebEngine" isVideo="true" videoUrl="https://youtu.be/E7CIIHT_jCk" videoLength="22:29">
|
||||
<description><![CDATA[Using the Qt WebEngine module.]]></description>
|
||||
<tags>qt webengine</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/worldsummit16.png" difficulty="" projectPath="" name="Developing for Multiple Screen Resolutions and Platforms" isVideo="true" videoUrl="https://youtu.be/qclquZ99ZVQ" videoLength="27:44">
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Multi-Platform and Screen Resolution" isVideo="true" videoUrl="https://youtu.be/qclquZ99ZVQ" videoLength="27:44">
|
||||
<description><![CDATA[Best practices for an efficient app lifecycle.]]></description>
|
||||
<tags>qt,qt quick,screen resolution</tags>
|
||||
<tags>qt,qt quick,screen resolution,ui,talk,2016</tags>
|
||||
</tutorial>
|
||||
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Mobile Applications - Tips and Examples" isVideo="true" videoUrl="https://www.youtube.com/watch?v=OqqarK73I9E" videoLength="53:57">
|
||||
<description><![CDATA[Technical tips and examples for developing and testing mobile apps.]]></description>
|
||||
<tags>android,ios,talk,2017</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt in Medical Devices - Overview" isVideo="true" videoUrl="https://www.youtube.com/watch?v=Xe5xebP9w94" videoLength="24:53">
|
||||
<description><![CDATA[Developing UX and UI for medical devices.]]></description>
|
||||
<tags>medical,ui,talk,2017</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Mobile Applications - Reducing Size" isVideo="true" videoUrl="https://www.youtube.com/watch?v=3o2Wo4YzlII" videoLength="23:41">
|
||||
<description><![CDATA[Making Android and iOS apps smaller.]]></description>
|
||||
<tags>android,ios,talk,2017</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Automotive Suite - Overview" isVideo="true" videoUrl="https://www.youtube.com/watch?v=7FqG2lpJ1KE" videoLength="23:38">
|
||||
<description><![CDATA[Introducing Qt Application Manager plugin in Qt Creator.]]></description>
|
||||
<tags>automotive,application manager,talk,2017</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Embedded Devices - Virtual Keyboards" isVideo="true" videoUrl="https://www.youtube.com/watch?v=g0X2IZ9ZCTA" videoLength="19:32">
|
||||
<description><![CDATA[Support text input via virtual keyboards on embedded devices.]]></description>
|
||||
<tags>embedded,virtual keyboard,talk,2017</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Quick Controls 2 - Mobile Business Applications" isVideo="true" videoUrl="https://www.youtube.com/watch?v=au3brB7lNms" videoLength="23:33">
|
||||
<description><![CDATA[Creating mobile business apps using Qt Quick Controls 2.]]></description>
|
||||
<tags>android,ios,qt quick,controls,talk,2017</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt Automotive Suite - Qt IVI" isVideo="true" videoUrl="https://www.youtube.com/watch?v=CVhVAK10TDw" videoLength="46:41">
|
||||
<description><![CDATA[Integrating and testing vehicle functions with Qt Automotive Suite.]]></description>
|
||||
<tags>automotive,ivi,talk,2017</tags>
|
||||
</tutorial>
|
||||
<tutorial imageUrl=":qtsupport/images/icons/qteventicon.png" difficulty="" projectPath="" name="Talk: Qt 3D - Simple and Skeletal Animations" isVideo="true" videoUrl="https://www.youtube.com/watch?v=Cj5enhBlL28" videoLength="">
|
||||
<description><![CDATA[Using the new animation subsystem of Qt 3D.]]></description>
|
||||
<tags>talk,2017</tags>
|
||||
</tutorial>
|
||||
</tutorials>
|
||||
</instructionals>
|
||||
|
||||
@@ -6,15 +6,8 @@
|
||||
<file>images/dark_qt_qrc.png</file>
|
||||
<file>images_areaofinterest.xml</file>
|
||||
<file>qtcreator_tutorials.xml</file>
|
||||
<file>images/icons/androidapp.png</file>
|
||||
<file>images/icons/buildrun.png</file>
|
||||
<file>images/icons/ddays13.png</file>
|
||||
<file>images/icons/ddays14.png</file>
|
||||
<file>images/icons/qtquick.png</file>
|
||||
<file>images/icons/qwidget.png</file>
|
||||
<file>images/icons/tutorialicon.png</file>
|
||||
<file>images/icons/worldsummit15.png</file>
|
||||
<file>images/icons/worldsummit16.png</file>
|
||||
<file>images/icons/videotutorialicon.png</file>
|
||||
<file>images/icons/qteventicon.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -44,6 +44,13 @@
|
||||
using namespace TextEditor;
|
||||
using namespace Internal;
|
||||
|
||||
/* TRANSLATOR TextEditor::Internal::Snippets
|
||||
|
||||
Snippets are text fragments that can be inserted into an editor via the usual completion
|
||||
mechanics using a trigger text. The translated text (trigger variant) is used to
|
||||
disambiguate between snippets with the same trigger.
|
||||
*/
|
||||
|
||||
namespace {
|
||||
|
||||
static bool snippetComp(const Snippet &a, const Snippet &b)
|
||||
@@ -359,7 +366,10 @@ QList<Snippet> SnippetsCollection::readXML(const QString &fileName, const QStrin
|
||||
if (isGroupKnown(groupId) && (snippetId.isEmpty() || snippetId == id)) {
|
||||
Snippet snippet(groupId, id);
|
||||
snippet.setTrigger(atts.value(kTrigger).toString());
|
||||
snippet.setComplement(atts.value(kComplement).toString());
|
||||
snippet.setComplement(QCoreApplication::translate(
|
||||
"TextEditor::Internal::Snippets",
|
||||
atts.value(kComplement).toString().toLatin1(),
|
||||
atts.value(kId).toString().toLatin1()));
|
||||
snippet.setIsRemoved(toBool(atts.value(kRemoved).toString()));
|
||||
snippet.setIsModified(toBool(atts.value(kModified).toString()));
|
||||
|
||||
|
||||
@@ -435,7 +435,7 @@ struct PaintEventData
|
||||
const QRect eventRect;
|
||||
qreal rightMargin = -1;
|
||||
const QTextDocument *doc;
|
||||
const TextDocumentLayout *documentLayout;
|
||||
TextDocumentLayout *documentLayout;
|
||||
const int documentWidth;
|
||||
const QTextCursor textCursor;
|
||||
const QTextBlock textCursorBlock;
|
||||
@@ -502,7 +502,8 @@ public:
|
||||
bool expanded,
|
||||
bool active,
|
||||
bool hovered) const;
|
||||
bool updateAnnotationBounds(TextBlockUserData *blockUserData, bool annotationsVisible);
|
||||
bool updateAnnotationBounds(TextBlockUserData *blockUserData, TextDocumentLayout *layout,
|
||||
bool annotationsVisible);
|
||||
void updateLineAnnotation(const PaintEventData &data, const PaintEventBlockData &blockData,
|
||||
QPainter &painter);
|
||||
void paintRightMarginArea(PaintEventData &data, QPainter &painter) const;
|
||||
@@ -1476,6 +1477,16 @@ void TextEditorWidget::gotoBlockEndWithSelection()
|
||||
}
|
||||
}
|
||||
|
||||
void TextEditorWidget::gotoDocumentStart()
|
||||
{
|
||||
moveCursor(QTextCursor::Start);
|
||||
}
|
||||
|
||||
void TextEditorWidget::gotoDocumentEnd()
|
||||
{
|
||||
moveCursor(QTextCursor::End);
|
||||
}
|
||||
|
||||
void TextEditorWidget::gotoLineStart()
|
||||
{
|
||||
d->handleHomeKey(false);
|
||||
@@ -4008,7 +4019,9 @@ QRectF TextEditorWidgetPrivate::getLastLineLineRect(const QTextBlock &block)
|
||||
return line.naturalTextRect().translated(contentOffset.x(), top).adjusted(0, 0, -1, -1);
|
||||
}
|
||||
|
||||
bool TextEditorWidgetPrivate::updateAnnotationBounds(TextBlockUserData *blockUserData, bool annotationsVisible)
|
||||
bool TextEditorWidgetPrivate::updateAnnotationBounds(TextBlockUserData *blockUserData,
|
||||
TextDocumentLayout *layout,
|
||||
bool annotationsVisible)
|
||||
{
|
||||
const bool additionalHeightNeeded = annotationsVisible
|
||||
&& m_displaySettings.m_annotationAlignment == AnnotationAlignment::BetweenLines;
|
||||
@@ -4017,6 +4030,7 @@ bool TextEditorWidgetPrivate::updateAnnotationBounds(TextBlockUserData *blockUse
|
||||
return false;
|
||||
blockUserData->setAdditionalAnnotationHeight(additionalHeight);
|
||||
q->viewport()->update();
|
||||
layout->emitDocumentSizeChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -4039,8 +4053,10 @@ void TextEditorWidgetPrivate::updateLineAnnotation(const PaintEventData &data,
|
||||
return !mark->lineAnnotation().isEmpty();
|
||||
});
|
||||
|
||||
if (updateAnnotationBounds(blockUserData, annotationsVisible) || !annotationsVisible)
|
||||
if (updateAnnotationBounds(blockUserData, data.documentLayout, annotationsVisible)
|
||||
|| !annotationsVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QRectF lineRect = getLastLineLineRect(data.block);
|
||||
if (lineRect.isNull())
|
||||
|
||||
@@ -381,6 +381,8 @@ public:
|
||||
void gotoBlockStartWithSelection();
|
||||
void gotoBlockEndWithSelection();
|
||||
|
||||
void gotoDocumentStart();
|
||||
void gotoDocumentEnd();
|
||||
void gotoLineStart();
|
||||
void gotoLineStartWithSelection();
|
||||
void gotoLineEnd();
|
||||
|
||||
@@ -432,6 +432,10 @@ void TextEditorActionHandlerPrivate::createActions()
|
||||
tr("Select Word Under Cursor"));
|
||||
|
||||
// register GOTO Actions
|
||||
registerAction(GOTO_DOCUMENT_START,
|
||||
[] (TextEditorWidget *w) { w->gotoDocumentStart(); }, true, tr("Go to Document Start"));
|
||||
registerAction(GOTO_DOCUMENT_END,
|
||||
[] (TextEditorWidget *w) { w->gotoDocumentEnd(); }, true, tr("Go to Document End"));
|
||||
registerAction(GOTO_LINE_START,
|
||||
[] (TextEditorWidget *w) { w->gotoLineStart(); }, true, tr("Go to Line Start"));
|
||||
registerAction(GOTO_LINE_END,
|
||||
|
||||
@@ -158,6 +158,8 @@ const char DELETE_START_OF_LINE[] = "TextEditor.DeleteStartOfLine";
|
||||
const char DELETE_START_OF_WORD_CAMEL_CASE[] = "TextEditor.DeleteStartOfWordCamelCase";
|
||||
const char SELECT_ENCODING[] = "TextEditor.SelectEncoding";
|
||||
const char REWRAP_PARAGRAPH[] = "TextEditor.RewrapParagraph";
|
||||
const char GOTO_DOCUMENT_START[] = "TextEditor.GotoDocumentStart";
|
||||
const char GOTO_DOCUMENT_END[] = "TextEditor.GotoDocumentEnd";
|
||||
const char GOTO_LINE_START[] = "TextEditor.GotoLineStart";
|
||||
const char GOTO_LINE_END[] = "TextEditor.GotoLineEnd";
|
||||
const char GOTO_NEXT_LINE[] = "TextEditor.GotoNextLine";
|
||||
|
||||
@@ -49,7 +49,7 @@ SshConnectionParameters ArgumentsCollector::collect(bool &success) const
|
||||
bool timeoutGiven = false;
|
||||
bool proxySettingGiven = false;
|
||||
int pos;
|
||||
int port;
|
||||
int port = 22;
|
||||
|
||||
for (pos = 1; pos < m_arguments.count() - 1; ++pos) {
|
||||
QString host;
|
||||
|
||||
@@ -48,7 +48,7 @@ Parameters ArgumentsCollector::collect(bool &success) const
|
||||
bool bigFileSizeGiven = false;
|
||||
bool proxySettingGiven = false;
|
||||
int pos;
|
||||
int port;
|
||||
int port = 22;
|
||||
for (pos = 1; pos < m_arguments.count() - 1; ++pos) {
|
||||
QString host;
|
||||
QString user;
|
||||
|
||||
@@ -51,7 +51,7 @@ SshConnectionParameters ArgumentsCollector::collect(bool &success) const
|
||||
bool timeoutGiven = false;
|
||||
bool proxySettingGiven = false;
|
||||
int pos;
|
||||
int port;
|
||||
int port = 22;
|
||||
|
||||
for (pos = 1; pos < m_arguments.count() - 1; ++pos) {
|
||||
QString user;
|
||||
|
||||
@@ -42,7 +42,7 @@ def main():
|
||||
test.fatal("Failed to activate kit %s" % kit)
|
||||
continue
|
||||
test.log("Running project Qt Quick UI Prototype (%s)" % kit)
|
||||
qmlViewer = modifyRunSettingsForHookIntoQtQuickUI(2, 1, workingDir, projectName, 11223, quick)
|
||||
qmlViewer = modifyRunSettingsForHookIntoQtQuickUI(1, 0, workingDir, projectName, 11223, quick)
|
||||
if qmlViewer!=None:
|
||||
qmlViewerPath = os.path.dirname(qmlViewer)
|
||||
qmlViewer = os.path.basename(qmlViewer)
|
||||
|
||||