27#include <osl/mutex.hxx>
39#include <officecfg/Office/Common.hxx>
48#define MAX_MENU_ITEMS 99
49#define MAX_MENU_ITEMS_PER_MODULE 5
53constexpr OUStringLiteral CMD_CLEAR_LIST =
u".uno:ClearRecentFileList";
54constexpr OUStringLiteral CMD_OPEN_AS_TEMPLATE =
u".uno:OpenTemplate";
55constexpr OUStringLiteral CMD_OPEN_REMOTE =
u".uno:OpenRemote";
57class RecentFilesMenuController :
public svt::PopupMenuControllerBase
59 using svt::PopupMenuControllerBase::disposing;
62 RecentFilesMenuController(
const uno::Reference< uno::XComponentContext >& xContext,
63 const uno::Sequence< uno::Any >&
args );
68 return "com.sun.star.comp.framework.RecentFilesMenuController";
78 return {
"com.sun.star.frame.PopupMenuController"};
82 virtual void SAL_CALL statusChanged(
const frame::FeatureStateEvent& Event )
override;
85 virtual void SAL_CALL
itemSelected(
const awt::MenuEvent& rEvent )
override;
86 virtual void SAL_CALL
itemActivated(
const awt::MenuEvent& rEvent )
override;
89 virtual uno::Reference< frame::XDispatch > SAL_CALL queryDispatch(
const util::URL&
aURL,
const OUString& sTarget, sal_Int32 nFlags )
override;
92 virtual void SAL_CALL dispatch(
const util::URL&
aURL,
const uno::Sequence< beans::PropertyValue >& seqProperties )
override;
95 virtual void SAL_CALL disposing(
const css::lang::EventObject&
Source )
override;
98 virtual void impl_setPopupMenu()
override;
99 void fillPopupMenu( css::uno::Reference< css::awt::XPopupMenu >
const & rPopupMenu );
100 void executeEntry( sal_Int32
nIndex );
102 std::vector<std::pair<OUString, bool>> m_aRecentFilesItems;
103 bool m_bDisabled : 1;
104 bool m_bShowToolbarEntries;
107RecentFilesMenuController::RecentFilesMenuController(
const uno::Reference< uno::XComponentContext >& xContext,
108 const uno::Sequence< uno::Any >&
args ) :
109 svt::PopupMenuControllerBase( xContext ),
110 m_bDisabled(
false ),
111 m_bShowToolbarEntries(
false )
113 css::beans::PropertyValue aPropValue;
117 if ( aPropValue.Name ==
"InToolbar" )
119 aPropValue.Value >>= m_bShowToolbarEntries;
125void InsertItem(
const css::uno::Reference<css::awt::XPopupMenu>& rPopupMenu,
126 const OUString& rCommand,
127 const css::uno::Reference<css::frame::XFrame>& rFrame)
129 sal_uInt16 nItemId = rPopupMenu->getItemCount() + 1;
139 rPopupMenu->insertItem(nItemId,
aLabel, 0, -1);
140 rPopupMenu->setItemImage(nItemId, xGraphic,
false);
141 rPopupMenu->setHelpText(nItemId, aTooltip);
144 rPopupMenu->insertItem(nItemId, OUString(), 0, -1);
146 rPopupMenu->setCommand(nItemId, rCommand);
155 resetPopupMenu( rPopupMenu );
159 int nPickListMenuItems = std::min<sal_Int32>( aHistoryList.size(),
MAX_MENU_ITEMS );
160 m_aRecentFilesItems.clear();
164 const bool bShowCurrentModuleOnly
165 = officecfg::Office::Common::History::ShowCurrentModuleOnly::get();
167 size_t nItemPosModule = 0;
168 size_t nItemPosPinned = 0;
169 if (( nPickListMenuItems > 0 ) && !m_bDisabled )
174 auto insertHistoryItemAtPos =
177 m_aRecentFilesItems.insert(m_aRecentFilesItems.begin() + aInsertPosition,
182 if (m_aModuleName !=
"com.sun.star.frame.StartModule")
189 for (
int i = 0;
i < nPickListMenuItems;
i++)
196 insertHistoryItemAtPos(rPickListEntry, nItemPosPinned);
201 else if ((bShowCurrentModuleOnly
206 insertHistoryItemAtPos(rPickListEntry, nItemPosModule);
210 else if (!bShowCurrentModuleOnly)
211 insertHistoryItemAtPos(rPickListEntry, nItemPos);
216 for (
int i = 0;
i < nPickListMenuItems;
i++)
220 insertHistoryItemAtPos(rPickListEntry,
221 rPickListEntry.
isPinned ? nItemPosModule++ : nItemPos);
226 if ( !m_aRecentFilesItems.empty() )
228 const sal_uInt32
nCount = m_aRecentFilesItems.size();
232 for ( sal_uInt32
i = 0;
i <
nCount;
i++ )
235 OUStringBuffer aMenuShortCut;
239 aMenuShortCut.append(
"1~0. " );
242 aMenuShortCut.append(
"~N. " );
248 aMenuShortCut.append( OUString::number(sal_Int32(
i + 1 ) ) +
". " );
251 OUString aURLString =
"vnd.sun.star.popup:RecentFileList?entry=" + OUString::number(
i);
256 OUString aTipHelpText(
aURL.getFSysPath( FSysStyle::Detect ) );
258 if (
aURL.GetProtocol() == INetProtocol::File )
269 aMenuShortCut.append( aMenuTitle );
271 rPopupMenu->insertItem(sal_uInt16(
i+1 ), aMenuShortCut.makeStringAndClear(), 0, -1);
273 if ( bIsIconsAllowed ) {
277 rPopupMenu->setItemImage(sal_uInt16(
i + 1),
Graphic(aThumbnail).GetXGraphic(),
false);
280 rPopupMenu->setTipHelpText(sal_uInt16(
i + 1), aTipHelpText);
281 rPopupMenu->setCommand(sal_uInt16(
i + 1), aURLString);
284 if (nItemPosPinned > 0 &&
i == nItemPosPinned - 1)
285 rPopupMenu->insertSeparator(-1);
288 if (nItemPosModule > 0 &&
i == nItemPosModule - 1)
289 rPopupMenu->insertSeparator(-1);
292 rPopupMenu->insertSeparator(-1);
294 rPopupMenu->insertItem(sal_uInt16(
nCount + 1),
FwkResId(STR_CLEAR_RECENT_FILES), 0, -1);
295 rPopupMenu->setCommand(sal_uInt16(
nCount + 1), CMD_CLEAR_LIST);
296 rPopupMenu->setHelpText(sal_uInt16(
nCount + 1),
FwkResId(STR_CLEAR_RECENT_FILES_HELP));
299 if ( m_bShowToolbarEntries )
301 rPopupMenu->insertSeparator(-1);
302 InsertItem(rPopupMenu, CMD_OPEN_AS_TEMPLATE,
m_xFrame);
303 InsertItem(rPopupMenu, CMD_OPEN_REMOTE,
m_xFrame);
308 if ( m_bShowToolbarEntries )
310 InsertItem(rPopupMenu, CMD_OPEN_AS_TEMPLATE,
m_xFrame);
311 InsertItem(rPopupMenu, CMD_OPEN_REMOTE,
m_xFrame);
317 rPopupMenu->insertSeparator(-1);
321 rPopupMenu->insertItem(1,
FwkResId(STR_NODOCUMENT),
static_cast<sal_Int16
>(MenuItemBits::NOSELECT), -1);
326void RecentFilesMenuController::executeEntry( sal_Int32
nIndex )
329 (
nIndex >= sal::static_int_cast<sal_Int32>( m_aRecentFilesItems.size() )))
341 if (m_aRecentFilesItems[
nIndex].second)
343 aArgsList.realloc(aArgsList.size()+1);
350void SAL_CALL RecentFilesMenuController::disposing(
const EventObject& )
358 if ( m_xPopupMenu.is() )
360 m_xPopupMenu.clear();
364void SAL_CALL RecentFilesMenuController::statusChanged(
const FeatureStateEvent& Event )
367 m_bDisabled = !Event.IsEnabled;
370void SAL_CALL RecentFilesMenuController::itemSelected(
const css::awt::MenuEvent& rEvent )
376 xPopupMenu = m_xPopupMenu;
379 if ( !xPopupMenu.is() )
382 const OUString
aCommand( xPopupMenu->getCommand( rEvent.MenuId ) );
388 "vnd.org.libreoffice.recentdocs:ClearRecentFileList",
389 css::uno::Sequence< css::beans::PropertyValue >() );
391 else if (
aCommand == CMD_OPEN_REMOTE )
396 else if (
aCommand == CMD_OPEN_AS_TEMPLATE )
402 executeEntry( rEvent.MenuId-1 );
405void SAL_CALL RecentFilesMenuController::itemActivated(
const css::awt::MenuEvent& )
412void RecentFilesMenuController::impl_setPopupMenu()
414 if ( m_xPopupMenu.is() )
415 fillPopupMenu( m_xPopupMenu );
426 throwIfDisposed(aLock);
428 if (
aURL.Complete.startsWith( m_aBaseURL ) )
435void SAL_CALL RecentFilesMenuController::dispatch(
441 throwIfDisposed(aLock);
443 if ( !
aURL.Complete.startsWith( m_aBaseURL ) )
447 sal_Int32 nQueryPart =
aURL.Complete.indexOf(
'?', m_aBaseURL.getLength() );
448 if ( nQueryPart <= 0 )
451 static constexpr OUStringLiteral aEntryArgStr(
u"entry=" );
452 sal_Int32 nEntryArg =
aURL.Complete.indexOf( aEntryArgStr, nQueryPart );
453 sal_Int32 nEntryPos = nEntryArg + aEntryArgStr.getLength();
454 if (( nEntryArg <= 0 ) || ( nEntryPos >=
aURL.Complete.getLength() ))
457 sal_Int32 nAddArgs =
aURL.Complete.indexOf(
'&', nEntryPos );
458 std::u16string_view aEntryArg;
461 aEntryArg =
aURL.Complete.subView( nEntryPos );
463 aEntryArg =
aURL.Complete.subView( nEntryPos, nAddArgs-nEntryPos );
466 executeEntry( nEntry );
471extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
473 css::uno::XComponentContext *context,
474 css::uno::Sequence<css::uno::Any>
const &args)
476 return cppu::acquire(
new RecentFilesMenuController(context,
args));
PropertiesInfo aProperties
css::uno::Reference< css::lang::XComponent > m_xFrame
css::uno::Reference< css::frame::XDispatch > m_xDispatch
static const OUString & GetSchemeName(INetProtocol eTheScheme)
bool GetUseImagesInMenus() const
OUString GetDocServiceNameFromFilter(const OUString &aFilterName)
OUString FwkResId(TranslateId aId)
void SAL_CALL itemActivated(const css::awt::MenuEvent &rEvent) override
void SAL_CALL itemSelected(const css::awt::MenuEvent &rEvent) override
void Clear(EHistoryType eHistory)
std::vector< HistoryItem > GetList(EHistoryType eHistory)
bool dispatchCommand(const OUString &rCommand, const uno::Reference< css::frame::XFrame > &rFrame, const css::uno::Sequence< css::beans::PropertyValue > &rArguments, const uno::Reference< css::frame::XDispatchResultListener > &rListener)
Reference< XComponentContext > getProcessComponentContext()
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
constexpr OUStringLiteral first
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
Sequence< beans::PropertyValue > GetCommandProperties(const OUString &rsCommandName, const OUString &rsModuleName)
OUString GetTooltipForCommand(const OUString &rsCommandName, const css::uno::Sequence< css::beans::PropertyValue > &rProperties, const Reference< frame::XFrame > &rxFrame)
Reference< graphic::XGraphic > GetXGraphicForCommand(const OUString &rsCommandName, const Reference< frame::XFrame > &rxFrame, vcl::ImageType eImageType)
OUString GetModuleIdentifier(const Reference< frame::XFrame > &rxFrame)
OUString GetPopupLabelForCommand(const css::uno::Sequence< css::beans::PropertyValue > &rProperties)