Merge "Merge remote-tracking branch 'origin/15.0'"

This commit is contained in:
The Qt Project
2025-01-16 08:32:58 +00:00
21 changed files with 88 additions and 32 deletions

View File

@@ -69,10 +69,16 @@ if(Crashpad_FOUND)
"${CRASHPAD_INCLUDE_DIR}/third_party/mini_chromium/mini_chromium"
"${CRASHPAD_GEN_DIR}")
if(WIN32)
set(COMMON_LIB "${CRASHPAD_LIB_DIR}/client/common.lib")
# might not exist in older versions
if (NOT EXISTS "${COMMON_LIB}")
set(COMMON_LIB "")
endif()
target_link_libraries(Crashpad::Crashpad INTERFACE
"${CRASHPAD_LIB_DIR}/third_party/mini_chromium/mini_chromium/base/base.lib"
"${CRASHPAD_LIB_DIR}/util/util.lib"
"${CRASHPAD_LIB_DIR}/client/client.lib"
"${COMMON_LIB}"
advapi32)
set_target_properties(Crashpad::Crashpad PROPERTIES
IMPORTED_LOCATION "${CRASHPAD_LIB_DIR}/client/client.lib")

View File

@@ -60,6 +60,7 @@
<li><a href="creator-how-tos.html#manage-projects">Manage Projects</a></li>
<li><a href="creator-how-tos.html#read-documentation">Read Documentation</a></li>
<li><a href="creator-how-tos.html#test">Test</a></li>
<li><a href="creator-how-tos.html#use-git">Use Git</a></li>
<li><a href="creator-how-tos.html#use-qt-creator">Use Qt Creator</a></li>
<li><a href="creator-how-tos.html#use-the-ui">Use the UI</a></li>
<li><a href="creator-how-tos.html">How To</a></li>

View File

@@ -103,7 +103,8 @@
\li \l{Change text encoding}
\row
\li \inlineimage icons/languageclient.png
\li View the language server for the current project, restart it, select
\li View the language server for the current project (such as clangd),
restart it, select
another one, \l{Inspect language clients}{inspect the communication}
between \QC and language servers, view server capabilities, and set
language server preferences.

View File

@@ -91,6 +91,8 @@ Module {
"QT_RESTRICTED_CAST_FROM_ASCII",
"QT_NO_FOREACH",
"QT_DISABLE_DEPRECATED_BEFORE=0x050900",
"QT_WARN_DEPRECATED_BEFORE=0x060400",
"QT_WARN_DEPRECATED_UP_TO=0x060400",
"QT_USE_QSTRINGBUILDER",
"QT_NO_QSNPRINTF",
].concat(withPluginTests ? ["WITH_TESTS"] : [])

View File

@@ -188,6 +188,7 @@ class DumperBase():
self.typeData = {}
self.isBigEndian = False
self.packCode = '<'
self.byteorder = 'little'
self.resetCaches()
self.resetStats()
@@ -1560,17 +1561,17 @@ class DumperBase():
primaryOpcode = data[0]
if primaryOpcode == relativeJumpCode:
# relative jump on 32 and 64 bit with a 32bit offset
offset = int.from_bytes(data[1:5], byteorder='little')
offset = int.from_bytes(data[1:5], byteorder=self.byteorder)
return address + 5 + offset
if primaryOpcode == jumpCode:
if data[1] != 0x25: # check for known extended opcode
return 0
# 0xff25 is a relative jump on 64bit and an absolute jump on 32 bit
if self.ptrSize() == 8:
offset = int.from_bytes(data[2:6], byteorder='little')
offset = int.from_bytes(data[2:6], byteorder=self.byteorder)
return address + 6 + offset
else:
return int.from_bytes(data[2:6], byteorder='little')
return int.from_bytes(data[2:6], byteorder=self.byteorder)
return 0
# Do not try to extract a function pointer if there are no values to compare with

View File

@@ -666,6 +666,7 @@ class Dumper(DumperBase):
self.isBigEndian = gdb.execute('show endian', to_string=True).find('big endian') > 0
self.packCode = '>' if self.isBigEndian else '<'
self.byteorder = 'big' if self.isBigEndian else 'little'
(ok, res) = self.tryFetchInterpreterVariables(args)
if ok:

View File

@@ -178,6 +178,7 @@ class DumperBase():
self.isBigEndian = False
self.packCode = '<'
self.byteorder = 'little'
self.resetCaches()
self.resetStats()
@@ -1767,17 +1768,17 @@ class DumperBase():
primaryOpcode = data[0]
if primaryOpcode == relativeJumpCode:
# relative jump on 32 and 64 bit with a 32bit offset
offset = int.from_bytes(data[1:5], byteorder='little')
offset = int.from_bytes(data[1:5], byteorder=self.byteorder)
return address + 5 + offset
if primaryOpcode == jumpCode:
if data[1] != 0x25: # check for known extended opcode
return 0
# 0xff25 is a relative jump on 64bit and an absolute jump on 32 bit
if self.ptrSize() == 8:
offset = int.from_bytes(data[2:6], byteorder='little')
offset = int.from_bytes(data[2:6], byteorder=self.byteorder)
return address + 6 + offset
else:
return int.from_bytes(data[2:6], byteorder='little')
return int.from_bytes(data[2:6], byteorder=self.byteorder)
return 0
# Do not try to extract a function pointer if there are no values to compare with
@@ -2532,7 +2533,7 @@ typename))
def extract_pointer_at_address(self, address):
blob = self.value_data_from_address(address, self.ptrSize())
return int.from_bytes(blob, byteorder='little')
return int.from_bytes(blob, byteorder=self.byteorder)
def value_extract_integer(self, value, size, signed):
if isinstance(value.lvalue, int):
@@ -2542,7 +2543,7 @@ typename))
#with self.dumper.timer('extractInt'):
value.check()
blob = self.value_data(value, size)
return int.from_bytes(blob, byteorder='little', signed=signed)
return int.from_bytes(blob, byteorder=self.byteorder, signed=signed)
def value_extract_something(self, valuish, size, signed=False):
if isinstance(valuish, int):
@@ -2551,7 +2552,7 @@ typename))
blob = self.value_data(valuish, size)
else:
raise RuntimeError('CANT EXTRACT FROM %s' % type(valuish))
res = int.from_bytes(blob, byteorder='little', signed=signed)
res = int.from_bytes(blob, byteorder=self.byteorder, signed=signed)
#self.warn("EXTRACTED %s SIZE %s FROM %s" % (res, size, blob))
return res

View File

@@ -679,6 +679,7 @@ class Dumper(DumperBase):
self.isBigEndian = gdb.execute('show endian', to_string=True).find('big endian') > 0
self.packCode = '>' if self.isBigEndian else '<'
self.byteorder = 'big' if self.isBigEndian else 'little'
#(ok, res) = self.tryFetchInterpreterVariables(args)
#if ok:

View File

@@ -146,7 +146,7 @@ class Dumper(DumperBase):
target_typeid = self.from_native_type(nativeTargetType)
target_address = nativeValue.GetValueAsUnsigned()
val = self.Value(self)
val.ldata = target_address.to_bytes(self.ptrSize(), 'little')
val.ldata = target_address.to_bytes(self.ptrSize(), self.byteorder)
if self.useDynamicType:
target_typeid = self.dynamic_typeid_at_address(target_typeid, target_address)
val.typeid = self.create_reference_typeid(target_typeid)
@@ -1381,6 +1381,9 @@ class Dumper(DumperBase):
return
self.isArmMac = frame.module.triple.startswith('arm64-apple')
self.isBigEndian = frame.module.byte_order == lldb.eByteOrderBig
self.packCode = '>' if self.isBigEndian else '<'
self.byteorder = 'big' if self.isBigEndian else 'little'
self.output = []
isPartial = len(self.partialVariable) > 0

View File

@@ -463,6 +463,11 @@ void startCrashpad(const AppInfo &appInfo, bool crashReportingEnabled)
->set_gather_indirectly_referenced_memory(crashpad::TriState::kEnabled, 0);
}
// Explicitly enable Crashpad handling. This is the default in vanilla Crashpad,
// but we use a version that only handles processes that enable it explicitly,
// so we do not handle arbitrary subprocesses
CrashpadInfo::GetCrashpadInfo()->set_crashpad_handler_behavior(crashpad::TriState::kEnabled);
// Optional arguments to pass to the handler
std::vector<std::string> arguments;
arguments.push_back("--no-rate-limit");

View File

@@ -286,7 +286,8 @@ if (_library_enabled)
# Deploy lldb.exe and its Python dependency
find_package(Clang QUIET)
if (LLVM_TOOLS_BINARY_DIR AND LLVM_LIBRARY_DIRS)
foreach(lldb_file lldb.exe lldb-dap.exe liblldb.dll python311.zip python311.dll)
file(GLOB python_files RELATIVE ${LLVM_TOOLS_BINARY_DIR} "${LLVM_TOOLS_BINARY_DIR}/python*")
foreach(lldb_file lldb.exe lldb-dap.exe liblldb.dll ${python_files})
if (EXISTS ${LLVM_TOOLS_BINARY_DIR}/${lldb_file})
install(FILES ${LLVM_TOOLS_BINARY_DIR}/${lldb_file}
DESTINATION bin/clang/bin
@@ -298,7 +299,7 @@ if (_library_enabled)
install(DIRECTORY ${LLVM_LIBRARY_DIRS}/site-packages
DESTINATION bin/clang/lib
COMPONENT qtcreatorcdbext
PATTERN _lldb.cp311-win_amd64.pyd EXCLUDE)
PATTERN "_lldb.cp*64.pyd" EXCLUDE)
endif()
endif()
endif()

View File

@@ -703,6 +703,12 @@ void Layout::setFieldGrowthPolicy(int policy)
lt->setFieldGrowthPolicy(QFormLayout::FieldGrowthPolicy(policy));
}
void Layout::setStretch(int index, int stretch)
{
if (auto lt = asBox())
lt->setStretch(index, stretch);
}
QWidget *Layout::emerge() const
{
const_cast<Layout *>(this)->flush();
@@ -809,6 +815,11 @@ void Widget::setCursor(Qt::CursorShape shape)
access(this)->setCursor(shape);
}
void Widget::setMinimumWidth(int minw)
{
access(this)->setMinimumWidth(minw);
}
void Widget::setSizePolicy(const QSizePolicy &policy)
{
access(this)->setSizePolicy(policy);
@@ -1160,6 +1171,11 @@ LayoutModifier spacing(int space)
return [space](Layout *layout) { layout->setSpacing(space); };
}
LayoutModifier stretch(int index, int stretch)
{
return [index, stretch](Layout *layout) { layout->setStretch(index, stretch); };
}
void addToLayout(Layout *layout, const Space &inner)
{
if (auto lt = layout->asBox())

View File

@@ -122,6 +122,7 @@ public:
void setColumnStretch(int column, int stretch);
void setSpacing(int space);
void setFieldGrowthPolicy(int policy);
void setStretch(int index, int stretch);
void attachTo(QWidget *);
@@ -264,6 +265,7 @@ public:
void setNormalMargins(int = 0);
void setContentsMargins(int left, int top, int right, int bottom);
void setCursor(Qt::CursorShape shape);
void setMinimumWidth(int);
void activateWindow();
void close();
@@ -617,6 +619,7 @@ QTCREATOR_UTILS_EXPORT void hr(Layout *);
QTCREATOR_UTILS_EXPORT void tight(Layout *); // noMargin + spacing(0)
QTCREATOR_UTILS_EXPORT LayoutModifier spacing(int space);
QTCREATOR_UTILS_EXPORT LayoutModifier stretch(int index, int stretch);
// Convenience

View File

@@ -127,10 +127,10 @@ expected_str<Unarchiver::SourceAndCommand> Unarchiver::sourceAndCommand(const Fi
static CommandLine unarchiveCommand(const CommandLine &commandTemplate, const FilePath &sourceFile,
const FilePath &destDir)
{
CommandLine command = commandTemplate;
command.setArguments(command.arguments().replace("%{src}", sourceFile.path())
.replace("%{dest}", destDir.path()));
return command;
const QStringList args = Utils::transform(commandTemplate.splitArguments(), [&](auto arg) {
return arg.replace("%{src}", sourceFile.path()).replace("%{dest}", destDir.path());
});
return CommandLine(commandTemplate.executable(), args);
}
void Unarchiver::start()

View File

@@ -113,11 +113,6 @@ static CMakeFileResult extractCMakeFilesData(const QFuture<void> &cancelFuture,
auto node = std::make_unique<FileNode>(info.path, FileType::Project);
node->setIsGenerated(info.isGenerated);
// We will have the CMakeLists.txt file in the Target nodes as a child node.
// Except the root CMakeLists.txt file.
if (info.isCMakeListsDotTxt && info.path.parentDir() != sourceDirectory)
node->setIsGenerated(true);
if (info.isCMakeListsDotTxt) {
result.cmakeListNodes.emplace_back(std::move(node));
} else if (info.path.isChildOf(sourceDirectory)) {

View File

@@ -420,11 +420,11 @@ public:
setTitle(Tr::tr("Accept Terms and Conditions"));
const QLatin1String legal = QLatin1String(
"I confirm that I have reviewed and accept the terms and conditions "
"of this extension. I confirm that I have the authority and ability to "
"accept the terms and conditions of this extension for the customer. "
"I acknowledge that if the customer and the Qt Company already have a "
"valid agreement in place, that agreement shall apply, but these terms "
"I confirm that I have reviewed and accept the terms and conditions\n"
"of this extension. I confirm that I have the authority and ability to\n"
"accept the terms and conditions of this extension for the customer.\n"
"I acknowledge that if the customer and the Qt Company already have a\n"
"valid agreement in place, that agreement shall apply, but these terms\n"
"shall govern the use of this extension.");
using namespace Layouting;

View File

@@ -114,6 +114,7 @@ CREATE_HAS_FUNC(setVisible, bool())
CREATE_HAS_FUNC(setIcon, Utils::Icon());
CREATE_HAS_FUNC(setContentsMargins, int(), int(), int(), int());
CREATE_HAS_FUNC(setCursor, Qt::CursorShape())
CREATE_HAS_FUNC(setMinimumWidth, int());
template<class T>
void setProperties(std::unique_ptr<T> &item, const sol::table &children, QObject *guard)
@@ -130,6 +131,12 @@ void setProperties(std::unique_ptr<T> &item, const sol::table &children, QObject
item->setCursor(*cursor);
}
if constexpr (has_setMinimumWidth<T>) {
const auto minw = children.get<sol::optional<int>>("minimumWidth");
if (minw)
item->setMinimumWidth(*minw);
}
if constexpr (has_setVisible<T>) {
const auto visible = children.get<sol::optional<bool>>("visible");
if (visible)
@@ -695,6 +702,7 @@ void setupGuiModule()
gui["normalMargin"] = &normalMargin;
gui["withFormAlignment"] = &withFormAlignment;
gui["spacing"] = &spacing;
gui["stretch"] = &stretch;
return gui;
});

View File

@@ -41,6 +41,7 @@ gui.baseWidgetOptions = {}
---@field fixedSize? integer[] Two integers representing the width and height
---@field contentMargins? integer[] Four integers represending left, top, right and bottom margins.
---@field cursor? CursorShape The cursor shape for the widget.
---@field minimumWidth? integer The minimum width in pixels.
gui.widgetOptions = {}
---@param options WidgetOptions
@@ -262,6 +263,11 @@ function gui.normalMargin() end
---Sets the alignment of a Grid layout according to the Form layout rules.
function gui.withFormAlignment() end
---Sets the stretch factor at position index to stretch.
---@param index integer The widget index.
---@param stretch integer The stretch factor.
function gui.stretch(index, stretch) end
--- Enum representing Text interaction flags
---@enum TextInteractionFlag
gui.TextInteractionFlag {

View File

@@ -91,7 +91,7 @@
<!-- Learning - first steps -->
<tutorial imageUrl=":qtsupport/images/icons/learn-qtc.webp" difficulty="" projectPath="" name="Getting Started: Qt Creator" isVideo="false" videoUrl="https://academy.qt.io/catalog/courses/4007722" videoLength="20:00">
<tutorial imageUrl=":qtsupport/images/icons/learn-qtc.webp" difficulty="" projectPath="" name="Getting Started: Qt Creator" docUrl="https://academy.qt.io/catalog/courses/4007722">
<description><![CDATA[Learn about Qt Creator.]]></description>
<tags>qt creator,ui,welcome,qt widgets designer,widgets,editing,debugging,learning,2024</tags>
<meta>
@@ -129,7 +129,7 @@
<!-- Learning - dig deeper -->
<tutorial imageUrl=":qtsupport/images/icons/learn-qtqui.webp" difficulty="" projectPath="" name="Introduction to Qt Quick" isVideo="false" videoUrl="https://academy.qt.io/catalog/courses/3799368" videoLength="60:00">
<tutorial imageUrl=":qtsupport/images/icons/learn-qtqui.webp" difficulty="" projectPath="" name="Introduction to Qt Quick" docUrl="https://academy.qt.io/catalog/courses/3799368">
<description><![CDATA[Learn about Qt Quick.]]></description>
<tags>qt,qt quick,2024</tags>
<meta>

View File

@@ -308,10 +308,13 @@ void StateListener::slotStateChanged()
state.clearPatchFile(); // Need a repository to patch
qCDebug(stateLog).noquote() << "VC:" << (vc ? vc->displayName() : QString("None")) << state;
QTimer::singleShot(500, this, [this, state, vc] {
auto updateState = [this, state, vc] {
EditorManager::updateWindowTitles();
emit stateChanged(state, vc);
});
};
updateState();
QTimer::singleShot(500, this, updateState); // QTCREATORBUG-31815
}
} // namespace Internal

View File

@@ -31,7 +31,9 @@ def commit(commitMessage, expectedLogMessage, uncheckUntracked=False):
def verifyItemsInGit(commitMessages):
gitEditor = waitForObject(":Qt Creator_Git::Internal::GitEditor")
waitFor("len(str(gitEditor.plainText)) > 0 and str(gitEditor.plainText) != 'Working...'", 20000)
if not waitFor("len(str(gitEditor.plainText))>0 and str(gitEditor.plainText)!='Working...'",
40000):
test.warning("Waiting for GitEditor timed out.")
plainText = str(gitEditor.plainText)
verifyItemOrder(commitMessages, plainText)
return plainText