R5.5: ElyTable right-click menus, Excel-style; three rounds used, last fixes tested
Grid and header menus share ely_office::menu with ElyDoc. Each item's availability is the kernel's state for the exact command it runs (patch 0045). Patch 0046 lets a header select its row or column while a shape is selected or its text is edited: the view shell ends the drawing edit, keeps the typed text, leaves drawing mode, then marks. Ely no longer sends Esc first. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
07c0b43542
commit
87886c8a8d
30 files changed
+1010
-106
No files matched your search
@@ -0,0 +1,86 @@
|
||||
LOK: read whether listed commands may run now
|
||||
|
||||
LOK pushes enable states only for a fixed list, and only after
|
||||
idle bindings update. A menu opened right after a selection needs
|
||||
the answer now, for commands outside that list (hide rows, column
|
||||
width, clear contents). getCommandValues(".uno:CommandStates?
|
||||
commands=.uno:A,.uno:B") flushes the dispatcher and asks it for
|
||||
each slot, as the menu bar would: true unless disabled or unknown
|
||||
to the current shells. A name that is no slot fails the read.
|
||||
|
||||
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
|
||||
--- a/desktop/source/lib/init.cxx
|
||||
+++ b/desktop/source/lib/init.cxx
|
||||
@@ -152,6 +152,7 @@
|
||||
#include <sfx2/docfile.hxx>
|
||||
#include <sfx2/viewsh.hxx>
|
||||
#include <sfx2/viewfrm.hxx>
|
||||
+#include <sfx2/msg.hxx>
|
||||
#include <sfx2/msgpool.hxx>
|
||||
#include <sfx2/dispatch.hxx>
|
||||
#include <sfx2/lokcomponenthelpers.hxx>
|
||||
@@ -6672,6 +6673,45 @@ enum class UndoOrRedo
|
||||
|
||||
}
|
||||
|
||||
+/// Whether each listed command may run now.
|
||||
+static char* getCommandStates(std::string_view aList)
|
||||
+{
|
||||
+ SfxViewShell* pViewShell = SfxViewShell::Current();
|
||||
+ if (!pViewShell)
|
||||
+ {
|
||||
+ SetLastExceptionMsg(u"CommandStates: no current view"_ustr);
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ SfxViewFrame& rFrame = pViewShell->GetViewFrame();
|
||||
+ SfxDispatcher* pDispatcher = rFrame.GetBindings().GetDispatcher();
|
||||
+ pDispatcher->Flush();
|
||||
+ const SfxSlotPool& rPool = SfxSlotPool::GetSlotPool(&rFrame);
|
||||
+ tools::JsonWriter aJson;
|
||||
+ {
|
||||
+ auto aStates = aJson.startNode("commandStates");
|
||||
+ sal_Int32 nIndex = 0;
|
||||
+ do
|
||||
+ {
|
||||
+ std::string_view aCommand = o3tl::getToken(aList, 0, ',', nIndex);
|
||||
+ if (!aCommand.starts_with(".uno:"))
|
||||
+ {
|
||||
+ SetLastExceptionMsg(u"CommandStates: not a .uno: command"_ustr);
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ const SfxSlot* pSlot = rPool.GetUnoSlot(OUString::fromUtf8(aCommand.substr(5)));
|
||||
+ if (!pSlot)
|
||||
+ {
|
||||
+ SetLastExceptionMsg(OUString::fromUtf8(aCommand) + u" : unknown command"_ustr);
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ SfxPoolItemHolder aState;
|
||||
+ const SfxItemState eState = pDispatcher->QueryState(pSlot->GetSlotId(), aState);
|
||||
+ aJson.put(aCommand, eState != SfxItemState::DISABLED && eState != SfxItemState::UNKNOWN);
|
||||
+ } while (nIndex >= 0);
|
||||
+ }
|
||||
+ return convertOString(aJson.finishAndGetAsOString());
|
||||
+}
|
||||
+
|
||||
/// Returns the JSON representation of either an undo or a redo stack.
|
||||
static char* getUndoOrRedo(LibreOfficeKitDocument* pThis, UndoOrRedo eCommand)
|
||||
{
|
||||
@@ -6808,6 +6848,7 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo
|
||||
static constexpr std::string_view aViewRowColumnHeaders(".uno:ViewRowColumnHeaders");
|
||||
static constexpr std::string_view aSheetGeometryData(".uno:SheetGeometryData");
|
||||
static constexpr std::string_view aFontSubset(".uno:FontSubset&name=");
|
||||
+ static constexpr std::string_view aCommandStates(".uno:CommandStates?commands=");
|
||||
|
||||
ITiledRenderable* pDoc = getTiledRenderable(pThis);
|
||||
if (!pDoc)
|
||||
@@ -6983,6 +7024,10 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo
|
||||
pDoc->getCellCursor(aJsonWriter);
|
||||
return convertOString(aJsonWriter.finishAndGetAsOString());
|
||||
}
|
||||
+ else if (aCommand.starts_with(aCommandStates))
|
||||
+ {
|
||||
+ return getCommandStates(aCommand.substr(aCommandStates.size()));
|
||||
+ }
|
||||
else if (aCommand.starts_with(aFontSubset))
|
||||
{
|
||||
return getFontSubset(aCommand.substr(aFontSubset.size()));
|
||||
@@ -0,0 +1,83 @@
|
||||
LOK: selecting a row or column leaves a drawing first
|
||||
|
||||
Calc's own headers call DrawDeselectAll before marking. Over LOK the
|
||||
header is the client's, and .uno:SelectRow / .uno:SelectColumn live
|
||||
only on the cell shell. While a shape is selected or its text is
|
||||
being edited, a drawing shell replaces the cell shell, so the command
|
||||
finds no slot and is dropped. The view shell now takes both slots in
|
||||
LOK: it ends any drawing edit (keeping the typed text), deselects,
|
||||
ends drawing mode as Escape does (rerunning the active tool's slot),
|
||||
then marks, as a header click does. Desktop keeps them on the cell
|
||||
shell only.
|
||||
|
||||
diff --git a/sc/sdi/tabvwsh.sdi b/sc/sdi/tabvwsh.sdi
|
||||
--- a/sc/sdi/tabvwsh.sdi
|
||||
+++ b/sc/sdi/tabvwsh.sdi
|
||||
@@ -42,6 +42,8 @@
|
||||
FID_TABLE_HIDE [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ]
|
||||
FID_TABLE_SHOW [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ]
|
||||
SID_SELECT_TABLES [ ExecMethod = Execute; StateMethod = GetState; ]
|
||||
+ SID_SELECT_COL [ ExecMethod = Execute; StateMethod = GetState; ]
|
||||
+ SID_SELECT_ROW [ ExecMethod = Execute; StateMethod = GetState; ]
|
||||
FID_TAB_MENU_SET_TAB_BG_COLOR [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ]
|
||||
FID_TAB_EVENTS [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ]
|
||||
}
|
||||
diff --git a/sc/source/ui/view/tabvwsh3.cxx b/sc/source/ui/view/tabvwsh3.cxx
|
||||
--- a/sc/source/ui/view/tabvwsh3.cxx
|
||||
+++ b/sc/source/ui/view/tabvwsh3.cxx
|
||||
@@ -45,6 +45,7 @@
|
||||
#include <reffact.hxx>
|
||||
#include <tabprotection.hxx>
|
||||
#include <protectiondlg.hxx>
|
||||
+#include <fupoor.hxx>
|
||||
#include <kitsheet.hxx>
|
||||
#include <docfunc.hxx>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
@@ -1304,6 +1305,31 @@
|
||||
rReq.Done();
|
||||
break;
|
||||
|
||||
+ // A drawing shell is on top: leave it, then mark.
|
||||
+ case SID_SELECT_COL:
|
||||
+ case SID_SELECT_ROW:
|
||||
+ {
|
||||
+ const SfxInt32Item* pIndex = rReq.GetArg<SfxInt32Item>(FN_PARAM_1);
|
||||
+ const SfxInt16Item* pModifier = rReq.GetArg<SfxInt16Item>(FN_PARAM_2);
|
||||
+ DrawDeselectAll();
|
||||
+ // End drawing mode as Escape does: rerun the tool's slot.
|
||||
+ if (FuPoor* pFunc = GetDrawFuncPtr(); pFunc && IsDrawSelMode())
|
||||
+ GetViewData().GetDispatcher().Execute(pFunc->GetSlotID(), SfxCallMode::SLOT | SfxCallMode::RECORD);
|
||||
+ if (nSlot == SID_SELECT_COL)
|
||||
+ {
|
||||
+ if (pIndex && pModifier)
|
||||
+ MarkColumns(static_cast<SCCOL>(pIndex->GetValue()), pModifier->GetValue());
|
||||
+ else
|
||||
+ MarkColumns();
|
||||
+ }
|
||||
+ else if (pIndex && pModifier)
|
||||
+ MarkRows(static_cast<SCROW>(pIndex->GetValue()), pModifier->GetValue());
|
||||
+ else
|
||||
+ MarkRows();
|
||||
+ rReq.Done();
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
case SID_SELECT_TABLES:
|
||||
{
|
||||
ScViewData& rViewData = GetViewData();
|
||||
diff --git a/sc/source/ui/view/tabvwsha.cxx b/sc/source/ui/view/tabvwsha.cxx
|
||||
--- a/sc/source/ui/view/tabvwsha.cxx
|
||||
+++ b/sc/source/ui/view/tabvwsha.cxx
|
||||
@@ -553,6 +553,12 @@
|
||||
rSet.DisableItem( nWhich ); // enabled only if several sheets are selected
|
||||
break;
|
||||
|
||||
+ case SID_SELECT_COL:
|
||||
+ case SID_SELECT_ROW:
|
||||
+ if (!comphelper::LibreOfficeKit::isActive())
|
||||
+ rSet.DisableItem( nWhich ); // desktop: the cell shell owns them
|
||||
+ break;
|
||||
+
|
||||
case FID_TOGGLEHIDDENCOLROW:
|
||||
const svtools::ColorConfig& rColorCfg = ScModule::get()->GetColorConfig();
|
||||
rSet.Put( SfxBoolItem( nWhich, rColorCfg.GetColorValue(svtools::CALCHIDDENROWCOL).bIsVisible) );
|
||||
Reference in new issue
Block a user