class LayoutValueSet : public ValueSet
{ private:
LayoutMenu& mrMenu;
/** Calculate the number of displayed rows. This depends on the given itemsize,thegivennumberofcolumns,andthesizeofthe control.Notethatthisisnotthenumberofrowsmanagedbythe valueset.Thisnumbermaybelarger.Inthatcaseavertical scrollbarisdisplayed.
*/ int CalculateRowCount(const Size& rItemSize, int nColumnCount);
void LayoutMenu::implConstruct( DrawDocShell& rDocumentShell )
{
OSL_ENSURE( mrBase.GetDocument()->GetDocSh() == &rDocumentShell, "LayoutMenu::implConstruct: hmm?" ); // if this fires, then my assumption that the rDocumentShell parameter to our first ctor is superfluous ...
(void) rDocumentShell;
bool LayoutValueSet::Command(const CommandEvent& rEvent)
{ if (rEvent.GetCommand() != CommandEventId::ContextMenu) returnfalse;
// As a preparation for the context menu the item under the mouse is // selected. if (rEvent.IsMouseEvent())
{
sal_uInt16 nIndex = GetItemId(rEvent.GetMousePosPixel()); if (nIndex > 0)
SelectItem(nIndex);
}
// Call SID_INSERTPAGE with the right arguments. This is because // the popup menu can not call this slot with arguments directly.
SfxRequest aRequest (CreateRequest(SID_INSERTPAGE, aLayout)); if (aRequest.GetArgs() != nullptr)
{
pDispatcher->Execute(
SID_INSERTPAGE,
SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
*aRequest.GetArgs());
}
UpdateSelection();
}
void LayoutMenu::InvalidateContent()
{ // Throw away the current set and fill the menu anew according to the // current settings (this includes the support for vertical writing.)
Fill();
if (mxSidebar.is())
mxSidebar->requestLayout();
// set selection inside the control during Impress start up
UpdateSelection();
}
int LayoutValueSet::CalculateRowCount (const Size&, int nColumnCount)
{ int nRowCount = 0;
/** The specified layout is assigned to the current page of the view shell inthecenterpane.
*/ void LayoutMenu::AssignLayoutToSelectedSlides (AutoLayout aLayout)
{ usingnamespace ::sd::slidesorter; usingnamespace ::sd::slidesorter::controller;
do
{ // The view shell in the center pane has to be present.
ViewShell* pMainViewShell = mrBase.GetMainViewShell().get(); if (pMainViewShell == nullptr) break;
// Determine if the current view is in an invalid master page mode. // The handout view is always in master page mode and therefore not // invalid. bool bMasterPageMode (false); switch (pMainViewShell->GetShellType())
{ case ViewShell::ST_NOTES: case ViewShell::ST_IMPRESS:
{
DrawViewShell* pDrawViewShell = static_cast<DrawViewShell*>(pMainViewShell); if (pDrawViewShell->GetEditMode() == EditMode::MasterPage)
bMasterPageMode = true; break;
} default: break;
} if (bMasterPageMode) break;
// Get a list of all selected slides and call the SID_MODIFYPAGE // slot for all of them.
::sd::slidesorter::SharedPageSelection pPageSelection;
// Get a list of selected pages. // First we try to obtain this list from a slide sorter. This is // possible only some of the view shells in the center pane. When // no valid slide sorter is available then ask the main view shell // for its current page.
SlideSorterViewShell* pSlideSorter = nullptr; switch (pMainViewShell->GetShellType())
{ case ViewShell::ST_IMPRESS: case ViewShell::ST_NOTES: case ViewShell::ST_SLIDE_SORTER:
pSlideSorter = SlideSorterViewShell::GetSlideSorter(mrBase); break; default: break;
} if (pSlideSorter != nullptr)
{ // There is a slide sorter visible so get the list of selected pages from it.
pPageSelection = pSlideSorter->GetPageSelection();
}
if( (pSlideSorter == nullptr) || !pPageSelection || pPageSelection->empty() )
{ // No valid slide sorter available. Ask the main view shell for // its current page.
pPageSelection = std::make_shared<::sd::slidesorter::SlideSorterViewShell::PageSelection>();
pPageSelection->push_back(pMainViewShell->GetActualPage());
}
if (pPageSelection->empty()) break;
for (constauto& rpPage : *pPageSelection)
{ if (rpPage == nullptr) continue;
// Call the SID_ASSIGN_LAYOUT slot with all the necessary parameters.
SfxRequest aRequest(mrBase.GetViewFrame(), SID_ASSIGN_LAYOUT);
aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATPAGE, (rpPage->GetPageNum()-1)/2));
aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATLAYOUT, aLayout));
pMainViewShell->ExecuteSlot (aRequest, false);
}
} while(false);
}
// Get URL of the view in the center pane.
OUString sCenterPaneViewName; try
{ if (mrBase.GetDrawController())
{
Reference<XResourceId> xPaneId (ResourceId::create(
::comphelper::getProcessComponentContext(),
FrameworkHelper::msCenterPaneURL));
Reference<XView> xView (FrameworkHelper::Instance(mrBase)->GetView(xPaneId)); if (xView.is())
sCenterPaneViewName = xView->getResourceId()->getResourceURL();
}
} catch (RuntimeException&)
{}
void LayoutMenu::ShowContextMenu(const Point* pPos)
{ if (SdModule::get()->GetWaterCan()) return;
// Determine the position where to show the menu.
Point aMenuPosition; if (pPos)
{ auto nItemId = mxLayoutValueSet->GetItemId(*pPos); if (nItemId <= 0) return;
mxLayoutValueSet->SelectItem(nItemId);
aMenuPosition = *pPos;
} else
{ if (mxLayoutValueSet->GetSelectedItemId() == sal_uInt16(-1)) return;
::tools::Rectangle aBBox(mxLayoutValueSet->GetItemRect(mxLayoutValueSet->GetSelectedItemId()));
aMenuPosition = aBBox.Center();
}
// Disable the SID_INSERTPAGE_LAYOUT_MENU item when // the document is read-only.
SfxPoolItemHolder aResult; const SfxItemState aState (
mrBase.GetViewFrame().GetDispatcher()->QueryState(SID_INSERTPAGE, aResult)); if (aState == SfxItemState::DISABLED)
xMenu->set_sensitive(u"insert"_ustr, false);
// Show the menu.
OnMenuItemSelected(xMenu->popup_at_rect(pPopupParent, aRect));
}
void LayoutMenu::OnMenuItemSelected(std::u16string_view ident)
{ if (ident.empty()) return;
if (ident == u"apply")
{
AssignLayoutToSelectedSlides(GetSelectedAutoLayout());
} elseif (ident == u"insert")
{ // Add arguments to this slot and forward it to the main view // shell.
InsertPageWithLayout(GetSelectedAutoLayout());
}
}
// Selects an appropriate layout of the slide inside control. // // Method may be called several times with the same item-id to be selected - // only once the actually state of the control will be changed. // void LayoutMenu::UpdateSelection()
{ bool bItemSelected = false;
do
{ // Get current page of main view.
ViewShell* pViewShell = mrBase.GetMainViewShell().get(); if (pViewShell == nullptr) break;
SdPage* pCurrentPage = pViewShell->getCurrentPage(); if (pCurrentPage == nullptr) break;
// Get layout of current page.
AutoLayout aLayout (pCurrentPage->GetAutoLayout()); if (aLayout<AUTOLAYOUT_START || aLayout>AUTOLAYOUT_END) break;
// Find the entry of the menu for to the layout. const sal_uInt16 nItemCount = mxLayoutValueSet->GetItemCount(); for (sal_uInt16 nId=1; nId<=nItemCount; nId++)
{ if (*static_cast<AutoLayout*>(mxLayoutValueSet->GetItemData(nId)) == aLayout)
{ // do not set selection twice to the same item if (mxLayoutValueSet->GetSelectedItemId() != nId)
{
mxLayoutValueSet->SetNoSelection();
mxLayoutValueSet->SelectItem(nId);
}
bItemSelected = true; // no need to call SetNoSelection() break;
}
}
} while (false);
if (!bItemSelected)
mxLayoutValueSet->SetNoSelection();
}
IMPL_LINK(LayoutMenu, EventMultiplexerListener, ::sd::tools::EventMultiplexerEvent&, rEvent, void)
{ switch (rEvent.meEventId)
{ // tdf#89890 During changes of the Layout of the slide when focus is not set inside main area // we do not receive notification EventMultiplexerEventId::CurrentPageChanged, but we receive the following 3 notification types. // => let's make UpdateSelection() also when some shape is changed (during Layout changes) case EventMultiplexerEventId::ShapeChanged: case EventMultiplexerEventId::ShapeInserted: case EventMultiplexerEventId::ShapeRemoved: case EventMultiplexerEventId::CurrentPageChanged: case EventMultiplexerEventId::SlideSortedSelection:
UpdateSelection(); break;
case EventMultiplexerEventId::MainViewAdded:
mbIsMainViewChangePending = true; break;
case EventMultiplexerEventId::MainViewRemoved:
mxLayoutValueSet->Invalidate(); // redraw without focus break;
case EventMultiplexerEventId::ConfigurationUpdated: if (mbIsMainViewChangePending)
{
mbIsMainViewChangePending = false;
InvalidateContent();
} break;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.