On macOS, "Tools - Macros - Organize Macros - Basic... - Macro From:"
erroneously listed all the per-application modules ("Access2Base", "Depot",
"Euro", ...) under "My Macros" instead of "Application Macros".
Change-Id: Ic997ab30d9205d8402136ea381745c08ce555623
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146673
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
If the Standard library is empty (has no modules), when the Basic IDE is opened it shows only a black screen with nothing.
This patch makes it so that when the Standard library has no modules, a generic module is created and shown.
Change-Id: I26dbe41b4244492a21649ab08c5fc2df24ca12a9
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145309
Reviewed-by: Heiko Tietze <heiko.tietze@documentfoundation.org>
Tested-by: Jenkins
UITest_writer_macro_tests occasionally failed with
> ==3730889==ERROR: AddressSanitizer: heap-use-after-free on address 0x60d00057d080 at pc 0x7f75353d933c bp 0x7ffcedf8de90 sp 0x7ffcedf8de88
> READ of size 8 at 0x60d00057d080 thread T0
> #0 in basctl::ModulWindow::GetState(SfxItemSet&) at basctl/source/basicide/baside2.cxx:1088:22
> #1 in basctl::Shell::GetState(SfxItemSet&) at basctl/source/basicide/basides1.cxx:1160:18
> #2 in SfxStubbasctl_ShellGetState(SfxShell*, SfxItemSet&) at workdir/SdiTarget/basctl/sdi/basslots.hxx:164:1
> #3 in SfxDispatcher::FillState_(SfxSlotServer const&, SfxItemSet&, SfxSlot const*) at sfx2/source/control/dispatch.cxx:1658:9
> #4 in SfxBindings::Update_Impl(SfxStateCache&) at sfx2/source/control/bindings.cxx:260:22
> #5 in SfxBindings::NextJob_Impl(Timer const*) at sfx2/source/control/bindings.cxx:1275:17
> #6 in SfxBindings::NextJob(Timer*) at sfx2/source/control/bindings.cxx:1220:5
> #7 in SfxBindings::LinkStubNextJob(void*, Timer*) at sfx2/source/control/bindings.cxx:1218:1
> #8 in Link<Timer*, void>::Call(Timer*) const at include/tools/link.hxx:111:45
> #9 in Timer::Invoke() at vcl/source/app/timer.cxx:75:21
> #10 in Scheduler::CallbackTaskScheduling() at vcl/source/app/scheduler.cxx:481:20
> #11 in SalTimer::CallCallback() at vcl/inc/saltimer.hxx:54:13
> #12 in SvpSalInstance::CheckTimeout(bool) at vcl/headless/svpinst.cxx:161:53
> #13 in SvpSalInstance::ImplYield(bool, bool) at vcl/headless/svpinst.cxx:399:17
> #14 in SvpSalInstance::DoYield(bool, bool) at vcl/headless/svpinst.cxx:471:21
> #15 in ImplYield(bool, bool) at vcl/source/app/svapp.cxx:475:48
> #16 in Application::Yield() at vcl/source/app/svapp.cxx:559:5
> #17 in Application::Execute() at vcl/source/app/svapp.cxx:453:13
> #18 in desktop::Desktop::Main() at desktop/source/app/app.cxx:1604:13
> #19 in ImplSVMain() at vcl/source/app/svmain.cxx:203:35
> #20 in SVMain() at vcl/source/app/svmain.cxx:235:12
> #21 in soffice_main at desktop/source/app/sofficemain.cxx:94:12
> #22 in sal_main at desktop/source/app/main.c:51:15
> #23 in main at desktop/source/app/main.c:49:1
>
> 0x60d00057d080 is located 0 bytes inside of 144-byte region [0x60d00057d080,0x60d00057d110)
> freed by thread T20 here:
> #0 in operator delete(void*, unsigned long) at /home/sbergman/github.com/llvm/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:164:3
> #1 in basctl::ModulWindow::~ModulWindow() at basctl/source/basicide/baside2.cxx:235:1
> #2 in VclReferenceBase::release() const at include/vcl/vclreferencebase.hxx:43:13
> #3 in rtl::Reference<basctl::BaseWindow>::~Reference() at include/rtl/ref.hxx:129:22
> #4 in VclPtr<basctl::BaseWindow>::disposeAndClear() at include/vcl/vclptr.hxx:209:5
> #5 in basctl::Shell::~Shell() at basctl/source/basicide/basidesh.cxx:246:23
> #6 in basctl::Shell::~Shell() at basctl/source/basicide/basidesh.cxx:228:1
> #7 in SfxViewFrame::ReleaseObjectShell_Impl() at sfx2/source/view/viewfrm.cxx:1114:9
> #8 in SfxViewFrame::~SfxViewFrame() at sfx2/source/view/viewfrm.cxx:1905:5
> #9 in SfxViewFrame::Close() at sfx2/source/view/viewfrm.cxx:1166:5
> #10 in SfxFrame::DoClose_Impl() at sfx2/source/view/frame.cxx:138:37
> #11 in SfxBaseController::dispose() at sfx2/source/view/sfxbasecontroller.cxx:931:28
> #12 in (anonymous namespace)::XFrameImpl::setComponent(com::sun::star::uno::Reference<com::sun::star::awt::XWindow> const&, com::sun::star::uno::Reference<com::sun::star::frame::XController> const&) at framework/source/services/frame.cxx:1493:33
> #13 in (anonymous namespace)::XFrameImpl::close(unsigned char) at framework/source/services/frame.cxx:1704:12
> #14 in SfxFrame::DoClose() at sfx2/source/view/frame.cxx:104:29
> #15 in SfxViewFrame::Notify(SfxBroadcaster&, SfxHint const&) at sfx2/source/view/viewfrm.cxx:1703:28
> #16 in SfxBroadcaster::Broadcast(SfxHint const&) at svl/source/notify/SfxBroadcaster.cxx:40:24
> #17 in (anonymous namespace)::SfxModelListener_Impl::notifyClosing(com::sun::star::lang::EventObject const&) at sfx2/source/doc/objxtor.cxx:145:12
> #18 in SfxBaseModel::close(unsigned char) at sfx2/source/doc/sfxbasemodel.cxx:1487:76
> #19 in SfxBaseModel::dispose() at sfx2/source/doc/sfxbasemodel.cxx:725:13
> #20 in gcc3::callVirtualMethod(void*, unsigned int, void*, _typelib_TypeDescriptionReference*, bool, unsigned long*, unsigned int, unsigned long*, double*) at bridges/source/cpp_uno/gcc3_linux_x86-64/callvirtualmethod.cxx:77:5
> #21 in cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy*, bridges::cpp_uno::shared::VtableSlot, _typelib_TypeDescriptionReference*, int, _typelib_MethodParameter*, void*, void**, _uno_Any**) at bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:233:13
> #22 in unoInterfaceProxyDispatch at bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx:413:13
> #23 in binaryurp::IncomingRequest::execute_throw(binaryurp::BinaryAny*, std::__debug::vector<binaryurp::BinaryAny, std::allocator<binaryurp::BinaryAny>>*) const at binaryurp/source/incomingrequest.cxx:236:13
> #24 in binaryurp::IncomingRequest::execute() const at binaryurp/source/incomingrequest.cxx:79:26
> #25 in request at binaryurp/source/reader.cxx:86:9
> #26 in cppu_threadpool::JobQueue::enter(void const*, bool) at cppu/source/threadpool/jobqueue.cxx:100:17
> #27 in cppu_threadpool::ORequestThread::run() at cppu/source/threadpool/thread.cxx:165:31
> #28 in threadFunc at include/osl/thread.hxx:189:15
> #29 in osl_thread_start_Impl(void*) at sal/osl/unx/thread.cxx:265:9
where the ModulWindow apparently happens to get deleted by the UNO worker thread
in the window of time when ModuleWindow::IsPasteAllowed temporarily dropped the
SolarMutex on the main thread.
Temporarily dropping the SolarMutex around the xClipboard->getContents() call
had been there ever since the code got introduced in
c29c7a86c8 "#92173# Reimplement Basic password
protection UI in Basic IDE", and at least theoretically it is of course the
right thing to do to not call that UNO API with the SolarMutex locked. But it
is of course also not a good idea to use SolarMutexReleaser, and that
xClipboard->getContents() call doesn't look like it leads to deadlock.
Change-Id: I3660065508d37801125f675440071d61e41906d1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146650
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
probably good in trunk since:
commit 6e2bd11251
Date: Sun Aug 7 12:49:11 2022 +0100
tdf#150291 Revert "Fix crash when no valid EntryDescriptor found"
but still visible in 7-4
Change-Id: I63898ed3e33f73f8a93528872449539c5df6574f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146645
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
if its a high contrast mode with white text on black background. Reuse
isOutputToWindow to distinguish between the case we are outputting to
screen but not using a vcl::Window (and want to use the appropiate color
for autocolor) vs the cases we are printing or exporting to pdf and not
using a vcl::Window where the color should be black.
Change-Id: Ib688892a6315fe88ba585613539088611d3995ad
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145234
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
In SdrPaintView (and subclasses) the mpModel variable is always
the same as the input (reference) model, so there is no need for
that extra variable.
Change the strange and confusing var. name mrSdrModelFromSdrView
(the input reference to SdrModel) to just mrModel and use that in
GetModel(). Change the GetModel() to return a reference instead
of a pointer and reactor the code to accomodate the change.
This gets rid of many nullptr checks for the pointer that the
GetModel() returns and makes the code more simple is some cases.
Change-Id: I18351a417fd82f49262a83de036ec1420a65399c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146373
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
This patch creates a separate color configuration entry for the background of the Basic Editor (svtools::BASICEDITOR). This allows the user to set the color of the Basic Editor independently from the color used as document background.
Currently the color used is DOCCOLOR, which means that if the user wants to use a different color in the Basic Editor, they must change the document color as well. However, the user may want to use f.i. a dark background in the Basic editor while maintaining a white color for documents, which is currently not possible.
By default, both color schemes "LibreOffice" and "LibreOffice Dark" use the same color for DOCCOLOR and BASICEDITOR to replicate the existing behavior. But now, if the user wants to use a different color for the Basic Editor, than it's possible to change it without affecting the color of documents.
Change-Id: I2f33b1ccb497d7e22faab7fa48cb96841785ce99
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145590
Tested-by: Jenkins
Reviewed-by: Heiko Tietze <heiko.tietze@documentfoundation.org>
As discussed in the ticket the Basic IDE does not make it clear that the currently opened module is read-only, which can cause confusion to the user, since they may be pressing keys and seeing no result.
With this patch the IDE clarifies that the module/dialog is read-only in two ways:
1) In the status bar the string "(Read-only)" is added after the module/dialog name
2) When a module/dialog is opened an infobar is shown warning that it is read-only.
3) In a module, if the user closed the infobar and tries to edit the code, the infobar is shown again.
Change-Id: I15197c4316bb2ed19e54be0c33f4fb61b5bbd862
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145307
Tested-by: Jenkins
Reviewed-by: Heiko Tietze <heiko.tietze@documentfoundation.org>
While editing dialogs in the Basic IDE the background of controls as labels, radio buttons and checkboxes is wrong. They're black in dark themes and white in light themes.
The correct color should be FaceColor to make it have the same backround as the window.
Change-Id: If436b0034dd7a665fc779e0df793703562adb5a2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144363
Tested-by: Jenkins
Reviewed-by: Heiko Tietze <heiko.tietze@documentfoundation.org>
Show "macros" and "events" for now if we know that are present so
they can be investigated by the user. There are other things which
could potentially be added in the future.
Change-Id: I981ee7a8e22791cd15405894f30fee659ba0b7ba
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143897
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Currently, the Basic IDE has a shared horizontal scrollbar used both for the code editor window and the dialog editor window.
However, the problem is that this causes the horizontal scrollbar to be placed at an unintuitive place when the code editor is being used. To avoid this problem the code editor already has its own vertical scrollbar.
This patch creates a separate horizontal scrollbar for the code editor window and places it underneath the editor window to make it clearer what this scrollbar is meant to scroll.
Change-Id: Ib873c004db902f0f729fd512c51effd8f5e38a9d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143580
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
This patch adds a ZoomSlider to thee Basic IDE. It has the following characteristics:
- The Zoom varies from 50% to 400% considering that 100% is the font size defined in Tools - Options - Fonts dialog.
- All open editor windows use the same Zoom factor
- The zoom level is saved and restored across sessions
Change-Id: I63df02d0dc828fca4360d61b8aa2c7af6610d4db
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143159
Tested-by: Jenkins
Tested-by: Heiko Tietze <heiko.tietze@documentfoundation.org>
Reviewed-by: Heiko Tietze <heiko.tietze@documentfoundation.org>
With 16k column support in Calc enabled by default in
commit 4c5f8ccf0a
Date: Tue Mar 8 12:44:49 2022 +0100
change default Calc number of columns to 16384 (tdf#50916)
, the number of Calc cells in a spreadsheet is larger than
SAL_MAX_INT32, meaning that a 32-bit a11y child index is no more
enough and using it resulted in integer overflows in
methods handling corresponding Calc cells in the a11y layer.
This e.g. had the effect of the Orca and NVDA screen readers
not announcing focused or selected cells properly when their
a11y child index was out of the 32-bit integer range.
Switch the internal a11y child indices to 64 bit to
be able to handle this properly internally.
Since the platform APIs (at least AT-SPI on Linux and
IAccessible2 on Windows; from what I can see LO's macOS
a11y bridge doesn't directly expose the child index)
are still restricted to 32 bit, larger child indices
still cannot be exposed via the platform APIs.
As a consequence, use of the the IAccessible2 and
AT-SPI methods that use the child index remains
problematic in those cases where the child index
is larger. However, as an alternative to using the
AT-SPI Table interface and the IAccessibleTable/
IAccessibleTable2 interfaces with the child index
to retrieve information about a specific cell,
both AT-SPI and IAccessible2 also provide interfaces
to retrieve that information directly
from the cell object (TableCell interface for AT-SPI,
IAccessibleTableCell for IAccessible2).
Those interfaces are already implemented/exposed
for winaccessibility (s. `CAccTable`) and the
qt5/qt6/kf5 VCL plugins (s. the `QAccessibleTableCellInterface`
methods implemented in `QtAccessibleInterface`).
With the switch to 64-bit internal a11y child indices,
these now behave correctly for cells with a child
index that doesn't fit into 32 bit as well.
NVDA on Windows already uses the IAccessibleTableCell
interface and thus announcing focused cells works fine
with this change in place.
Orca on Linux currently doesn't make use of the AT-SPI
TableCell interface yet, but with a suggested change to
do so [1], announcement of selected cells works
with the qt6 VCL plugin with a current qtbase dev branch
as well - when combined with the suggested changes
to implement support for the AT-SPI TableCell interface
in Qt [2] [3] and the LO change based on that [4] and
a fix for a nullptr dereference [5].
The gtk3 VCL plugin doesn't expose the AT-SPI
TableCell interface yet, but once it does so
(via `AtkTableCell`), it also works with the
suggested Orca change [1] in place.
(Adding that is planned for an upcoming change,
works with a local WIP patch.)
For handling return values that are larger than what
platform APIs support, the following approach has
been chosen for now:
1) When the return value is for the count of
(selected) children, the maximum value N
supported by the platform API is returned.
(This is what `ScAccessibleTableBase::getAccessibleChildCount`
did previously.)
The first N elements can be accessed by their
actual (selection) indices.
2) When the return value is the child/cell index,
-2 is returned for objects whose index is greater
than the maximum value supported by the platform
API.
Using a non-negative value would mean that the
index would refer to *another* actually existing
child. A child index of -1 on the other hand
tends to be interpreted as "child is invalid" or
"object isn't actually a child of its (previous)
parent any more)". For the Orca case, this would
result in objects with a child index of -1
not being announced, as they are considered
"zombies" [6].
What's still somewhat problematic is the case where
more than 2^31 children are *selected*, since access
to those children still happens by the index into
the selection in the platform APIs, and not all
selected items are accessible this way.
(Screen readers usually just retrieve
the first and last element from the selection and
announce those.)
Orca already seems to apply different handling for the
case for fully selected rows and columns, so
"All cells selected" or "Columns ... to ... selected"
is announced just fine even if more than 2^31
cells are selected.
(Side note: While Microsoft User Interface
Automation - UIA - also uses 32-bit indices, it also
has specific methods in the ISelectionProvider2
interface that allow to explicitly retrieve the
first and last selected item,
`ISelectionProvider2::get_FirstSelectedItem` and
`ISelectionProvider2::get_LastSelectedItem`, but
we currently don't support UIA on Windows.)
Bound checks at the beginning of the methods from the
`XAccessibleContext`, `XAccessibleSelection` and
`XAccessibleTable` interfaces that take a child index
(or in helper methods called by those) should generally
already prevent too large indices from being passed to
the methods in the lower layer code that take smaller
integer types. Such bound checking has been
been added in various places where it wasn't present yet.
If there any remaining issues of this
kind that show after this commit, they can probably be
solved in a similar way (s.e.g. the change to
`AccessibleBrowseBox::getAccessibleChild` in this
commit).
A few asserts were also added at
places where my understanding is that values shouldn't
be larger than what is supported by a called method
anyway.
A test case will be added in a following change.
[1] https://gitlab.gnome.org/GNOME/orca/-/merge_requests/131
[2] https://codereview.qt-project.org/c/qt/qtbase/+/428566
[3] https://codereview.qt-project.org/c/qt/qtbase/+/428567
[4] https://gerrit.libreoffice.org/c/core/+/138750
[5] https://codereview.qt-project.org/c/qt/qtbase/+/430157
[6] https://gitlab.gnome.org/GNOME/orca/-/blob/82c8542002e36e0d3d918088d583162d25136143/src/orca/script_utilities.py#L5155
Change-Id: I3af590c988b0e6754fc72545918412f39e8fea07
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139258
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Which means we can get rid of the majestic hack of ScCaptionPtr
Previously, SdrObject was manually managed, and the ownership
passed around in very complicated fashion.
Notes:
(*) SvxShape has a strong reference to SdrObject, where
previously it had a weak reference. It is now strong
since otherwise the SdrObject will go away very eagerly.
(*) SdrObject still has a weak reference to SvxShape
(*) In the existing places that an SdrObject is being
deleted, we now just clear the reference
(*) instead of SwVirtFlyDrawObj removing itself from the
page that contains inside it's destructor, make the call site
do the removing from the page.
(*) Needed to take the SolarMutex in UndoManagerHelper_Impl::impl_clear
because this can be called from UNO (e.g. sfx2_complex JUnit test)
and the SdrObjects need the SolarMutex when destructing.
(*) handle a tricky situation with SwDrawVirtObj in the SwDrawModel
destructor because the existing code wants mpDrawObj in
SwAnchoredObject to be sometimes owning, sometimes not, which
results in a cycle with the new code.
Change-Id: I4d79df1660e386388e5d51030653755bca02a163
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138837
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
...so that its TOOLS_WARN_EXCEPTION can be used in
comphelper/source/misc/logging.cxx in a follow-up commit. (And while at it,
rename from diangose_ex.h to the more appropriate diagnose_ex.hxx. The
comphelper module is sufficiently low-level for this immediate use case, so use
that at least for now; o3tl might be even more suitable but doesn't have a
Library until now. Also, for the immediate use case it would have sufficed to
only break DbgGetCaughtException, exceptionToString, TOOLS_WARN_EXCEPTION,
TOOLS_WARN_EXCEPTION_IF, and TOOLS_INFO_EXCEPTION out of
include/tools/diagnose_ex.h into an additional new
include/comphelper/diagnose_ex.hxx, but its probably easier overall to just move
the complete include file as is.)
Change-Id: I9f3222d4ccf1a9ac29d7eb9ba1530d53e2affaee
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/138451
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
This reverts commit 499ecbf3a3 because
it causes the dialog not to start with the default selected macro
auto-expanded like it used to. Possibly the other fix for tdf#150291
solves the original problem.
Change-Id: Ic91410de073fe87d4edebde18b60ffcc1ad324a3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137923
Tested-by: Jenkins
Tested-by: Caolán McNamara <caolanm@redhat.com>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
which is internal API, unused (as far as I can tell) by external
users.
This state is purely a bitset
(as implemented by utl::AccessibleStateSetHelper)
so we can just return it as a 64-bit value.
This shaves significant time off the performance profiles
of code that loads very complex shapes, because this state
is frequently used, and we no longer need to allocate a return
value on the heap for every call.
Change-Id: Icf1b3bd367c256646ae9015f9127025f59459c2c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136786
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
When opening macro run dlg, the last selected entry is displayed again.
When no entry was found, a crash occured in some situations
(GetLastEntryDescriptor() returned garbage).
Initialize m_aLastEntryDesc properly, and make sure the method returns
when no last selected macro was found.
Also fix some nullptr crashes which occurred during UITests
Change-Id: I7bd1a0b8824725f9935876ae26d8222410a3bc25
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136140
Tested-by: Jenkins
Reviewed-by: Samuel Mehrbrodt <samuel.mehrbrodt@allotropia.de>
announce to dnd that tree supports COPY and MOVE, but on accepting a drop
return MOVE only if that's something the AcceptDrop has set as desirable.
a) makes ctrl+dnd to select 'copy' work for gtk, including gtk on wayland
b) makes gen correctly draw its copy dnd icon.
git show -w
Change-Id: Ie985f8c9201634afc5ae717fd2aef0dbc18a39e4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134486
Tested-by: Caolán McNamara <caolanm@redhat.com>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
otherwise we double-free it, so do what TreeListBox::CloneEntry used to
before it was dropped as unused at
commit 4a72d6f474
Date: Tue Feb 11 13:50:50 2020 +0000
drop newly unused TreeListBox
Change-Id: I127511ef4f752cf9a2da26a541e6f1add2a9cf9a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134484
Tested-by: Caolán McNamara <caolanm@redhat.com>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>